From 4ed7055a1b7d657fb29128a40e32645faa22d071 Mon Sep 17 00:00:00 2001 From: Planeshifter Date: Mon, 12 Dec 2016 18:28:03 -0500 Subject: [PATCH 1/7] Add utility to retrieve user's home directory --- .../@stdlib/utils/homedir/README.md | 88 +++++ .../@stdlib/utils/homedir/bin/cli | 90 +++++ .../@stdlib/utils/homedir/bin/opts.json | 14 + .../@stdlib/utils/homedir/bin/usage.txt | 8 + .../@stdlib/utils/homedir/examples/index.js | 5 + .../@stdlib/utils/homedir/lib/homedir.js | 55 +++ .../@stdlib/utils/homedir/lib/index.js | 23 ++ .../@stdlib/utils/homedir/package.json | 54 +++ .../utils/homedir/test/test.homedir.js | 365 ++++++++++++++++++ .../@stdlib/utils/homedir/test/test.js | 39 ++ 10 files changed, 741 insertions(+) create mode 100644 lib/node_modules/@stdlib/utils/homedir/README.md create mode 100644 lib/node_modules/@stdlib/utils/homedir/bin/cli create mode 100644 lib/node_modules/@stdlib/utils/homedir/bin/opts.json create mode 100644 lib/node_modules/@stdlib/utils/homedir/bin/usage.txt create mode 100644 lib/node_modules/@stdlib/utils/homedir/examples/index.js create mode 100644 lib/node_modules/@stdlib/utils/homedir/lib/homedir.js create mode 100644 lib/node_modules/@stdlib/utils/homedir/lib/index.js create mode 100644 lib/node_modules/@stdlib/utils/homedir/package.json create mode 100644 lib/node_modules/@stdlib/utils/homedir/test/test.homedir.js create mode 100644 lib/node_modules/@stdlib/utils/homedir/test/test.js diff --git a/lib/node_modules/@stdlib/utils/homedir/README.md b/lib/node_modules/@stdlib/utils/homedir/README.md new file mode 100644 index 000000000000..f70f6d73114b --- /dev/null +++ b/lib/node_modules/@stdlib/utils/homedir/README.md @@ -0,0 +1,88 @@ +# homedir + +> Return the current user's home directory. + + + + +
+ +
+ + + + + +
+ +## Usage + +``` javascript +var homedir = require( '@stdlib/lib/node_modules/@stdlib/utils/homedir' ); +``` + +#### homedir() + +Returns the current user's `home` directory. + +``` javascript +var home = homedir(); +// e.g., returns '/Users/' +``` + +If unable to locate a `home` directory, the module returns `null`. + +``` javascript +var home = homedir(); +// returns null +``` + +
+ + + + + +
+ +## Notes + +* This module primarily checks various [environment variables][environment-variables] to locate a `home` directory. Note that this approach has __security vulnerabilities__, as attackers can tamper with [environment variables][environment-variables]. + +
+ + + + + +
+ +## Examples + +``` javascript +var homedir = require( '@stdlib/lib/node_modules/@stdlib/utils/homedir' ); + +console.log( homedir() ); +``` + +
+ + + + + +
+ +
+ + + + + + + + diff --git a/lib/node_modules/@stdlib/utils/homedir/bin/cli b/lib/node_modules/@stdlib/utils/homedir/bin/cli new file mode 100644 index 000000000000..522ce5ba08c1 --- /dev/null +++ b/lib/node_modules/@stdlib/utils/homedir/bin/cli @@ -0,0 +1,90 @@ +#!/usr/bin/env node +'use strict'; + +// MODULES // + +var fs = require( 'fs' ); +var path = require( 'path' ); +var parseArgs = require( 'minimist' ); +var notifier = require( 'update-notifier' ); +var pkg = require( './../package.json' ); +var opts = require( './opts.json' ); +var homedir = require( './../lib' ); + + +// FUNCTIONS // + +/** +* Performs initialization tasks. +* +* @private +* @example +* init(); +*/ +function init() { + var opts; + + // Check if newer versions exist for this package: + opts = { + 'pkg': pkg + }; + notifier( opts ).notify(); + + // Set the process title to allow the process to be more easily identified: + process.title = pkg.name; + process.stdout.on( 'error', process.exit ); +} // end FUNCTION init() + +/** +* Prints usage information. +* +* @private +* @example +* help(); +* // => '...' +*/ +function help() { + var fpath = path.join( __dirname, 'usage.txt' ); + fs.createReadStream( fpath ) + .pipe( process.stdout ) + .on( 'close', onClose ); + + function onClose() { + process.exit( 0 ); + } +} // end FUNCTION help() + +/** +* Prints the package version. +* +* @private +* @example +* version(); +* // => '#.#.#' +*/ +function version() { + var msg = pkg.version.toString()+'\n'; + process.stdout.write( msg, 'utf8' ); + process.exit( 0 ); +} // end FUNCTION version() + + +// VARIABLES // + +var args; + + +// MAIN // + +init(); + +// Parse command-line arguments: +args = parseArgs( process.argv.slice( 2 ), opts ); + +if ( args.help ) { + return help(); +} +if ( args.version ) { + return version(); +} +console.log( homedir() ); diff --git a/lib/node_modules/@stdlib/utils/homedir/bin/opts.json b/lib/node_modules/@stdlib/utils/homedir/bin/opts.json new file mode 100644 index 000000000000..f245a17e6317 --- /dev/null +++ b/lib/node_modules/@stdlib/utils/homedir/bin/opts.json @@ -0,0 +1,14 @@ +{ + "boolean": [ + "help", + "version" + ], + "alias": { + "help": [ + "h" + ], + "version": [ + "V" + ] + } +} diff --git a/lib/node_modules/@stdlib/utils/homedir/bin/usage.txt b/lib/node_modules/@stdlib/utils/homedir/bin/usage.txt new file mode 100644 index 000000000000..2d9f602c7fb0 --- /dev/null +++ b/lib/node_modules/@stdlib/utils/homedir/bin/usage.txt @@ -0,0 +1,8 @@ + +Usage: homedir [options] + +Options: + + -h, --help Print this message. + -V, --version Print the package version. + diff --git a/lib/node_modules/@stdlib/utils/homedir/examples/index.js b/lib/node_modules/@stdlib/utils/homedir/examples/index.js new file mode 100644 index 000000000000..624c8bfc89ce --- /dev/null +++ b/lib/node_modules/@stdlib/utils/homedir/examples/index.js @@ -0,0 +1,5 @@ +'use strict'; + +var homedir = require( './../lib' ); + +console.log( homedir() ); diff --git a/lib/node_modules/@stdlib/utils/homedir/lib/homedir.js b/lib/node_modules/@stdlib/utils/homedir/lib/homedir.js new file mode 100644 index 000000000000..5171893c946e --- /dev/null +++ b/lib/node_modules/@stdlib/utils/homedir/lib/homedir.js @@ -0,0 +1,55 @@ +'use strict'; + +// MODULES // + +var isWindows = require( '@stdlib/utils/is-windows' ); +var platform = require( '@stdlib/utils/platform' ); + + +// MAIN // + +/** +* Returns the current user's home directory. +* +* @returns {(string|null)} home directory +* +* @example +* var home = homedir(); +* // e.g., returns '/Users/' +*/ +function homedir() { + var home; + var user; + var env; + + env = process.env; + if ( isWindows ) { + // https://github.com/libuv/libuv/blob/764877fd9e4ea67c0cbe27bf81b2b294ed33b0f5/src/win/util.c#L1170 + // https://en.wikipedia.org/wiki/Environment_variable#Windows + home = env[ 'USERPROFILE' ] || env[ 'HOMEDRIVE' ]+env[ 'HOMEPATH' ] || env[ 'HOME' ]; + return ( home ) ? home : null; + } + // https://github.com/libuv/libuv/blob/9fbcca048181b927cfcdb5c6c49e5bdff173aad5/src/unix/core.c#L1030 + home = env[ 'HOME' ]; + if ( home ) { + return home; + } + // Get the current user account (https://docs.python.org/2/library/getpass.html): + user = env[ 'LOGNAME' ] || env[ 'USER' ] || env[ 'LNAME' ] || env[ 'USERNAME' ]; + + // If on Mac OSX, use the Mac path convention (http://apple.stackexchange.com/questions/119230/what-is-standard-for-os-x-filesystem-e-g-opt-vs-usr)... + if ( platform === 'darwin' ) { + return ( user ) ? '/Users/'+user : null; + } + // Check if running as 'root' (https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard)... + if ( process.getuid() === 0 ) { + return '/root'; + } + // If on Linux, use the Linux path convention (https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard)... + return ( user ) ? '/home/'+user : null; +} // end FUNCTION homedir() + + +// EXPORTS // + +module.exports = homedir; diff --git a/lib/node_modules/@stdlib/utils/homedir/lib/index.js b/lib/node_modules/@stdlib/utils/homedir/lib/index.js new file mode 100644 index 000000000000..7f6f6ec1dd07 --- /dev/null +++ b/lib/node_modules/@stdlib/utils/homedir/lib/index.js @@ -0,0 +1,23 @@ +'use strict'; + +/** +* Return the current user's home directory. +* +* @module @stdlib/utils/homedir +* +* @example +* var homedir = require( '@stdlib/utils/homedir' ); +* var home = homedir(); +* // e.g., returns '/Users/' +*/ + +// MODULES // + +var os = require( 'os' ); +var isFunction = require( '@stdlib/utils/is-function' ); +var homedir = require( './homedir.js' ); + + +// EXPORTS // + +module.exports = isFunction( os.homedir ) ? os.homedir : homedir; diff --git a/lib/node_modules/@stdlib/utils/homedir/package.json b/lib/node_modules/@stdlib/utils/homedir/package.json new file mode 100644 index 000000000000..3447154a55df --- /dev/null +++ b/lib/node_modules/@stdlib/utils/homedir/package.json @@ -0,0 +1,54 @@ +{ + "name": "homedir", + "version": "0.0.0", + "description": "Return the current user's home directory.", + "author": { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + }, + "contributors": [ + { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + } + ], + "bin": { + "homedir": "./bin/cli" + }, + "scripts": {}, + "main": "./lib", + "repository": { + "type": "git", + "url": "git://github.com/stdlib-js/stdlib.git" + }, + "homepage": "https://github.com/stdlib-js/stdlib", + "keywords": [ + "stdlib", + "stdutils", + "stdutil", + "utilities", + "utility", + "utils", + "util", + "homedir", + "dir", + "directory", + "home", + "user", + "os", + "windows", + "darwin", + "linux", + "mac", + "pc" + ], + "bugs": { + "url": "https://github.com/stdlib-js/stdlib/issues" + }, + "dependencies": {}, + "devDependencies": {}, + "engines": { + "node": ">=0.10.0" + }, + "license": "Apache-2.0" +} diff --git a/lib/node_modules/@stdlib/utils/homedir/test/test.homedir.js b/lib/node_modules/@stdlib/utils/homedir/test/test.homedir.js new file mode 100644 index 000000000000..3de71981873d --- /dev/null +++ b/lib/node_modules/@stdlib/utils/homedir/test/test.homedir.js @@ -0,0 +1,365 @@ +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var proxyquire = require( 'proxyquire' ); + + +// VARIABLES // + +var mpath = './../lib/homedir.js'; + + +// FUNCTIONS // + +/** +* Returns a copy of the default proxyquire options. +* +* @private +* @returns {Object} options object +*/ +function makeOpts() { + var opts = { + '@stdlib/utils/platform': 'darwin', + '@stdlib/utils/is-windows': false + }; + return opts; +} // end FUNCTION makeOpts() + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + var homedir; + + t.ok( true, __filename ); + homedir = require( mpath ); + t.strictEqual( typeof homedir, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function supports older Node versions', function test( t ) { + var homedir; + var opts; + var env; + + opts = makeOpts(); + homedir = proxyquire( mpath, opts ); + env = process.env; + process.env = { + 'HOME': '/Users/beep' + }; + + t.strictEqual( homedir(), '/Users/beep', 'returns home directory' ); + process.env = env; + t.end(); +}); + +tape( 'the function returns a home directory in a non-windows environment (HOME)', function test( t ) { + var homedir; + var opts; + var env; + + opts = makeOpts(); + opts[ '@stdlib/utils/platform' ] = 'darwin'; + homedir = proxyquire( mpath, opts ); + + env = process.env; + process.env = { + 'HOME': '/Users/beep' + }; + + t.strictEqual( homedir(), '/Users/beep', 'returns home directory' ); + process.env = env; + t.end(); +}); + +tape( 'the function returns a home directory in a Mac OSX environment (LOGNAME)', function test( t ) { + var homedir; + var opts; + var env; + + opts = makeOpts(); + opts[ '@stdlib/utils/platform' ] = 'darwin'; + homedir = proxyquire( mpath, opts ); + + env = process.env; + process.env = { + 'LOGNAME': 'beep' + }; + + t.strictEqual( homedir(), '/Users/beep', 'returns home directory' ); + process.env = env; + t.end(); +}); + +tape( 'the function returns a home directory in a Linux environment (LOGNAME)', function test( t ) { + var homedir; + var opts; + var env; + + opts = makeOpts(); + opts[ '@stdlib/utils/platform' ] = 'linux'; + homedir = proxyquire( mpath, opts ); + + env = process.env; + process.env = { + 'LOGNAME': 'beep' + }; + + t.strictEqual( homedir(), '/home/beep', 'returns home directory' ); + process.env = env; + t.end(); +}); + +tape( 'the function returns a home directory in a Mac OSX environment (USER)', function test( t ) { + var homedir; + var opts; + var env; + + opts = makeOpts(); + opts[ '@stdlib/utils/platform' ] = 'darwin'; + homedir = proxyquire( mpath, opts ); + + env = process.env; + process.env = { + 'USER': 'beep' + }; + + t.strictEqual( homedir(), '/Users/beep', 'returns home directory' ); + process.env = env; + t.end(); +}); + +tape( 'the function returns a home directory in a Linux environment (USER)', function test( t ) { + var homedir; + var opts; + var env; + + opts = makeOpts(); + opts[ '@stdlib/utils/platform' ] = 'linux'; + homedir = proxyquire( mpath, opts ); + + env = process.env; + process.env = { + 'USER': 'beep' + }; + + t.strictEqual( homedir(), '/home/beep', 'returns home directory' ); + process.env = env; + t.end(); +}); + +tape( 'the function returns a home directory in a Mac OSX environment (LNAME)', function test( t ) { + var homedir; + var opts; + var env; + + opts = makeOpts(); + opts[ '@stdlib/utils/platform' ] = 'darwin'; + homedir = proxyquire( mpath, opts ); + + env = process.env; + process.env = { + 'LNAME': 'beep' + }; + + t.strictEqual( homedir(), '/Users/beep', 'returns home directory' ); + process.env = env; + t.end(); +}); + +tape( 'the function returns a home directory in a Linux environment (LNAME)', function test( t ) { + var homedir; + var opts; + var env; + + opts = makeOpts(); + opts[ '@stdlib/utils/platform' ] = 'linux'; + homedir = proxyquire( mpath, opts ); + + env = process.env; + process.env = { + 'LNAME': 'beep' + }; + + t.strictEqual( homedir(), '/home/beep', 'returns home directory' ); + process.env = env; + t.end(); +}); + +tape( 'the function returns a home directory in a Mac OSX environment (USERNAME)', function test( t ) { + var homedir; + var opts; + var env; + + opts = makeOpts(); + opts[ '@stdlib/utils/platform' ] = 'darwin'; + homedir = proxyquire( mpath, opts ); + + env = process.env; + process.env = { + 'USERNAME': 'beep' + }; + + t.strictEqual( homedir(), '/Users/beep', 'returns home directory' ); + process.env = env; + t.end(); +}); + +tape( 'the function returns a home directory in a Linux environment (USERNAME)', function test( t ) { + var homedir; + var opts; + var env; + + opts = makeOpts(); + opts[ '@stdlib/utils/platform' ] = 'linux'; + homedir = proxyquire( mpath, opts ); + + env = process.env; + process.env = { + 'USERNAME': 'beep' + }; + + t.strictEqual( homedir(), '/home/beep', 'returns home directory' ); + process.env = env; + t.end(); +}); + +tape( 'the function returns `null` if unable to locate a home directory in a Mac OS X environment', function test( t ) { + var homedir; + var opts; + var env; + + opts = makeOpts(); + opts[ '@stdlib/utils/platform' ] = 'darwin'; + homedir = proxyquire( mpath, opts ); + + env = process.env; + process.env = {}; + + t.strictEqual( homedir(), null, 'returns null' ); + process.env = env; + t.end(); +}); + +tape( 'the function returns `null` if unable to locate a home directory in a linux environment', function test( t ) { + var homedir; + var opts; + var env; + + opts = makeOpts(); + opts[ '@stdlib/utils/platform' ] = 'linux'; + homedir = proxyquire( mpath, opts ); + + env = process.env; + process.env = {}; + + t.strictEqual( homedir(), null, 'returns null' ); + process.env = env; + t.end(); +}); + +tape( 'the function returns the `/root` directory if run as `root` in a linux environment', function test( t ) { + var homedir; + var opts; + var env; + var fcn; + + opts = makeOpts(); + opts[ '@stdlib/utils/platform' ] = 'linux'; + homedir = proxyquire( mpath, opts ); + + env = process.env; + process.env = {}; + + fcn = process.getuid; + process.getuid = getuid; + + t.strictEqual( homedir(), '/root', 'returns root directory' ); + + process.env = env; + process.getuid = fcn; + + t.end(); + + function getuid() { + return 0; + } +}); + +tape( 'the function returns a home directory on Windows (USERPROFILE)', function test( t ) { + var homedir; + var opts; + var env; + + opts = makeOpts(); + opts[ '@stdlib/utils/is-windows' ] = true; + homedir = proxyquire( mpath, opts ); + + env = process.env; + process.env = { + 'USERPROFILE': 'C:\\Users\\boop' + }; + + t.strictEqual( homedir(), 'C:\\Users\\boop', 'returns home directory' ); + process.env = env; + t.end(); +}); + +tape( 'the function returns a home directory on Windows (HOMEDRIVE+HOMEPATH)', function test( t ) { + var homedir; + var opts; + var env; + + opts = makeOpts(); + opts[ '@stdlib/utils/is-windows' ] = true; + homedir = proxyquire( mpath, opts ); + + env = process.env; + process.env = { + 'HOMEDRIVE': 'C:', + 'HOMEPATH': '\\Users\\boop' + }; + + t.strictEqual( homedir(), 'C:\\Users\\boop', 'returns home directory' ); + process.env = env; + t.end(); +}); + +tape( 'the function returns a home directory on Windows (HOME)', function test( t ) { + var homedir; + var opts; + var env; + + opts = makeOpts(); + opts[ '@stdlib/utils/is-windows' ] = true; + homedir = proxyquire( mpath, opts ); + + env = process.env; + process.env = { + 'HOME': 'C:\\Users\\boop' + }; + + t.strictEqual( homedir(), 'C:\\Users\\boop', 'returns home directory' ); + process.env = env; + t.end(); +}); + +tape( 'the function returns `null` if unable to locate a home directory on Windows', function test( t ) { + var homedir; + var opts; + var env; + + opts = makeOpts(); + opts[ '@stdlib/utils/is-windows' ] = true; + homedir = proxyquire( mpath, opts ); + + env = process.env; + process.env = {}; + + t.strictEqual( homedir(), null, 'returns null' ); + process.env = env; + t.end(); +}); diff --git a/lib/node_modules/@stdlib/utils/homedir/test/test.js b/lib/node_modules/@stdlib/utils/homedir/test/test.js new file mode 100644 index 000000000000..9f9a596128bf --- /dev/null +++ b/lib/node_modules/@stdlib/utils/homedir/test/test.js @@ -0,0 +1,39 @@ +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var proxyquire = require( 'proxyquire' ); + + +// VARIABLES // + +var mpath = './../lib/'; + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + var homedir; + t.ok( true, __filename ); + homedir = require( mpath ); + t.strictEqual( typeof homedir, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function aliases `os.homedir` if available', function test( t ) { + var homedir; + var opts; + + opts = { + 'os': { + 'homedir': mock + } + }; + homedir = proxyquire( mpath, opts ); + + t.strictEqual( homedir, mock, 'equals `os.homedir`' ); + t.end(); + + function mock(){} +}); From 0d49e5ce80631f90eb7e5242ed3165f1f906c68c Mon Sep 17 00:00:00 2001 From: Planeshifter Date: Mon, 12 Dec 2016 21:42:39 -0500 Subject: [PATCH 2/7] Fix require paths --- lib/node_modules/@stdlib/utils/homedir/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/node_modules/@stdlib/utils/homedir/README.md b/lib/node_modules/@stdlib/utils/homedir/README.md index f70f6d73114b..df10a19d0cb3 100644 --- a/lib/node_modules/@stdlib/utils/homedir/README.md +++ b/lib/node_modules/@stdlib/utils/homedir/README.md @@ -18,7 +18,7 @@ ## Usage ``` javascript -var homedir = require( '@stdlib/lib/node_modules/@stdlib/utils/homedir' ); +var homedir = require( '@stdlib/utils/homedir' ); ``` #### homedir() @@ -60,7 +60,7 @@ var home = homedir(); ## Examples ``` javascript -var homedir = require( '@stdlib/lib/node_modules/@stdlib/utils/homedir' ); +var homedir = require( '@stdlib/utils/homedir' ); console.log( homedir() ); ``` From 279c34c495fa3c2656c822a5a06e672a0cd747c9 Mon Sep 17 00:00:00 2001 From: Planeshifter Date: Mon, 12 Dec 2016 21:48:42 -0500 Subject: [PATCH 3/7] Add CLI section and improve wording --- .../@stdlib/utils/homedir/README.md | 51 ++++++++++++++++--- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/lib/node_modules/@stdlib/utils/homedir/README.md b/lib/node_modules/@stdlib/utils/homedir/README.md index df10a19d0cb3..6f21b72b63f3 100644 --- a/lib/node_modules/@stdlib/utils/homedir/README.md +++ b/lib/node_modules/@stdlib/utils/homedir/README.md @@ -30,12 +30,7 @@ var home = homedir(); // e.g., returns '/Users/' ``` -If unable to locate a `home` directory, the module returns `null`. - -``` javascript -var home = homedir(); -// returns null -``` +If unable to locate a `home` directory, the function returns `null`. @@ -47,7 +42,7 @@ var home = homedir(); ## Notes -* This module primarily checks various [environment variables][environment-variables] to locate a `home` directory. Note that this approach has __security vulnerabilities__, as attackers can tamper with [environment variables][environment-variables]. +* The implementation primarily checks various [environment variables][environment-variables] to locate a `home` directory. Note that this approach has __security vulnerabilities__, as attackers can tamper with [environment variables][environment-variables]. @@ -77,6 +72,48 @@ console.log( homedir() ); + +--- + +
+ +## CLI + +
+ +### Usage + +``` bash +Usage: homedir [options] + +Options: + + -h, --help Print this message. + -V, --version Print the package version. +``` + +
+ + + + +
+ +### Examples + +``` bash +$ homedir +e.g., /Users/ +``` + +
+ + + +
+ + +