Skip to content

Commit

Permalink
Merge pull request #2 from rosen-vladimirov/vladimirov/get-global-path
Browse files Browse the repository at this point in the history
Get result from which/where first
  • Loading branch information
rosen-vladimirov authored Jun 29, 2017
2 parents 41b36b2 + 464570e commit 2445cbe
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 14 deletions.
42 changes: 32 additions & 10 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,16 @@ const getPathFromExecutableNameOnWindows = (packageName, executableName) => {
const pathToExecutable = line && line.trim(),
pathToLib = pathToExecutable && path.join(path.dirname(pathToExecutable), nodeModulesDirName, packageName);

if (pathToLib && fs.existsSync(pathToLib)) {
return pathToLib;
if (pathToLib) {
if (fs.existsSync(pathToLib)) {
return pathToLib;
}

// In case the path to <package>/bin/ is added to the PATH
const resolvedPath = getPathWhenExecutableIsAddedDirectlyToPath(packageName, pathToExecutable);
if (resolvedPath) {
return resolvedPath;
}
}
}
} catch (err) {
Expand Down Expand Up @@ -100,6 +108,9 @@ const getPathFromExecutableNameOnNonWindows = (packageName, executableName) => {
return packagePathMatch[1];
}
}

// In case executable is added to PATH directly
return getPathWhenExecutableIsAddedDirectlyToPath(packageName, whichResult);
}
} catch (err) {
console.error(err.message);
Expand All @@ -108,6 +119,18 @@ const getPathFromExecutableNameOnNonWindows = (packageName, executableName) => {
return null;
};

const getPathWhenExecutableIsAddedDirectlyToPath = (packageName, executablePath) => {
const pathToPackageJson = path.join(path.dirname(executablePath), "..", "package.json");
if (fs.existsSync(pathToPackageJson)) {
const packageNameFromPackageJson = JSON.parse(fs.readFileSync(pathToPackageJson)).name;
if (packageNameFromPackageJson === packageName) {
return path.dirname(pathToPackageJson);
}
}

return null;
};

// For some packages executable name is not the same as package name
// For example our package is called nativescript, but the executable name is called "tns"
const getPath = (packageName, executableName) => {
Expand All @@ -117,19 +140,18 @@ const getPath = (packageName, executableName) => {
throw new Error(`OS '${platform}' is not supported.'`);
}

const resultWithNpmConfig = getPathFromNpmConfig(platform, packageName);

if (resultWithNpmConfig) {
return resultWithNpmConfig;
}

let foundPath = null;
if (executableName) {
return platform === "win32" ?
foundPath = platform === "win32" ?
getPathFromExecutableNameOnWindows(packageName, executableName) :
getPathFromExecutableNameOnNonWindows(packageName, executableName);
}

return null;
if (!foundPath) {
foundPath = getPathFromNpmConfig(platform, packageName);
}

return foundPath;
};

module.exports = {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "global-modules-path",
"version": "1.0.0",
"version": "2.0.0",
"description": "Returns path to globally installed package",
"main": "./lib/index.js",
"scripts": {
Expand Down
148 changes: 145 additions & 3 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ let fs = require("fs"),
const originalExecSync = childProcess.execSync;
const originalConsoleError = console.error;
const originalExistsSync = fs.existsSync;
const originalReadFileSync = fs.readFileSync;

describe("getPath", () => {

Expand All @@ -23,6 +24,7 @@ describe("getPath", () => {
childProcess.execSync = originalExecSync;
console.error = originalConsoleError;
fs.existsSync = originalExistsSync;
fs.readFileSync = originalReadFileSync;
});

// platform independant tests. Execute them by simulating all supported platforms, but results should be the same.
Expand Down Expand Up @@ -173,13 +175,77 @@ describe("getPath", () => {
assert.deepEqual(result, path.join(executableDirName, "node_modules", packageName));
});

it("returns correct result when where result is correct, and package is added to PATH via its bin dir", () => {
const packageName = "test1",
executableName = "test1.js",
executableDirName = path.join("C:", "Users", "username", "nativescript-cli", "bin"),
whereResult = path.join(executableDirName, executableName);

fs.existsSync = (filePath) => {
return filePath.indexOf("package.json") !== -1;
};

fs.readFileSync = (filePath) => {
if (filePath.indexOf("package.json") !== -1) {
return JSON.stringify({
"name": packageName
});
}

return "";
};

childProcess.execSync = (command) => {
if (command.indexOf("where") !== -1) {
return whereResult;
}

return null;
};

const result = index.getPath(packageName, executableName);
assert.deepEqual(result, path.join(path.dirname(executableDirName)));
});

it("returns null when package is added to PATH via its bin dir, but the name in package.json is incorrect", () => {
const packageName = "test1",
executableName = "test1.js",
executableDirName = path.join("C:", "Users", "username", "nativescript-cli", "bin"),
whereResult = path.join(executableDirName, executableName);

fs.existsSync = (filePath) => {
return filePath.indexOf("package.json") !== -1;
};

fs.readFileSync = (filePath) => {
if (filePath.indexOf("package.json") !== -1) {
return JSON.stringify({
"name": "invalidName"
});
}

return "";
};

childProcess.execSync = (command) => {
if (command.indexOf("where") !== -1) {
return whereResult;
}

return null;
};

const result = index.getPath(packageName, executableName);
assert.deepEqual(result, null);
});

it("returns correct result when where result returns multiple lines correct", () => {
const packageName = "test1",
executableName = "test1.js",
executableDirName = path.join("C:", "Users", "username", "AppData", "Roaming", "npm"),
invalidName = "invalidName",
invalidLineOfWhereResult = path.join(executableDirName, invalidName, executableName),
whereResult = invalidLineOfWhereResult + "\n" + invalidLineOfWhereResult + "\r\n" + path.join(executableDirName, executableName);
invalidLineOfWhereResult = path.join(executableDirName, invalidName, invalidName, executableName),
whereResult = invalidLineOfWhereResult + "\n" + invalidLineOfWhereResult + "\r\n" + path.join(executableDirName, executableName);

fs.existsSync = (filePath) => {
if (filePath && filePath.indexOf(invalidName) !== -1) {
Expand Down Expand Up @@ -348,14 +414,90 @@ describe("getPath", () => {
const result = index.getPath(packageName, executableName);
assert.deepEqual(result, null);
});

it("returns correct result when which result is correct, and package is added to PATH via its bin dir", () => {
const packageName = "test1",
executableName = "test1.js",
executableDirName = path.join("/usr", "username", "repository_name", "bin"),
whichResult = path.join(executableDirName, executableName),
lsLResult = `lrwxrwxrwx 1 rvladimirov rvladimirov 52 Oct 20 14:51 ${whichResult} -> incorrect`;

fs.existsSync = (filePath) => {
return filePath.indexOf("package.json") !== -1;
};

childProcess.execSync = (command) => {

if (command.indexOf("ls -l") !== -1) {
return lsLResult;
}

if (command.indexOf("which") !== -1) {
return whichResult;
}

return null;
};

fs.readFileSync = (filePath) => {
if (filePath.indexOf("package.json") !== -1) {
return JSON.stringify({
"name": packageName
});
}

return "";
};

const result = index.getPath(packageName, executableName);
assert.deepEqual(result, path.dirname(executableDirName));
});

it("returns null when package is added to PATH via its bin dir, but the name in package.json is incorrect", () => {
const packageName = "test1",
executableName = "test1.js",
executableDirName = path.join("/usr", "username", "repository_name", "bin"),
whichResult = path.join(executableDirName, executableName),
lsLResult = `lrwxrwxrwx 1 rvladimirov rvladimirov 52 Oct 20 14:51 ${whichResult} -> incorrect`;

fs.existsSync = (filePath) => {
return filePath.indexOf("package.json") !== -1;
};

childProcess.execSync = (command) => {

if (command.indexOf("ls -l") !== -1) {
return lsLResult;
}

if (command.indexOf("which") !== -1) {
return whichResult;
}

return null;
};

fs.readFileSync = (filePath) => {
if (filePath.indexOf("package.json") !== -1) {
return JSON.stringify({
"name": "invalid name"
});
}

return "";
};

const result = index.getPath(packageName, executableName);
assert.deepEqual(result, null);
});
}
});
});
});

it("throws error when process.platform is not valid", () => {
require("../lib/process-wrapper").getProcessPlatform = () => "1";
assert.throws( () => index.getPath("test1", "test1"), "OS '1' is not supported" );
assert.throws(() => index.getPath("test1", "test1"), "OS '1' is not supported");
});

});

0 comments on commit 2445cbe

Please sign in to comment.