summaryrefslogtreecommitdiff
path: root/std/path
diff options
context:
space:
mode:
authorCasper Beyer <caspervonb@pm.me>2021-02-02 19:05:46 +0800
committerGitHub <noreply@github.com>2021-02-02 12:05:46 +0100
commit6abf126c2a7a451cded8c6b5e6ddf1b69c84055d (patch)
treefd94c013a19fcb38954844085821ec1601c20e18 /std/path
parenta2b5d44f1aa9d64f448a2a3cc2001272e2f60b98 (diff)
chore: remove std directory (#9361)
This removes the std folder from the tree. Various parts of the tests are pretty tightly dependent on std (47 direct imports and 75 indirect imports, not counting the cli tests that use them as fixtures) so I've added std as a submodule for now.
Diffstat (limited to 'std/path')
-rw-r--r--std/path/README.md22
-rw-r--r--std/path/_constants.ts48
-rw-r--r--std/path/_interface.ts30
-rw-r--r--std/path/_util.ts117
-rw-r--r--std/path/basename_test.ts74
-rw-r--r--std/path/common.ts39
-rw-r--r--std/path/common_test.ts44
-rw-r--r--std/path/dirname_test.ts60
-rw-r--r--std/path/extname_test.ts88
-rw-r--r--std/path/from_file_url_test.ts51
-rw-r--r--std/path/glob.ts387
-rw-r--r--std/path/glob_test.ts638
-rw-r--r--std/path/isabsolute_test.ts32
-rw-r--r--std/path/join_test.ts128
-rw-r--r--std/path/mod.ts34
-rw-r--r--std/path/parse_format_test.ts186
-rw-r--r--std/path/posix.ts504
-rw-r--r--std/path/relative_test.ts65
-rw-r--r--std/path/resolve_test.ts49
-rw-r--r--std/path/separator.ts7
-rw-r--r--std/path/test.ts2
-rw-r--r--std/path/to_file_url_test.ts49
-rw-r--r--std/path/win32.ts1001
-rw-r--r--std/path/zero_length_strings_test.ts46
24 files changed, 0 insertions, 3701 deletions
diff --git a/std/path/README.md b/std/path/README.md
deleted file mode 100644
index c1debfc31..000000000
--- a/std/path/README.md
+++ /dev/null
@@ -1,22 +0,0 @@
-# Deno Path Manipulation Libraries
-
-Usage:
-
-```ts
-import * as path from "https://deno.land/std@$STD_VERSION/path/mod.ts";
-```
-
-### globToRegExp
-
-Generate a regex based on glob pattern and options This was meant to be using
-the `fs.walk` function but can be used anywhere else.
-
-```ts
-import { globToRegExp } from "https://deno.land/std@$STD_VERSION/path/glob.ts";
-
-globToRegExp("foo/**/*.json", {
- flags: "g",
- extended: true,
- globstar: true,
-}); // returns the regex to find all .json files in the folder foo.
-```
diff --git a/std/path/_constants.ts b/std/path/_constants.ts
deleted file mode 100644
index 88374ae05..000000000
--- a/std/path/_constants.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright the Browserify authors. MIT License.
-// Ported from https://github.com/browserify/path-browserify/
-// This module is browser compatible.
-
-// 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 */
diff --git a/std/path/_interface.ts b/std/path/_interface.ts
deleted file mode 100644
index d5015cbeb..000000000
--- a/std/path/_interface.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
-// This module is browser compatible.
-
-/**
- * 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/path/_util.ts b/std/path/_util.ts
deleted file mode 100644
index 046c44337..000000000
--- a/std/path/_util.ts
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright the Browserify authors. MIT License.
-// Ported from https://github.com/browserify/path-browserify/
-// This module is browser compatible.
-
-import type { FormatInputPathObject } from "./_interface.ts";
-import {
- CHAR_BACKWARD_SLASH,
- CHAR_DOT,
- CHAR_FORWARD_SLASH,
- CHAR_LOWERCASE_A,
- CHAR_LOWERCASE_Z,
- CHAR_UPPERCASE_A,
- CHAR_UPPERCASE_Z,
-} 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 | undefined;
- 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/path/basename_test.ts b/std/path/basename_test.ts
deleted file mode 100644
index 9e2265db9..000000000
--- a/std/path/basename_test.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright the Browserify authors. MIT License.
-// Ported from https://github.com/browserify/path-browserify/
-import { assertEquals } from "../testing/asserts.ts";
-import * as path from "./mod.ts";
-
-Deno.test("basename", function () {
- 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,
- );
-});
-
-Deno.test("basenameWin32", function () {
- 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/path/common.ts b/std/path/common.ts
deleted file mode 100644
index 390c04f1d..000000000
--- a/std/path/common.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
-// This module is browser compatible.
-
-import { SEP } from "./separator.ts";
-
-/** Determines the common path from a set of paths, using an optional separator,
- * which defaults to the OS default separator.
- *
- * import { common } from "https://deno.land/std/path/mod.ts";
- * const p = common([
- * "./deno/std/path/mod.ts",
- * "./deno/std/fs/mod.ts",
- * ]);
- * console.log(p); // "./deno/std/"
- *
- */
-export function common(paths: string[], sep = SEP): string {
- const [first = "", ...remaining] = paths;
- if (first === "" || remaining.length === 0) {
- return first.substring(0, first.lastIndexOf(sep) + 1);
- }
- const parts = first.split(sep);
-
- let endOfPrefix = parts.length;
- for (const path of remaining) {
- const compare = path.split(sep);
- for (let i = 0; i < endOfPrefix; i++) {
- if (compare[i] !== parts[i]) {
- endOfPrefix = i;
- }
- }
-
- if (endOfPrefix === 0) {
- return "";
- }
- }
- const prefix = parts.slice(0, endOfPrefix).join(sep);
- return prefix.endsWith(sep) ? prefix : `${prefix}${sep}`;
-}
diff --git a/std/path/common_test.ts b/std/path/common_test.ts
deleted file mode 100644
index b34b54741..000000000
--- a/std/path/common_test.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
-import { assertEquals } from "../testing/asserts.ts";
-import { common } from "./mod.ts";
-
-Deno.test({
- name: "path - common - basic usage",
- fn() {
- const actual = common(
- [
- "file://deno/cli/js/deno.ts",
- "file://deno/std/path/mod.ts",
- "file://deno/cli/js/main.ts",
- ],
- "/",
- );
- assertEquals(actual, "file://deno/");
- },
-});
-
-Deno.test({
- name: "path - common - no shared",
- fn() {
- const actual = common(
- ["file://deno/cli/js/deno.ts", "https://deno.land/std/path/mod.ts"],
- "/",
- );
- assertEquals(actual, "");
- },
-});
-
-Deno.test({
- name: "path - common - windows sep",
- fn() {
- const actual = common(
- [
- "c:\\deno\\cli\\js\\deno.ts",
- "c:\\deno\\std\\path\\mod.ts",
- "c:\\deno\\cli\\js\\main.ts",
- ],
- "\\",
- );
- assertEquals(actual, "c:\\deno\\");
- },
-});
diff --git a/std/path/dirname_test.ts b/std/path/dirname_test.ts
deleted file mode 100644
index 210d3a9ec..000000000
--- a/std/path/dirname_test.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright the Browserify authors. MIT License.
-// Ported from https://github.com/browserify/path-browserify/
-import { assertEquals } from "../testing/asserts.ts";
-import * as path from "./mod.ts";
-
-Deno.test("dirname", function () {
- 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"), ".");
-});
-
-Deno.test("dirnameWin32", function () {
- 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/path/extname_test.ts b/std/path/extname_test.ts
deleted file mode 100644
index 7e1abf4bc..000000000
--- a/std/path/extname_test.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright the Browserify authors. MIT License.
-// Ported from https://github.com/browserify/path-browserify/
-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.//", "."],
-];
-
-Deno.test("extname", function () {
- 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.\\\\"), ".\\\\");
-});
-
-Deno.test("extnameWin32", function () {
- 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/path/from_file_url_test.ts b/std/path/from_file_url_test.ts
deleted file mode 100644
index 61a45a89b..000000000
--- a/std/path/from_file_url_test.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
-import { posix, win32 } from "./mod.ts";
-import { assertEquals, assertThrows } from "../testing/asserts.ts";
-
-Deno.test("[path] fromFileUrl", function () {
- assertEquals(posix.fromFileUrl(new URL("file:///home/foo")), "/home/foo");
- assertEquals(posix.fromFileUrl("file:///"), "/");
- assertEquals(posix.fromFileUrl("file:///home/foo"), "/home/foo");
- assertEquals(posix.fromFileUrl("file:///home/foo%20bar"), "/home/foo bar");
- assertEquals(posix.fromFileUrl("file:///%"), "/%");
- assertEquals(posix.fromFileUrl("file://localhost/foo"), "/foo");
- assertEquals(posix.fromFileUrl("file:///C:"), "/C:");
- assertEquals(posix.fromFileUrl("file:///C:/"), "/C:/");
- assertEquals(posix.fromFileUrl("file:///C:/Users/"), "/C:/Users/");
- assertEquals(posix.fromFileUrl("file:///C:foo/bar"), "/C:foo/bar");
- assertThrows(
- () => posix.fromFileUrl("http://localhost/foo"),
- TypeError,
- "Must be a file URL.",
- );
- assertThrows(
- () => posix.fromFileUrl("abcd://localhost/foo"),
- TypeError,
- "Must be a file URL.",
- );
-});
-
-Deno.test("[path] fromFileUrl (win32)", function () {
- assertEquals(win32.fromFileUrl(new URL("file:///home/foo")), "\\home\\foo");
- assertEquals(win32.fromFileUrl("file:///"), "\\");
- assertEquals(win32.fromFileUrl("file:///home/foo"), "\\home\\foo");
- assertEquals(win32.fromFileUrl("file:///home/foo%20bar"), "\\home\\foo bar");
- assertEquals(win32.fromFileUrl("file:///%"), "\\%");
- assertEquals(win32.fromFileUrl("file://localhost/foo"), "\\\\localhost\\foo");
- assertEquals(win32.fromFileUrl("file:///C:"), "C:\\");
- assertEquals(win32.fromFileUrl("file:///C:/"), "C:\\");
- // Drop the hostname if a drive letter is parsed.
- assertEquals(win32.fromFileUrl("file://localhost/C:/"), "C:\\");
- assertEquals(win32.fromFileUrl("file:///C:/Users/"), "C:\\Users\\");
- assertEquals(win32.fromFileUrl("file:///C:foo/bar"), "\\C:foo\\bar");
- assertThrows(
- () => win32.fromFileUrl("http://localhost/foo"),
- TypeError,
- "Must be a file URL.",
- );
- assertThrows(
- () => win32.fromFileUrl("abcd://localhost/foo"),
- TypeError,
- "Must be a file URL.",
- );
-});
diff --git a/std/path/glob.ts b/std/path/glob.ts
deleted file mode 100644
index d599c1b88..000000000
--- a/std/path/glob.ts
+++ /dev/null
@@ -1,387 +0,0 @@
-// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
-// This module is browser compatible.
-
-import { osType } from "../_util/os.ts";
-import { join, normalize } from "./mod.ts";
-import { SEP, SEP_PATTERN } from "./separator.ts";
-
-export interface GlobOptions {
- /** Extended glob syntax.
- * See https://www.linuxjournal.com/content/bash-extended-globbing. Defaults
- * to true. */
- extended?: boolean;
- /** Globstar syntax.
- * See https://www.linuxjournal.com/content/globstar-new-bash-globbing-option.
- * If false, `**` is treated like `*`. Defaults to true. */
- globstar?: boolean;
- /** Operating system. Defaults to the native OS. */
- os?: typeof Deno.build.os;
-}
-
-export type GlobToRegExpOptions = GlobOptions;
-
-// deno-fmt-ignore
-const regExpEscapeChars = ["!", "$", "(", ")", "*", "+", ".", "=", "?", "[", "\\", "^", "{", "|"];
-const rangeEscapeChars = ["-", "\\", "]"];
-
-/** Convert a glob string to a regular expression.
- *
- * Tries to match bash glob expansion as closely as possible.
- *
- * Basic glob syntax:
- * - `*` - Matches everything without leaving the path segment.
- * - `{foo,bar}` - Matches `foo` or `bar`.
- * - `[abcd]` - Matches `a`, `b`, `c` or `d`.
- * - `[a-d]` - Matches `a`, `b`, `c` or `d`.
- * - `[!abcd]` - Matches any single character besides `a`, `b`, `c` or `d`.
- * - `[[:<class>:]]` - Matches any character belonging to `<class>`.
- * - `[[:alnum:]]` - Matches any digit or letter.
- * - `[[:digit:]abc]` - Matches any digit, `a`, `b` or `c`.
- * - See https://facelessuser.github.io/wcmatch/glob/#posix-character-classes
- * for a complete list of supported character classes.
- * - `\` - Escapes the next character for an `os` other than `"windows"`.
- * - \` - Escapes the next character for `os` set to `"windows"`.
- * - `/` - Path separator.
- * - `\` - Additional path separator only for `os` set to `"windows"`.
- *
- * Extended syntax:
- * - Requires `{ extended: true }`.
- * - `?(foo|bar)` - Matches 0 or 1 instance of `{foo,bar}`.
- * - `@(foo|bar)` - Matches 1 instance of `{foo,bar}`. They behave the same.
- * - `*(foo|bar)` - Matches _n_ instances of `{foo,bar}`.
- * - `+(foo|bar)` - Matches _n > 0_ instances of `{foo,bar}`.
- * - `!(foo|bar)` - Matches anything other than `{foo,bar}`.
- * - See https://www.linuxjournal.com/content/bash-extended-globbing.
- *
- * Globstar syntax:
- * - Requires `{ globstar: true }`.
- * - `**` - Matches any number of any path segments.
- * - Must comprise its entire path segment in the provided glob.
- * - See https://www.linuxjournal.com/content/globstar-new-bash-globbing-option.
- *
- * Note the following properties:
- * - The generated `RegExp` is anchored at both start and end.
- * - Repeating and trailing separators are tolerated. Trailing separators in the
- * provided glob have no meaning and are discarded.
- * - Absolute globs will only match absolute paths, etc.
- * - Empty globs will match nothing.
- * - Any special glob syntax must be contained to one path segment. For example,
- * `?(foo|bar/baz)` is invalid. The separator will take precendence and the
- * first segment ends with an unclosed group.
- * - If a path segment ends with unclosed groups or a dangling escape prefix, a
- * parse error has occured. Every character for that segment is taken
- * literally in this event.
- *
- * Limitations:
- * - A negative group like `!(foo|bar)` will wrongly be converted to a negative
- * look-ahead followed by a wildcard. This means that `!(foo).js` will wrongly
- * fail to match `foobar.js`, even though `foobar` is not `foo`. Effectively,
- * `!(foo|bar)` is treated like `!(@(foo|bar)*)`. This will work correctly if
- * the group occurs not nested at the end of the segment. */
-export function globToRegExp(
- glob: string,
- { extended = true, globstar: globstarOption = true, os = osType }:
- GlobToRegExpOptions = {},
-): RegExp {
- if (glob == "") {
- return /(?!)/;
- }
-
- const sep = os == "windows" ? "(?:\\\\|/)+" : "/+";
- const sepMaybe = os == "windows" ? "(?:\\\\|/)*" : "/*";
- const seps = os == "windows" ? ["\\", "/"] : ["/"];
- const globstar = os == "windows"
- ? "(?:[^\\\\/]*(?:\\\\|/|$)+)*"
- : "(?:[^/]*(?:/|$)+)*";
- const wildcard = os == "windows" ? "[^\\\\/]*" : "[^/]*";
- const escapePrefix = os == "windows" ? "`" : "\\";
-
- // Remove trailing separators.
- let newLength = glob.length;
- for (; newLength > 1 && seps.includes(glob[newLength - 1]); newLength--);
- glob = glob.slice(0, newLength);
-
- let regExpString = "";
-
- // Terminates correctly. Trust that `j` is incremented every iteration.
- for (let j = 0; j < glob.length;) {
- let segment = "";
- const groupStack = [];
- let inRange = false;
- let inEscape = false;
- let endsWithSep = false;
- let i = j;
-
- // Terminates with `i` at the non-inclusive end of the current segment.
- for (; i < glob.length && !seps.includes(glob[i]); i++) {
- if (inEscape) {
- inEscape = false;
- const escapeChars = inRange ? rangeEscapeChars : regExpEscapeChars;
- segment += escapeChars.includes(glob[i]) ? `\\${glob[i]}` : glob[i];
- continue;
- }
-
- if (glob[i] == escapePrefix) {
- inEscape = true;
- continue;
- }
-
- if (glob[i] == "[") {
- if (!inRange) {
- inRange = true;
- segment += "[";
- if (glob[i + 1] == "!") {
- i++;
- segment += "^";
- } else if (glob[i + 1] == "^") {
- i++;
- segment += "\\^";
- }
- continue;
- } else if (glob[i + 1] == ":") {
- let k = i + 1;
- let value = "";
- while (glob[k + 1] != null && glob[k + 1] != ":") {
- value += glob[k + 1];
- k++;
- }
- if (glob[k + 1] == ":" && glob[k + 2] == "]") {
- i = k + 2;
- if (value == "alnum") segment += "\\dA-Za-z";
- else if (value == "alpha") segment += "A-Za-z";
- else if (value == "ascii") segment += "\x00-\x7F";
- else if (value == "blank") segment += "\t ";
- else if (value == "cntrl") segment += "\x00-\x1F\x7F";
- else if (value == "digit") segment += "\\d";
- else if (value == "graph") segment += "\x21-\x7E";
- else if (value == "lower") segment += "a-z";
- else if (value == "print") segment += "\x20-\x7E";
- else if (value == "punct") {
- segment += "!\"#$%&'()*+,\\-./:;<=>?@[\\\\\\]^_‘{|}~";
- } else if (value == "space") segment += "\\s\v";
- else if (value == "upper") segment += "A-Z";
- else if (value == "word") segment += "\\w";
- else if (value == "xdigit") segment += "\\dA-Fa-f";
- continue;
- }
- }
- }
-
- if (glob[i] == "]" && inRange) {
- inRange = false;
- segment += "]";
- continue;
- }
-
- if (inRange) {
- if (glob[i] == "\\") {
- segment += `\\\\`;
- } else {
- segment += glob[i];
- }
- continue;
- }
-
- if (
- glob[i] == ")" && groupStack.length > 0 &&
- groupStack[groupStack.length - 1] != "BRACE"
- ) {
- segment += ")";
- const type = groupStack.pop()!;
- if (type == "!") {
- segment += wildcard;
- } else if (type != "@") {
- segment += type;
- }
- continue;
- }
-
- if (
- glob[i] == "|" && groupStack.length > 0 &&
- groupStack[groupStack.length - 1] != "BRACE"
- ) {
- segment += "|";
- continue;
- }
-
- if (glob[i] == "+" && extended && glob[i + 1] == "(") {
- i++;
- groupStack.push("+");
- segment += "(?:";
- continue;
- }
-
- if (glob[i] == "@" && extended && glob[i + 1] == "(") {
- i++;
- groupStack.push("@");
- segment += "(?:";
- continue;
- }
-
- if (glob[i] == "?") {
- if (extended && glob[i + 1] == "(") {
- i++;
- groupStack.push("?");
- segment += "(?:";
- } else {
- segment += ".";
- }
- continue;
- }
-
- if (glob[i] == "!" && extended && glob[i + 1] == "(") {
- i++;
- groupStack.push("!");
- segment += "(?!";
- continue;
- }
-
- if (glob[i] == "{") {
- groupStack.push("BRACE");
- segment += "(?:";
- continue;
- }
-
- if (glob[i] == "}" && groupStack[groupStack.length - 1] == "BRACE") {
- groupStack.pop();
- segment += ")";
- continue;
- }
-
- if (glob[i] == "," && groupStack[groupStack.length - 1] == "BRACE") {
- segment += "|";
- continue;
- }
-
- if (glob[i] == "*") {
- if (extended && glob[i + 1] == "(") {
- i++;
- groupStack.push("*");
- segment += "(?:";
- } else {
- const prevChar = glob[i - 1];
- let numStars = 1;
- while (glob[i + 1] == "*") {
- i++;
- numStars++;
- }
- const nextChar = glob[i + 1];
- if (
- globstarOption && numStars == 2 &&
- [...seps, undefined].includes(prevChar) &&
- [...seps, undefined].includes(nextChar)
- ) {
- segment += globstar;
- endsWithSep = true;
- } else {
- segment += wildcard;
- }
- }
- continue;
- }
-
- segment += regExpEscapeChars.includes(glob[i]) ? `\\${glob[i]}` : glob[i];
- }
-
- // Check for unclosed groups or a dangling backslash.
- if (groupStack.length > 0 || inRange || inEscape) {
- // Parse failure. Take all characters from this segment literally.
- segment = "";
- for (const c of glob.slice(j, i)) {
- segment += regExpEscapeChars.includes(c) ? `\\${c}` : c;
- endsWithSep = false;
- }
- }
-
- regExpString += segment;
- if (!endsWithSep) {
- regExpString += i < glob.length ? sep : sepMaybe;
- endsWithSep = true;
- }
-
- // Terminates with `i` at the start of the next segment.
- while (seps.includes(glob[i])) i++;
-
- // Check that the next value of `j` is indeed higher than the current value.
- if (!(i > j)) {
- throw new Error("Assertion failure: i > j (potential infinite loop)");
- }
- j = i;
- }
-
- regExpString = `^${regExpString}$`;
- return new RegExp(regExpString);
-}
-
-/** Test whether the given string is a glob */
-export function isGlob(str: string): boolean {
- const chars: Record<string, string> = { "{": "}", "(": ")", "[": "]" };
- const regex =
- /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/;
-
- if (str === "") {
- return false;
- }
-
- let match: RegExpExecArray | null;
-
- while ((match = regex.exec(str))) {
- if (match[2]) return true;
- let idx = match.index + match[0].length;
-
- // if an open bracket/brace/paren is escaped,
- // set the index to the next closing character
- const open = match[1];
- const close = open ? chars[open] : null;
- if (open && close) {
- const n = str.indexOf(close, idx);
- if (n !== -1) {
- idx = n + 1;
- }
- }
-
- str = str.slice(idx);
- }
-
- return false;
-}
-
-/** Like normalize(), but doesn't collapse "**\/.." when `globstar` is true. */
-export function normalizeGlob(
- glob: string,
- { globstar = false }: GlobOptions = {},
-): string {
- if (glob.match(/\0/g)) {
- throw new Error(`Glob contains invalid characters: "${glob}"`);
- }
- if (!globstar) {
- return normalize(glob);
- }
- const s = SEP_PATTERN.source;
- const badParentPattern = new RegExp(
- `(?<=(${s}|^)\\*\\*${s})\\.\\.(?=${s}|$)`,
- "g",
- );
- return normalize(glob.replace(badParentPattern, "\0")).replace(/\0/g, "..");
-}
-
-/** Like join(), but doesn't collapse "**\/.." when `globstar` is true. */
-export function joinGlobs(
- globs: string[],
- { extended = false, globstar = false }: GlobOptions = {},
-): string {
- if (!globstar || globs.length == 0) {
- return join(...globs);
- }
- if (globs.length === 0) return ".";
- let joined: string | undefined;
- for (const glob of globs) {
- const path = glob;
- if (path.length > 0) {
- if (!joined) joined = path;
- else joined += `${SEP}${path}`;
- }
- }
- if (!joined) return ".";
- return normalizeGlob(joined, { extended, globstar });
-}
diff --git a/std/path/glob_test.ts b/std/path/glob_test.ts
deleted file mode 100644
index cf46a3c5c..000000000
--- a/std/path/glob_test.ts
+++ /dev/null
@@ -1,638 +0,0 @@
-// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
-import { assert, assertEquals } from "../testing/asserts.ts";
-import {
- globToRegExp,
- GlobToRegExpOptions,
- isGlob,
- joinGlobs,
- normalizeGlob,
-} from "./glob.ts";
-import { SEP } from "./mod.ts";
-
-function match(
- glob: string,
- path: string,
- opts: GlobToRegExpOptions = {},
-): boolean {
- if (opts.os == null) {
- const matchDarwin = path.match(
- globToRegExp(glob, { ...opts, os: "darwin" }),
- );
- if (matchDarwin) {
- assertEquals(matchDarwin.length, 1);
- }
- const matchLinux = path.match(globToRegExp(glob, { ...opts, os: "linux" }));
- if (matchLinux) {
- assertEquals(matchLinux.length, 1);
- }
- const matchWindows = path.match(
- globToRegExp(glob, { ...opts, os: "windows" }),
- );
- if (matchWindows) {
- assertEquals(matchWindows.length, 1);
- }
- return !!matchDarwin && !!matchLinux && !!matchWindows;
- } else {
- const match = path.match(globToRegExp(glob, opts));
- if (match) {
- assertEquals(match.length, 1);
- }
- return !!match;
- }
-}
-
-Deno.test({
- name: "[path] globToRegExp() Basic RegExp",
- fn(): void {
- assertEquals(globToRegExp("*.js", { os: "linux" }), /^[^/]*\.js\/*$/);
- },
-});
-
-Deno.test({
- name: "[path] globToRegExp() Empty glob",
- fn(): void {
- assertEquals(globToRegExp(""), /(?!)/);
- assertEquals(globToRegExp("*.js", { os: "linux" }), /^[^/]*\.js\/*$/);
- },
-});
-
-Deno.test({
- name: "[path] globToRegExp() * (wildcard)",
- fn(): void {
- assert(match("*", "foo", { extended: false, globstar: false }));
- assert(match("*", "foo", { extended: false, globstar: false }));
- assert(match("f*", "foo", { extended: false, globstar: false }));
- assert(match("f*", "foo", { extended: false, globstar: false }));
- assert(match("*o", "foo", { extended: false, globstar: false }));
- assert(match("*o", "foo", { extended: false, globstar: false }));
- assert(match("u*orn", "unicorn", { extended: false, globstar: false }));
- assert(match("u*orn", "unicorn", { extended: false, globstar: false }));
- assert(!match("ico", "unicorn", { extended: false, globstar: false }));
- assert(match("u*nicorn", "unicorn", { extended: false, globstar: false }));
- assert(match("u*nicorn", "unicorn", { extended: false, globstar: false }));
- },
-});
-
-Deno.test({
- name: "[path] globToRegExp() ? (match one character)",
- fn(): void {
- assert(match("f?o", "foo", { extended: false, globstar: false }));
- assert(match("f?o?", "fooo", { extended: false, globstar: false }));
- assert(!match("f?oo", "foo", { extended: false, globstar: false }));
- assert(!match("?fo", "fooo", { extended: false, globstar: false }));
- assert(!match("f?oo", "foo", { extended: false, globstar: false }));
- assert(!match("foo?", "foo", { extended: false, globstar: false }));
- },
-});
-
-Deno.test({
- name: "[path] globToRegExp() [seq] (character range)",
- fn(): void {
- assert(match("fo[oz]", "foo", { extended: false, globstar: false }));
- assert(match("fo[oz]", "foz", { extended: false, globstar: false }));
- assert(!match("fo[oz]", "fog", { extended: false, globstar: false }));
- assert(match("fo[a-z]", "fob", { extended: false, globstar: false }));
- assert(!match("fo[a-d]", "fot", { extended: false, globstar: false }));
- assert(!match("fo[!tz]", "fot", { extended: false, globstar: false }));
- assert(match("fo[!tz]", "fob", { extended: false, globstar: false }));
- },
-});
-
-Deno.test({
- name: "[path] globToRegExp() [[:alnum:]] (character class in range)",
- fn(): void {
- assert(
- match(
- "[[:alnum:]]/bar.txt",
- "a/bar.txt",
- { extended: false, globstar: false },
- ),
- );
- assert(
- match(
- "[[:alnum:]abc]/bar.txt",
- "1/bar.txt",
- { extended: false, globstar: false },
- ),
- );
- assert(
- !match(
- "[[:alnum:]]/bar.txt",
- "!/bar.txt",
- { extended: false, globstar: false },
- ),
- );
- for (const c of "09AGZagz") {
- assert(match("[[:alnum:]]", c, { extended: false, globstar: false }), c);
- }
- for (const c of "AGZagz") {
- assert(match("[[:alpha:]]", c, { extended: false, globstar: false }), c);
- }
- for (const c of "\x00\x20\x7F") {
- assert(match("[[:ascii:]]", c, { extended: false, globstar: false }), c);
- }
- for (const c of "\t ") {
- assert(match("[[:blank:]]", c, { extended: false, globstar: false }), c);
- }
- for (const c of "\x00\x1F\x7F") {
- assert(match("[[:cntrl:]]", c, { extended: false, globstar: false }), c);
- }
- for (const c of "09") {
- assert(match("[[:digit:]]", c, { extended: false, globstar: false }), c);
- }
- for (const c of "\x21\x7E") {
- assert(match("[[:graph:]]", c, { extended: false, globstar: false }), c);
- }
- for (const c of "az") {
- assert(match("[[:lower:]]", c, { extended: false, globstar: false }), c);
- }
- for (const c of "\x20\x7E") {
- assert(match("[[:print:]]", c, { extended: false, globstar: false }), c);
- }
- for (const c of "!\"#$%&'()*+,-./:;<=>?@[\\]^_‘{|}~") {
- assert(match("[[:punct:]]", c, { extended: false, globstar: false }), c);
- }
- for (const c of "\t\n\v\f\r ") {
- assert(match("[[:space:]]", c, { extended: false, globstar: false }), c);
- }
- for (const c of "AZ") {
- assert(match("[[:upper:]]", c, { extended: false, globstar: false }), c);
- }
- for (const c of "09AZaz_") {
- assert(match("[[:word:]]", c, { extended: false, globstar: false }), c);
- }
- for (const c of "09AFaf") {
- assert(match("[[:xdigit:]]", c, { extended: false, globstar: false }), c);
- }
- },
-});
-
-Deno.test({
- name: "[path] globToRegExp() {} (brace expansion)",
- fn(): void {
- assert(
- match("foo{bar,baaz}", "foobaaz", { extended: false, globstar: false }),
- );
- assert(
- match("foo{bar,baaz}", "foobar", { extended: false, globstar: false }),
- );
- assert(
- !match("foo{bar,baaz}", "foobuzz", { extended: false, globstar: false }),
- );
- assert(
- match("foo{bar,b*z}", "foobuzz", { extended: false, globstar: false }),
- );
- },
-});
-
-Deno.test({
- name: "[path] globToRegExp() Complex matches",
- fn(): void {
- assert(
- match(
- "http://?o[oz].b*z.com/{*.js,*.html}",
- "http://foo.baaz.com/jquery.min.js",
- { extended: false, globstar: false },
- ),
- );
- assert(
- match(
- "http://?o[oz].b*z.com/{*.js,*.html}",
- "http://moz.buzz.com/index.html",
- { extended: false, globstar: false },
- ),
- );
- assert(
- !match(
- "http://?o[oz].b*z.com/{*.js,*.html}",
- "http://moz.buzz.com/index.htm",
- { extended: false, globstar: false },
- ),
- );
- assert(
- !match(
- "http://?o[oz].b*z.com/{*.js,*.html}",
- "http://moz.bar.com/index.html",
- { extended: false, globstar: false },
- ),
- );
- assert(
- !match(
- "http://?o[oz].b*z.com/{*.js,*.html}",
- "http://flozz.buzz.com/index.html",
- { extended: false, globstar: false },
- ),
- );
- },
-});
-
-Deno.test({
- name: "[path] globToRegExp() ** (globstar)",
- fn(): void {
- assert(match("/foo/**", "/foo/bar.txt"));
- assert(match("/foo/**", "/foo/bar/baz.txt"));
- assert(!match("/foo/**", "/foo/bar/baz.txt", { globstar: false }));
- assert(match("/foo/**", "/foo/bar", { globstar: false }));
- assert(match("/foo/**/*.txt", "/foo/bar/baz.txt"));
- assert(match("/foo/**/*.txt", "/foo/bar/baz/qux.txt"));
- assert(match("/foo/**/bar.txt", "/foo/bar.txt"));
- assert(match("/foo/**/**/bar.txt", "/foo/bar.txt"));
- assert(match("/foo/**/*/baz.txt", "/foo/bar/baz.txt"));
- assert(match("/foo/**/*.txt", "/foo/bar.txt"));
- assert(match("/foo/**/**/*.txt", "/foo/bar.txt"));
- assert(match("/foo/**/*/*.txt", "/foo/bar/baz.txt"));
- assert(match("**/*.txt", "/foo/bar/baz/qux.txt"));
- assert(match("**/foo.txt", "foo.txt"));
- assert(match("**/*.txt", "foo.txt"));
- assert(!match("/foo/**.txt", "/foo/bar/baz/qux.txt"));
- assert(
- !match("/foo/bar**/*.txt", "/foo/bar/baz/qux.txt"),
- );
- assert(!match("/foo/bar**", "/foo/bar/baz.txt"));
- assert(!match("**/.txt", "/foo/bar/baz/qux.txt"));
- assert(
- !match(
- "http://foo.com/*",
- "http://foo.com/bar/baz/jquery.min.js",
- ),
- );
- assert(
- !match("http://foo.com/*", "http://foo.com/bar/baz/jquery.min.js"),
- );
- assert(
- match("http://foo.com/**", "http://foo.com/bar/baz/jquery.min.js"),
- );
- assert(
- match(
- "http://foo.com/**/jquery.min.js",
- "http://foo.com/bar/baz/jquery.min.js",
- ),
- );
- assert(
- !match(
- "http://foo.com/*/jquery.min.js",
- "http://foo.com/bar/baz/jquery.min.js",
- ),
- );
- },
-});
-
-Deno.test({
- name: "[path] globToRegExp() ?(pattern-list) (extended: match zero or one)",
- fn(): void {
- assert(match("?(foo).txt", "foo.txt"));
- assert(!match("?(foo).txt", "foo.txt", { extended: false }));
- assert(match("?(foo).txt", "a(foo).txt", { extended: false }));
- assert(match("?(foo).txt", ".txt"));
- assert(match("?(foo|bar)baz.txt", "foobaz.txt"));
- assert(match("?(ba[zr]|qux)baz.txt", "bazbaz.txt"));
- assert(match("?(ba[zr]|qux)baz.txt", "barbaz.txt"));
- assert(match("?(ba[zr]|qux)baz.txt", "quxbaz.txt"));
- assert(match("?(ba[!zr]|qux)baz.txt", "batbaz.txt"));
- assert(match("?(ba*|qux)baz.txt", "batbaz.txt"));
- assert(match("?(ba*|qux)baz.txt", "batttbaz.txt"));
- assert(match("?(ba*|qux)baz.txt", "quxbaz.txt"));
- assert(match("?(ba?(z|r)|qux)baz.txt", "bazbaz.txt"));
- assert(match("?(ba?(z|?(r))|qux)baz.txt", "bazbaz.txt"));
- assert(!match("?(foo|bar)baz.txt", "foobarbaz.txt"));
- assert(!match("?(ba[zr]|qux)baz.txt", "bazquxbaz.txt"));
- assert(!match("?(ba[!zr]|qux)baz.txt", "bazbaz.txt"));
- },
-});
-
-Deno.test({
- name: "[path] globToRegExp() *(pattern-list) (extended: match zero or more)",
- fn(): void {
- assert(match("*(foo).txt", "foo.txt"));
- assert(!match("*(foo).txt", "foo.txt", { extended: false }));
- assert(match("*(foo).txt", "bar(foo).txt", { extended: false }));
- assert(match("*(foo).txt", "foofoo.txt"));
- assert(match("*(foo).txt", ".txt"));
- assert(match("*(fooo).txt", ".txt"));
- assert(!match("*(fooo).txt", "foo.txt"));
- assert(match("*(foo|bar).txt", "foobar.txt"));
- assert(match("*(foo|bar).txt", "barbar.txt"));
- assert(match("*(foo|bar).txt", "barfoobar.txt"));
- assert(match("*(foo|bar).txt", ".txt"));
- assert(match("*(foo|ba[rt]).txt", "bat.txt"));
- assert(match("*(foo|b*[rt]).txt", "blat.txt"));
- assert(!match("*(foo|b*[rt]).txt", "tlat.txt"));
- assert(match("*(*).txt", "whatever.txt"));
- assert(match("*(foo|bar)/**/*.txt", "foo/hello/world/bar.txt"));
- assert(match("*(foo|bar)/**/*.txt", "foo/world/bar.txt"));
- },
-});
-
-Deno.test({
- name: "[path] globToRegExp() +(pattern-list) (extended: match 1 or more)",
- fn(): void {
- assert(match("+(foo).txt", "foo.txt"));
- assert(!match("+(foo).txt", "foo.txt", { extended: false }));
- assert(match("+(foo).txt", "+(foo).txt", { extended: false }));
- assert(!match("+(foo).txt", ".txt"));
- assert(match("+(foo|bar).txt", "foobar.txt"));
- },
-});
-
-Deno.test({
- name: "[path] globToRegExp() @(pattern-list) (extended: match one)",
- fn(): void {
- assert(match("@(foo).txt", "foo.txt"));
- assert(!match("@(foo).txt", "foo.txt", { extended: false }));
- assert(match("@(foo).txt", "@(foo).txt", { extended: false }));
- assert(match("@(foo|baz)bar.txt", "foobar.txt"));
- assert(!match("@(foo|baz)bar.txt", "foobazbar.txt"));
- assert(!match("@(foo|baz)bar.txt", "foofoobar.txt"));
- assert(!match("@(foo|baz)bar.txt", "toofoobar.txt"));
- },
-});
-
-Deno.test({
- name: "[path] globToRegExp() !(pattern-list) (extended: match any except)",
- fn(): void {
- assert(match("!(boo).txt", "foo.txt"));
- assert(!match("!(boo).txt", "foo.txt", { extended: false }));
- assert(match("!(boo).txt", "!(boo).txt", { extended: false }));
- assert(match("!(foo|baz)bar.txt", "buzbar.txt"));
- assert(match("!({foo,bar})baz.txt", "notbaz.txt"));
- assert(!match("!({foo,bar})baz.txt", "foobaz.txt"));
- },
-});
-
-Deno.test({
- name:
- "[path] globToRegExp() Special extended characters should match themselves",
- fn(): void {
- const glob = "\\/$^+.()=!|,.*";
- assert(match(glob, glob));
- assert(match(glob, glob, { extended: false }));
- },
-});
-
-Deno.test({
- name: "[path] globToRegExp() Special extended characters in range",
- fn(): void {
- assertEquals(globToRegExp("[?*+@!|]", { os: "linux" }), /^[?*+@!|]\/*$/);
- assertEquals(globToRegExp("[!?*+@!|]", { os: "linux" }), /^[^?*+@!|]\/*$/);
- },
-});
-
-Deno.test({
- name: "[path] globToRegExp() Special RegExp characters in range",
- fn(): void {
- // Excluding characters checked in the previous test.
- assertEquals(globToRegExp("[\\\\$^.=]", { os: "linux" }), /^[\\$^.=]\/*$/);
- assertEquals(
- globToRegExp("[!\\\\$^.=]", { os: "linux" }),
- /^[^\\$^.=]\/*$/,
- );
- assertEquals(globToRegExp("[^^]", { os: "linux" }), /^[\^^]\/*$/);
- },
-});
-
-Deno.test({
- name: "[path] globToRegExp() Repeating separators",
- fn() {
- assert(match("foo/bar", "foo//bar"));
- assert(match("foo//bar", "foo/bar"));
- assert(match("foo//bar", "foo//bar"));
- assert(match("**/bar", "foo//bar"));
- assert(match("**//bar", "foo/bar"));
- assert(match("**//bar", "foo//bar"));
- },
-});
-
-Deno.test({
- name: "[path] globToRegExp() Trailing separators",
- fn() {
- assert(match("foo", "foo/"));
- assert(match("foo/", "foo"));
- assert(match("foo/", "foo/"));
- assert(match("**", "foo/"));
- assert(match("**/", "foo"));
- assert(match("**/", "foo/"));
- },
-});
-
-Deno.test({
- name: "[path] globToRegExp() Backslashes on Windows",
- fn() {
- assert(match("foo/bar", "foo\\bar", { os: "windows" }));
- assert(match("foo\\bar", "foo/bar", { os: "windows" }));
- assert(match("foo\\bar", "foo\\bar", { os: "windows" }));
- assert(match("**/bar", "foo\\bar", { os: "windows" }));
- assert(match("**\\bar", "foo/bar", { os: "windows" }));
- assert(match("**\\bar", "foo\\bar", { os: "windows" }));
- },
-});
-
-Deno.test({
- name: "[path] globToRegExp() Unclosed groups",
- fn() {
- assert(match("{foo,bar}/[ab", "foo/[ab"));
- assert(match("{foo,bar}/{foo,bar", "foo/{foo,bar"));
- assert(match("{foo,bar}/?(foo|bar", "foo/?(foo|bar"));
- assert(match("{foo,bar}/@(foo|bar", "foo/@(foo|bar"));
- assert(match("{foo,bar}/*(foo|bar", "foo/*(foo|bar"));
- assert(match("{foo,bar}/+(foo|bar", "foo/+(foo|bar"));
- assert(match("{foo,bar}/!(foo|bar", "foo/!(foo|bar"));
- assert(match("{foo,bar}/?({)}", "foo/?({)}"));
- assert(match("{foo,bar}/{?(})", "foo/{?(})"));
- },
-});
-
-Deno.test({
- name: "[path] globToRegExp() Escape glob characters",
- fn() {
- assert(match("\\[ab]", "[ab]", { os: "linux" }));
- assert(match("`[ab]", "[ab]", { os: "windows" }));
- assert(match("\\{foo,bar}", "{foo,bar}", { os: "linux" }));
- assert(match("`{foo,bar}", "{foo,bar}", { os: "windows" }));
- assert(match("\\?(foo|bar)", "?(foo|bar)", { os: "linux" }));
- assert(match("`?(foo|bar)", "?(foo|bar)", { os: "windows" }));
- assert(match("\\@(foo|bar)", "@(foo|bar)", { os: "linux" }));
- assert(match("`@(foo|bar)", "@(foo|bar)", { os: "windows" }));
- assert(match("\\*(foo|bar)", "*(foo|bar)", { os: "linux" }));
- assert(match("`*(foo|bar)", "*(foo|bar)", { os: "windows" }));
- assert(match("\\+(foo|bar)", "+(foo|bar)", { os: "linux" }));
- assert(match("`+(foo|bar)", "+(foo|bar)", { os: "windows" }));
- assert(match("\\!(foo|bar)", "!(foo|bar)", { os: "linux" }));
- assert(match("`!(foo|bar)", "!(foo|bar)", { os: "windows" }));
- assert(match("@\\(foo|bar)", "@(foo|bar)", { os: "linux" }));
- assert(match("@`(foo|bar)", "@(foo|bar)", { os: "windows" }));
- assert(match("{foo,bar}/[ab]\\", "foo/[ab]\\", { os: "linux" }));
- assert(match("{foo,bar}/[ab]`", "foo/[ab]`", { os: "windows" }));
- },
-});
-
-Deno.test({
- name: "[path] globToRegExp() Dangling escape prefix",
- fn() {
- assert(match("{foo,bar}/[ab]\\", "foo/[ab]\\", { os: "linux" }));
- assert(match("{foo,bar}/[ab]`", "foo/[ab]`", { os: "windows" }));
- },
-});
-
-Deno.test({
- name: "[path] GlobToRegExpOptions::extended",
- fn() {
- const pattern1 = globToRegExp("?(foo|bar)");
- assertEquals("foo".match(pattern1)?.[0], "foo");
- assertEquals("bar".match(pattern1)?.[0], "bar");
-
- const pattern2 = globToRegExp("?(foo|bar)", { extended: false });
- assertEquals("foo".match(pattern2)?.[0], undefined);
- assertEquals("bar".match(pattern2)?.[0], undefined);
- assertEquals("?(foo|bar)".match(pattern2)?.[0], "?(foo|bar)");
- },
-});
-
-Deno.test({
- name: "[path] GlobToRegExpOptions::globstar",
- fn() {
- const pattern1 = globToRegExp("**/foo");
- assertEquals("foo".match(pattern1)?.[0], "foo");
- assertEquals("path/to/foo".match(pattern1)?.[0], "path/to/foo");
-
- const pattern2 = globToRegExp("**/foo", { globstar: false });
- assertEquals("foo".match(pattern2)?.[0], undefined);
- assertEquals("path/to/foo".match(pattern2)?.[0], undefined);
- assertEquals("path-to/foo".match(pattern2)?.[0], "path-to/foo");
- },
-});
-
-Deno.test({
- name: "[path] GlobToRegExpOptions::os",
- fn() {
- const pattern1 = globToRegExp("foo/bar", { os: "linux" });
- assertEquals("foo/bar".match(pattern1)?.[0], "foo/bar");
- assertEquals("foo\\bar".match(pattern1)?.[0], undefined);
-
- const pattern2 = globToRegExp("foo/bar", { os: "windows" });
- assertEquals("foo/bar".match(pattern2)?.[0], "foo/bar");
- assertEquals("foo\\bar".match(pattern2)?.[0], "foo\\bar");
- },
-});
-
-Deno.test({
- name: "[path] isGlob()",
- fn(): void {
- // should be true if valid glob pattern
- assert(isGlob("!foo.js"));
- assert(isGlob("*.js"));
- assert(isGlob("!*.js"));
- assert(isGlob("!foo"));
- assert(isGlob("!foo.js"));
- assert(isGlob("**/abc.js"));
- assert(isGlob("abc/*.js"));
- assert(isGlob("@.(?:abc)"));
- assert(isGlob("@.(?!abc)"));
-
- // should be false if invalid glob pattern
- assert(!isGlob(""));
- assert(!isGlob("~/abc"));
- assert(!isGlob("~/abc"));
- assert(!isGlob("~/(abc)"));
- assert(!isGlob("+~(abc)"));
- assert(!isGlob("."));
- assert(!isGlob("@.(abc)"));
- assert(!isGlob("aa"));
- assert(!isGlob("who?"));
- assert(!isGlob("why!?"));
- assert(!isGlob("where???"));
- assert(!isGlob("abc!/def/!ghi.js"));
- assert(!isGlob("abc.js"));
- assert(!isGlob("abc/def/!ghi.js"));
- assert(!isGlob("abc/def/ghi.js"));
-
- // Should be true if path has regex capture group
- assert(isGlob("abc/(?!foo).js"));
- assert(isGlob("abc/(?:foo).js"));
- assert(isGlob("abc/(?=foo).js"));
- assert(isGlob("abc/(a|b).js"));
- assert(isGlob("abc/(a|b|c).js"));
- assert(isGlob("abc/(foo bar)/*.js"));
-
- // Should be false if the path has parens but is not a valid capture group
- assert(!isGlob("abc/(?foo).js"));
- assert(!isGlob("abc/(a b c).js"));
- assert(!isGlob("abc/(ab).js"));
- assert(!isGlob("abc/(abc).js"));
- assert(!isGlob("abc/(foo bar).js"));
-
- // should be false if the capture group is imbalanced
- assert(!isGlob("abc/(?ab.js"));
- assert(!isGlob("abc/(ab.js"));
- assert(!isGlob("abc/(a|b.js"));
- assert(!isGlob("abc/(a|b|c.js"));
-
- // should be true if the path has a regex character class
- assert(isGlob("abc/[abc].js"));
- assert(isGlob("abc/[^abc].js"));
- assert(isGlob("abc/[1-3].js"));
-
- // should be false if the character class is not balanced
- assert(!isGlob("abc/[abc.js"));
- assert(!isGlob("abc/[^abc.js"));
- assert(!isGlob("abc/[1-3.js"));
-
- // should be false if the character class is escaped
- assert(!isGlob("abc/\\[abc].js"));
- assert(!isGlob("abc/\\[^abc].js"));
- assert(!isGlob("abc/\\[1-3].js"));
-
- // should be true if the path has brace characters
- assert(isGlob("abc/{a,b}.js"));
- assert(isGlob("abc/{a..z}.js"));
- assert(isGlob("abc/{a..z..2}.js"));
-
- // should be false if (basic) braces are not balanced
- assert(!isGlob("abc/\\{a,b}.js"));
- assert(!isGlob("abc/\\{a..z}.js"));
- assert(!isGlob("abc/\\{a..z..2}.js"));
-
- // should be true if the path has regex characters
- assert(isGlob("!&(abc)"));
- assert(isGlob("!*.js"));
- assert(isGlob("!foo"));
- assert(isGlob("!foo.js"));
- assert(isGlob("**/abc.js"));
- assert(isGlob("*.js"));
- assert(isGlob("*z(abc)"));
- assert(isGlob("[1-10].js"));
- assert(isGlob("[^abc].js"));
- assert(isGlob("[a-j]*[^c]b/c"));
- assert(isGlob("[abc].js"));
- assert(isGlob("a/b/c/[a-z].js"));
- assert(isGlob("abc/(aaa|bbb).js"));
- assert(isGlob("abc/*.js"));
- assert(isGlob("abc/{a,b}.js"));
- assert(isGlob("abc/{a..z..2}.js"));
- assert(isGlob("abc/{a..z}.js"));
-
- assert(!isGlob("$(abc)"));
- assert(!isGlob("&(abc)"));
- assert(!isGlob("Who?.js"));
- assert(!isGlob("? (abc)"));
- assert(!isGlob("?.js"));
- assert(!isGlob("abc/?.js"));
-
- // should be false if regex characters are escaped
- assert(!isGlob("\\?.js"));
- assert(!isGlob("\\[1-10\\].js"));
- assert(!isGlob("\\[^abc\\].js"));
- assert(!isGlob("\\[a-j\\]\\*\\[^c\\]b/c"));
- assert(!isGlob("\\[abc\\].js"));
- assert(!isGlob("\\a/b/c/\\[a-z\\].js"));
- assert(!isGlob("abc/\\(aaa|bbb).js"));
- assert(!isGlob("abc/\\?.js"));
- },
-});
-
-Deno.test("[path] normalizeGlob() Globstar", function (): void {
- assertEquals(normalizeGlob(`**${SEP}..`, { globstar: true }), `**${SEP}..`);
-});
-
-Deno.test("[path] joinGlobs() Globstar", function (): void {
- assertEquals(joinGlobs(["**", ".."], { globstar: true }), `**${SEP}..`);
-});
diff --git a/std/path/isabsolute_test.ts b/std/path/isabsolute_test.ts
deleted file mode 100644
index 88ed54417..000000000
--- a/std/path/isabsolute_test.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright the Browserify authors. MIT License.
-// Ported from https://github.com/browserify/path-browserify/
-import { assertEquals } from "../testing/asserts.ts";
-import * as path from "./mod.ts";
-
-Deno.test("isAbsolute", function () {
- 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);
-});
-
-Deno.test("isAbsoluteWin32", function () {
- 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/path/join_test.ts b/std/path/join_test.ts
deleted file mode 100644
index 122376be1..000000000
--- a/std/path/join_test.ts
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
-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"],
-];
-
-Deno.test("join", function () {
- joinTests.forEach(function (p) {
- const _p = p[0] as string[];
- const actual = path.posix.join.apply(null, _p);
- assertEquals(actual, p[1]);
- });
-});
-
-Deno.test("joinWin32", function () {
- 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/path/mod.ts b/std/path/mod.ts
deleted file mode 100644
index 5fd793c75..000000000
--- a/std/path/mod.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright the Browserify authors. MIT License.
-// Ported mostly from https://github.com/browserify/path-browserify/
-// This module is browser compatible.
-
-import { isWindows } from "../_util/os.ts";
-import * as _win32 from "./win32.ts";
-import * as _posix from "./posix.ts";
-
-const path = isWindows ? _win32 : _posix;
-
-export const win32 = _win32;
-export const posix = _posix;
-export const {
- basename,
- delimiter,
- dirname,
- extname,
- format,
- fromFileUrl,
- isAbsolute,
- join,
- normalize,
- parse,
- relative,
- resolve,
- sep,
- toFileUrl,
- toNamespacedPath,
-} = path;
-
-export * from "./common.ts";
-export { SEP, SEP_PATTERN } from "./separator.ts";
-export * from "./_interface.ts";
-export * from "./glob.ts";
diff --git a/std/path/parse_format_test.ts b/std/path/parse_format_test.ts
deleted file mode 100644
index 785588359..000000000
--- a/std/path/parse_format_test.ts
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright the Browserify authors. MIT License.
-// Ported from https://github.com/browserify/path-browserify/
-import type { FormatInputPathObject, ParsedPath } from "./mod.ts";
-
-import { assertEquals } from "../testing/asserts.ts";
-import { posix, win32 } from "./mod.ts";
-
-type FormatTestCase = [FormatInputPathObject, string];
-type ParseTestCase = [string, ParsedPath];
-
-const winPaths: Array<[string, string]> = [
- // [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: ParseTestCase[] = [
- ["/foo/bar", { root: "/", dir: "/foo", base: "bar", ext: "", name: "bar" }],
-];
-
-const winSpecialCaseFormatTests: FormatTestCase[] = [
- [{ 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: Array<[string, string]> = [
- // [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: FormatTestCase[] = [
- [{ 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: typeof win32 | typeof posix,
- testCases: Array<[string, string]>,
-): void {
- testCases.forEach(([element, root]) => {
- 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.root, root);
- assertEquals(output.dir, output.dir ? path.dirname(element) : "");
- assertEquals(output.base, path.basename(element));
- assertEquals(output.ext, path.extname(element));
- });
-}
-
-function checkSpecialCaseParseFormat(
- path: typeof win32 | typeof posix,
- testCases: ParseTestCase[],
-): void {
- testCases.forEach(([element, expect]) => {
- assertEquals(path.parse(element), expect);
- });
-}
-
-function checkFormat(
- path: typeof win32 | typeof posix,
- testCases: FormatTestCase[],
-): void {
- testCases.forEach((testCase) => {
- assertEquals(path.format(testCase[0]), testCase[1]);
- });
-}
-
-Deno.test("parseWin32", function () {
- checkParseFormat(win32, winPaths);
- checkSpecialCaseParseFormat(win32, winSpecialCaseParseTests);
-});
-
-Deno.test("parse", function () {
- checkParseFormat(posix, unixPaths);
-});
-
-Deno.test("formatWin32", function () {
- checkFormat(win32, winSpecialCaseFormatTests);
-});
-
-Deno.test("format", function () {
- checkFormat(posix, unixSpecialCaseFormatTests);
-});
-
-// Test removal of trailing path separators
-const windowsTrailingTests: ParseTestCase[] = [
- [".\\", { 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: ParseTestCase[] = [
- ["./", { 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" },
- ],
-];
-
-Deno.test("parseTrailingWin32", function () {
- windowsTrailingTests.forEach(function (p) {
- const actual = win32.parse(p[0]);
- const expected = p[1];
- assertEquals(actual, expected);
- });
-});
-
-Deno.test("parseTrailing", function () {
- posixTrailingTests.forEach(function (p) {
- const actual = posix.parse(p[0]);
- const expected = p[1];
- assertEquals(actual, expected);
- });
-});
diff --git a/std/path/posix.ts b/std/path/posix.ts
deleted file mode 100644
index ed3649bd3..000000000
--- a/std/path/posix.ts
+++ /dev/null
@@ -1,504 +0,0 @@
-// Copyright the Browserify authors. MIT License.
-// Ported from https://github.com/browserify/path-browserify/
-// This module is browser compatible.
-
-import type { FormatInputPathObject, ParsedPath } from "./_interface.ts";
-import { CHAR_DOT, CHAR_FORWARD_SLASH } from "./_constants.ts";
-
-import {
- _format,
- assertPath,
- isPosixPathSeparator,
- normalizeString,
-} from "./_util.ts";
-
-export const sep = "/";
-export const delimiter = ":";
-
-// path.resolve([from ...], to)
-/**
- * Resolves `pathSegments` into an absolute path.
- * @param pathSegments an array of path segments
- */
-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 {
- if (globalThis.Deno == null) {
- throw new TypeError("Resolved a relative path without a CWD.");
- }
- path = Deno.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 ".";
-}
-
-/**
- * Normalize the `path`, resolving `'..'` and `'.'` segments.
- * @param path to be normalized
- */
-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;
-}
-
-/**
- * Verifies whether provided path is absolute
- * @param path to be verified as absolute
- */
-export function isAbsolute(path: string): boolean {
- assertPath(path);
- return path.length > 0 && path.charCodeAt(0) === CHAR_FORWARD_SLASH;
-}
-
-/**
- * Join all given a sequence of `paths`,then normalizes the resulting path.
- * @param paths to be joined and normalized
- */
-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);
-}
-
-/**
- * Return the relative path from `from` to `to` based on current working directory.
- * @param from path in current working directory
- * @param to path in current working directory
- */
-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);
- }
-}
-
-/**
- * Resolves path to a namespace path
- * @param path to resolve to namespace
- */
-export function toNamespacedPath(path: string): string {
- // Non-op on posix systems
- return path;
-}
-
-/**
- * Return the directory name of a `path`.
- * @param path to determine name for
- */
-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);
-}
-
-/**
- * Return the last portion of a `path`. Trailing directory separators are ignored.
- * @param path to process
- * @param ext of path directory
- */
-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);
- }
-}
-
-/**
- * Return the extension of the `path`.
- * @param path with extension
- */
-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);
-}
-
-/**
- * Generate a path from `FormatInputPathObject` object.
- * @param pathObject with path
- */
-export function format(pathObject: FormatInputPathObject): string {
- if (pathObject === null || typeof pathObject !== "object") {
- throw new TypeError(
- `The "pathObject" argument must be of type Object. Received type ${typeof pathObject}`,
- );
- }
- return _format("/", pathObject);
-}
-
-/**
- * Return a `ParsedPath` object of the `path`.
- * @param path to process
- */
-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;
-}
-
-/**
- * Converts a file URL to a path string.
- *
- * fromFileUrl("file:///home/foo"); // "/home/foo"
- * @param url of a file URL
- */
-export function fromFileUrl(url: string | URL): string {
- url = url instanceof URL ? url : new URL(url);
- if (url.protocol != "file:") {
- throw new TypeError("Must be a file URL.");
- }
- return decodeURIComponent(
- url.pathname.replace(/%(?![0-9A-Fa-f]{2})/g, "%25"),
- );
-}
-
-/**
- * Converts a path string to a file URL.
- *
- * toFileUrl("/home/foo"); // new URL("file:///home/foo")
- * @param path to convert to file URL
- */
-export function toFileUrl(path: string): URL {
- if (!isAbsolute(path)) {
- throw new TypeError("Must be an absolute path.");
- }
- const url = new URL("file:///");
- url.pathname = path.replace(/%/g, "%25").replace(/\\/g, "%5C");
- return url;
-}
diff --git a/std/path/relative_test.ts b/std/path/relative_test.ts
deleted file mode 100644
index e00e16d73..000000000
--- a/std/path/relative_test.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright the Browserify authors. MIT License.
-// Ported from https://github.com/browserify/path-browserify/
-import { assertEquals } from "../testing/asserts.ts";
-import * as path from "./mod.ts";
-
-const relativeTests = {
- // arguments result
- win32: [
- ["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"],
- ],
- // arguments result
- posix: [
- ["/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"],
- ],
-};
-
-Deno.test("relative", function () {
- relativeTests.posix.forEach(function (p) {
- const expected = p[2];
- const actual = path.posix.relative(p[0], p[1]);
- assertEquals(actual, expected);
- });
-});
-
-Deno.test("relativeWin32", function () {
- 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/path/resolve_test.ts b/std/path/resolve_test.ts
deleted file mode 100644
index dec032f47..000000000
--- a/std/path/resolve_test.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright the Browserify authors. MIT License.
-// Ported from https://github.com/browserify/path-browserify/
-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/", "../../.."], Deno.cwd()],
- [["."], Deno.cwd()],
- [["/some/dir", ".", "/absolute/"], "/absolute"],
- [["/foo/tmp.3/", "../tmp.3/cycles/root.js"], "/foo/tmp.3/cycles/root.js"],
- ];
-
-Deno.test("resolve", function () {
- posixTests.forEach(function (p) {
- const _p = p[0] as string[];
- const actual = path.posix.resolve.apply(null, _p);
- assertEquals(actual, p[1]);
- });
-});
-
-Deno.test("resolveWin32", function () {
- 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/path/separator.ts b/std/path/separator.ts
deleted file mode 100644
index d897e07e6..000000000
--- a/std/path/separator.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
-// This module is browser compatible.
-
-import { isWindows } from "../_util/os.ts";
-
-export const SEP = isWindows ? "\\" : "/";
-export const SEP_PATTERN = isWindows ? /[\\/]+/ : /\/+/;
diff --git a/std/path/test.ts b/std/path/test.ts
deleted file mode 100644
index 590417055..000000000
--- a/std/path/test.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
-import "./mod.ts";
diff --git a/std/path/to_file_url_test.ts b/std/path/to_file_url_test.ts
deleted file mode 100644
index c4ee1a236..000000000
--- a/std/path/to_file_url_test.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
-import { posix, win32 } from "./mod.ts";
-import { assertEquals, assertThrows } from "../testing/asserts.ts";
-
-Deno.test("[path] toFileUrl", function () {
- assertEquals(posix.toFileUrl("/home/foo").href, "file:///home/foo");
- assertEquals(posix.toFileUrl("/home/ ").href, "file:///home/%20");
- assertEquals(posix.toFileUrl("/home/%20").href, "file:///home/%2520");
- assertEquals(posix.toFileUrl("/home\\foo").href, "file:///home%5Cfoo");
- assertThrows(
- () => posix.toFileUrl("foo").href,
- TypeError,
- "Must be an absolute path.",
- );
- assertThrows(
- () => posix.toFileUrl("C:/"),
- TypeError,
- "Must be an absolute path.",
- );
- assertEquals(
- posix.toFileUrl("//localhost/home/foo").href,
- "file:////localhost/home/foo",
- );
- assertEquals(posix.toFileUrl("//localhost/").href, "file:////localhost/");
- assertEquals(posix.toFileUrl("//:/home/foo").href, "file:////:/home/foo");
-});
-
-Deno.test("[path] toFileUrl (win32)", function () {
- assertEquals(win32.toFileUrl("/home/foo").href, "file:///home/foo");
- assertEquals(win32.toFileUrl("/home/ ").href, "file:///home/%20");
- assertEquals(win32.toFileUrl("/home/%20").href, "file:///home/%2520");
- assertEquals(win32.toFileUrl("/home\\foo").href, "file:///home/foo");
- assertThrows(
- () => win32.toFileUrl("foo").href,
- TypeError,
- "Must be an absolute path.",
- );
- assertEquals(win32.toFileUrl("C:/").href, "file:///C:/");
- assertEquals(
- win32.toFileUrl("//localhost/home/foo").href,
- "file://localhost/home/foo",
- );
- assertEquals(win32.toFileUrl("//localhost/").href, "file:////localhost/");
- assertThrows(
- () => win32.toFileUrl("//:/home/foo").href,
- TypeError,
- "Invalid hostname.",
- );
-});
diff --git a/std/path/win32.ts b/std/path/win32.ts
deleted file mode 100644
index d456c68e4..000000000
--- a/std/path/win32.ts
+++ /dev/null
@@ -1,1001 +0,0 @@
-// Copyright the Browserify authors. MIT License.
-// Ported from https://github.com/browserify/path-browserify/
-// This module is browser compatible.
-
-import type { FormatInputPathObject, ParsedPath } from "./_interface.ts";
-import {
- CHAR_BACKWARD_SLASH,
- CHAR_COLON,
- CHAR_DOT,
- CHAR_QUESTION_MARK,
-} from "./_constants.ts";
-
-import {
- _format,
- assertPath,
- isPathSeparator,
- isWindowsDeviceRoot,
- normalizeString,
-} from "./_util.ts";
-import { assert } from "../_util/assert.ts";
-
-export const sep = "\\";
-export const delimiter = ";";
-
-/**
- * Resolves path segments into a `path`
- * @param pathSegments to process to path
- */
-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) {
- if (globalThis.Deno == null) {
- throw new TypeError("Resolved a drive-letter-less path without a CWD.");
- }
- path = Deno.cwd();
- } else {
- if (globalThis.Deno == null) {
- throw new TypeError("Resolved a relative path without a CWD.");
- }
- // 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 = Deno.env.get(`=${resolvedDevice}`) || Deno.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 || ".";
-}
-
-/**
- * Normalizes a `path`
- * @param path to normalize
- */
-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;
- }
-}
-
-/**
- * Verifies whether path is absolute
- * @param path to verify
- */
-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;
-}
-
-/**
- * Join all given a sequence of `paths`,then normalizes the resulting path.
- * @param paths to be joined and normalized
- */
-export function join(...paths: string[]): string {
- const pathsCount = paths.length;
- if (pathsCount === 0) return ".";
-
- let joined: string | undefined;
- let firstPart: string | null = null;
- 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;
- assert(firstPart != null);
- 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'
- * @param from relative path
- * @param to relative path
- */
-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);
- }
-}
-
-/**
- * Resolves path to a namespace path
- * @param path to resolve to namespace
- */
-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;
-}
-
-/**
- * Return the directory name of a `path`.
- * @param path to determine name for
- */
-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);
-}
-
-/**
- * Return the last portion of a `path`. Trailing directory separators are ignored.
- * @param path to process
- * @param ext of path directory
- */
-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);
- }
-}
-
-/**
- * Return the extension of the `path`.
- * @param path with extension
- */
-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);
-}
-
-/**
- * Generate a path from `FormatInputPathObject` object.
- * @param pathObject with path
- */
-export function format(pathObject: FormatInputPathObject): string {
- if (pathObject === null || typeof pathObject !== "object") {
- throw new TypeError(
- `The "pathObject" argument must be of type Object. Received type ${typeof pathObject}`,
- );
- }
- return _format("\\", pathObject);
-}
-
-/**
- * Return a `ParsedPath` object of the `path`.
- * @param path to process
- */
-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;
-}
-
-/**
- * Converts a file URL to a path string.
- *
- * fromFileUrl("file:///home/foo"); // "\\home\\foo"
- * fromFileUrl("file:///C:/Users/foo"); // "C:\\Users\\foo"
- * fromFileUrl("file://localhost/home/foo"); // "\\\\localhost\\home\\foo"
- * @param url of a file URL
- */
-export function fromFileUrl(url: string | URL): string {
- url = url instanceof URL ? url : new URL(url);
- if (url.protocol != "file:") {
- throw new TypeError("Must be a file URL.");
- }
- let path = decodeURIComponent(
- url.pathname.replace(/\//g, "\\").replace(/%(?![0-9A-Fa-f]{2})/g, "%25"),
- ).replace(/^\\*([A-Za-z]:)(\\|$)/, "$1\\");
- if (url.hostname != "") {
- // Note: The `URL` implementation guarantees that the drive letter and
- // hostname are mutually exclusive. Otherwise it would not have been valid
- // to append the hostname and path like this.
- path = `\\\\${url.hostname}${path}`;
- }
- return path;
-}
-
-/**
- * Converts a path string to a file URL.
- *
- * toFileUrl("\\home\\foo"); // new URL("file:///home/foo")
- * toFileUrl("C:\\Users\\foo"); // new URL("file:///C:/Users/foo")
- * toFileUrl("\\\\localhost\\home\\foo"); // new URL("file://localhost/home/foo")
- * @param path to convert to file URL
- */
-export function toFileUrl(path: string): URL {
- if (!isAbsolute(path)) {
- throw new TypeError("Must be an absolute path.");
- }
- const [, hostname, pathname] = path.match(
- /^(?:[/\\]{2}([^/\\]+)(?=[/\\][^/\\]))?(.*)/,
- )!;
- const url = new URL("file:///");
- url.pathname = pathname.replace(/%/g, "%25");
- if (hostname != null) {
- url.hostname = hostname;
- if (!url.hostname) {
- throw new TypeError("Invalid hostname.");
- }
- }
- return url;
-}
diff --git a/std/path/zero_length_strings_test.ts b/std/path/zero_length_strings_test.ts
deleted file mode 100644
index e2ec466a5..000000000
--- a/std/path/zero_length_strings_test.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright the Browserify authors. MIT License.
-// Ported from https://github.com/browserify/path-browserify/
-import { assertEquals } from "../testing/asserts.ts";
-import * as path from "./mod.ts";
-
-const pwd = Deno.cwd();
-
-Deno.test("joinZeroLength", function () {
- // 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);
-});
-
-Deno.test("normalizeZeroLength", function () {
- // 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);
-});
-
-Deno.test("isAbsoluteZeroLength", function () {
- // 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);
-});
-
-Deno.test("resolveZeroLength", function () {
- // resolve, internally ignores all the zero-length strings and returns the
- // current working directory
- assertEquals(path.resolve(""), pwd);
- assertEquals(path.resolve("", ""), pwd);
-});
-
-Deno.test("relativeZeroLength", function () {
- // relative, internally calls resolve. So, '' is actually the current
- // directory
- assertEquals(path.relative("", pwd), "");
- assertEquals(path.relative(pwd, ""), "");
- assertEquals(path.relative(pwd, pwd), "");
-});