From dd6d4244ac3eafef4a2eb5f2d381bbb9404ccab7 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Thu, 2 Jun 2016 17:43:26 -0700 Subject: [PATCH 1/5] doc: general improvements to path.md copy --- doc/api/path.md | 355 +++++++++++++++++++++++++++++++----------------- 1 file changed, 230 insertions(+), 125 deletions(-) diff --git a/doc/api/path.md b/doc/api/path.md index 3cbab43c6cc841..90dcf69022b4b7 100644 --- a/doc/api/path.md +++ b/doc/api/path.md @@ -2,37 +2,91 @@ Stability: 2 - Stable -This module contains utilities for handling and transforming file -paths. The file system is not consulted to check whether paths are valid. +The `path` module provides utilities for working with file paths. It can be +accessed using: -Use `require('path')` to use this module. The following methods are provided: +```js +const path = require('path'); +``` + +## Windows vs. POSIX + +The default operation of the `path` module varies based on the operating system +on which a Node.js application is running. Specifically, when running on a +Windows operating system, the `path` module will assume that Window-style +paths are being used. + +For example, using the `path.basename()` function with the Windows file path +`C:\temp\myfile.html`, will yield different results when running on POSIX than +when run on Windows: + +On POSIX: + +```js +path.basename('C:\\temp\\myfile.html'); + // returns 'C:\temp\myfile.html' +``` + +On Windows: + +```js +path.basename('C:\\temp\\myfile.html'); + // returns 'myfile.html' +``` + +To achieve consistent results when working with Windows file paths on any +operating system, use [`path.win32`][]: + +On POSIX and Windows: +```js +path.win32.basename('C:\\temp\\myfile.html'); + // returns 'myfile.html' +``` + +To achieve consistent results when working with POSIX file paths on any +operating system, use [`path.posix`]: + +On POSIX and Windows: +```js +path.posix.basename('/tmp/myfile.html'); + // returns 'myfile.html' +``` ## path.basename(path[, ext]) -Return the last portion of a path, similar to the Unix `basename` command. -`path` must be a string. `ext`, if given, must also be a string. +* `path` {String} A file path +* `ext` {String} An optional file extension -Examples: +The `path.basename()` methods returns the last portion of a `path`, similar to +the Unix `basename` command. + +For example: ```js path.basename('/foo/bar/baz/asdf/quux.html') -// returns 'quux.html' + // returns 'quux.html' path.basename('/foo/bar/baz/asdf/quux.html', '.html') -// returns 'quux' + // returns 'quux' ``` +A [`TypeError`][] is thrown if `path` is not a string or if `ext` is given +and is not a string. + ## path.delimiter -The platform-specific path delimiter, `;` or `':'`. +Returns the platform-specific path delimiter: -An example on \*nix: +* `;` for Windows +* `:` for POSIX + +For example, on POSIX: ```js console.log(process.env.PATH) @@ -42,7 +96,7 @@ process.env.PATH.split(path.delimiter) // returns ['/usr/bin', '/bin', '/usr/sbin', '/sbin', '/usr/local/bin'] ``` -An example on Windows: +On Windows: ```js console.log(process.env.PATH) @@ -57,27 +111,34 @@ process.env.PATH.split(path.delimiter) added: v0.1.16 --> -Return the directory name of a path, similar to the Unix `dirname` command. -`path` must be a string. +* `path` {String} A file path + +The `path.dirname()` method returns the directory name of a `path`, similar to +the Unix `dirname` command. -Example: +For example: ```js path.dirname('/foo/bar/baz/asdf/quux') // returns '/foo/bar/baz/asdf' ``` +A [`TypeError`][] is thrown if `path` is not a string. + ## path.extname(path) -Return the extension of the path, from the last '.' to end of string -in the last portion of the path. If there is no '.' in the last portion -of the path or the first character of it is '.', then it returns -an empty string. `path` must be a string. +* `path` {String} A file path + +The `path.extname()` method returns the extension of the `path`, from the last +occurance of the `.` (period) character to end of string in the last portion of +the `path`. If there is no `.` in the last portion of the `path`, or if the +first character of the basename of `path` (see `path.basename()`) is `.`, then +an empty string is returned. -Examples: +For example: ```js path.extname('index.html') @@ -96,66 +157,73 @@ path.extname('.index') // returns '' ``` +A [`TypeError`][] is thrown if `path` is not a string. + ## path.format(pathObject) -Returns a path string from an object. This is the opposite of [`path.parse`][]. - -If `pathObject` has `dir` and `base` properties, the returned string will -be a concatenation of the `dir` property, the platform-dependent path separator, -and the `base` property. +* `pathObject` {Object} + * `dir` {String} + * `root` {String} + * `base` {String} + * `name` {String} + * `ext` {String} -If the `dir` property is not supplied, the `root` property will be used as the -`dir` property. However, it will be assumed that the `root` property already -ends with the platform-dependent path separator. In this case, the returned -string will be the concatenation of the `root` property and the `base` property. +The `path.format()` method returns a path string from an object. This is the +opposite of [`path.parse`][]. -If both the `dir` and the `root` properties are not supplied, then the returned -string will be the contents of the `base` property. +The following process is used when constructing the path string: -If the `base` property is not supplied, a concatenation of the `name` property -and the `ext` property will be used as the `base` property. +* `output` is set to an empty string. +* If `pathObject.dir` is specified, `pathObject.dir` is appended to `output` + followed by the value of `path.sep`; +* Otherwise, if `pathObject.root` is specified, `pathObject.root` is appended + to `output`. +* If `pathObject.base` is specified, `pathObject.base` is appended to `output`; +* Otherwise: + * If `pathObject.name` is specified, `pathObject.name` is appended to `output` + * If `pathObject.ext` is specified, `pathObject.ext` is appended to `output`. +* Return `output` -Examples: - -Some Posix system examples: +For example, on POSIX: ```js -// If `dir` and `base` are provided, `dir` + platform separator + `base` +// If `dir` and `base` are provided, +// `${dir}${path.sep}${base}` // will be returned. path.format({ - dir: '/home/user/dir', - base: 'file.txt' + dir: '/home/user/dir', + base: 'file.txt' }); // returns '/home/user/dir/file.txt' // `root` will be used if `dir` is not specified. -// `name` + `ext` will be used if `base` is not specified. // If only `root` is provided or `dir` is equal to `root` then the // platform separator will not be included. path.format({ - root: '/', - base: 'file.txt' + root: '/', + base: 'file.txt' }); // returns '/file.txt' +// `name` + `ext` will be used if `base` is not specified. path.format({ - dir: '/', - root: '/', - name: 'file', - ext: '.txt' + root: '/', + name: 'file', + ext: '.txt' }); // returns '/file.txt' // `base` will be returned if `dir` or `root` are not provided. path.format({ - base: 'file.txt' + base: 'file.txt' }); // returns 'file.txt' ``` -An example on Windows: + +On Windows: ```js path.format({ @@ -173,11 +241,13 @@ path.format({ added: v0.11.2 --> -Determines whether `path` is an absolute path. An absolute path will always -resolve to the same location, regardless of the working directory. `path` must -be a string. +* `path` {String} + +The `path.isAbsolute()` method determines if `path` is an absolute path. + +If the given `path` is a zero-length string, `false` will be returned. -Examples on \*nix: +For example on POSIX: ```js path.isAbsolute('/foo/bar') // true @@ -186,7 +256,7 @@ path.isAbsolute('qux/') // false path.isAbsolute('.') // false ``` -Examples on Windows: +On Windows: ```js path.isAbsolute('//server') // true @@ -195,66 +265,88 @@ path.isAbsolute('bar\\baz') // false path.isAbsolute('.') // false ``` -*Note:* If the path string passed as parameter is a zero-length string, unlike - other path module functions, it will be used as-is and `false` will be - returned. +A [`TypeError`][] is thrown if `path` is not a string. ## path.join([path1][, path2][, ...]) -Join all arguments together and normalize the resulting path. +* `path1` {String} A path segment +* `path2` {String} A path segment +* `[, ...]` {String} Additional path segments -All arguments must be strings. In v0.8, non-string arguments were -silently ignored. In v0.10 and up, an exception is thrown. +The `path.join()` method join all given path segments together using the +platform specific separator as a delimiter, then normalizes the resulting path. -Examples: +Zero-length strings passed as segments are ignored. If the joined path string is +a zero-length string then `'.'` will be returned, representing the current +working directory. + +For example: ```js path.join('/foo', 'bar', 'baz/asdf', 'quux', '..') // returns '/foo/bar/baz/asdf' path.join('foo', {}, 'bar') -// throws exception -TypeError: Arguments to path.join must be strings +// throws TypeError: Arguments to path.join must be strings ``` -*Note:* If the arguments to `join` have zero-length strings, unlike other path - module functions, they will be ignored. If the joined path string is a - zero-length string then `'.'` will be returned, which represents the - current working directory. +A [`TypeError`] is thrown if any of the path segments is not a string. ## path.normalize(path) -Normalize a path, taking care of `'..'` and `'.'` parts. `path` must be a -string. +* `path` {String} + +The `path.normalize()` method normalizes the given `path`, resolving `'..'` and +`'.'` segments. + +When multiple, sequential path segment separation characters are found (e.g. +`/` on POSIX and `\` on Windows), they are replaced by a single instance of the +platform specific path segment separator. Trailing separators are preserved. -When multiple slashes are found, they're replaced by a single one; -when the path contains a trailing slash, it is preserved. -On Windows backslashes are used. +If the `path` is a zero-length string, `'.'` is returned, representing the +current working directory. -Example: +For example on POSIX: ```js path.normalize('/foo/bar//baz/asdf/quux/..') // returns '/foo/bar/baz/asdf' ``` -*Note:* If the path string passed as argument is a zero-length string then `'.'` - will be returned, which represents the current working directory. +On Windows: + +```js +path.normalize('C:\\temp\\\\foo\\bar\\..\\'); +// returns 'C:\\temp\\foo\\' +``` + +A [`TypeError`][] is thrown if `path` is not a string. ## path.parse(path) -Returns an object from a path. `path` must be a string. +* `path` {String} A file path + +The `path.parse()` method returns an object whose properties represent +significant elements of the `path`. + +The returned object will have the following properties: -An example on \*nix: +* `root` {String} +* `dir` {String} +* `base` {String} +* `ext` {String} +* `name` {String} + +For example on POSIX: ```js path.parse('/home/user/dir/file.txt') @@ -268,91 +360,98 @@ path.parse('/home/user/dir/file.txt') // } ``` -An example on Windows: +```text +┌─────────────────────┬────────────┐ +│ dir │ base │ +├──────┬ ├──────┬─────┤ +│ root │ │ name │ ext │ +" / home/user/dir / file .txt " +└──────┴──────────────┴──────┴─────┘ +(all spaces in the "" line should be ignored -- they're purely for formatting) +``` + +On Windows: ```js -path.parse('C:\\path\\dir\\index.html') +path.parse('C:\\path\\dir\\file.txt') // returns // { // root : "C:\\", // dir : "C:\\path\\dir", -// base : "index.html", -// ext : ".html", -// name : "index" +// base : "file.txt", +// ext : ".txt", +// name : "file" // } ``` +```text +┌─────────────────────┬────────────┐ +│ dir │ base │ +├──────┬ ├──────┬─────┤ +│ root │ │ name │ ext │ +" C:\ path\dir \ file .txt " +└──────┴──────────────┴──────┴─────┘ +(all spaces in the "" line should be ignored -- they're purely for formatting) +``` + +A [`TypeError`][] is thrown if `path` is not a string. + ## path.posix -Provide access to aforementioned `path` methods but always interact in a posix -compatible way. +The `path.posix' property provides access to POSIX specific implementations +of the `path` methods. ## path.relative(from, to) -Solve the relative path from `from` to `to`. `from` and `to` must be strings. +* `from` {String} A file path +* `to` {String} A file path -At times we have two absolute paths, and we need to derive the relative -path from one to the other. This is actually the reverse transform of -`path.resolve`, which means we see that: +The `path.relative()` method returns the relative path from `from` to `to`. +If `from` and `to` are equal, a zero-length string is returned. + +If a zero-length string is passed as `from` or `to`, the current working +directory will be used instead of the zero-length strings. + +For example on POSIX: ```js -path.resolve(from, path.relative(from, to)) == path.resolve(to) +path.relative('/data/orandea/test/aaa', '/data/orandea/impl/bbb') +// returns '../../impl/bbb' ``` -Examples: +On Windows: ```js path.relative('C:\\orandea\\test\\aaa', 'C:\\orandea\\impl\\bbb') // returns '..\\..\\impl\\bbb' - -path.relative('/data/orandea/test/aaa', '/data/orandea/impl/bbb') -// returns '../../impl/bbb' ``` -*Note:* If the arguments to `relative` have zero-length strings then the current - working directory will be used instead of the zero-length strings. If - both the paths are the same then a zero-length string will be returned. +A [`TypeError`][] is thrown if neither `from` or `to` is a string. ## path.resolve([from ...], to) -Resolves `to` to an absolute path. All arguments must be strings. +* `[from ...]` {String} One or more file paths +* `to` {String} A file path -If `to` isn't already absolute `from` arguments are prepended in right to left -order, until an absolute path is found. If after using all `from` paths still -no absolute path is found, the current working directory is used as well. The -resulting path is normalized, and trailing slashes are removed unless the path -gets resolved to the root directory. Empty string `from` arguments are -ignored. +The `path.resolve()` method resolves `to` to an absolute path. -Another way to think of it is as a sequence of `cd` commands in a shell. +If `to` is not already an absolute path, each `from` argument is prepended in +right to left order, until an absolute path is constructed. If after using all +`from` paths still no absolute path is found, the current working directory is +used as well. The resulting path is normalized, and trailing slashes are removed +unless the path is resolved to the root directory. Empty string `from` arguments +are ignored. -```js -path.resolve('foo/bar', '/tmp/file/', '..', 'a/../subfile') -``` - -Is similar to: - -``` -cd foo/bar -cd /tmp/file/ -cd .. -cd a/../subfile -pwd -``` - -The difference is that the different paths don't need to exist and may also be -files. - -Examples: +For example: ```js path.resolve('/foo/bar', './baz') @@ -366,21 +465,26 @@ path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif') // '/home/myself/node/wwwroot/static_files/gif/image.gif' ``` +A [`TypeError`][] is thrown if any of the arguments is not a string. + ## path.sep -The platform-specific file separator. `'\\'` or `'/'`. +Returns the platform-specific path segment separator: + +* `\` on Windows +* `/` on POSIX -An example on \*nix: +For example on POSIX: ```js 'foo/bar/baz'.split(path.sep) // returns ['foo', 'bar', 'baz'] ``` -An example on Windows: +On Windows: ```js 'foo\\bar\\baz'.split(path.sep) @@ -392,7 +496,8 @@ An example on Windows: added: v0.11.15 --> -Provide access to aforementioned `path` methods but always interact in a win32 -compatible way. +The `path.win32` property provides access to Windows-specific implementations +of the `path` methods. [`path.parse`]: #path_path_parse_path +[`TypeError`]: errors.html#errors_class_typeerror From cd597532e7bdbe00b101ca8371e760c09a63bac0 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Fri, 3 Jun 2016 08:36:42 -0700 Subject: [PATCH 2/5] Address nits --- doc/api/path.md | 72 ++++++++++++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 28 deletions(-) diff --git a/doc/api/path.md b/doc/api/path.md index 90dcf69022b4b7..0384d1cd4b7d35 100644 --- a/doc/api/path.md +++ b/doc/api/path.md @@ -38,15 +38,17 @@ To achieve consistent results when working with Windows file paths on any operating system, use [`path.win32`][]: On POSIX and Windows: + ```js path.win32.basename('C:\\temp\\myfile.html'); // returns 'myfile.html' ``` To achieve consistent results when working with POSIX file paths on any -operating system, use [`path.posix`]: +operating system, use [`path.posix`][]: On POSIX and Windows: + ```js path.posix.basename('/tmp/myfile.html'); // returns 'myfile.html' @@ -81,7 +83,7 @@ and is not a string. added: v0.9.3 --> -Returns the platform-specific path delimiter: +Provides the platform-specific path delimiter: * `;` for Windows * `:` for POSIX @@ -106,6 +108,8 @@ process.env.PATH.split(path.delimiter) // returns ['C:\\Windows\\system32', 'C:\\Windows', 'C:\\Program Files\\node\\'] ``` +*Note*: This property is *not* read-only and may be modified. + ## path.dirname(path) -* `path1` {String} A path segment -* `path2` {String} A path segment -* `[, ...]` {String} Additional path segments +* `[path[, ...]]` {String} A sequence of path segments -The `path.join()` method join all given path segments together using the +The `path.join()` method join all given `path` segments together using the platform specific separator as a delimiter, then normalizes the resulting path. Zero-length strings passed as segments are ignored. If the joined path string is @@ -293,7 +295,7 @@ path.join('foo', {}, 'bar') // throws TypeError: Arguments to path.join must be strings ``` -A [`TypeError`] is thrown if any of the path segments is not a string. +A [`TypeError`][] is thrown if any of the path segments is not a string. ## path.normalize(path) -The `path.posix' property provides access to POSIX specific implementations +The `path.posix` property provides access to POSIX specific implementations of the `path` methods. ## path.relative(from, to) @@ -409,11 +411,12 @@ of the `path` methods. added: v0.5.0 --> -* `from` {String} A file path -* `to` {String} A file path +* `from` {String} +* `to` {String} The `path.relative()` method returns the relative path from `from` to `to`. -If `from` and `to` are equal, a zero-length string is returned. +If `from` and `to` each resolve to the same path (after calling `path.resolve()` +on each), a zero-length string is returned. If a zero-length string is passed as `from` or `to`, the current working directory will be used instead of the zero-length strings. @@ -432,24 +435,33 @@ path.relative('C:\\orandea\\test\\aaa', 'C:\\orandea\\impl\\bbb') // returns '..\\..\\impl\\bbb' ``` -A [`TypeError`][] is thrown if neither `from` or `to` is a string. +A [`TypeError`][] is thrown if neither `from` nor `to` is a string. -## path.resolve([from ...], to) +## path.resolve([path[, ...]]) -* `[from ...]` {String} One or more file paths -* `to` {String} A file path +* `[path[, ...]]` {String} A sequence of paths or path segments + +The `path.resolve()` method resolves a sequence of paths or path segments into +an absolute path. -The `path.resolve()` method resolves `to` to an absolute path. +The given sequence of paths is processed from right to left, with each +subsequent `path` prepended until an absolute path is constructed. +For instance, given the sequence of path segments: `/foo`, `/bar`, `baz`, +calling `path.resolve('/foo', '/bar', 'baz')` would return `/bar/baz`. -If `to` is not already an absolute path, each `from` argument is prepended in -right to left order, until an absolute path is constructed. If after using all -`from` paths still no absolute path is found, the current working directory is -used as well. The resulting path is normalized, and trailing slashes are removed -unless the path is resolved to the root directory. Empty string `from` arguments -are ignored. +If after processing all given `path` segments an absolute path has not yet +been generated, the current working directory is used. + +The resulting path is normalized and trailing slashes are removed unless the +path is resolved to the root directory. + +Any `path` segments passed as empty strings are ignored. + +If no `path` segments are passed, `path.resolve()` will return the absolute path +of the current working directory. For example: @@ -461,8 +473,8 @@ path.resolve('/foo/bar', '/tmp/file/') // returns '/tmp/file' path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif') -// if currently in /home/myself/node, it returns -// '/home/myself/node/wwwroot/static_files/gif/image.gif' +// if the current working directory is /home/myself/node, +// this returns '/home/myself/node/wwwroot/static_files/gif/image.gif' ``` A [`TypeError`][] is thrown if any of the arguments is not a string. @@ -472,7 +484,7 @@ A [`TypeError`][] is thrown if any of the arguments is not a string. added: v0.7.9 --> -Returns the platform-specific path segment separator: +Provides the platform-specific path segment separator: * `\` on Windows * `/` on POSIX @@ -491,6 +503,8 @@ On Windows: // returns ['foo', 'bar', 'baz'] ``` +*Note*: This property is *not* read-only and may be modified. + ## path.win32 -* `path` {String} A file path +* `path` {String} * `ext` {String} An optional file extension The `path.basename()` methods returns the last portion of a `path`, similar to @@ -113,7 +113,7 @@ process.env.PATH.split(path.delimiter) added: v0.1.16 --> -* `path` {String} A file path +* `path` {String} The `path.dirname()` method returns the directory name of a `path`, similar to the Unix `dirname` command. @@ -132,7 +132,7 @@ A [`TypeError`][] is thrown if `path` is not a string. added: v0.1.25 --> -* `path` {String} A file path +* `path` {String} The `path.extname()` method returns the extension of the `path`, from the last occurance of the `.` (period) character to end of string in the last portion of @@ -333,7 +333,7 @@ A [`TypeError`][] is thrown if `path` is not a string. added: v0.11.15 --> -* `path` {String} A file path +* `path` {String} The `path.parse()` method returns an object whose properties represent significant elements of the `path`.