Skip to content

Commit

Permalink
feat(create): Migrate npm info subprocess to libnpm.manifest
Browse files Browse the repository at this point in the history
  • Loading branch information
evocateur committed Dec 7, 2018
1 parent 7411299 commit 65a1d1b
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 48 deletions.
16 changes: 12 additions & 4 deletions commands/create/__tests__/create-command.test.js
@@ -1,14 +1,15 @@
"use strict";

jest.mock("../lib/get-latest-version");
jest.mock("libnpm/manifest");

const fs = require("fs-extra");
const path = require("path");
const execa = require("execa");
const slash = require("slash");
const { Conf } = require("@lerna/npm-conf");

// mocked modules
const getLatestVersion = require("../lib/get-latest-version");
const getManifest = require("libnpm/manifest");

// helpers
const initFixture = require("@lerna-test/init-fixture")(__dirname);
Expand Down Expand Up @@ -44,7 +45,7 @@ const manifestCreated = async cwd => {
};

describe("CreateCommand", () => {
getLatestVersion.mockReturnValue("1.0.0-mocked");
getManifest.mockImplementation(() => Promise.resolve({ version: "1.0.0-mocked" }));

// preserve value from @lerna-test/set-npm-userconfig
const userconfig = process.env.npm_config_userconfig;
Expand Down Expand Up @@ -124,7 +125,14 @@ describe("CreateCommand", () => {
expect(result).toMatchSnapshot();

// yargs is automatically added when CLI is stubbed
expect(getLatestVersion).toHaveBeenLastCalledWith("yargs", expect.objectContaining({ cwd }));
expect(getManifest).toHaveBeenLastCalledWith(
expect.objectContaining({
name: "yargs",
type: "tag",
fetchSpec: "latest",
}),
expect.any(Conf)
);
});

it("creates a stub cli with a custom name", async () => {
Expand Down
84 changes: 51 additions & 33 deletions commands/create/index.js
Expand Up @@ -7,7 +7,9 @@ const { URL } = require("whatwg-url");
const camelCase = require("camelcase");
const dedent = require("dedent");
const initPackageJson = require("pify")(require("init-package-json"));
const getManifest = require("libnpm/manifest");
const npa = require("libnpm/parse-arg");
const pReduce = require("p-reduce");
const slash = require("slash");

const Command = require("@lerna/command");
Expand All @@ -16,7 +18,6 @@ const npmConf = require("@lerna/npm-conf");
const ValidationError = require("@lerna/validation-error");
const builtinNpmrc = require("./lib/builtin-npmrc");
const catFile = require("./lib/cat-file");
const getLatestVersion = require("./lib/get-latest-version");

const LERNA_MODULE_DATA = require.resolve("./lib/lerna-module-data.js");
const DEFAULT_DESCRIPTION = [
Expand Down Expand Up @@ -140,7 +141,8 @@ class CreateCommand extends Command {
this.setHomepage();
this.setPublishConfig();
this.setRepository();
this.setDependencies();

return Promise.resolve(this.setDependencies());
}

execute() {
Expand Down Expand Up @@ -179,10 +181,6 @@ class CreateCommand extends Command {
return ChildProcessUtilities.execSync("git", ["config", "--get", prop], this.execOpts);
}

latestVersion(depName) {
return getLatestVersion(depName, this.execOpts);
}

collectExternalVersions() {
// collect all current externalDependencies
const extVersions = new Map();
Expand Down Expand Up @@ -217,7 +215,7 @@ class CreateCommand extends Command {
}

setDependencies() {
const inputs = new Set(this.options.dependencies);
const inputs = new Set((this.options.dependencies || []).sort());

// add yargs if a bin is required
if (this.options.bin) {
Expand All @@ -228,48 +226,68 @@ class CreateCommand extends Command {
return;
}

const dependencies = {};
const exts = this.collectExternalVersions();
const localRelative = this.hasLocalRelativeFileSpec();
const savePrefix = this.conf.get("save-exact") ? "" : this.conf.get("save-prefix");

for (const spec of [...inputs].sort().map(i => npa(i))) {
const depType = spec.type;
const depName = spec.name;

let version;

if (this.packageGraph.has(depName)) {
const decideVersion = spec => {
if (this.packageGraph.has(spec.name)) {
// sibling dependency
const depNode = this.packageGraph.get(depName);
const depNode = this.packageGraph.get(spec.name);

if (localRelative) {
// a local `file:../foo` specifier
version = this.resolveRelative(depNode);
} else {
// yarn workspace or lerna packages config
version = `${savePrefix}${depNode.version}`;
return this.resolveRelative(depNode);
}
} else if (depType === "tag" && spec.fetchSpec === "latest") {

// yarn workspace or lerna packages config
return `${savePrefix}${depNode.version}`;
}

if (spec.type === "tag" && spec.fetchSpec === "latest") {
// resolve the latest version
if (exts.has(depName)) {
if (exts.has(spec.name)) {
// from local external dependency
version = exts.get(depName);
} else {
// from registry
version = `${savePrefix}${this.latestVersion(depName)}`;
return exts.get(spec.name);
}
} else if (depType === "git") {

// from registry
return getManifest(spec, this.conf).then(pkg => `${savePrefix}${pkg.version}`);
}

if (spec.type === "git") {
throw new ValidationError("EGIT", "Do not use git dependencies");
} else {
// TODO: resolve this if it's weird? (foo@1, bar@^2, etc)
version = spec.rawSpec;
}

dependencies[depName] = version;
}
// TODO: resolve this if it's weird? (foo@1, bar@^2, etc)
return spec.rawSpec;
};

let chain = Promise.resolve();

chain = chain.then(() =>
pReduce(
inputs,
(obj, input) => {
const spec = npa(input);

return Promise.resolve(spec)
.then(decideVersion)
.then(version => {
obj[spec.name] = version;

return obj;
});
},
{}
)
);

chain = chain.then(dependencies => {
this.conf.set("dependencies", dependencies);
});

this.conf.set("dependencies", dependencies);
return chain;
}

setFiles() {
Expand Down
11 changes: 0 additions & 11 deletions commands/create/lib/get-latest-version.js

This file was deleted.

1 change: 1 addition & 0 deletions commands/create/package.json
Expand Up @@ -42,6 +42,7 @@
"globby": "^8.0.1",
"init-package-json": "^1.10.3",
"libnpm": "^2.0.1",
"p-reduce": "^1.0.0",
"pify": "^3.0.0",
"semver": "^5.5.0",
"slash": "^1.0.0",
Expand Down
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 65a1d1b

Please sign in to comment.