diff options
Diffstat (limited to 'std/fs/path')
-rw-r--r-- | std/fs/path/README.md | 7 | ||||
-rw-r--r-- | std/fs/path/basename_test.ts | 76 | ||||
-rw-r--r-- | std/fs/path/constants.ts | 54 | ||||
-rw-r--r-- | std/fs/path/dirname_test.ts | 62 | ||||
-rw-r--r-- | std/fs/path/extname_test.ts | 90 | ||||
-rw-r--r-- | std/fs/path/interface.ts | 27 | ||||
-rw-r--r-- | std/fs/path/isabsolute_test.ts | 34 | ||||
-rw-r--r-- | std/fs/path/join_test.ts | 128 | ||||
-rw-r--r-- | std/fs/path/mod.ts | 25 | ||||
-rw-r--r-- | std/fs/path/parse_format_test.ts | 180 | ||||
-rw-r--r-- | std/fs/path/posix.ts | 422 | ||||
-rw-r--r-- | std/fs/path/relative_test.ts | 73 | ||||
-rw-r--r-- | std/fs/path/resolve_test.ts | 52 | ||||
-rw-r--r-- | std/fs/path/test.ts | 9 | ||||
-rw-r--r-- | std/fs/path/utils.ts | 116 | ||||
-rw-r--r-- | std/fs/path/win32.ts | 896 | ||||
-rw-r--r-- | std/fs/path/zero_length_strings_test.ts | 49 |
17 files changed, 0 insertions, 2300 deletions
diff --git a/std/fs/path/README.md b/std/fs/path/README.md deleted file mode 100644 index 93d268aa7..000000000 --- a/std/fs/path/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Deno Path Manipulation Libraries - -Usage: - -```ts -import * as path from "https://deno.land/std/fs/path.ts"; -``` diff --git a/std/fs/path/basename_test.ts b/std/fs/path/basename_test.ts deleted file mode 100644 index f7770d1ca..000000000 --- a/std/fs/path/basename_test.ts +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright the Browserify authors. MIT License. -// Ported from https://github.com/browserify/path-browserify/ - -import { test } from "../../testing/mod.ts"; -import { assertEquals } from "../../testing/asserts.ts"; -import * as path from "./mod.ts"; - -test(function basename() { - assertEquals(path.basename(".js", ".js"), ""); - assertEquals(path.basename(""), ""); - assertEquals(path.basename("/dir/basename.ext"), "basename.ext"); - assertEquals(path.basename("/basename.ext"), "basename.ext"); - assertEquals(path.basename("basename.ext"), "basename.ext"); - assertEquals(path.basename("basename.ext/"), "basename.ext"); - assertEquals(path.basename("basename.ext//"), "basename.ext"); - assertEquals(path.basename("aaa/bbb", "/bbb"), "bbb"); - assertEquals(path.basename("aaa/bbb", "a/bbb"), "bbb"); - assertEquals(path.basename("aaa/bbb", "bbb"), "bbb"); - assertEquals(path.basename("aaa/bbb//", "bbb"), "bbb"); - assertEquals(path.basename("aaa/bbb", "bb"), "b"); - assertEquals(path.basename("aaa/bbb", "b"), "bb"); - assertEquals(path.basename("/aaa/bbb", "/bbb"), "bbb"); - assertEquals(path.basename("/aaa/bbb", "a/bbb"), "bbb"); - assertEquals(path.basename("/aaa/bbb", "bbb"), "bbb"); - assertEquals(path.basename("/aaa/bbb//", "bbb"), "bbb"); - assertEquals(path.basename("/aaa/bbb", "bb"), "b"); - assertEquals(path.basename("/aaa/bbb", "b"), "bb"); - assertEquals(path.basename("/aaa/bbb"), "bbb"); - assertEquals(path.basename("/aaa/"), "aaa"); - assertEquals(path.basename("/aaa/b"), "b"); - assertEquals(path.basename("/a/b"), "b"); - assertEquals(path.basename("//a"), "a"); - - // On unix a backslash is just treated as any other character. - assertEquals( - path.posix.basename("\\dir\\basename.ext"), - "\\dir\\basename.ext" - ); - assertEquals(path.posix.basename("\\basename.ext"), "\\basename.ext"); - assertEquals(path.posix.basename("basename.ext"), "basename.ext"); - assertEquals(path.posix.basename("basename.ext\\"), "basename.ext\\"); - assertEquals(path.posix.basename("basename.ext\\\\"), "basename.ext\\\\"); - assertEquals(path.posix.basename("foo"), "foo"); - - // POSIX filenames may include control characters - const controlCharFilename = "Icon" + String.fromCharCode(13); - assertEquals( - path.posix.basename("/a/b/" + controlCharFilename), - controlCharFilename - ); -}); - -test(function basenameWin32() { - assertEquals(path.win32.basename("\\dir\\basename.ext"), "basename.ext"); - assertEquals(path.win32.basename("\\basename.ext"), "basename.ext"); - assertEquals(path.win32.basename("basename.ext"), "basename.ext"); - assertEquals(path.win32.basename("basename.ext\\"), "basename.ext"); - assertEquals(path.win32.basename("basename.ext\\\\"), "basename.ext"); - assertEquals(path.win32.basename("foo"), "foo"); - assertEquals(path.win32.basename("aaa\\bbb", "\\bbb"), "bbb"); - assertEquals(path.win32.basename("aaa\\bbb", "a\\bbb"), "bbb"); - assertEquals(path.win32.basename("aaa\\bbb", "bbb"), "bbb"); - assertEquals(path.win32.basename("aaa\\bbb\\\\\\\\", "bbb"), "bbb"); - assertEquals(path.win32.basename("aaa\\bbb", "bb"), "b"); - assertEquals(path.win32.basename("aaa\\bbb", "b"), "bb"); - assertEquals(path.win32.basename("C:"), ""); - assertEquals(path.win32.basename("C:."), "."); - assertEquals(path.win32.basename("C:\\"), ""); - assertEquals(path.win32.basename("C:\\dir\\base.ext"), "base.ext"); - assertEquals(path.win32.basename("C:\\basename.ext"), "basename.ext"); - assertEquals(path.win32.basename("C:basename.ext"), "basename.ext"); - assertEquals(path.win32.basename("C:basename.ext\\"), "basename.ext"); - assertEquals(path.win32.basename("C:basename.ext\\\\"), "basename.ext"); - assertEquals(path.win32.basename("C:foo"), "foo"); - assertEquals(path.win32.basename("file:stream"), "file:stream"); -}); diff --git a/std/fs/path/constants.ts b/std/fs/path/constants.ts deleted file mode 100644 index 1e1eeeb49..000000000 --- a/std/fs/path/constants.ts +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright the Browserify authors. MIT License. -// Ported from https://github.com/browserify/path-browserify/ - -const { build } = Deno; - -// Alphabet chars. -export const CHAR_UPPERCASE_A = 65; /* A */ -export const CHAR_LOWERCASE_A = 97; /* a */ -export const CHAR_UPPERCASE_Z = 90; /* Z */ -export const CHAR_LOWERCASE_Z = 122; /* z */ - -// Non-alphabetic chars. -export const CHAR_DOT = 46; /* . */ -export const CHAR_FORWARD_SLASH = 47; /* / */ -export const CHAR_BACKWARD_SLASH = 92; /* \ */ -export const CHAR_VERTICAL_LINE = 124; /* | */ -export const CHAR_COLON = 58; /* : */ -export const CHAR_QUESTION_MARK = 63; /* ? */ -export const CHAR_UNDERSCORE = 95; /* _ */ -export const CHAR_LINE_FEED = 10; /* \n */ -export const CHAR_CARRIAGE_RETURN = 13; /* \r */ -export const CHAR_TAB = 9; /* \t */ -export const CHAR_FORM_FEED = 12; /* \f */ -export const CHAR_EXCLAMATION_MARK = 33; /* ! */ -export const CHAR_HASH = 35; /* # */ -export const CHAR_SPACE = 32; /* */ -export const CHAR_NO_BREAK_SPACE = 160; /* \u00A0 */ -export const CHAR_ZERO_WIDTH_NOBREAK_SPACE = 65279; /* \uFEFF */ -export const CHAR_LEFT_SQUARE_BRACKET = 91; /* [ */ -export const CHAR_RIGHT_SQUARE_BRACKET = 93; /* ] */ -export const CHAR_LEFT_ANGLE_BRACKET = 60; /* < */ -export const CHAR_RIGHT_ANGLE_BRACKET = 62; /* > */ -export const CHAR_LEFT_CURLY_BRACKET = 123; /* { */ -export const CHAR_RIGHT_CURLY_BRACKET = 125; /* } */ -export const CHAR_HYPHEN_MINUS = 45; /* - */ -export const CHAR_PLUS = 43; /* + */ -export const CHAR_DOUBLE_QUOTE = 34; /* " */ -export const CHAR_SINGLE_QUOTE = 39; /* ' */ -export const CHAR_PERCENT = 37; /* % */ -export const CHAR_SEMICOLON = 59; /* ; */ -export const CHAR_CIRCUMFLEX_ACCENT = 94; /* ^ */ -export const CHAR_GRAVE_ACCENT = 96; /* ` */ -export const CHAR_AT = 64; /* @ */ -export const CHAR_AMPERSAND = 38; /* & */ -export const CHAR_EQUAL = 61; /* = */ - -// Digits -export const CHAR_0 = 48; /* 0 */ -export const CHAR_9 = 57; /* 9 */ - -export const isWindows = build.os === "win"; -export const EOL = isWindows ? "\r\n" : "\n"; -export const SEP = isWindows ? "\\" : "/"; -export const SEP_PATTERN = isWindows ? /[\\/]+/ : /\/+/; diff --git a/std/fs/path/dirname_test.ts b/std/fs/path/dirname_test.ts deleted file mode 100644 index 047d4859b..000000000 --- a/std/fs/path/dirname_test.ts +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright the Browserify authors. MIT License. -// Ported from https://github.com/browserify/path-browserify/ - -import { test } from "../../testing/mod.ts"; -import { assertEquals } from "../../testing/asserts.ts"; -import * as path from "./mod.ts"; - -test(function dirname() { - assertEquals(path.posix.dirname("/a/b/"), "/a"); - assertEquals(path.posix.dirname("/a/b"), "/a"); - assertEquals(path.posix.dirname("/a"), "/"); - assertEquals(path.posix.dirname(""), "."); - assertEquals(path.posix.dirname("/"), "/"); - assertEquals(path.posix.dirname("////"), "/"); - assertEquals(path.posix.dirname("//a"), "//"); - assertEquals(path.posix.dirname("foo"), "."); -}); - -test(function dirnameWin32() { - assertEquals(path.win32.dirname("c:\\"), "c:\\"); - assertEquals(path.win32.dirname("c:\\foo"), "c:\\"); - assertEquals(path.win32.dirname("c:\\foo\\"), "c:\\"); - assertEquals(path.win32.dirname("c:\\foo\\bar"), "c:\\foo"); - assertEquals(path.win32.dirname("c:\\foo\\bar\\"), "c:\\foo"); - assertEquals(path.win32.dirname("c:\\foo\\bar\\baz"), "c:\\foo\\bar"); - assertEquals(path.win32.dirname("\\"), "\\"); - assertEquals(path.win32.dirname("\\foo"), "\\"); - assertEquals(path.win32.dirname("\\foo\\"), "\\"); - assertEquals(path.win32.dirname("\\foo\\bar"), "\\foo"); - assertEquals(path.win32.dirname("\\foo\\bar\\"), "\\foo"); - assertEquals(path.win32.dirname("\\foo\\bar\\baz"), "\\foo\\bar"); - assertEquals(path.win32.dirname("c:"), "c:"); - assertEquals(path.win32.dirname("c:foo"), "c:"); - assertEquals(path.win32.dirname("c:foo\\"), "c:"); - assertEquals(path.win32.dirname("c:foo\\bar"), "c:foo"); - assertEquals(path.win32.dirname("c:foo\\bar\\"), "c:foo"); - assertEquals(path.win32.dirname("c:foo\\bar\\baz"), "c:foo\\bar"); - assertEquals(path.win32.dirname("file:stream"), "."); - assertEquals(path.win32.dirname("dir\\file:stream"), "dir"); - assertEquals(path.win32.dirname("\\\\unc\\share"), "\\\\unc\\share"); - assertEquals(path.win32.dirname("\\\\unc\\share\\foo"), "\\\\unc\\share\\"); - assertEquals(path.win32.dirname("\\\\unc\\share\\foo\\"), "\\\\unc\\share\\"); - assertEquals( - path.win32.dirname("\\\\unc\\share\\foo\\bar"), - "\\\\unc\\share\\foo" - ); - assertEquals( - path.win32.dirname("\\\\unc\\share\\foo\\bar\\"), - "\\\\unc\\share\\foo" - ); - assertEquals( - path.win32.dirname("\\\\unc\\share\\foo\\bar\\baz"), - "\\\\unc\\share\\foo\\bar" - ); - assertEquals(path.win32.dirname("/a/b/"), "/a"); - assertEquals(path.win32.dirname("/a/b"), "/a"); - assertEquals(path.win32.dirname("/a"), "/"); - assertEquals(path.win32.dirname(""), "."); - assertEquals(path.win32.dirname("/"), "/"); - assertEquals(path.win32.dirname("////"), "/"); - assertEquals(path.win32.dirname("foo"), "."); -}); diff --git a/std/fs/path/extname_test.ts b/std/fs/path/extname_test.ts deleted file mode 100644 index 336d6b0b2..000000000 --- a/std/fs/path/extname_test.ts +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright the Browserify authors. MIT License. -// Ported from https://github.com/browserify/path-browserify/ - -import { test } from "../../testing/mod.ts"; -import { assertEquals } from "../../testing/asserts.ts"; -import * as path from "./mod.ts"; - -const slashRE = /\//g; - -const pairs = [ - ["", ""], - ["/path/to/file", ""], - ["/path/to/file.ext", ".ext"], - ["/path.to/file.ext", ".ext"], - ["/path.to/file", ""], - ["/path.to/.file", ""], - ["/path.to/.file.ext", ".ext"], - ["/path/to/f.ext", ".ext"], - ["/path/to/..ext", ".ext"], - ["/path/to/..", ""], - ["file", ""], - ["file.ext", ".ext"], - [".file", ""], - [".file.ext", ".ext"], - ["/file", ""], - ["/file.ext", ".ext"], - ["/.file", ""], - ["/.file.ext", ".ext"], - [".path/file.ext", ".ext"], - ["file.ext.ext", ".ext"], - ["file.", "."], - [".", ""], - ["./", ""], - [".file.ext", ".ext"], - [".file", ""], - [".file.", "."], - [".file..", "."], - ["..", ""], - ["../", ""], - ["..file.ext", ".ext"], - ["..file", ".file"], - ["..file.", "."], - ["..file..", "."], - ["...", "."], - ["...ext", ".ext"], - ["....", "."], - ["file.ext/", ".ext"], - ["file.ext//", ".ext"], - ["file/", ""], - ["file//", ""], - ["file./", "."], - ["file.//", "."] -]; - -test(function extname() { - pairs.forEach(function(p) { - const input = p[0]; - const expected = p[1]; - assertEquals(expected, path.posix.extname(input)); - }); - - // On *nix, backslash is a valid name component like any other character. - assertEquals(path.posix.extname(".\\"), ""); - assertEquals(path.posix.extname("..\\"), ".\\"); - assertEquals(path.posix.extname("file.ext\\"), ".ext\\"); - assertEquals(path.posix.extname("file.ext\\\\"), ".ext\\\\"); - assertEquals(path.posix.extname("file\\"), ""); - assertEquals(path.posix.extname("file\\\\"), ""); - assertEquals(path.posix.extname("file.\\"), ".\\"); - assertEquals(path.posix.extname("file.\\\\"), ".\\\\"); -}); - -test(function extnameWin32() { - pairs.forEach(function(p) { - const input = p[0].replace(slashRE, "\\"); - const expected = p[1]; - assertEquals(expected, path.win32.extname(input)); - assertEquals(expected, path.win32.extname("C:" + input)); - }); - - // On Windows, backslash is a path separator. - assertEquals(path.win32.extname(".\\"), ""); - assertEquals(path.win32.extname("..\\"), ""); - assertEquals(path.win32.extname("file.ext\\"), ".ext"); - assertEquals(path.win32.extname("file.ext\\\\"), ".ext"); - assertEquals(path.win32.extname("file\\"), ""); - assertEquals(path.win32.extname("file\\\\"), ""); - assertEquals(path.win32.extname("file.\\"), "."); - assertEquals(path.win32.extname("file.\\\\"), "."); -}); diff --git a/std/fs/path/interface.ts b/std/fs/path/interface.ts deleted file mode 100644 index b31c89ea7..000000000 --- a/std/fs/path/interface.ts +++ /dev/null @@ -1,27 +0,0 @@ -/** - * A parsed path object generated by path.parse() or consumed by path.format(). - */ -export interface ParsedPath { - /** - * The root of the path such as '/' or 'c:\' - */ - root: string; - /** - * The full directory path such as '/home/user/dir' or 'c:\path\dir' - */ - dir: string; - /** - * The file name including extension (if any) such as 'index.html' - */ - base: string; - /** - * The file extension (if any) such as '.html' - */ - ext: string; - /** - * The file name without extension (if any) such as 'index' - */ - name: string; -} - -export type FormatInputPathObject = Partial<ParsedPath>; diff --git a/std/fs/path/isabsolute_test.ts b/std/fs/path/isabsolute_test.ts deleted file mode 100644 index 87218a185..000000000 --- a/std/fs/path/isabsolute_test.ts +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright the Browserify authors. MIT License. -// Ported from https://github.com/browserify/path-browserify/ - -import { test } from "../../testing/mod.ts"; -import { assertEquals } from "../../testing/asserts.ts"; -import * as path from "./mod.ts"; - -test(function isAbsolute() { - assertEquals(path.posix.isAbsolute("/home/foo"), true); - assertEquals(path.posix.isAbsolute("/home/foo/.."), true); - assertEquals(path.posix.isAbsolute("bar/"), false); - assertEquals(path.posix.isAbsolute("./baz"), false); -}); - -test(function isAbsoluteWin32() { - assertEquals(path.win32.isAbsolute("/"), true); - assertEquals(path.win32.isAbsolute("//"), true); - assertEquals(path.win32.isAbsolute("//server"), true); - assertEquals(path.win32.isAbsolute("//server/file"), true); - assertEquals(path.win32.isAbsolute("\\\\server\\file"), true); - assertEquals(path.win32.isAbsolute("\\\\server"), true); - assertEquals(path.win32.isAbsolute("\\\\"), true); - assertEquals(path.win32.isAbsolute("c"), false); - assertEquals(path.win32.isAbsolute("c:"), false); - assertEquals(path.win32.isAbsolute("c:\\"), true); - assertEquals(path.win32.isAbsolute("c:/"), true); - assertEquals(path.win32.isAbsolute("c://"), true); - assertEquals(path.win32.isAbsolute("C:/Users/"), true); - assertEquals(path.win32.isAbsolute("C:\\Users\\"), true); - assertEquals(path.win32.isAbsolute("C:cwd/another"), false); - assertEquals(path.win32.isAbsolute("C:cwd\\another"), false); - assertEquals(path.win32.isAbsolute("directory/directory"), false); - assertEquals(path.win32.isAbsolute("directory\\directory"), false); -}); diff --git a/std/fs/path/join_test.ts b/std/fs/path/join_test.ts deleted file mode 100644 index 2c0f35e48..000000000 --- a/std/fs/path/join_test.ts +++ /dev/null @@ -1,128 +0,0 @@ -import { test } from "../../testing/mod.ts"; -import { assertEquals } from "../../testing/asserts.ts"; -import * as path from "./mod.ts"; - -const backslashRE = /\\/g; - -const joinTests = - // arguments result - [ - [[".", "x/b", "..", "/b/c.js"], "x/b/c.js"], - [[], "."], - [["/.", "x/b", "..", "/b/c.js"], "/x/b/c.js"], - [["/foo", "../../../bar"], "/bar"], - [["foo", "../../../bar"], "../../bar"], - [["foo/", "../../../bar"], "../../bar"], - [["foo/x", "../../../bar"], "../bar"], - [["foo/x", "./bar"], "foo/x/bar"], - [["foo/x/", "./bar"], "foo/x/bar"], - [["foo/x/", ".", "bar"], "foo/x/bar"], - [["./"], "./"], - [[".", "./"], "./"], - [[".", ".", "."], "."], - [[".", "./", "."], "."], - [[".", "/./", "."], "."], - [[".", "/////./", "."], "."], - [["."], "."], - [["", "."], "."], - [["", "foo"], "foo"], - [["foo", "/bar"], "foo/bar"], - [["", "/foo"], "/foo"], - [["", "", "/foo"], "/foo"], - [["", "", "foo"], "foo"], - [["foo", ""], "foo"], - [["foo/", ""], "foo/"], - [["foo", "", "/bar"], "foo/bar"], - [["./", "..", "/foo"], "../foo"], - [["./", "..", "..", "/foo"], "../../foo"], - [[".", "..", "..", "/foo"], "../../foo"], - [["", "..", "..", "/foo"], "../../foo"], - [["/"], "/"], - [["/", "."], "/"], - [["/", ".."], "/"], - [["/", "..", ".."], "/"], - [[""], "."], - [["", ""], "."], - [[" /foo"], " /foo"], - [[" ", "foo"], " /foo"], - [[" ", "."], " "], - [[" ", "/"], " /"], - [[" ", ""], " "], - [["/", "foo"], "/foo"], - [["/", "/foo"], "/foo"], - [["/", "//foo"], "/foo"], - [["/", "", "/foo"], "/foo"], - [["", "/", "foo"], "/foo"], - [["", "/", "/foo"], "/foo"] - ]; - -// Windows-specific join tests -const windowsJoinTests = [ - // arguments result - // UNC path expected - [["//foo/bar"], "\\\\foo\\bar\\"], - [["\\/foo/bar"], "\\\\foo\\bar\\"], - [["\\\\foo/bar"], "\\\\foo\\bar\\"], - // UNC path expected - server and share separate - [["//foo", "bar"], "\\\\foo\\bar\\"], - [["//foo/", "bar"], "\\\\foo\\bar\\"], - [["//foo", "/bar"], "\\\\foo\\bar\\"], - // UNC path expected - questionable - [["//foo", "", "bar"], "\\\\foo\\bar\\"], - [["//foo/", "", "bar"], "\\\\foo\\bar\\"], - [["//foo/", "", "/bar"], "\\\\foo\\bar\\"], - // UNC path expected - even more questionable - [["", "//foo", "bar"], "\\\\foo\\bar\\"], - [["", "//foo/", "bar"], "\\\\foo\\bar\\"], - [["", "//foo/", "/bar"], "\\\\foo\\bar\\"], - // No UNC path expected (no double slash in first component) - [["\\", "foo/bar"], "\\foo\\bar"], - [["\\", "/foo/bar"], "\\foo\\bar"], - [["", "/", "/foo/bar"], "\\foo\\bar"], - // No UNC path expected (no non-slashes in first component - - // questionable) - [["//", "foo/bar"], "\\foo\\bar"], - [["//", "/foo/bar"], "\\foo\\bar"], - [["\\\\", "/", "/foo/bar"], "\\foo\\bar"], - [["//"], "\\"], - // No UNC path expected (share name missing - questionable). - [["//foo"], "\\foo"], - [["//foo/"], "\\foo\\"], - [["//foo", "/"], "\\foo\\"], - [["//foo", "", "/"], "\\foo\\"], - // No UNC path expected (too many leading slashes - questionable) - [["///foo/bar"], "\\foo\\bar"], - [["////foo", "bar"], "\\foo\\bar"], - [["\\\\\\/foo/bar"], "\\foo\\bar"], - // Drive-relative vs drive-absolute paths. This merely describes the - // status quo, rather than being obviously right - [["c:"], "c:."], - [["c:."], "c:."], - [["c:", ""], "c:."], - [["", "c:"], "c:."], - [["c:.", "/"], "c:.\\"], - [["c:.", "file"], "c:file"], - [["c:", "/"], "c:\\"], - [["c:", "file"], "c:\\file"] -]; - -test(function join() { - joinTests.forEach(function(p) { - const _p = p[0] as string[]; - const actual = path.posix.join.apply(null, _p); - assertEquals(actual, p[1]); - }); -}); - -test(function joinWin32() { - joinTests.forEach(function(p) { - const _p = p[0] as string[]; - const actual = path.win32.join.apply(null, _p).replace(backslashRE, "/"); - assertEquals(actual, p[1]); - }); - windowsJoinTests.forEach(function(p) { - const _p = p[0] as string[]; - const actual = path.win32.join.apply(null, _p); - assertEquals(actual, p[1]); - }); -}); diff --git a/std/fs/path/mod.ts b/std/fs/path/mod.ts deleted file mode 100644 index 660c061d6..000000000 --- a/std/fs/path/mod.ts +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright the Browserify authors. MIT License. -// Ported from https://github.com/browserify/path-browserify/ - -import * as _win32 from "./win32.ts"; -import * as _posix from "./posix.ts"; - -import { isWindows } from "./constants.ts"; - -const path = isWindows ? _win32 : _posix; - -export const win32 = _win32; -export const posix = _posix; -export const resolve = path.resolve; -export const normalize = path.normalize; -export const isAbsolute = path.isAbsolute; -export const join = path.join; -export const relative = path.relative; -export const toNamespacedPath = path.toNamespacedPath; -export const dirname = path.dirname; -export const basename = path.basename; -export const extname = path.extname; -export const format = path.format; -export const parse = path.parse; -export const sep = path.sep; -export const delimiter = path.delimiter; diff --git a/std/fs/path/parse_format_test.ts b/std/fs/path/parse_format_test.ts deleted file mode 100644 index db83c3354..000000000 --- a/std/fs/path/parse_format_test.ts +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright the Browserify authors. MIT License. -// Ported from https://github.com/browserify/path-browserify/ -/* eslint-disable @typescript-eslint/no-explicit-any */ -// TODO(kt3k): fix any types in this file - -import { test } from "../../testing/mod.ts"; -import { assertEquals } from "../../testing/asserts.ts"; -import * as path from "./mod.ts"; - -const winPaths = [ - // [path, root] - ["C:\\path\\dir\\index.html", "C:\\"], - ["C:\\another_path\\DIR\\1\\2\\33\\\\index", "C:\\"], - ["another_path\\DIR with spaces\\1\\2\\33\\index", ""], - ["\\", "\\"], - ["\\foo\\C:", "\\"], - ["file", ""], - ["file:stream", ""], - [".\\file", ""], - ["C:", "C:"], - ["C:.", "C:"], - ["C:..", "C:"], - ["C:abc", "C:"], - ["C:\\", "C:\\"], - ["C:\\abc", "C:\\"], - ["", ""], - - // unc - ["\\\\server\\share\\file_path", "\\\\server\\share\\"], - [ - "\\\\server two\\shared folder\\file path.zip", - "\\\\server two\\shared folder\\" - ], - ["\\\\teela\\admin$\\system32", "\\\\teela\\admin$\\"], - ["\\\\?\\UNC\\server\\share", "\\\\?\\UNC\\"] -]; - -const winSpecialCaseParseTests = [["/foo/bar", { root: "/" }]]; - -const winSpecialCaseFormatTests = [ - [{ dir: "some\\dir" }, "some\\dir\\"], - [{ base: "index.html" }, "index.html"], - [{ root: "C:\\" }, "C:\\"], - [{ name: "index", ext: ".html" }, "index.html"], - [{ dir: "some\\dir", name: "index", ext: ".html" }, "some\\dir\\index.html"], - [{ root: "C:\\", name: "index", ext: ".html" }, "C:\\index.html"], - [{}, ""] -]; - -const unixPaths = [ - // [path, root] - ["/home/user/dir/file.txt", "/"], - ["/home/user/a dir/another File.zip", "/"], - ["/home/user/a dir//another&File.", "/"], - ["/home/user/a$$$dir//another File.zip", "/"], - ["user/dir/another File.zip", ""], - ["file", ""], - [".\\file", ""], - ["./file", ""], - ["C:\\foo", ""], - ["/", "/"], - ["", ""], - [".", ""], - ["..", ""], - ["/foo", "/"], - ["/foo.", "/"], - ["/foo.bar", "/"], - ["/.", "/"], - ["/.foo", "/"], - ["/.foo.bar", "/"], - ["/foo/bar.baz", "/"] -]; - -const unixSpecialCaseFormatTests = [ - [{ dir: "some/dir" }, "some/dir/"], - [{ base: "index.html" }, "index.html"], - [{ root: "/" }, "/"], - [{ name: "index", ext: ".html" }, "index.html"], - [{ dir: "some/dir", name: "index", ext: ".html" }, "some/dir/index.html"], - [{ root: "/", name: "index", ext: ".html" }, "/index.html"], - [{}, ""] -]; - -function checkParseFormat(path: any, paths: any): void { - paths.forEach(function(p: Array<Record<string, unknown>>) { - const element = p[0]; - const output = path.parse(element); - assertEquals(typeof output.root, "string"); - assertEquals(typeof output.dir, "string"); - assertEquals(typeof output.base, "string"); - assertEquals(typeof output.ext, "string"); - assertEquals(typeof output.name, "string"); - assertEquals(path.format(output), element); - assertEquals(output.rooroot, undefined); - assertEquals(output.dir, output.dir ? path.dirname(element) : ""); - assertEquals(output.base, path.basename(element)); - }); -} - -function checkSpecialCaseParseFormat(path: any, testCases: any): void { - testCases.forEach(function(testCase: Array<Record<string, unknown>>) { - const element = testCase[0]; - const expect = testCase[1]; - const output = path.parse(element); - Object.keys(expect).forEach(function(key) { - assertEquals(output[key], expect[key]); - }); - }); -} - -function checkFormat(path: any, testCases: unknown[][]): void { - testCases.forEach(function(testCase) { - assertEquals(path.format(testCase[0]), testCase[1]); - }); -} - -test(function parseWin32() { - checkParseFormat(path.win32, winPaths); - checkSpecialCaseParseFormat(path.win32, winSpecialCaseParseTests); -}); - -test(function parse() { - checkParseFormat(path.posix, unixPaths); -}); - -test(function formatWin32() { - checkFormat(path.win32, winSpecialCaseFormatTests); -}); - -test(function format() { - checkFormat(path.posix, unixSpecialCaseFormatTests); -}); - -// Test removal of trailing path separators -const windowsTrailingTests = [ - [".\\", { root: "", dir: "", base: ".", ext: "", name: "." }], - ["\\\\", { root: "\\", dir: "\\", base: "", ext: "", name: "" }], - ["\\\\", { root: "\\", dir: "\\", base: "", ext: "", name: "" }], - [ - "c:\\foo\\\\\\", - { root: "c:\\", dir: "c:\\", base: "foo", ext: "", name: "foo" } - ], - [ - "D:\\foo\\\\\\bar.baz", - { - root: "D:\\", - dir: "D:\\foo\\\\", - base: "bar.baz", - ext: ".baz", - name: "bar" - } - ] -]; - -const posixTrailingTests = [ - ["./", { root: "", dir: "", base: ".", ext: "", name: "." }], - ["//", { root: "/", dir: "/", base: "", ext: "", name: "" }], - ["///", { root: "/", dir: "/", base: "", ext: "", name: "" }], - ["/foo///", { root: "/", dir: "/", base: "foo", ext: "", name: "foo" }], - [ - "/foo///bar.baz", - { root: "/", dir: "/foo//", base: "bar.baz", ext: ".baz", name: "bar" } - ] -]; - -test(function parseTrailingWin32() { - windowsTrailingTests.forEach(function(p) { - const actual = path.win32.parse(p[0] as string); - const expected = p[1]; - assertEquals(actual, expected); - }); -}); - -test(function parseTrailing() { - posixTrailingTests.forEach(function(p) { - const actual = path.posix.parse(p[0] as string); - const expected = p[1]; - assertEquals(actual, expected); - }); -}); diff --git a/std/fs/path/posix.ts b/std/fs/path/posix.ts deleted file mode 100644 index 4377fd542..000000000 --- a/std/fs/path/posix.ts +++ /dev/null @@ -1,422 +0,0 @@ -// Copyright the Browserify authors. MIT License. -// Ported from https://github.com/browserify/path-browserify/ - -const { cwd } = Deno; -import { FormatInputPathObject, ParsedPath } from "./interface.ts"; -import { CHAR_DOT, CHAR_FORWARD_SLASH } from "./constants.ts"; - -import { - assertPath, - normalizeString, - isPosixPathSeparator, - _format -} from "./utils.ts"; - -export const sep = "/"; -export const delimiter = ":"; - -// path.resolve([from ...], to) -export function resolve(...pathSegments: string[]): string { - let resolvedPath = ""; - let resolvedAbsolute = false; - - for (let i = pathSegments.length - 1; i >= -1 && !resolvedAbsolute; i--) { - let path: string; - - if (i >= 0) path = pathSegments[i]; - else path = cwd(); - - assertPath(path); - - // Skip empty entries - if (path.length === 0) { - continue; - } - - resolvedPath = `${path}/${resolvedPath}`; - resolvedAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH; - } - - // At this point the path should be resolved to a full absolute path, but - // handle relative paths to be safe (might happen when process.cwd() fails) - - // Normalize the path - resolvedPath = normalizeString( - resolvedPath, - !resolvedAbsolute, - "/", - isPosixPathSeparator - ); - - if (resolvedAbsolute) { - if (resolvedPath.length > 0) return `/${resolvedPath}`; - else return "/"; - } else if (resolvedPath.length > 0) return resolvedPath; - else return "."; -} - -export function normalize(path: string): string { - assertPath(path); - - if (path.length === 0) return "."; - - const isAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH; - const trailingSeparator = - path.charCodeAt(path.length - 1) === CHAR_FORWARD_SLASH; - - // Normalize the path - path = normalizeString(path, !isAbsolute, "/", isPosixPathSeparator); - - if (path.length === 0 && !isAbsolute) path = "."; - if (path.length > 0 && trailingSeparator) path += "/"; - - if (isAbsolute) return `/${path}`; - return path; -} - -export function isAbsolute(path: string): boolean { - assertPath(path); - return path.length > 0 && path.charCodeAt(0) === CHAR_FORWARD_SLASH; -} - -export function join(...paths: string[]): string { - if (paths.length === 0) return "."; - let joined: string | undefined; - for (let i = 0, len = paths.length; i < len; ++i) { - const path = paths[i]; - assertPath(path); - if (path.length > 0) { - if (!joined) joined = path; - else joined += `/${path}`; - } - } - if (!joined) return "."; - return normalize(joined); -} - -export function relative(from: string, to: string): string { - assertPath(from); - assertPath(to); - - if (from === to) return ""; - - from = resolve(from); - to = resolve(to); - - if (from === to) return ""; - - // Trim any leading backslashes - let fromStart = 1; - const fromEnd = from.length; - for (; fromStart < fromEnd; ++fromStart) { - if (from.charCodeAt(fromStart) !== CHAR_FORWARD_SLASH) break; - } - const fromLen = fromEnd - fromStart; - - // Trim any leading backslashes - let toStart = 1; - const toEnd = to.length; - for (; toStart < toEnd; ++toStart) { - if (to.charCodeAt(toStart) !== CHAR_FORWARD_SLASH) break; - } - const toLen = toEnd - toStart; - - // Compare paths to find the longest common path from root - const length = fromLen < toLen ? fromLen : toLen; - let lastCommonSep = -1; - let i = 0; - for (; i <= length; ++i) { - if (i === length) { - if (toLen > length) { - if (to.charCodeAt(toStart + i) === CHAR_FORWARD_SLASH) { - // We get here if `from` is the exact base path for `to`. - // For example: from='/foo/bar'; to='/foo/bar/baz' - return to.slice(toStart + i + 1); - } else if (i === 0) { - // We get here if `from` is the root - // For example: from='/'; to='/foo' - return to.slice(toStart + i); - } - } else if (fromLen > length) { - if (from.charCodeAt(fromStart + i) === CHAR_FORWARD_SLASH) { - // We get here if `to` is the exact base path for `from`. - // For example: from='/foo/bar/baz'; to='/foo/bar' - lastCommonSep = i; - } else if (i === 0) { - // We get here if `to` is the root. - // For example: from='/foo'; to='/' - lastCommonSep = 0; - } - } - break; - } - const fromCode = from.charCodeAt(fromStart + i); - const toCode = to.charCodeAt(toStart + i); - if (fromCode !== toCode) break; - else if (fromCode === CHAR_FORWARD_SLASH) lastCommonSep = i; - } - - let out = ""; - // Generate the relative path based on the path difference between `to` - // and `from` - for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) { - if (i === fromEnd || from.charCodeAt(i) === CHAR_FORWARD_SLASH) { - if (out.length === 0) out += ".."; - else out += "/.."; - } - } - - // Lastly, append the rest of the destination (`to`) path that comes after - // the common path parts - if (out.length > 0) return out + to.slice(toStart + lastCommonSep); - else { - toStart += lastCommonSep; - if (to.charCodeAt(toStart) === CHAR_FORWARD_SLASH) ++toStart; - return to.slice(toStart); - } -} - -export function toNamespacedPath(path: string): string { - // Non-op on posix systems - return path; -} - -export function dirname(path: string): string { - assertPath(path); - if (path.length === 0) return "."; - const hasRoot = path.charCodeAt(0) === CHAR_FORWARD_SLASH; - let end = -1; - let matchedSlash = true; - for (let i = path.length - 1; i >= 1; --i) { - if (path.charCodeAt(i) === CHAR_FORWARD_SLASH) { - if (!matchedSlash) { - end = i; - break; - } - } else { - // We saw the first non-path separator - matchedSlash = false; - } - } - - if (end === -1) return hasRoot ? "/" : "."; - if (hasRoot && end === 1) return "//"; - return path.slice(0, end); -} - -export function basename(path: string, ext = ""): string { - if (ext !== undefined && typeof ext !== "string") - throw new TypeError('"ext" argument must be a string'); - assertPath(path); - - let start = 0; - let end = -1; - let matchedSlash = true; - let i: number; - - if (ext !== undefined && ext.length > 0 && ext.length <= path.length) { - if (ext.length === path.length && ext === path) return ""; - let extIdx = ext.length - 1; - let firstNonSlashEnd = -1; - for (i = path.length - 1; i >= 0; --i) { - const code = path.charCodeAt(i); - if (code === CHAR_FORWARD_SLASH) { - // If we reached a path separator that was not part of a set of path - // separators at the end of the string, stop now - if (!matchedSlash) { - start = i + 1; - break; - } - } else { - if (firstNonSlashEnd === -1) { - // We saw the first non-path separator, remember this index in case - // we need it if the extension ends up not matching - matchedSlash = false; - firstNonSlashEnd = i + 1; - } - if (extIdx >= 0) { - // Try to match the explicit extension - if (code === ext.charCodeAt(extIdx)) { - if (--extIdx === -1) { - // We matched the extension, so mark this as the end of our path - // component - end = i; - } - } else { - // Extension does not match, so our result is the entire path - // component - extIdx = -1; - end = firstNonSlashEnd; - } - } - } - } - - if (start === end) end = firstNonSlashEnd; - else if (end === -1) end = path.length; - return path.slice(start, end); - } else { - for (i = path.length - 1; i >= 0; --i) { - if (path.charCodeAt(i) === CHAR_FORWARD_SLASH) { - // If we reached a path separator that was not part of a set of path - // separators at the end of the string, stop now - if (!matchedSlash) { - start = i + 1; - break; - } - } else if (end === -1) { - // We saw the first non-path separator, mark this as the end of our - // path component - matchedSlash = false; - end = i + 1; - } - } - - if (end === -1) return ""; - return path.slice(start, end); - } -} - -export function extname(path: string): string { - assertPath(path); - let startDot = -1; - let startPart = 0; - let end = -1; - let matchedSlash = true; - // Track the state of characters (if any) we see before our first dot and - // after any path separator we find - let preDotState = 0; - for (let i = path.length - 1; i >= 0; --i) { - const code = path.charCodeAt(i); - if (code === CHAR_FORWARD_SLASH) { - // If we reached a path separator that was not part of a set of path - // separators at the end of the string, stop now - if (!matchedSlash) { - startPart = i + 1; - break; - } - continue; - } - if (end === -1) { - // We saw the first non-path separator, mark this as the end of our - // extension - matchedSlash = false; - end = i + 1; - } - if (code === CHAR_DOT) { - // If this is our first dot, mark it as the start of our extension - if (startDot === -1) startDot = i; - else if (preDotState !== 1) preDotState = 1; - } else if (startDot !== -1) { - // We saw a non-dot and non-path separator before our dot, so we should - // have a good chance at having a non-empty extension - preDotState = -1; - } - } - - if ( - startDot === -1 || - end === -1 || - // We saw a non-dot character immediately before the dot - preDotState === 0 || - // The (right-most) trimmed path component is exactly '..' - (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) - ) { - return ""; - } - return path.slice(startDot, end); -} - -export function format(pathObject: FormatInputPathObject): string { - /* eslint-disable max-len */ - if (pathObject === null || typeof pathObject !== "object") { - throw new TypeError( - `The "pathObject" argument must be of type Object. Received type ${typeof pathObject}` - ); - } - return _format("/", pathObject); -} - -export function parse(path: string): ParsedPath { - assertPath(path); - - const ret: ParsedPath = { root: "", dir: "", base: "", ext: "", name: "" }; - if (path.length === 0) return ret; - const isAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH; - let start: number; - if (isAbsolute) { - ret.root = "/"; - start = 1; - } else { - start = 0; - } - let startDot = -1; - let startPart = 0; - let end = -1; - let matchedSlash = true; - let i = path.length - 1; - - // Track the state of characters (if any) we see before our first dot and - // after any path separator we find - let preDotState = 0; - - // Get non-dir info - for (; i >= start; --i) { - const code = path.charCodeAt(i); - if (code === CHAR_FORWARD_SLASH) { - // If we reached a path separator that was not part of a set of path - // separators at the end of the string, stop now - if (!matchedSlash) { - startPart = i + 1; - break; - } - continue; - } - if (end === -1) { - // We saw the first non-path separator, mark this as the end of our - // extension - matchedSlash = false; - end = i + 1; - } - if (code === CHAR_DOT) { - // If this is our first dot, mark it as the start of our extension - if (startDot === -1) startDot = i; - else if (preDotState !== 1) preDotState = 1; - } else if (startDot !== -1) { - // We saw a non-dot and non-path separator before our dot, so we should - // have a good chance at having a non-empty extension - preDotState = -1; - } - } - - if ( - startDot === -1 || - end === -1 || - // We saw a non-dot character immediately before the dot - preDotState === 0 || - // The (right-most) trimmed path component is exactly '..' - (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) - ) { - if (end !== -1) { - if (startPart === 0 && isAbsolute) { - ret.base = ret.name = path.slice(1, end); - } else { - ret.base = ret.name = path.slice(startPart, end); - } - } - } else { - if (startPart === 0 && isAbsolute) { - ret.name = path.slice(1, startDot); - ret.base = path.slice(1, end); - } else { - ret.name = path.slice(startPart, startDot); - ret.base = path.slice(startPart, end); - } - ret.ext = path.slice(startDot, end); - } - - if (startPart > 0) ret.dir = path.slice(0, startPart - 1); - else if (isAbsolute) ret.dir = "/"; - - return ret; -} diff --git a/std/fs/path/relative_test.ts b/std/fs/path/relative_test.ts deleted file mode 100644 index 0188b5368..000000000 --- a/std/fs/path/relative_test.ts +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright the Browserify authors. MIT License. -// Ported from https://github.com/browserify/path-browserify/ - -import { test } from "../../testing/mod.ts"; -import { assertEquals } from "../../testing/asserts.ts"; -import * as path from "./mod.ts"; - -const relativeTests = { - win32: - // arguments result - [ - ["c:/blah\\blah", "d:/games", "d:\\games"], - ["c:/aaaa/bbbb", "c:/aaaa", ".."], - ["c:/aaaa/bbbb", "c:/cccc", "..\\..\\cccc"], - ["c:/aaaa/bbbb", "c:/aaaa/bbbb", ""], - ["c:/aaaa/bbbb", "c:/aaaa/cccc", "..\\cccc"], - ["c:/aaaa/", "c:/aaaa/cccc", "cccc"], - ["c:/", "c:\\aaaa\\bbbb", "aaaa\\bbbb"], - ["c:/aaaa/bbbb", "d:\\", "d:\\"], - ["c:/AaAa/bbbb", "c:/aaaa/bbbb", ""], - ["c:/aaaaa/", "c:/aaaa/cccc", "..\\aaaa\\cccc"], - ["C:\\foo\\bar\\baz\\quux", "C:\\", "..\\..\\..\\.."], - [ - "C:\\foo\\test", - "C:\\foo\\test\\bar\\package.json", - "bar\\package.json" - ], - ["C:\\foo\\bar\\baz-quux", "C:\\foo\\bar\\baz", "..\\baz"], - ["C:\\foo\\bar\\baz", "C:\\foo\\bar\\baz-quux", "..\\baz-quux"], - ["\\\\foo\\bar", "\\\\foo\\bar\\baz", "baz"], - ["\\\\foo\\bar\\baz", "\\\\foo\\bar", ".."], - ["\\\\foo\\bar\\baz-quux", "\\\\foo\\bar\\baz", "..\\baz"], - ["\\\\foo\\bar\\baz", "\\\\foo\\bar\\baz-quux", "..\\baz-quux"], - ["C:\\baz-quux", "C:\\baz", "..\\baz"], - ["C:\\baz", "C:\\baz-quux", "..\\baz-quux"], - ["\\\\foo\\baz-quux", "\\\\foo\\baz", "..\\baz"], - ["\\\\foo\\baz", "\\\\foo\\baz-quux", "..\\baz-quux"], - ["C:\\baz", "\\\\foo\\bar\\baz", "\\\\foo\\bar\\baz"], - ["\\\\foo\\bar\\baz", "C:\\baz", "C:\\baz"] - ], - posix: - // arguments result - [ - ["/var/lib", "/var", ".."], - ["/var/lib", "/bin", "../../bin"], - ["/var/lib", "/var/lib", ""], - ["/var/lib", "/var/apache", "../apache"], - ["/var/", "/var/lib", "lib"], - ["/", "/var/lib", "var/lib"], - ["/foo/test", "/foo/test/bar/package.json", "bar/package.json"], - ["/Users/a/web/b/test/mails", "/Users/a/web/b", "../.."], - ["/foo/bar/baz-quux", "/foo/bar/baz", "../baz"], - ["/foo/bar/baz", "/foo/bar/baz-quux", "../baz-quux"], - ["/baz-quux", "/baz", "../baz"], - ["/baz", "/baz-quux", "../baz-quux"] - ] -}; - -test(function relative() { - relativeTests.posix.forEach(function(p) { - const expected = p[2]; - const actual = path.posix.relative(p[0], p[1]); - assertEquals(actual, expected); - }); -}); - -test(function relativeWin32() { - relativeTests.win32.forEach(function(p) { - const expected = p[2]; - const actual = path.win32.relative(p[0], p[1]); - assertEquals(actual, expected); - }); -}); diff --git a/std/fs/path/resolve_test.ts b/std/fs/path/resolve_test.ts deleted file mode 100644 index 606570aad..000000000 --- a/std/fs/path/resolve_test.ts +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright the Browserify authors. MIT License. -// Ported from https://github.com/browserify/path-browserify/ - -const { cwd } = Deno; -import { test } from "../../testing/mod.ts"; -import { assertEquals } from "../../testing/asserts.ts"; -import * as path from "./mod.ts"; - -const windowsTests = - // arguments result - [ - [["c:/blah\\blah", "d:/games", "c:../a"], "c:\\blah\\a"], - [["c:/ignore", "d:\\a/b\\c/d", "\\e.exe"], "d:\\e.exe"], - [["c:/ignore", "c:/some/file"], "c:\\some\\file"], - [["d:/ignore", "d:some/dir//"], "d:\\ignore\\some\\dir"], - [["//server/share", "..", "relative\\"], "\\\\server\\share\\relative"], - [["c:/", "//"], "c:\\"], - [["c:/", "//dir"], "c:\\dir"], - [["c:/", "//server/share"], "\\\\server\\share\\"], - [["c:/", "//server//share"], "\\\\server\\share\\"], - [["c:/", "///some//dir"], "c:\\some\\dir"], - [ - ["C:\\foo\\tmp.3\\", "..\\tmp.3\\cycles\\root.js"], - "C:\\foo\\tmp.3\\cycles\\root.js" - ] - ]; -const posixTests = - // arguments result - [ - [["/var/lib", "../", "file/"], "/var/file"], - [["/var/lib", "/../", "file/"], "/file"], - [["a/b/c/", "../../.."], cwd()], - [["."], cwd()], - [["/some/dir", ".", "/absolute/"], "/absolute"], - [["/foo/tmp.3/", "../tmp.3/cycles/root.js"], "/foo/tmp.3/cycles/root.js"] - ]; - -test(function resolve() { - posixTests.forEach(function(p) { - const _p = p[0] as string[]; - const actual = path.posix.resolve.apply(null, _p); - assertEquals(actual, p[1]); - }); -}); - -test(function resolveWin32() { - windowsTests.forEach(function(p) { - const _p = p[0] as string[]; - const actual = path.win32.resolve.apply(null, _p); - assertEquals(actual, p[1]); - }); -}); diff --git a/std/fs/path/test.ts b/std/fs/path/test.ts deleted file mode 100644 index 3664ae5f1..000000000 --- a/std/fs/path/test.ts +++ /dev/null @@ -1,9 +0,0 @@ -import "./basename_test.ts"; -import "./dirname_test.ts"; -import "./extname_test.ts"; -import "./isabsolute_test.ts"; -import "./join_test.ts"; -import "./parse_format_test.ts"; -import "./relative_test.ts"; -import "./resolve_test.ts"; -import "./zero_length_strings_test.ts"; diff --git a/std/fs/path/utils.ts b/std/fs/path/utils.ts deleted file mode 100644 index 7a4cd7299..000000000 --- a/std/fs/path/utils.ts +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright the Browserify authors. MIT License. -// Ported from https://github.com/browserify/path-browserify/ - -import { FormatInputPathObject } from "./interface.ts"; -import { - CHAR_UPPERCASE_A, - CHAR_LOWERCASE_A, - CHAR_UPPERCASE_Z, - CHAR_LOWERCASE_Z, - CHAR_DOT, - CHAR_FORWARD_SLASH, - CHAR_BACKWARD_SLASH -} from "./constants.ts"; - -export function assertPath(path: string): void { - if (typeof path !== "string") { - throw new TypeError( - `Path must be a string. Received ${JSON.stringify(path)}` - ); - } -} - -export function isPosixPathSeparator(code: number): boolean { - return code === CHAR_FORWARD_SLASH; -} - -export function isPathSeparator(code: number): boolean { - return isPosixPathSeparator(code) || code === CHAR_BACKWARD_SLASH; -} - -export function isWindowsDeviceRoot(code: number): boolean { - return ( - (code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z) || - (code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z) - ); -} - -// Resolves . and .. elements in a path with directory names -export function normalizeString( - path: string, - allowAboveRoot: boolean, - separator: string, - isPathSeparator: (code: number) => boolean -): string { - let res = ""; - let lastSegmentLength = 0; - let lastSlash = -1; - let dots = 0; - let code: number; - for (let i = 0, len = path.length; i <= len; ++i) { - if (i < len) code = path.charCodeAt(i); - else if (isPathSeparator(code!)) break; - else code = CHAR_FORWARD_SLASH; - - if (isPathSeparator(code)) { - if (lastSlash === i - 1 || dots === 1) { - // NOOP - } else if (lastSlash !== i - 1 && dots === 2) { - if ( - res.length < 2 || - lastSegmentLength !== 2 || - res.charCodeAt(res.length - 1) !== CHAR_DOT || - res.charCodeAt(res.length - 2) !== CHAR_DOT - ) { - if (res.length > 2) { - const lastSlashIndex = res.lastIndexOf(separator); - if (lastSlashIndex === -1) { - res = ""; - lastSegmentLength = 0; - } else { - res = res.slice(0, lastSlashIndex); - lastSegmentLength = res.length - 1 - res.lastIndexOf(separator); - } - lastSlash = i; - dots = 0; - continue; - } else if (res.length === 2 || res.length === 1) { - res = ""; - lastSegmentLength = 0; - lastSlash = i; - dots = 0; - continue; - } - } - if (allowAboveRoot) { - if (res.length > 0) res += `${separator}..`; - else res = ".."; - lastSegmentLength = 2; - } - } else { - if (res.length > 0) res += separator + path.slice(lastSlash + 1, i); - else res = path.slice(lastSlash + 1, i); - lastSegmentLength = i - lastSlash - 1; - } - lastSlash = i; - dots = 0; - } else if (code === CHAR_DOT && dots !== -1) { - ++dots; - } else { - dots = -1; - } - } - return res; -} - -export function _format( - sep: string, - pathObject: FormatInputPathObject -): string { - const dir: string | undefined = pathObject.dir || pathObject.root; - const base: string = - pathObject.base || (pathObject.name || "") + (pathObject.ext || ""); - if (!dir) return base; - if (dir === pathObject.root) return dir + base; - return dir + sep + base; -} diff --git a/std/fs/path/win32.ts b/std/fs/path/win32.ts deleted file mode 100644 index 79e04ea6e..000000000 --- a/std/fs/path/win32.ts +++ /dev/null @@ -1,896 +0,0 @@ -// Copyright the Browserify authors. MIT License. -// Ported from https://github.com/browserify/path-browserify/ - -const { cwd, env } = Deno; -import { FormatInputPathObject, ParsedPath } from "./interface.ts"; -import { - CHAR_DOT, - CHAR_BACKWARD_SLASH, - CHAR_COLON, - CHAR_QUESTION_MARK -} from "./constants.ts"; - -import { - assertPath, - isPathSeparator, - isWindowsDeviceRoot, - normalizeString, - _format -} from "./utils.ts"; - -export const sep = "\\"; -export const delimiter = ";"; - -export function resolve(...pathSegments: string[]): string { - let resolvedDevice = ""; - let resolvedTail = ""; - let resolvedAbsolute = false; - - for (let i = pathSegments.length - 1; i >= -1; i--) { - let path: string; - if (i >= 0) { - path = pathSegments[i]; - } else if (!resolvedDevice) { - path = cwd(); - } else { - // Windows has the concept of drive-specific current working - // directories. If we've resolved a drive letter but not yet an - // absolute path, get cwd for that drive, or the process cwd if - // the drive cwd is not available. We're sure the device is not - // a UNC path at this points, because UNC paths are always absolute. - path = env()[`=${resolvedDevice}`] || cwd(); - - // Verify that a cwd was found and that it actually points - // to our drive. If not, default to the drive's root. - if ( - path === undefined || - path.slice(0, 3).toLowerCase() !== `${resolvedDevice.toLowerCase()}\\` - ) { - path = `${resolvedDevice}\\`; - } - } - - assertPath(path); - - const len = path.length; - - // Skip empty entries - if (len === 0) continue; - - let rootEnd = 0; - let device = ""; - let isAbsolute = false; - const code = path.charCodeAt(0); - - // Try to match a root - if (len > 1) { - if (isPathSeparator(code)) { - // Possible UNC root - - // If we started with a separator, we know we at least have an - // absolute path of some kind (UNC or otherwise) - isAbsolute = true; - - if (isPathSeparator(path.charCodeAt(1))) { - // Matched double path separator at beginning - let j = 2; - let last = j; - // Match 1 or more non-path separators - for (; j < len; ++j) { - if (isPathSeparator(path.charCodeAt(j))) break; - } - if (j < len && j !== last) { - const firstPart = path.slice(last, j); - // Matched! - last = j; - // Match 1 or more path separators - for (; j < len; ++j) { - if (!isPathSeparator(path.charCodeAt(j))) break; - } - if (j < len && j !== last) { - // Matched! - last = j; - // Match 1 or more non-path separators - for (; j < len; ++j) { - if (isPathSeparator(path.charCodeAt(j))) break; - } - if (j === len) { - // We matched a UNC root only - device = `\\\\${firstPart}\\${path.slice(last)}`; - rootEnd = j; - } else if (j !== last) { - // We matched a UNC root with leftovers - - device = `\\\\${firstPart}\\${path.slice(last, j)}`; - rootEnd = j; - } - } - } - } else { - rootEnd = 1; - } - } else if (isWindowsDeviceRoot(code)) { - // Possible device root - - if (path.charCodeAt(1) === CHAR_COLON) { - device = path.slice(0, 2); - rootEnd = 2; - if (len > 2) { - if (isPathSeparator(path.charCodeAt(2))) { - // Treat separator following drive name as an absolute path - // indicator - isAbsolute = true; - rootEnd = 3; - } - } - } - } - } else if (isPathSeparator(code)) { - // `path` contains just a path separator - rootEnd = 1; - isAbsolute = true; - } - - if ( - device.length > 0 && - resolvedDevice.length > 0 && - device.toLowerCase() !== resolvedDevice.toLowerCase() - ) { - // This path points to another device so it is not applicable - continue; - } - - if (resolvedDevice.length === 0 && device.length > 0) { - resolvedDevice = device; - } - if (!resolvedAbsolute) { - resolvedTail = `${path.slice(rootEnd)}\\${resolvedTail}`; - resolvedAbsolute = isAbsolute; - } - - if (resolvedAbsolute && resolvedDevice.length > 0) break; - } - - // At this point the path should be resolved to a full absolute path, - // but handle relative paths to be safe (might happen when process.cwd() - // fails) - - // Normalize the tail path - resolvedTail = normalizeString( - resolvedTail, - !resolvedAbsolute, - "\\", - isPathSeparator - ); - - return resolvedDevice + (resolvedAbsolute ? "\\" : "") + resolvedTail || "."; -} - -export function normalize(path: string): string { - assertPath(path); - const len = path.length; - if (len === 0) return "."; - let rootEnd = 0; - let device: string | undefined; - let isAbsolute = false; - const code = path.charCodeAt(0); - - // Try to match a root - if (len > 1) { - if (isPathSeparator(code)) { - // Possible UNC root - - // If we started with a separator, we know we at least have an absolute - // path of some kind (UNC or otherwise) - isAbsolute = true; - - if (isPathSeparator(path.charCodeAt(1))) { - // Matched double path separator at beginning - let j = 2; - let last = j; - // Match 1 or more non-path separators - for (; j < len; ++j) { - if (isPathSeparator(path.charCodeAt(j))) break; - } - if (j < len && j !== last) { - const firstPart = path.slice(last, j); - // Matched! - last = j; - // Match 1 or more path separators - for (; j < len; ++j) { - if (!isPathSeparator(path.charCodeAt(j))) break; - } - if (j < len && j !== last) { - // Matched! - last = j; - // Match 1 or more non-path separators - for (; j < len; ++j) { - if (isPathSeparator(path.charCodeAt(j))) break; - } - if (j === len) { - // We matched a UNC root only - // Return the normalized version of the UNC root since there - // is nothing left to process - - return `\\\\${firstPart}\\${path.slice(last)}\\`; - } else if (j !== last) { - // We matched a UNC root with leftovers - - device = `\\\\${firstPart}\\${path.slice(last, j)}`; - rootEnd = j; - } - } - } - } else { - rootEnd = 1; - } - } else if (isWindowsDeviceRoot(code)) { - // Possible device root - - if (path.charCodeAt(1) === CHAR_COLON) { - device = path.slice(0, 2); - rootEnd = 2; - if (len > 2) { - if (isPathSeparator(path.charCodeAt(2))) { - // Treat separator following drive name as an absolute path - // indicator - isAbsolute = true; - rootEnd = 3; - } - } - } - } - } else if (isPathSeparator(code)) { - // `path` contains just a path separator, exit early to avoid unnecessary - // work - return "\\"; - } - - let tail: string; - if (rootEnd < len) { - tail = normalizeString( - path.slice(rootEnd), - !isAbsolute, - "\\", - isPathSeparator - ); - } else { - tail = ""; - } - if (tail.length === 0 && !isAbsolute) tail = "."; - if (tail.length > 0 && isPathSeparator(path.charCodeAt(len - 1))) - tail += "\\"; - if (device === undefined) { - if (isAbsolute) { - if (tail.length > 0) return `\\${tail}`; - else return "\\"; - } else if (tail.length > 0) { - return tail; - } else { - return ""; - } - } else if (isAbsolute) { - if (tail.length > 0) return `${device}\\${tail}`; - else return `${device}\\`; - } else if (tail.length > 0) { - return device + tail; - } else { - return device; - } -} - -export function isAbsolute(path: string): boolean { - assertPath(path); - const len = path.length; - if (len === 0) return false; - - const code = path.charCodeAt(0); - if (isPathSeparator(code)) { - return true; - } else if (isWindowsDeviceRoot(code)) { - // Possible device root - - if (len > 2 && path.charCodeAt(1) === CHAR_COLON) { - if (isPathSeparator(path.charCodeAt(2))) return true; - } - } - return false; -} - -export function join(...paths: string[]): string { - const pathsCount = paths.length; - if (pathsCount === 0) return "."; - - let joined: string | undefined; - let firstPart: string; - for (let i = 0; i < pathsCount; ++i) { - const path = paths[i]; - assertPath(path); - if (path.length > 0) { - if (joined === undefined) joined = firstPart = path; - else joined += `\\${path}`; - } - } - - if (joined === undefined) return "."; - - // Make sure that the joined path doesn't start with two slashes, because - // normalize() will mistake it for an UNC path then. - // - // This step is skipped when it is very clear that the user actually - // intended to point at an UNC path. This is assumed when the first - // non-empty string arguments starts with exactly two slashes followed by - // at least one more non-slash character. - // - // Note that for normalize() to treat a path as an UNC path it needs to - // have at least 2 components, so we don't filter for that here. - // This means that the user can use join to construct UNC paths from - // a server name and a share name; for example: - // path.join('//server', 'share') -> '\\\\server\\share\\') - let needsReplace = true; - let slashCount = 0; - firstPart = firstPart!; - if (isPathSeparator(firstPart.charCodeAt(0))) { - ++slashCount; - const firstLen = firstPart.length; - if (firstLen > 1) { - if (isPathSeparator(firstPart.charCodeAt(1))) { - ++slashCount; - if (firstLen > 2) { - if (isPathSeparator(firstPart.charCodeAt(2))) ++slashCount; - else { - // We matched a UNC path in the first part - needsReplace = false; - } - } - } - } - } - if (needsReplace) { - // Find any more consecutive slashes we need to replace - for (; slashCount < joined.length; ++slashCount) { - if (!isPathSeparator(joined.charCodeAt(slashCount))) break; - } - - // Replace the slashes if needed - if (slashCount >= 2) joined = `\\${joined.slice(slashCount)}`; - } - - return normalize(joined); -} - -// It will solve the relative path from `from` to `to`, for instance: -// from = 'C:\\orandea\\test\\aaa' -// to = 'C:\\orandea\\impl\\bbb' -// The output of the function should be: '..\\..\\impl\\bbb' -export function relative(from: string, to: string): string { - assertPath(from); - assertPath(to); - - if (from === to) return ""; - - const fromOrig = resolve(from); - const toOrig = resolve(to); - - if (fromOrig === toOrig) return ""; - - from = fromOrig.toLowerCase(); - to = toOrig.toLowerCase(); - - if (from === to) return ""; - - // Trim any leading backslashes - let fromStart = 0; - let fromEnd = from.length; - for (; fromStart < fromEnd; ++fromStart) { - if (from.charCodeAt(fromStart) !== CHAR_BACKWARD_SLASH) break; - } - // Trim trailing backslashes (applicable to UNC paths only) - for (; fromEnd - 1 > fromStart; --fromEnd) { - if (from.charCodeAt(fromEnd - 1) !== CHAR_BACKWARD_SLASH) break; - } - const fromLen = fromEnd - fromStart; - - // Trim any leading backslashes - let toStart = 0; - let toEnd = to.length; - for (; toStart < toEnd; ++toStart) { - if (to.charCodeAt(toStart) !== CHAR_BACKWARD_SLASH) break; - } - // Trim trailing backslashes (applicable to UNC paths only) - for (; toEnd - 1 > toStart; --toEnd) { - if (to.charCodeAt(toEnd - 1) !== CHAR_BACKWARD_SLASH) break; - } - const toLen = toEnd - toStart; - - // Compare paths to find the longest common path from root - const length = fromLen < toLen ? fromLen : toLen; - let lastCommonSep = -1; - let i = 0; - for (; i <= length; ++i) { - if (i === length) { - if (toLen > length) { - if (to.charCodeAt(toStart + i) === CHAR_BACKWARD_SLASH) { - // We get here if `from` is the exact base path for `to`. - // For example: from='C:\\foo\\bar'; to='C:\\foo\\bar\\baz' - return toOrig.slice(toStart + i + 1); - } else if (i === 2) { - // We get here if `from` is the device root. - // For example: from='C:\\'; to='C:\\foo' - return toOrig.slice(toStart + i); - } - } - if (fromLen > length) { - if (from.charCodeAt(fromStart + i) === CHAR_BACKWARD_SLASH) { - // We get here if `to` is the exact base path for `from`. - // For example: from='C:\\foo\\bar'; to='C:\\foo' - lastCommonSep = i; - } else if (i === 2) { - // We get here if `to` is the device root. - // For example: from='C:\\foo\\bar'; to='C:\\' - lastCommonSep = 3; - } - } - break; - } - const fromCode = from.charCodeAt(fromStart + i); - const toCode = to.charCodeAt(toStart + i); - if (fromCode !== toCode) break; - else if (fromCode === CHAR_BACKWARD_SLASH) lastCommonSep = i; - } - - // We found a mismatch before the first common path separator was seen, so - // return the original `to`. - if (i !== length && lastCommonSep === -1) { - return toOrig; - } - - let out = ""; - if (lastCommonSep === -1) lastCommonSep = 0; - // Generate the relative path based on the path difference between `to` and - // `from` - for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) { - if (i === fromEnd || from.charCodeAt(i) === CHAR_BACKWARD_SLASH) { - if (out.length === 0) out += ".."; - else out += "\\.."; - } - } - - // Lastly, append the rest of the destination (`to`) path that comes after - // the common path parts - if (out.length > 0) return out + toOrig.slice(toStart + lastCommonSep, toEnd); - else { - toStart += lastCommonSep; - if (toOrig.charCodeAt(toStart) === CHAR_BACKWARD_SLASH) ++toStart; - return toOrig.slice(toStart, toEnd); - } -} - -export function toNamespacedPath(path: string): string { - // Note: this will *probably* throw somewhere. - if (typeof path !== "string") return path; - if (path.length === 0) return ""; - - const resolvedPath = resolve(path); - - if (resolvedPath.length >= 3) { - if (resolvedPath.charCodeAt(0) === CHAR_BACKWARD_SLASH) { - // Possible UNC root - - if (resolvedPath.charCodeAt(1) === CHAR_BACKWARD_SLASH) { - const code = resolvedPath.charCodeAt(2); - if (code !== CHAR_QUESTION_MARK && code !== CHAR_DOT) { - // Matched non-long UNC root, convert the path to a long UNC path - return `\\\\?\\UNC\\${resolvedPath.slice(2)}`; - } - } - } else if (isWindowsDeviceRoot(resolvedPath.charCodeAt(0))) { - // Possible device root - - if ( - resolvedPath.charCodeAt(1) === CHAR_COLON && - resolvedPath.charCodeAt(2) === CHAR_BACKWARD_SLASH - ) { - // Matched device root, convert the path to a long UNC path - return `\\\\?\\${resolvedPath}`; - } - } - } - - return path; -} - -export function dirname(path: string): string { - assertPath(path); - const len = path.length; - if (len === 0) return "."; - let rootEnd = -1; - let end = -1; - let matchedSlash = true; - let offset = 0; - const code = path.charCodeAt(0); - - // Try to match a root - if (len > 1) { - if (isPathSeparator(code)) { - // Possible UNC root - - rootEnd = offset = 1; - - if (isPathSeparator(path.charCodeAt(1))) { - // Matched double path separator at beginning - let j = 2; - let last = j; - // Match 1 or more non-path separators - for (; j < len; ++j) { - if (isPathSeparator(path.charCodeAt(j))) break; - } - if (j < len && j !== last) { - // Matched! - last = j; - // Match 1 or more path separators - for (; j < len; ++j) { - if (!isPathSeparator(path.charCodeAt(j))) break; - } - if (j < len && j !== last) { - // Matched! - last = j; - // Match 1 or more non-path separators - for (; j < len; ++j) { - if (isPathSeparator(path.charCodeAt(j))) break; - } - if (j === len) { - // We matched a UNC root only - return path; - } - if (j !== last) { - // We matched a UNC root with leftovers - - // Offset by 1 to include the separator after the UNC root to - // treat it as a "normal root" on top of a (UNC) root - rootEnd = offset = j + 1; - } - } - } - } - } else if (isWindowsDeviceRoot(code)) { - // Possible device root - - if (path.charCodeAt(1) === CHAR_COLON) { - rootEnd = offset = 2; - if (len > 2) { - if (isPathSeparator(path.charCodeAt(2))) rootEnd = offset = 3; - } - } - } - } else if (isPathSeparator(code)) { - // `path` contains just a path separator, exit early to avoid - // unnecessary work - return path; - } - - for (let i = len - 1; i >= offset; --i) { - if (isPathSeparator(path.charCodeAt(i))) { - if (!matchedSlash) { - end = i; - break; - } - } else { - // We saw the first non-path separator - matchedSlash = false; - } - } - - if (end === -1) { - if (rootEnd === -1) return "."; - else end = rootEnd; - } - return path.slice(0, end); -} - -export function basename(path: string, ext = ""): string { - if (ext !== undefined && typeof ext !== "string") - throw new TypeError('"ext" argument must be a string'); - - assertPath(path); - - let start = 0; - let end = -1; - let matchedSlash = true; - let i: number; - - // Check for a drive letter prefix so as not to mistake the following - // path separator as an extra separator at the end of the path that can be - // disregarded - if (path.length >= 2) { - const drive = path.charCodeAt(0); - if (isWindowsDeviceRoot(drive)) { - if (path.charCodeAt(1) === CHAR_COLON) start = 2; - } - } - - if (ext !== undefined && ext.length > 0 && ext.length <= path.length) { - if (ext.length === path.length && ext === path) return ""; - let extIdx = ext.length - 1; - let firstNonSlashEnd = -1; - for (i = path.length - 1; i >= start; --i) { - const code = path.charCodeAt(i); - if (isPathSeparator(code)) { - // If we reached a path separator that was not part of a set of path - // separators at the end of the string, stop now - if (!matchedSlash) { - start = i + 1; - break; - } - } else { - if (firstNonSlashEnd === -1) { - // We saw the first non-path separator, remember this index in case - // we need it if the extension ends up not matching - matchedSlash = false; - firstNonSlashEnd = i + 1; - } - if (extIdx >= 0) { - // Try to match the explicit extension - if (code === ext.charCodeAt(extIdx)) { - if (--extIdx === -1) { - // We matched the extension, so mark this as the end of our path - // component - end = i; - } - } else { - // Extension does not match, so our result is the entire path - // component - extIdx = -1; - end = firstNonSlashEnd; - } - } - } - } - - if (start === end) end = firstNonSlashEnd; - else if (end === -1) end = path.length; - return path.slice(start, end); - } else { - for (i = path.length - 1; i >= start; --i) { - if (isPathSeparator(path.charCodeAt(i))) { - // If we reached a path separator that was not part of a set of path - // separators at the end of the string, stop now - if (!matchedSlash) { - start = i + 1; - break; - } - } else if (end === -1) { - // We saw the first non-path separator, mark this as the end of our - // path component - matchedSlash = false; - end = i + 1; - } - } - - if (end === -1) return ""; - return path.slice(start, end); - } -} - -export function extname(path: string): string { - assertPath(path); - let start = 0; - let startDot = -1; - let startPart = 0; - let end = -1; - let matchedSlash = true; - // Track the state of characters (if any) we see before our first dot and - // after any path separator we find - let preDotState = 0; - - // Check for a drive letter prefix so as not to mistake the following - // path separator as an extra separator at the end of the path that can be - // disregarded - - if ( - path.length >= 2 && - path.charCodeAt(1) === CHAR_COLON && - isWindowsDeviceRoot(path.charCodeAt(0)) - ) { - start = startPart = 2; - } - - for (let i = path.length - 1; i >= start; --i) { - const code = path.charCodeAt(i); - if (isPathSeparator(code)) { - // If we reached a path separator that was not part of a set of path - // separators at the end of the string, stop now - if (!matchedSlash) { - startPart = i + 1; - break; - } - continue; - } - if (end === -1) { - // We saw the first non-path separator, mark this as the end of our - // extension - matchedSlash = false; - end = i + 1; - } - if (code === CHAR_DOT) { - // If this is our first dot, mark it as the start of our extension - if (startDot === -1) startDot = i; - else if (preDotState !== 1) preDotState = 1; - } else if (startDot !== -1) { - // We saw a non-dot and non-path separator before our dot, so we should - // have a good chance at having a non-empty extension - preDotState = -1; - } - } - - if ( - startDot === -1 || - end === -1 || - // We saw a non-dot character immediately before the dot - preDotState === 0 || - // The (right-most) trimmed path component is exactly '..' - (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) - ) { - return ""; - } - return path.slice(startDot, end); -} - -export function format(pathObject: FormatInputPathObject): string { - /* eslint-disable max-len */ - if (pathObject === null || typeof pathObject !== "object") { - throw new TypeError( - `The "pathObject" argument must be of type Object. Received type ${typeof pathObject}` - ); - } - return _format("\\", pathObject); -} - -export function parse(path: string): ParsedPath { - assertPath(path); - - const ret: ParsedPath = { root: "", dir: "", base: "", ext: "", name: "" }; - - const len = path.length; - if (len === 0) return ret; - - let rootEnd = 0; - let code = path.charCodeAt(0); - - // Try to match a root - if (len > 1) { - if (isPathSeparator(code)) { - // Possible UNC root - - rootEnd = 1; - if (isPathSeparator(path.charCodeAt(1))) { - // Matched double path separator at beginning - let j = 2; - let last = j; - // Match 1 or more non-path separators - for (; j < len; ++j) { - if (isPathSeparator(path.charCodeAt(j))) break; - } - if (j < len && j !== last) { - // Matched! - last = j; - // Match 1 or more path separators - for (; j < len; ++j) { - if (!isPathSeparator(path.charCodeAt(j))) break; - } - if (j < len && j !== last) { - // Matched! - last = j; - // Match 1 or more non-path separators - for (; j < len; ++j) { - if (isPathSeparator(path.charCodeAt(j))) break; - } - if (j === len) { - // We matched a UNC root only - - rootEnd = j; - } else if (j !== last) { - // We matched a UNC root with leftovers - - rootEnd = j + 1; - } - } - } - } - } else if (isWindowsDeviceRoot(code)) { - // Possible device root - - if (path.charCodeAt(1) === CHAR_COLON) { - rootEnd = 2; - if (len > 2) { - if (isPathSeparator(path.charCodeAt(2))) { - if (len === 3) { - // `path` contains just a drive root, exit early to avoid - // unnecessary work - ret.root = ret.dir = path; - return ret; - } - rootEnd = 3; - } - } else { - // `path` contains just a drive root, exit early to avoid - // unnecessary work - ret.root = ret.dir = path; - return ret; - } - } - } - } else if (isPathSeparator(code)) { - // `path` contains just a path separator, exit early to avoid - // unnecessary work - ret.root = ret.dir = path; - return ret; - } - - if (rootEnd > 0) ret.root = path.slice(0, rootEnd); - - let startDot = -1; - let startPart = rootEnd; - let end = -1; - let matchedSlash = true; - let i = path.length - 1; - - // Track the state of characters (if any) we see before our first dot and - // after any path separator we find - let preDotState = 0; - - // Get non-dir info - for (; i >= rootEnd; --i) { - code = path.charCodeAt(i); - if (isPathSeparator(code)) { - // If we reached a path separator that was not part of a set of path - // separators at the end of the string, stop now - if (!matchedSlash) { - startPart = i + 1; - break; - } - continue; - } - if (end === -1) { - // We saw the first non-path separator, mark this as the end of our - // extension - matchedSlash = false; - end = i + 1; - } - if (code === CHAR_DOT) { - // If this is our first dot, mark it as the start of our extension - if (startDot === -1) startDot = i; - else if (preDotState !== 1) preDotState = 1; - } else if (startDot !== -1) { - // We saw a non-dot and non-path separator before our dot, so we should - // have a good chance at having a non-empty extension - preDotState = -1; - } - } - - if ( - startDot === -1 || - end === -1 || - // We saw a non-dot character immediately before the dot - preDotState === 0 || - // The (right-most) trimmed path component is exactly '..' - (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) - ) { - if (end !== -1) { - ret.base = ret.name = path.slice(startPart, end); - } - } else { - ret.name = path.slice(startPart, startDot); - ret.base = path.slice(startPart, end); - ret.ext = path.slice(startDot, end); - } - - // If the directory is the root, use the entire root as the `dir` including - // the trailing slash if any (`C:\abc` -> `C:\`). Otherwise, strip out the - // trailing slash (`C:\abc\def` -> `C:\abc`). - if (startPart > 0 && startPart !== rootEnd) { - ret.dir = path.slice(0, startPart - 1); - } else ret.dir = ret.root; - - return ret; -} diff --git a/std/fs/path/zero_length_strings_test.ts b/std/fs/path/zero_length_strings_test.ts deleted file mode 100644 index 744e97735..000000000 --- a/std/fs/path/zero_length_strings_test.ts +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright the Browserify authors. MIT License. -// Ported from https://github.com/browserify/path-browserify/ - -const { cwd } = Deno; -import { test } from "../../testing/mod.ts"; -import { assertEquals } from "../../testing/asserts.ts"; -import * as path from "./mod.ts"; - -const pwd = cwd(); - -test(function joinZeroLength() { - // join will internally ignore all the zero-length strings and it will return - // '.' if the joined string is a zero-length string. - assertEquals(path.posix.join(""), "."); - assertEquals(path.posix.join("", ""), "."); - if (path.win32) assertEquals(path.win32.join(""), "."); - if (path.win32) assertEquals(path.win32.join("", ""), "."); - assertEquals(path.join(pwd), pwd); - assertEquals(path.join(pwd, ""), pwd); -}); - -test(function normalizeZeroLength() { - // normalize will return '.' if the input is a zero-length string - assertEquals(path.posix.normalize(""), "."); - if (path.win32) assertEquals(path.win32.normalize(""), "."); - assertEquals(path.normalize(pwd), pwd); -}); - -test(function isAbsoluteZeroLength() { - // Since '' is not a valid path in any of the common environments, - // return false - assertEquals(path.posix.isAbsolute(""), false); - if (path.win32) assertEquals(path.win32.isAbsolute(""), false); -}); - -test(function resolveZeroLength() { - // resolve, internally ignores all the zero-length strings and returns the - // current working directory - assertEquals(path.resolve(""), pwd); - assertEquals(path.resolve("", ""), pwd); -}); - -test(function relativeZeroLength() { - // relative, internally calls resolve. So, '' is actually the current - // directory - assertEquals(path.relative("", pwd), ""); - assertEquals(path.relative(pwd, ""), ""); - assertEquals(path.relative(pwd, pwd), ""); -}); |