Skip to content

Commit

Permalink
Merge pull request #38 from Anifacted/lazy-flag
Browse files Browse the repository at this point in the history
Add `lazy` flag
  • Loading branch information
Anifacted authored Apr 15, 2019
2 parents 55d7b39 + 7229630 commit 6729047
Show file tree
Hide file tree
Showing 6 changed files with 234 additions and 18 deletions.
5 changes: 5 additions & 0 deletions bin/lernaupdate
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ const { input, flags } = meow(
--non-interactive Prevent any interactive prompts (Requires --dependency flag to be specified)
--lazy Runs a single install command after updating package.json files, instead installing inside each individual package (Useful for workspaces)
Examples:
$ lernaupdate ./myproject --dedupe
Expand Down Expand Up @@ -50,6 +52,9 @@ const { input, flags } = meow(
newIntallsMode: {
type: "string",
},
lazy: {
type: "boolean",
},
},
}
);
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"lodash": "^4.17.4",
"meow": "^4.0.0",
"minimist": "^1.2.0",
"prettier-package-json": "^2.1.0",
"semver-compare": "^1.0.0"
},
"devDependencies": {
Expand Down
91 changes: 73 additions & 18 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const orderBy = require("lodash/orderBy");
const globby = require("globby");
const semverCompare = require("semver-compare");
const perf = require("execution-time")();
const fs = require("fs-extra");

const runCommand = require("./utils/runCommand");
const fileExists = require("./utils/fileExists");
Expand All @@ -14,6 +15,7 @@ const plural = require("./utils/plural");
const invariant = require("./utils/invariant");
const parseDependency = require("./utils/parseDependency");
const sanitizeGitBranchName = require("./utils/sanitizeGitBranchName");
const modifyPackageJson = require("./utils/modifyPackageJson");

inquirer.registerPrompt(
"autocomplete",
Expand Down Expand Up @@ -353,22 +355,42 @@ module.exports = async ({ input, flags }) => {

targetVersion = promptedTarget;
}
let targetVersionResolved = targetVersion;

let targetVersionLookup = (await runCommand(
`npm info ${targetDependency}@${targetVersion} version`,
{
startMessage: `Resolving dependency version for "${targetDependency}@${targetVersion}"`,
logOutput: false,
}
)).trim();

invariant(
targetVersionLookup,
`The version "${targetVersion}" was not found for "${targetDependency}"`
);

// If targeting a specific tag (such as @latest),
const versionFromDistTag = npmPackageInfo["dist-tags"][targetVersion];
if (versionFromDistTag) {
targetVersionResolved = `^${versionFromDistTag}`;
}

ui.log.write(chalk.green(`Using version ${targetVersionResolved} ✓\n`));

perf.start();
let totalInstalls = 0;

const dependencyManager = (await fileExists(resolve(projectDir, "yarn.lock")))
? "yarn"
: "npm";

// Install process
for (let depName of targetPackages) {
const existingDependency = dependencyMap[targetDependency];

let source = "dependencies";

const dependencyManager = (await fileExists(
resolve(projectDir, "yarn.lock")
))
? "yarn"
: "npm";

if (existingDependency && existingDependency.packs[depName]) {
const { version, source: theSource } =
existingDependency.packs[depName] || {};
Expand Down Expand Up @@ -406,9 +428,10 @@ module.exports = async ({ input, flags }) => {
}[flags.newInstallsMode];
}

const { path: packageDir } = packages.find(
({ config: { name } }) => name === depName
);
const {
path: packageDir,
config: { name: packageName },
} = packages.find(({ config: { name } }) => name === depName);

const sourceParam = {
yarn: {
Expand All @@ -421,20 +444,52 @@ module.exports = async ({ input, flags }) => {
},
}[dependencyManager][source || "dependencies"];

const installCmd = (dependencyManager === "yarn"
? ["yarn", "add", sourceParam, `${targetDependency}@${targetVersion}`]
: ["npm", "install", sourceParam, `${targetDependency}@${targetVersion}`]
).join(" ");
if (flags.lazy) {
const packageJsonPath = resolve(packageDir, "package.json");
const targetPackageJson = require(packageJsonPath);

await runCommand(`cd ${packageDir} && ${installCmd}`, {
startMessage: `${chalk.white.bold(depName)}: ${installCmd}`,
endMessage: chalk.green(`${depName} ✓`),
logTime: true,
});
fs.writeFileSync(
packageJsonPath,
modifyPackageJson(targetPackageJson, {
[source]: { [targetDependency]: targetVersionResolved },
})
);

ui.log.write(
chalk`{white.bold ${packageName}}: {green package.json updated ✓}\n`
);
} else {
const installCmd = (dependencyManager === "yarn"
? ["yarn", "add", sourceParam, `${targetDependency}@${targetVersion}`]
: [
"npm",
"install",
sourceParam,
`${targetDependency}@${targetVersion}`,
]
).join(" ");

await runCommand(`cd ${packageDir} && ${installCmd}`, {
startMessage: `${chalk.white.bold(depName)}: ${installCmd}`,
endMessage: chalk.green(`${depName} ✓`),
logTime: true,
});
}
totalInstalls++;
}

if (flags.lazy) {
ui.log.write("");

const installCmd = dependencyManager === "yarn" ? "yarn" : "npm install";

await runCommand(`cd ${projectDir} && ${installCmd}`, {
startMessage: `${chalk.white.bold(projectName)}: ${installCmd}`,
endMessage: chalk.green(`Packages installed ✓`),
logTime: true,
});
}

if (totalInstalls === 0) process.exit();

ui.log.write(
Expand Down
7 changes: 7 additions & 0 deletions src/utils/modifyPackageJson.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const { format } = require("prettier-package-json");
const merge = require("lodash/merge");

module.exports = (basePackageJson, modificationsBlob) => {
const merged = merge(basePackageJson, modificationsBlob);
return format(merged);
};
81 changes: 81 additions & 0 deletions src/utils/modifyPackageJson.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
const expect = require("unexpected");
const modifyPackageJson = require("./modifyPackageJson");

const baseJson = JSON.parse(`{
"name": "lerna-update-wizard",
"bin": {
"lernaupdate": "./bin/lernaupdate"
},
"version": "0.12.0",
"main": "index.js",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/Anifacted/lerna-update-wizard"
},
"dependencies": {
"chalk": "^2.3.0",
"semver-compare": "^1.0.0"
},
"devDependencies": {
},
"scripts": {
"test": "jest --verbose --runInBand"
},
"jest": {
"testURL": "http://localhost"
}
}`);

describe("modifyPackageJson", () => {
it("should work", () => {
const mods = {
dependencies: {
d3: "3",
},
devDependencies: {
lodash: "3",
},
peerDependencies: {
underscore: "~2",
},
};

expect(
modifyPackageJson,
"when called with",
[baseJson, mods],
"to equal",
`{
"name": "lerna-update-wizard",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/Anifacted/lerna-update-wizard"
},
"version": "0.12.0",
"main": "index.js",
"bin": {
"lernaupdate": "./bin/lernaupdate"
},
"scripts": {
"test": "jest --verbose --runInBand"
},
"dependencies": {
"chalk": "^2.3.0",
"d3": "3",
"semver-compare": "^1.0.0"
},
"peerDependencies": {
"underscore": "~2"
},
"devDependencies": {
"lodash": "3"
},
"jest": {
"testURL": "http://localhost"
}
}\n`
);
});
});
67 changes: 67 additions & 0 deletions test/lazy.flag.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
const { default: runProgram } = require("./utils/runProgram");
const generateProject = require("./utils/generateProject");

describe("Lazy install dependency", async () => {
describe("dep is not installed in any of the packages", () => {
it("lazily installs the dependency", async () => {
// eslint-disable-next-line
jest.setTimeout(100000);

const projectPath = await generateProject({
name: "project-a",
packages: [
{ name: "sub-package-a" },
{
name: "sub-package-b",
dependencies: { lodash: "0.1.0" },
},
],
});

await runProgram(
`${projectPath} --lazy --dependency "treediff@latest"`,
`
Fetching package information for "treediff"
>>> wait
? Select packages to affect: (Press <space> to select, <a> to toggle all, <i> to
invert selection)
❯◯ sub-package-a
◯ sub-package-b
>>> input SPACE
>>> input ENTER
Resolving dependency version for "treediff@latest"
>>> wait
Using version ^0.2.5 ✓
>>> wait
? Select dependency installation type for "sub-package-a" (Use arrow keys)
❯ dependencies
devDependencies
>>> input ENTER
project-a: npm install
>>> wait
? Do you want to create a new git branch for the change? (Y/n)
>>> input n
>>> input ENTER
? Do you want to create a new git commit for the change? (Y/n)
>>> input n
>>> input ENTER
`
);
});
});
});

0 comments on commit 6729047

Please sign in to comment.