Skip to content

Commit 7d7c0ba

Browse files
authored
fix: wrong info command in yarn >1 (#255)
Co-authored-by: nathanhleung <nathanhleung@users.noreply.github.com>
1 parent c19292d commit 7d7c0ba

2 files changed

Lines changed: 58 additions & 24 deletions

File tree

src/cli.js

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@ const { name, version } = pkg;
2222
* parse the package string.
2323
*/
2424
function printPackageFormatError() {
25-
console.log(
25+
console.error(
2626
`${C.errorText} Please specify the package to install with peerDeps in the form of \`package\` or \`package@n.n.n\``
2727
);
28-
console.log(
28+
console.error(
2929
`${C.errorText} At this time you must provide the full semver version of the package.`
3030
);
31-
console.log(
31+
console.error(
3232
`${C.errorText} Alternatively, omit it to automatically install the latest version of the package.`
3333
);
3434
}
@@ -64,7 +64,7 @@ console.log(clc.bold(`${name} v${version}`));
6464

6565
// Make sure we're installing at least one package
6666
if (program.args.length === 0) {
67-
console.log(
67+
console.error(
6868
`${C.errorText} Please specify a package to install with peerDeps.`
6969
);
7070
// An exit code of "9" indicates an invalid argument
@@ -75,7 +75,7 @@ if (program.args.length === 0) {
7575

7676
// Make sure we're installing no more than one package
7777
if (program.args.length > 1) {
78-
console.log(
78+
console.error(
7979
`${C.errorText} Too many arguments. Please specify ONE package at a time to install with peerDeps. Alternatively, pass extra arguments with --extra-args "<extra_args>".`
8080
);
8181
// An exit code of "9" indicates an invalid argument
@@ -99,7 +99,7 @@ if (!packageName) {
9999
let packageManager = C.npm; // Default package manager is npm
100100

101101
if (program.yarn && program.pnpm) {
102-
console.log(
102+
console.error(
103103
`${C.errorText} Option --yarn and --pnpm cannot be used concurrently.`
104104
);
105105
process.exit(9);
@@ -113,7 +113,7 @@ if (program.pnpm) {
113113

114114
// Yarn does not allow silent install of dependencies
115115
if (program.yarn && program.silent) {
116-
console.log(`${C.errorText} Option --silent cannot be used with --yarn.`);
116+
console.error(`${C.errorText} Option --silent cannot be used with --yarn.`);
117117
process.exit(9);
118118
}
119119

@@ -122,15 +122,15 @@ const devMode = program.dev || program.D;
122122
// since --dev means it should be saved
123123
// as a devDependency
124124
if (devMode && program.silent) {
125-
console.log(`${C.errorText} Option --silent cannot be used with --dev.`);
125+
console.error(`${C.errorText} Option --silent cannot be used with --dev.`);
126126
process.exit(9);
127127
}
128128

129129
// Dev option can't be used with global,
130130
// since --dev means it should be saved
131131
// as a devDependency (locally)
132132
if (devMode && program.silent) {
133-
console.log(`${C.errorText} Option --dev cannot be used with --global.`);
133+
console.error(`${C.errorText} Option --dev cannot be used with --global.`);
134134
process.exit(9);
135135
}
136136

@@ -172,7 +172,7 @@ if (hasYarn() && packageManager !== C.yarn && !program.silent) {
172172
})
173173
.catch(err => {
174174
if (err) {
175-
console.log(`${C.errorText} ${err.message}`);
175+
console.error(`${C.errorText} ${err.message}`);
176176
process.exit(1);
177177
}
178178
});
@@ -190,11 +190,10 @@ if (hasYarn() && packageManager !== C.yarn && !program.silent) {
190190
*/
191191
function installCb(err) {
192192
if (err) {
193-
console.log(`${C.errorText} ${err.message}`);
193+
console.error(`${C.errorText} ${err.message}`);
194194
process.exit(1);
195195
}
196-
let successMessage = `${C.successText} ${packageName}
197-
and its peerDeps were installed successfully.`;
196+
let successMessage = `${C.successText} ${packageName} and its peerDeps were installed successfully.`;
198197
if (program.onlyPeers) {
199198
successMessage = `${C.successText} The peerDeps of ${packageName} were installed successfully.`;
200199
}

src/install-peerdeps.js

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,22 +48,38 @@ const spawnCommand = (command, args) => {
4848
}
4949
);
5050
cmdProcess.stdout.on("data", chunk => {
51-
stdout += chunk;
51+
if (chunk instanceof Buffer) {
52+
stdout += chunk.toString("utf8");
53+
} else {
54+
stdout += chunk;
55+
}
5256
});
5357
cmdProcess.stderr.on("data", chunk => {
54-
stderr += chunk;
58+
if (chunk instanceof Buffer) {
59+
stderr += chunk.toString("utf8");
60+
} else {
61+
stderr += chunk;
62+
}
5563
});
5664
cmdProcess.on("error", reject);
5765
cmdProcess.on("exit", code => {
5866
if (code === 0) {
5967
resolve(stdout);
6068
} else {
61-
reject(stderr);
69+
reject(new Error(`${[stdout, stderr].filter(Boolean).join("\n\n")}`));
6270
}
6371
});
6472
});
6573
};
6674

75+
/**
76+
* Gets the current Yarn version
77+
* @returns {string} - The current Yarn version
78+
*/
79+
function getYarnVersion() {
80+
return spawnCommand("yarn", ["--version"]).then(it => it.trim());
81+
}
82+
6783
/**
6884
* Parse a registry manifest to get the best matching version
6985
* @param {Object} requestInfo - information needed to make the request for the data
@@ -91,26 +107,45 @@ function findPackageVersion({ data, version }) {
91107
* Gets metadata about the package from the provided registry
92108
* @param {Object} requestInfo - information needed to make the request for the data
93109
* @param {string} requestInfo.packageName - the name of the package
94-
* @param {string} requestInfo.packageManager - the package manager to use (Yarn or npm)
110+
* @param {string} requestInfo.packageManager - the package manager to use
95111
* @param {string} requestInfo.version - the version (or version tag) to attempt to install
96112
* @returns {Promise<Object>} - a Promise which resolves to the JSON response from the registry
97113
*/
98114
function getPackageData({ packageName, packageManager, version }) {
99115
const pkgString = version ? `${packageName}@${version}` : packageName;
100-
const args = ["info", pkgString, "--json"];
101-
return spawnCommand(packageManager, args).then(response => {
102-
const parsed = JSON.parse(response);
103-
// Yarn returns with an extra nested { data } that NPM doesn't
104-
return parsed.data || parsed;
105-
});
116+
return getYarnVersion()
117+
.catch(err => {
118+
if (packageManager === C.yarn) {
119+
throw err;
120+
}
121+
// If we're not trying to install with Yarn, we won't re-throw and instead will ignore the error and continue
122+
})
123+
.then(yarnVersion => {
124+
// In Yarn versions >= 2, the `yarn info` command was replaced with `yarn npm info`
125+
const isUsingYarnGreaterThan1 =
126+
yarnVersion && !yarnVersion.startsWith("1.");
127+
128+
const args = [
129+
...(isUsingYarnGreaterThan1 ? ["npm", "info"] : ["info"]),
130+
pkgString,
131+
"--json"
132+
];
133+
134+
return spawnCommand(packageManager, args).then(response => {
135+
const parsed = JSON.parse(response);
136+
137+
// Yarn 1 returns with an extra nested { data } that NPM doesn't
138+
return parsed.data || parsed;
139+
});
140+
});
106141
}
107142

108143
/**
109144
* Gets the contents of the package.json for a package at a specific version
110145
* @param {Object} requestInfo - information needed to make the request for the data
111146
* @param {string} requestInfo.packageName - the name of the package
112147
* @param {Boolean} requestInfo.noRegistry - Gets the package dependencies list from the local node_modules instead of remote registry
113-
* @param {string} requestInfo.packageManager - the package manager to use (Yarn or npm)
148+
* @param {string} requestInfo.packageManager - the package manager to use
114149
* @param {string} requestInfo.version - the version (or version tag) to attempt to install. Ignored if an installed version of the package is found in node_modules.
115150
* @returns {Promise<Object>} - a Promise which resolves to the JSON response from the registry
116151
*/

0 commit comments

Comments
 (0)