.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / eslint / lib / shared / runtime-info.js
1 /**
2  * @fileoverview Utility to get information about the execution environment.
3  * @author Kai Cataldo
4  */
5
6 "use strict";
7
8 //------------------------------------------------------------------------------
9 // Requirements
10 //------------------------------------------------------------------------------
11
12 const path = require("path");
13 const spawn = require("cross-spawn");
14 const os = require("os");
15 const log = require("../shared/logging");
16 const packageJson = require("../../package.json");
17
18 //------------------------------------------------------------------------------
19 // Helpers
20 //------------------------------------------------------------------------------
21
22 /**
23  * Generates and returns execution environment information.
24  * @returns {string} A string that contains execution environment information.
25  */
26 function environment() {
27     const cache = new Map();
28
29     /**
30      * Checks if a path is a child of a directory.
31      * @param {string} parentPath The parent path to check.
32      * @param {string} childPath The path to check.
33      * @returns {boolean} Whether or not the given path is a child of a directory.
34      */
35     function isChildOfDirectory(parentPath, childPath) {
36         return !path.relative(parentPath, childPath).startsWith("..");
37     }
38
39     /**
40      * Synchronously executes a shell command and formats the result.
41      * @param {string} cmd The command to execute.
42      * @param {Array} args The arguments to be executed with the command.
43      * @returns {string} The version returned by the command.
44      */
45     function execCommand(cmd, args) {
46         const key = [cmd, ...args].join(" ");
47
48         if (cache.has(key)) {
49             return cache.get(key);
50         }
51
52         const process = spawn.sync(cmd, args, { encoding: "utf8" });
53
54         if (process.error) {
55             throw process.error;
56         }
57
58         const result = process.stdout.trim();
59
60         cache.set(key, result);
61         return result;
62     }
63
64     /**
65      * Normalizes a version number.
66      * @param {string} versionStr The string to normalize.
67      * @returns {string} The normalized version number.
68      */
69     function normalizeVersionStr(versionStr) {
70         return versionStr.startsWith("v") ? versionStr : `v${versionStr}`;
71     }
72
73     /**
74      * Gets bin version.
75      * @param {string} bin The bin to check.
76      * @returns {string} The normalized version returned by the command.
77      */
78     function getBinVersion(bin) {
79         const binArgs = ["--version"];
80
81         try {
82             return normalizeVersionStr(execCommand(bin, binArgs));
83         } catch (e) {
84             log.error(`Error finding ${bin} version running the command \`${bin} ${binArgs.join(" ")}\``);
85             throw e;
86         }
87     }
88
89     /**
90      * Gets installed npm package version.
91      * @param {string} pkg The package to check.
92      * @param {boolean} global Whether to check globally or not.
93      * @returns {string} The normalized version returned by the command.
94      */
95     function getNpmPackageVersion(pkg, { global = false } = {}) {
96         const npmBinArgs = ["bin", "-g"];
97         const npmLsArgs = ["ls", "--depth=0", "--json", "eslint"];
98
99         if (global) {
100             npmLsArgs.push("-g");
101         }
102
103         try {
104             const parsedStdout = JSON.parse(execCommand("npm", npmLsArgs));
105
106             /*
107              * Checking globally returns an empty JSON object, while local checks
108              * include the name and version of the local project.
109              */
110             if (Object.keys(parsedStdout).length === 0 || !(parsedStdout.dependencies && parsedStdout.dependencies.eslint)) {
111                 return "Not found";
112             }
113
114             const [, processBinPath] = process.argv;
115             let npmBinPath;
116
117             try {
118                 npmBinPath = execCommand("npm", npmBinArgs);
119             } catch (e) {
120                 log.error(`Error finding npm binary path when running command \`npm ${npmBinArgs.join(" ")}\``);
121                 throw e;
122             }
123
124             const isGlobal = isChildOfDirectory(npmBinPath, processBinPath);
125             let pkgVersion = parsedStdout.dependencies.eslint.version;
126
127             if ((global && isGlobal) || (!global && !isGlobal)) {
128                 pkgVersion += " (Currently used)";
129             }
130
131             return normalizeVersionStr(pkgVersion);
132         } catch (e) {
133             log.error(`Error finding ${pkg} version running the command \`npm ${npmLsArgs.join(" ")}\``);
134             throw e;
135         }
136     }
137
138     return [
139         "Environment Info:",
140         "",
141         `Node version: ${getBinVersion("node")}`,
142         `npm version: ${getBinVersion("npm")}`,
143         `Local ESLint version: ${getNpmPackageVersion("eslint", { global: false })}`,
144         `Global ESLint version: ${getNpmPackageVersion("eslint", { global: true })}`,
145         `Operating System: ${os.platform()} ${os.release()}`
146     ].join("\n");
147 }
148
149 /**
150  * Returns version of currently executing ESLint.
151  * @returns {string} The version from the currently executing ESLint's package.json.
152  */
153 function version() {
154     return `v${packageJson.version}`;
155 }
156
157 //------------------------------------------------------------------------------
158 // Public Interface
159 //------------------------------------------------------------------------------
160
161 module.exports = {
162     environment,
163     version
164 };