Skip to content

Commit a01d896

Browse files
committed
Handle Windows network drives
1 parent 025e460 commit a01d896

File tree

6 files changed

+34
-23
lines changed

6 files changed

+34
-23
lines changed

deno.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
},
2727
"imports": {
2828
"is-what": "https://deno.land/x/is_what@v4.1.15/src/index.ts",
29-
"deno/": "https://deno.land/std@0.196.0/",
29+
"deno/": "https://deno.land/std@0.204.0/",
3030
"outdent": "https://deno.land/x/outdent@v0.8.0/mod.ts"
3131
}
3232
}

src/deps.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,17 @@ import * as outdent from "https://deno.land/x/outdent@v0.8.0/mod.ts"
88
export { outdent }
99

1010
// importing super specifically to reduce final npm bundle size
11-
import * as crypto from "https://deno.land/std@0.196.0/crypto/mod.ts"
12-
import { moveSync } from "https://deno.land/std@0.196.0/fs/move.ts"
13-
import { readLines } from "https://deno.land/std@0.196.0/io/read_lines.ts"
14-
import { writeAll } from "https://deno.land/std@0.196.0/streams/write_all.ts"
15-
import { parse as parseYaml } from "https://deno.land/std@0.196.0/yaml/parse.ts"
16-
import { SEP } from "https://deno.land/std@0.196.0/path/mod.ts"
11+
import * as crypto from "https://deno.land/std@0.204.0/crypto/mod.ts"
12+
import { moveSync } from "https://deno.land/std@0.204.0/fs/move.ts"
13+
import { readLines } from "https://deno.land/std@0.204.0/io/read_lines.ts"
14+
import { writeAll } from "https://deno.land/std@0.204.0/streams/write_all.ts"
15+
import { parse as parseYaml } from "https://deno.land/std@0.204.0/yaml/parse.ts"
16+
import { SEP } from "https://deno.land/std@0.204.0/path/mod.ts"
17+
import { fromFileUrl } from "https://deno.land/std@0.204.0/path/from_file_url.ts"
1718

1819
const streams = { writeAll }
1920
const io = { readLines }
2021
const fs = { moveSync }
21-
const deno = { readLines, crypto, fs, io, streams, parseYaml, SEP }
22+
const deno = { readLines, crypto, fs, io, streams, parseYaml, SEP, fromFileUrl }
2223

2324
export { deno }

src/hooks/useConfig.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { flatmap } from "../utils/misc.ts"
2+
import { deno } from "../deps.ts"
23
import host from "../utils/host.ts"
34
import Path from "../utils/Path.ts"
45

@@ -64,8 +65,7 @@ export function ConfigDefault(env = Deno.env.toObject()): Config {
6465

6566
function getv(): string | undefined {
6667
if (typeof Deno === 'undefined') {
67-
const url = new URL(import.meta.url)
68-
const path = new Path(url.pathname).parent().parent().parent().join("package.json")
68+
const path = new Path(deno.fromFileUrl(import.meta.url)).parent().parent().parent().join("package.json")
6969
const blob = Deno.readFileSync(path.string)
7070
const txt = new TextDecoder().decode(blob)
7171
const { version } = JSON.parse(txt)

src/hooks/useTestConfig.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import useConfig, { ConfigDefault } from "./useConfig.ts"
2+
import { fromFileUrl } from "deno/path/from_file_url.ts"
23
import Path from "../utils/Path.ts"
34

45
export function useBaseTestConfig(env?: Record<string, string>) {
@@ -31,11 +32,7 @@ export const srcroot = (() => {
3132
if (Path.cwd().parent().parent().join("fixtures").isDirectory()) {
3233
return Path.cwd().parent().parent()
3334
} else {
34-
let path = new URL(import.meta.url).pathname
35-
if (Deno.build.os == 'windows') {
36-
path = path.slice(1) // /D:/foo/bar -> D:/foo/bar
37-
}
38-
return new Path(path).parent().parent().parent()
35+
return new Path(fromFileUrl(import.meta.url)).parent().parent().parent()
3936
}
4037
})()
4138

src/utils/Path.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,13 +240,22 @@ Deno.test({
240240
assertEquals(p.string, "Y:\\")
241241
assertEquals(p.parent().string, "Y:\\")
242242
assertEquals(p.parent().parent().parent().string, "Y:\\")
243+
244+
const q = new Path("\\\\bar\\foo\\baz")
245+
246+
assertEquals(q.string, "\\\\bar\\foo\\baz")
247+
assertEquals(q.parent().string, "\\\\bar\\foo")
248+
assertEquals(q.parent().parent().parent().string, "\\\\bar\\foo") // the first path after the hostname is actually a root
243249
}
244250
})
245251

246252
Deno.test("join roots", () => {
247253
if (Deno.build.os == "windows") {
248254
assertEquals(new Path("C:\\foo").join("D:\\bar").string, "D:\\bar")
249255
assertEquals(new Path("C:").join("D:\\bar\baz").string, "D:\\bar\baz")
256+
257+
assertEquals(new Path("c:\\foo\bar").join("\\\\bar\\baz").string, "\\\\bar\\baz")
258+
250259
} else {
251260
assertEquals(new Path("/foo").join("/bar").string, "/bar")
252261
}

src/utils/Path.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,14 @@ export default class Path {
5959
if (!input.startsWith("/") && !input.startsWith("\\")) {
6060
throw new Error(`invalid absolute path: ${input}`)
6161
}
62-
//TODO shouldn’t be C: necessarily
63-
// should it be based on PWD or system default drive?
64-
// NOTE also: maybe we shouldn't do this anyway?
65-
input = `C:\\${input}`
62+
if (!input.startsWith('\\\\')) {
63+
// ^^ \\network\drive is valid path notation on windows
64+
65+
//TODO shouldn’t be C: necessarily
66+
// should it be based on PWD or system default drive?
67+
// NOTE also: maybe we shouldn't do this anyway?
68+
input = `C:\\${input}`
69+
}
6670
}
6771
input = input.replace(/\//g, '\\')
6872
} else if (input[0] != '/') {
@@ -72,10 +76,10 @@ export default class Path {
7276
this.string = normalize(input)
7377

7478
function normalize(path: string): string {
75-
const segments = path.split(SEP);
76-
const result = [];
79+
const segments = path.split(SEP)
80+
const result = []
7781

78-
const start = Deno.build.os == 'windows' ? (segments.shift() ?? 'C:') + '\\' : '/'
82+
const start = Deno.build.os == 'windows' ? (segments.shift() || '\\') + '\\' : '/'
7983

8084
for (const segment of segments) {
8185
if (segment === '..') {
@@ -151,7 +155,7 @@ export default class Path {
151155
return this
152156
}
153157
function isAbsolute(part: string) {
154-
if (Deno.build.os == 'windows' && part?.match(/^[a-zA-Z]:/)) {
158+
if (Deno.build.os == 'windows' && (part?.match(/^[a-zA-Z]:/) || part?.startsWith("\\\\"))) {
155159
return true
156160
} else {
157161
return part.startsWith('/')

0 commit comments

Comments
 (0)