From 02ffb9620e03e021ae75c4aa05f7d977596a32f0 Mon Sep 17 00:00:00 2001 From: Henry Zhu Date: Fri, 17 Jun 2016 11:08:43 -0400 Subject: [PATCH 01/13] typo [skip ci] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4caf03bd8c..1df1d9788e 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ repositories is *messy* and difficult to track, and testing across repositories gets complicated really fast. To solve these (and many other) problems, some projects will organize their -codebases into multi-package repostories (sometimes called [monorepos](https://github.com/babel/babel/blob/master/doc/design/monorepo.md)). Projects like [Babel](https://github.com/babel/babel/tree/master/packages), [React](https://github.com/facebook/react/tree/master/packages), [Angular](https://github.com/angular/angular/tree/master/modules), +codebases into multi-package repositories (sometimes called [monorepos](https://github.com/babel/babel/blob/master/doc/design/monorepo.md)). Projects like [Babel](https://github.com/babel/babel/tree/master/packages), [React](https://github.com/facebook/react/tree/master/packages), [Angular](https://github.com/angular/angular/tree/master/modules), [Ember](https://github.com/emberjs/ember.js/tree/master/packages), [Meteor](https://github.com/meteor/meteor/tree/devel/packages), [Jest](https://github.com/facebook/jest/tree/master/packages), and many others develop all of their packages within a single repository. From c0f1e8d61f63b3d0d825d7e9a8ee1d2bdb7c9c5c Mon Sep 17 00:00:00 2001 From: James Kyle Date: Mon, 20 Jun 2016 14:45:52 -0700 Subject: [PATCH 02/13] Fix bootstrap install to use quotes around versions (#235) * Fix bootstrap install to use quotes around versions * Address PR feedback --- src/commands/BootstrapCommand.js | 3 ++- test/BootstrapCommand.js | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/commands/BootstrapCommand.js b/src/commands/BootstrapCommand.js index a02892ad37..135b1a567e 100644 --- a/src/commands/BootstrapCommand.js +++ b/src/commands/BootstrapCommand.js @@ -109,7 +109,8 @@ export default class BootstrapCommand extends Command { return !this.hasDependencyInstalled(pkg, dependency); }) .map(dependency => { - return dependency + "@" + allDependencies[dependency]; + // Needs "quotes" for versions like "^1.0.0 || ^2.0.0" + return `${dependency}@"${allDependencies[dependency]}"`; }); if (externalPackages.length) { diff --git a/test/BootstrapCommand.js b/test/BootstrapCommand.js index 922fb0c03e..fd2ed045a4 100644 --- a/test/BootstrapCommand.js +++ b/test/BootstrapCommand.js @@ -28,7 +28,7 @@ describe("BootstrapCommand", () => { assertStubbedCalls([ [ChildProcessUtilities, "spawn", { nodeCallback: true }, [ - { args: ["npm", ["install", "package-1@^0.0.0"], { cwd: path.join(testDir, "packages/package-4"), stdio: "ignore" }] } + { args: ["npm", ["install", "package-1@\"^0.0.0\""], { cwd: path.join(testDir, "packages/package-4"), stdio: "ignore" }] } ]] ]); @@ -77,7 +77,7 @@ describe("BootstrapCommand", () => { assertStubbedCalls([ [ChildProcessUtilities, "spawn", { nodeCallback: true }, [ - { args: ["npm", ["install", "package-1@^0.0.0"], { cwd: path.join(testDir, "packages/package-4"), stdio: "ignore" }] } + { args: ["npm", ["install", "package-1@\"^0.0.0\""], { cwd: path.join(testDir, "packages/package-4"), stdio: "ignore" }] } ]] ]); @@ -131,7 +131,7 @@ describe("BootstrapCommand", () => { let installed = false; stub(ChildProcessUtilities, "spawn", (command, args, options, callback) => { - assert.deepEqual(args, ["install", "external@^1.0.0"]) + assert.deepEqual(args, ["install", "external@\"^1.0.0\""]) assert.deepEqual(options, { cwd: path.join(testDir, "packages/package-1"), stdio: "ignore" }) installed = true; callback(); From 90988eddd732b5efad524d4f183fe3ccc3dbe578 Mon Sep 17 00:00:00 2001 From: James Kyle Date: Mon, 20 Jun 2016 15:20:31 -0700 Subject: [PATCH 03/13] 2.0.0-beta.21 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4f494b0eb8..3ca53c38d8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lerna", - "version": "2.0.0-beta.20", + "version": "2.0.0-beta.21", "description": "Tool for managing JavaScript projects with multiple packages", "main": "lib/index.js", "scripts": { From 8364ee4cb479a580db96ce58e0fa2db79a8d22b8 Mon Sep 17 00:00:00 2001 From: James Kyle Date: Mon, 20 Jun 2016 17:18:43 -0700 Subject: [PATCH 04/13] Revert "Fix bootstrap install to use quotes around versions (#235)" This reverts commit c0f1e8d61f63b3d0d825d7e9a8ee1d2bdb7c9c5c. --- src/commands/BootstrapCommand.js | 3 +-- test/BootstrapCommand.js | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/commands/BootstrapCommand.js b/src/commands/BootstrapCommand.js index 135b1a567e..a02892ad37 100644 --- a/src/commands/BootstrapCommand.js +++ b/src/commands/BootstrapCommand.js @@ -109,8 +109,7 @@ export default class BootstrapCommand extends Command { return !this.hasDependencyInstalled(pkg, dependency); }) .map(dependency => { - // Needs "quotes" for versions like "^1.0.0 || ^2.0.0" - return `${dependency}@"${allDependencies[dependency]}"`; + return dependency + "@" + allDependencies[dependency]; }); if (externalPackages.length) { diff --git a/test/BootstrapCommand.js b/test/BootstrapCommand.js index fd2ed045a4..922fb0c03e 100644 --- a/test/BootstrapCommand.js +++ b/test/BootstrapCommand.js @@ -28,7 +28,7 @@ describe("BootstrapCommand", () => { assertStubbedCalls([ [ChildProcessUtilities, "spawn", { nodeCallback: true }, [ - { args: ["npm", ["install", "package-1@\"^0.0.0\""], { cwd: path.join(testDir, "packages/package-4"), stdio: "ignore" }] } + { args: ["npm", ["install", "package-1@^0.0.0"], { cwd: path.join(testDir, "packages/package-4"), stdio: "ignore" }] } ]] ]); @@ -77,7 +77,7 @@ describe("BootstrapCommand", () => { assertStubbedCalls([ [ChildProcessUtilities, "spawn", { nodeCallback: true }, [ - { args: ["npm", ["install", "package-1@\"^0.0.0\""], { cwd: path.join(testDir, "packages/package-4"), stdio: "ignore" }] } + { args: ["npm", ["install", "package-1@^0.0.0"], { cwd: path.join(testDir, "packages/package-4"), stdio: "ignore" }] } ]] ]); @@ -131,7 +131,7 @@ describe("BootstrapCommand", () => { let installed = false; stub(ChildProcessUtilities, "spawn", (command, args, options, callback) => { - assert.deepEqual(args, ["install", "external@\"^1.0.0\""]) + assert.deepEqual(args, ["install", "external@^1.0.0"]) assert.deepEqual(options, { cwd: path.join(testDir, "packages/package-1"), stdio: "ignore" }) installed = true; callback(); From 7eb4763030b4596048d331b2d25e9317e18401e2 Mon Sep 17 00:00:00 2001 From: Henry Zhu Date: Wed, 22 Jun 2016 20:25:37 -0400 Subject: [PATCH 05/13] Revert "Use sync-exec for node 0.10" (#242) --- .travis.yml | 1 - package.json | 3 +- src/ChildProcessUtilities.js | 13 ++----- test/UpdatedCommand.js | 71 +++++++++++++++++------------------- test/_initFixture.js | 3 +- 5 files changed, 39 insertions(+), 52 deletions(-) diff --git a/.travis.yml b/.travis.yml index fbe195923f..48e36db80f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,6 @@ cache: - node_modules node_js: - - "0.10" - "0.12" - "4" - stable diff --git a/package.json b/package.json index 3ca53c38d8..a25c6ad747 100644 --- a/package.json +++ b/package.json @@ -37,8 +37,7 @@ "progress": "^1.1.8", "rimraf": "^2.4.4", "semver": "^5.1.0", - "signal-exit": "^2.1.2", - "sync-exec": "^0.6.2" + "signal-exit": "^2.1.2" }, "bin": { "lerna": "./bin/lerna.js" diff --git a/src/ChildProcessUtilities.js b/src/ChildProcessUtilities.js index 1257e68a3a..689d8c4999 100644 --- a/src/ChildProcessUtilities.js +++ b/src/ChildProcessUtilities.js @@ -1,6 +1,5 @@ import child from "child_process"; import objectAssign from "object-assign"; -import syncExec from "sync-exec"; export default class ChildProcessUtilities { static exec(command, opts, callback) { @@ -22,15 +21,9 @@ export default class ChildProcessUtilities { } static execSync(command) { - if (child.execSync) { - return child.execSync(command, { - encoding: "utf8" - }).trim(); - } else { - return syncExec(command, { - encoding: "utf8" - }).stdout.trim(); - } + return child.execSync(command, { + encoding: "utf8" + }).trim(); } static spawn(command, args, opts, callback) { diff --git a/test/UpdatedCommand.js b/test/UpdatedCommand.js index 8925b15acd..cc2ee6410e 100644 --- a/test/UpdatedCommand.js +++ b/test/UpdatedCommand.js @@ -2,7 +2,6 @@ import assert from "assert"; import child from "child_process"; import path from "path"; import fs from "fs"; -import syncExec from "sync-exec"; import UpdatedCommand from "../src/commands/UpdatedCommand"; import exitWithCode from "./_exitWithCode"; @@ -10,8 +9,6 @@ import initFixture from "./_initFixture"; import logger from "../src/logger"; import stub from "./_stub"; -const execSync = (child.execSync || syncExec); - describe("UpdatedCommand", () => { /** ========================================================================= @@ -26,10 +23,10 @@ describe("UpdatedCommand", () => { }); it("should list changes", done => { - execSync("git tag v1.0.0"); - execSync("touch " + path.join(testDir, "packages/package-2/random-file")); - execSync("git add -A"); - execSync("git commit -m 'Commit'"); + child.execSync("git tag v1.0.0"); + child.execSync("touch " + path.join(testDir, "packages/package-2/random-file")); + child.execSync("git add -A"); + child.execSync("git commit -m 'Commit'"); const updatedCommand = new UpdatedCommand([], {}); @@ -49,10 +46,10 @@ describe("UpdatedCommand", () => { }); it("should list changes with --force-publish *", done => { - execSync("git tag v1.0.0"); - execSync("touch " + path.join(testDir, "packages/package-2/random-file")); - execSync("git add -A"); - execSync("git commit -m 'Commit'"); + child.execSync("git tag v1.0.0"); + child.execSync("touch " + path.join(testDir, "packages/package-2/random-file")); + child.execSync("git add -A"); + child.execSync("git commit -m 'Commit'"); const updatedCommand = new UpdatedCommand([], { forcePublish: "*" @@ -74,10 +71,10 @@ describe("UpdatedCommand", () => { }); it("should list changes with --force-publish [package,package]", done => { - execSync("git tag v1.0.0"); - execSync("touch " + path.join(testDir, "packages/package-3/random-file")); - execSync("git add -A"); - execSync("git commit -m 'Commit'"); + child.execSync("git tag v1.0.0"); + child.execSync("touch " + path.join(testDir, "packages/package-3/random-file")); + child.execSync("git add -A"); + child.execSync("git commit -m 'Commit'"); const updatedCommand = new UpdatedCommand([], { forcePublish: "package-2,package-4" @@ -106,11 +103,11 @@ describe("UpdatedCommand", () => { }; fs.writeFileSync(lernaJsonLocation, JSON.stringify(lernaJson, null, 2)); - execSync("git tag v1.0.0"); - execSync("touch " + path.join(testDir, "packages/package-2/ignored-file")); - execSync("touch " + path.join(testDir, "packages/package-3/random-file")); - execSync("git add -A"); - execSync("git commit -m 'Commit'"); + child.execSync("git tag v1.0.0"); + child.execSync("touch " + path.join(testDir, "packages/package-2/ignored-file")); + child.execSync("touch " + path.join(testDir, "packages/package-3/random-file")); + child.execSync("git add -A"); + child.execSync("git commit -m 'Commit'"); const updatedCommand = new UpdatedCommand([], {}); @@ -142,10 +139,10 @@ describe("UpdatedCommand", () => { }); it("should list changes", done => { - execSync("git tag v1.0.0"); - execSync("touch " + path.join(testDir, "packages/package-3/random-file")); - execSync("git add -A"); - execSync("git commit -m 'Commit'"); + child.execSync("git tag v1.0.0"); + child.execSync("touch " + path.join(testDir, "packages/package-3/random-file")); + child.execSync("git add -A"); + child.execSync("git commit -m 'Commit'"); const updatedCommand = new UpdatedCommand([], {}); @@ -165,10 +162,10 @@ describe("UpdatedCommand", () => { }); it("should list changes with --force-publish *", done => { - execSync("git tag v1.0.0"); - execSync("touch " + path.join(testDir, "packages/package-2/random-file")); - execSync("git add -A"); - execSync("git commit -m 'Commit'"); + child.execSync("git tag v1.0.0"); + child.execSync("touch " + path.join(testDir, "packages/package-2/random-file")); + child.execSync("git add -A"); + child.execSync("git commit -m 'Commit'"); const updatedCommand = new UpdatedCommand([], { forcePublish: "*" @@ -190,10 +187,10 @@ describe("UpdatedCommand", () => { }); it("should list changes with --force-publish [package,package]", done => { - execSync("git tag v1.0.0"); - execSync("touch " + path.join(testDir, "packages/package-4/random-file")); - execSync("git add -A"); - execSync("git commit -m 'Commit'"); + child.execSync("git tag v1.0.0"); + child.execSync("touch " + path.join(testDir, "packages/package-4/random-file")); + child.execSync("git add -A"); + child.execSync("git commit -m 'Commit'"); const updatedCommand = new UpdatedCommand([], { forcePublish: "package-2" @@ -222,11 +219,11 @@ describe("UpdatedCommand", () => { }; fs.writeFileSync(lernaJsonLocation, JSON.stringify(lernaJson, null, 2)); - execSync("git tag v1.0.0"); - execSync("touch " + path.join(testDir, "packages/package-2/ignored-file")); - execSync("touch " + path.join(testDir, "packages/package-3/random-file")); - execSync("git add -A"); - execSync("git commit -m 'Commit'"); + child.execSync("git tag v1.0.0"); + child.execSync("touch " + path.join(testDir, "packages/package-2/ignored-file")); + child.execSync("touch " + path.join(testDir, "packages/package-3/random-file")); + child.execSync("git add -A"); + child.execSync("git commit -m 'Commit'"); const updatedCommand = new UpdatedCommand([], {}); diff --git a/test/_initFixture.js b/test/_initFixture.js index f8d1f4c434..df6da11e94 100644 --- a/test/_initFixture.js +++ b/test/_initFixture.js @@ -2,7 +2,6 @@ import rimraf from "rimraf"; import child from "child_process"; import path from "path"; import cpr from "cpr"; -import syncExec from "sync-exec"; const tmpDir = path.resolve(__dirname, "../tmp"); const originalCwd = process.cwd(); @@ -30,7 +29,7 @@ export default function initFixture(fixturePath, callback) { }, err => { if (err) return callback(err); process.chdir(testDir); - (child.execSync || syncExec)("git init . && git add -A && git commit -m 'Init commit'"); + child.execSync("git init . && git add -A && git commit -m 'Init commit'"); callback(); }); From 599aae4521361611ad0bce0560fc2539f6770280 Mon Sep 17 00:00:00 2001 From: Bo Borgerson Date: Wed, 22 Jun 2016 17:37:52 -0700 Subject: [PATCH 06/13] Lerna import (#173) * Add `lerna import` command Imports a package with git history from a foreign repository. * Add tests for `lerna import` * Fix linter violations * Import "external" repo instead of "foreign" repo * Add some commentary around mechanics of import * Add some detail to the README entry for `import` * Fix a README typo * Add some whitespace around a concatenation operator * Eliminate a "space-infix-ops" eslint rule violation This is necessary for compatibility with #188. * Handle `--yes` flag in import command * Use directory name instead of package name during import * Nicer error message for missing directory Also add tests for error messages * Don't import into pre-existing target directory * Don't claim to use package name during import in README --- README.md | 15 ++ bin/lerna.js | 1 + src/commands/ImportCommand.js | 99 ++++++++++++ src/index.js | 2 + test/ImportCommand.js | 148 ++++++++++++++++++ test/_initExternalFixture.js | 33 ++++ test/fixtures/ImportCommand/basic/lerna.json | 4 + .../fixtures/ImportCommand/basic/package.json | 3 + .../ImportCommand/basic/packages/.keep | 0 .../ImportCommand/external/package.json | 4 + 10 files changed, 309 insertions(+) create mode 100644 src/commands/ImportCommand.js create mode 100644 test/ImportCommand.js create mode 100644 test/_initExternalFixture.js create mode 100644 test/fixtures/ImportCommand/basic/lerna.json create mode 100644 test/fixtures/ImportCommand/basic/package.json create mode 100644 test/fixtures/ImportCommand/basic/packages/.keep create mode 100644 test/fixtures/ImportCommand/external/package.json diff --git a/README.md b/README.md index 1df1d9788e..66e32c1fc6 100644 --- a/README.md +++ b/README.md @@ -384,6 +384,21 @@ $ lerna exec --scope my-component -- ls -la $ lerna exec --concurrency 1 -- ls -la ``` +### import + +```sh +$ lerna import +``` + +Import the package at ``, with commit history, +into `packages/`. Original commit authors, dates and messages +are preserved. Commits are applied to the current branch. + +This is useful for gathering pre-existing standalone packages into a Lerna +repo. Each commit is modified to make changes relative to the package +directory. So, for example, the commit that added `package.json` will +instead add `packages//package.json`. + ## Misc Lerna will log to a `lerna-debug.log` file (same as `npm-debug.log`) when it encounters an error running a command. diff --git a/bin/lerna.js b/bin/lerna.js index 40b4a76b4d..b205b78679 100755 --- a/bin/lerna.js +++ b/bin/lerna.js @@ -12,6 +12,7 @@ var cli = meow([ " bootstrap Link together local packages and npm install remaining package dependencies", " publish Publish updated packages to npm", " updated Check which packages have changed since the last release", + " import Import a package with git history from an external repository", " clean Remove the node_modules directory from all packages", " diff Diff all packages or a single package since the last release", " init Initialize a lerna repo", diff --git a/src/commands/ImportCommand.js b/src/commands/ImportCommand.js new file mode 100644 index 0000000000..b3caa94fc1 --- /dev/null +++ b/src/commands/ImportCommand.js @@ -0,0 +1,99 @@ +import fs from "fs"; +import path from "path"; +import child from "child_process"; +import Command from "../Command"; +import progressBar from "../progressBar"; +import PromptUtilities from "../PromptUtilities"; + +export default class ImportCommand extends Command { + initialize(callback) { + const inputPath = this.input[0]; + + if (!inputPath) { + return callback(new Error("Missing argument: Path to external repository")); + } + + const externalRepoPath = path.resolve(inputPath); + const externalRepoBase = path.basename(externalRepoPath); + + try { + const stats = fs.statSync(externalRepoPath); + if (!stats.isDirectory()) { + throw new Error(`Input path "${inputPath}" is not a directory`); + } + const packageJson = path.join(externalRepoPath, "package.json"); + const packageName = require(packageJson).name; + if (!packageName) { + throw new Error(`No package name specified in "${packageJson}"`); + } + } catch (e) { + if (e.code === "ENOENT") { + return callback(new Error(`No repository found at "${inputPath}"`)); + } + return callback(e); + } + + this.targetDir = "packages/" + externalRepoBase; + + try { + if (fs.statSync(this.targetDir)) { + return callback(new Error(`Target directory already exists "${this.targetDir}"`)); + } + } catch (e) { /* Pass */ } + + this.externalExecOpts = { + encoding: "utf8", + cwd: externalRepoPath + }; + + this.commits = this.externalExecSync("git log --format=\"%h\"").split("\n").reverse(); + + if (!this.commits.length) { + callback(new Error(`No git commits to import at "${inputPath}"`)); + } + + this.logger.info(`About to import ${this.commits.length} commits into from ${inputPath} into ${this.targetDir}`); + + if (this.flags.yes) { + callback(null, true); + } else { + PromptUtilities.confirm("Are you sure you want to import these commits onto the current branch?", confirmed => { + if (confirmed) { + callback(null, true); + } else { + this.logger.info("Okay bye!"); + callback(null, false); + } + }); + } + } + + externalExecSync(command) { + return child.execSync(command, this.externalExecOpts).trim(); + } + + execute(callback) { + const replacement = "$1/" + this.targetDir; + + progressBar.init(this.commits.length); + + this.commits.forEach(sha => { + progressBar.tick(sha); + + // Create a patch file for this commit and prepend the target directory + // to all affected files. This moves the git history for the entire + // external repository into the package subdirectory, commit by commit. + const patch = this.externalExecSync(`git format-patch -1 ${sha} --stdout`) + .replace(/^([-+]{3} [ab])/mg, replacement) + .replace(/^(diff --git a)/mg, replacement) + .replace(/^(diff --git \S+ b)/mg, replacement); + + // Apply the modified patch to the current lerna repository, preserving + // original commit date, author and message. + child.execSync("git am", {input: patch}); + }); + progressBar.terminate(); + this.logger.info("Import complete!"); + callback(null, true); + } +} diff --git a/src/index.js b/src/index.js index d574e7d716..b98089e47b 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,7 @@ import BootstrapCommand from "./commands/BootstrapCommand"; import PublishCommand from "./commands/PublishCommand"; import UpdatedCommand from "./commands/UpdatedCommand"; +import ImportCommand from "./commands/ImportCommand"; import CleanCommand from "./commands/CleanCommand"; import DiffCommand from "./commands/DiffCommand"; import InitCommand from "./commands/InitCommand"; @@ -12,6 +13,7 @@ export const __commands__ = { bootstrap: BootstrapCommand, publish: PublishCommand, updated: UpdatedCommand, + import: ImportCommand, clean: CleanCommand, diff: DiffCommand, init: InitCommand, diff --git a/test/ImportCommand.js b/test/ImportCommand.js new file mode 100644 index 0000000000..6d5b734cb2 --- /dev/null +++ b/test/ImportCommand.js @@ -0,0 +1,148 @@ +import child from "child_process"; +import pathExists from "path-exists"; +import assert from "assert"; +import path from "path"; +import fs from "fs"; + +import PromptUtilities from "../src/PromptUtilities"; +import ImportCommand from "../src/commands/ImportCommand"; +import exitWithCode from "./_exitWithCode"; +import initFixture from "./_initFixture"; +import initExternalFixture from "./_initExternalFixture"; +import assertStubbedCalls from "./_assertStubbedCalls"; + +describe("ImportCommand", () => { + + describe("import", () => { + let testDir, externalDir; + + beforeEach(done => { + testDir = initFixture("ImportCommand/basic", done); + }); + + beforeEach(done => { + externalDir = initExternalFixture("ImportCommand/external", done); + }); + + it("should import into packages with commit history", done => { + const importCommand = new ImportCommand([externalDir], {}); + + importCommand.runValidations(); + importCommand.runPreparations(); + + assertStubbedCalls([ + [PromptUtilities, "confirm", { valueCallback: true }, [ + { args: ["Are you sure you want to import these commits onto the current branch?"], returns: true } + ]], + ]); + + importCommand.runCommand(exitWithCode(0, err => { + if (err) return done(err); + + try { + const lastCommit = child.execSync("git log --format=\"%s\"", {encoding:"utf8"}).split("\n")[0]; + const packageJson = path.join(testDir, "packages", path.basename(externalDir), "package.json"); + assert.ok(!pathExists.sync(path.join(testDir, "lerna-debug.log"))); + assert.ok(pathExists.sync(packageJson)); + assert.equal(lastCommit, "Init external commit"); + done(); + } catch (err) { + done(err); + } + })); + }); + + it("should be possible to skip asking for confirmation", done => { + + const importCommand = new ImportCommand([externalDir], { + yes: true + }); + + importCommand.runValidations(); + importCommand.runPreparations(); + + importCommand.initialize(done); + }); + + it("should fail without an argument", done => { + const importCommand = new ImportCommand([], {}); + + importCommand.runValidations(); + importCommand.runPreparations(); + + importCommand.runCommand(exitWithCode(1, err => { + const expect = "Missing argument: Path to external repository"; + assert.equal((err || {}).message, expect); + done(); + })); + }); + + it("should fail with a missing external directory", done => { + const missing = externalDir + "_invalidSuffix"; + const importCommand = new ImportCommand([missing], {}); + + importCommand.runValidations(); + importCommand.runPreparations(); + + importCommand.runCommand(exitWithCode(1, err => { + const expect = `No repository found at "${missing}"`; + assert.equal((err || {}).message, expect); + done(); + })); + }); + + it("should fail with a missing package.json", done => { + const importCommand = new ImportCommand([externalDir], {}); + + const packageJson = path.join(externalDir, "package.json"); + + fs.unlinkSync(packageJson); + + importCommand.runValidations(); + importCommand.runPreparations(); + + importCommand.runCommand(exitWithCode(1, err => { + const expect = `Cannot find module '${packageJson}'`; + assert.equal((err || {}).message, expect); + done(); + })); + }); + + it("should fail with no name in package.json", done => { + const importCommand = new ImportCommand([externalDir], {}); + + const packageJson = path.join(externalDir, "package.json"); + + fs.writeFileSync(packageJson, "{}"); + + importCommand.runValidations(); + importCommand.runPreparations(); + + importCommand.runCommand(exitWithCode(1, err => { + const expect = `No package name specified in "${packageJson}"`; + assert.equal((err || {}).message, expect); + done(); + })); + }); + + it("should fail if target directory exists", done => { + const importCommand = new ImportCommand([externalDir], {}); + + const targetDir = path.relative( + process.cwd(), + path.join(testDir, "packages", path.basename(externalDir)) + ); + + fs.mkdirSync(targetDir); + + importCommand.runValidations(); + importCommand.runPreparations(); + + importCommand.runCommand(exitWithCode(1, err => { + const expect = `Target directory already exists "${targetDir}"`; + assert.equal((err || {}).message, expect); + done(); + })); + }); + }); +}); diff --git a/test/_initExternalFixture.js b/test/_initExternalFixture.js new file mode 100644 index 0000000000..1582a86147 --- /dev/null +++ b/test/_initExternalFixture.js @@ -0,0 +1,33 @@ +import rimraf from "rimraf"; +import child from "child_process"; +import path from "path"; +import cpr from "cpr"; + +const tmpDir = path.resolve(__dirname, "../tmp"); + +const createdDirectories = []; + +after(() => { + createdDirectories.map(dir => rimraf.sync(dir)); +}); + +let uniqueId = 0; + +export default function initExternalFixture(fixturePath, callback) { + const fixtureDir = path.resolve(__dirname, "./fixtures/" + fixturePath); + const testDir = path.resolve(tmpDir, "test-external-" + Date.now() + "-" + (uniqueId++)); + + createdDirectories.push(testDir); + + cpr(fixtureDir, testDir, { + confirm: true + }, err => { + if (err) return callback(err); + child.execSync("git init . && git add -A && git commit -m 'Init external commit'", { + cwd: testDir + }); + callback(); + }); + + return testDir; +} diff --git a/test/fixtures/ImportCommand/basic/lerna.json b/test/fixtures/ImportCommand/basic/lerna.json new file mode 100644 index 0000000000..d8474fbed2 --- /dev/null +++ b/test/fixtures/ImportCommand/basic/lerna.json @@ -0,0 +1,4 @@ +{ + "lerna": "__TEST_VERSION__", + "version": "1.0.0" +} diff --git a/test/fixtures/ImportCommand/basic/package.json b/test/fixtures/ImportCommand/basic/package.json new file mode 100644 index 0000000000..46358b1693 --- /dev/null +++ b/test/fixtures/ImportCommand/basic/package.json @@ -0,0 +1,3 @@ +{ + "name": "independent" +} diff --git a/test/fixtures/ImportCommand/basic/packages/.keep b/test/fixtures/ImportCommand/basic/packages/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/fixtures/ImportCommand/external/package.json b/test/fixtures/ImportCommand/external/package.json new file mode 100644 index 0000000000..6c7291598b --- /dev/null +++ b/test/fixtures/ImportCommand/external/package.json @@ -0,0 +1,4 @@ +{ + "//": "Import should use _directory_ name, not package name", + "name": "external-name" +} From b7b465327f72eb84222ba629a0d36412742d194c Mon Sep 17 00:00:00 2001 From: Bo Borgerson Date: Wed, 22 Jun 2016 17:46:58 -0700 Subject: [PATCH 07/13] Consistent naming in README `import` section (#243) [skip ci] That last commit in #173 updated _one_ reference to package name, but missed another. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 66e32c1fc6..69a3162af0 100644 --- a/README.md +++ b/README.md @@ -397,7 +397,7 @@ are preserved. Commits are applied to the current branch. This is useful for gathering pre-existing standalone packages into a Lerna repo. Each commit is modified to make changes relative to the package directory. So, for example, the commit that added `package.json` will -instead add `packages//package.json`. +instead add `packages//package.json`. ## Misc From 9d2f71503fd2033ec55d880ad59ddbdb03eeb38d Mon Sep 17 00:00:00 2001 From: Henry Zhu Date: Wed, 22 Jun 2016 20:58:14 -0400 Subject: [PATCH 08/13] 2.0.0-beta.22 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a25c6ad747..f6d94e0091 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lerna", - "version": "2.0.0-beta.21", + "version": "2.0.0-beta.22", "description": "Tool for managing JavaScript projects with multiple packages", "main": "lib/index.js", "scripts": { From c400fd490ef453f127974cbf83c1fcfa3194661a Mon Sep 17 00:00:00 2001 From: Bo Borgerson Date: Fri, 24 Jun 2016 11:17:30 -0700 Subject: [PATCH 09/13] Re-introduce node 0.10 support (#248) * Revert "Revert "Use sync-exec for node 0.10" (#242)" This reverts commit 7eb4763030b4596048d331b2d25e9317e18401e2. * Node 0.10 compatibility for the `import` command --- .travis.yml | 1 + package.json | 3 +- src/ChildProcessUtilities.js | 12 ++++-- src/commands/ImportCommand.js | 16 ++++---- test/ImportCommand.js | 4 +- test/UpdatedCommand.js | 71 ++++++++++++++++++----------------- test/_initExternalFixture.js | 3 +- test/_initFixture.js | 3 +- 8 files changed, 64 insertions(+), 49 deletions(-) diff --git a/.travis.yml b/.travis.yml index 48e36db80f..fbe195923f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ cache: - node_modules node_js: + - "0.10" - "0.12" - "4" - stable diff --git a/package.json b/package.json index f6d94e0091..0d3cbe0bbe 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,8 @@ "progress": "^1.1.8", "rimraf": "^2.4.4", "semver": "^5.1.0", - "signal-exit": "^2.1.2" + "signal-exit": "^2.1.2", + "sync-exec": "^0.6.2" }, "bin": { "lerna": "./bin/lerna.js" diff --git a/src/ChildProcessUtilities.js b/src/ChildProcessUtilities.js index 689d8c4999..7c7eea6b30 100644 --- a/src/ChildProcessUtilities.js +++ b/src/ChildProcessUtilities.js @@ -1,5 +1,6 @@ import child from "child_process"; import objectAssign from "object-assign"; +import syncExec from "sync-exec"; export default class ChildProcessUtilities { static exec(command, opts, callback) { @@ -20,10 +21,15 @@ export default class ChildProcessUtilities { }); } - static execSync(command) { - return child.execSync(command, { + static execSync(command, opts) { + const mergedOpts = objectAssign({ encoding: "utf8" - }).trim(); + }, opts); + if (child.execSync) { + return child.execSync(command, mergedOpts).trim(); + } else { + return syncExec(command, mergedOpts).stdout.trim(); + } } static spawn(command, args, opts, callback) { diff --git a/src/commands/ImportCommand.js b/src/commands/ImportCommand.js index b3caa94fc1..5b92c00bb9 100644 --- a/src/commands/ImportCommand.js +++ b/src/commands/ImportCommand.js @@ -1,9 +1,10 @@ import fs from "fs"; import path from "path"; -import child from "child_process"; +import async from "async"; import Command from "../Command"; import progressBar from "../progressBar"; import PromptUtilities from "../PromptUtilities"; +import ChildProcessUtilities from "../ChildProcessUtilities"; export default class ImportCommand extends Command { initialize(callback) { @@ -69,7 +70,7 @@ export default class ImportCommand extends Command { } externalExecSync(command) { - return child.execSync(command, this.externalExecOpts).trim(); + return ChildProcessUtilities.execSync(command, this.externalExecOpts).trim(); } execute(callback) { @@ -77,7 +78,7 @@ export default class ImportCommand extends Command { progressBar.init(this.commits.length); - this.commits.forEach(sha => { + async.series(this.commits.map(sha => done => { progressBar.tick(sha); // Create a patch file for this commit and prepend the target directory @@ -90,10 +91,11 @@ export default class ImportCommand extends Command { // Apply the modified patch to the current lerna repository, preserving // original commit date, author and message. - child.execSync("git am", {input: patch}); + ChildProcessUtilities.exec("git am", {}, done).stdin.end(patch); + }), err => { + progressBar.terminate(); + this.logger.info("Import complete!"); + callback(err, !err); }); - progressBar.terminate(); - this.logger.info("Import complete!"); - callback(null, true); } } diff --git a/test/ImportCommand.js b/test/ImportCommand.js index 6d5b734cb2..de3834ed6f 100644 --- a/test/ImportCommand.js +++ b/test/ImportCommand.js @@ -1,10 +1,10 @@ -import child from "child_process"; import pathExists from "path-exists"; import assert from "assert"; import path from "path"; import fs from "fs"; import PromptUtilities from "../src/PromptUtilities"; +import ChildProcessUtilities from "../src/ChildProcessUtilities"; import ImportCommand from "../src/commands/ImportCommand"; import exitWithCode from "./_exitWithCode"; import initFixture from "./_initFixture"; @@ -40,7 +40,7 @@ describe("ImportCommand", () => { if (err) return done(err); try { - const lastCommit = child.execSync("git log --format=\"%s\"", {encoding:"utf8"}).split("\n")[0]; + const lastCommit = ChildProcessUtilities.execSync("git log --format=\"%s\"", {encoding:"utf8"}).split("\n")[0]; const packageJson = path.join(testDir, "packages", path.basename(externalDir), "package.json"); assert.ok(!pathExists.sync(path.join(testDir, "lerna-debug.log"))); assert.ok(pathExists.sync(packageJson)); diff --git a/test/UpdatedCommand.js b/test/UpdatedCommand.js index cc2ee6410e..8925b15acd 100644 --- a/test/UpdatedCommand.js +++ b/test/UpdatedCommand.js @@ -2,6 +2,7 @@ import assert from "assert"; import child from "child_process"; import path from "path"; import fs from "fs"; +import syncExec from "sync-exec"; import UpdatedCommand from "../src/commands/UpdatedCommand"; import exitWithCode from "./_exitWithCode"; @@ -9,6 +10,8 @@ import initFixture from "./_initFixture"; import logger from "../src/logger"; import stub from "./_stub"; +const execSync = (child.execSync || syncExec); + describe("UpdatedCommand", () => { /** ========================================================================= @@ -23,10 +26,10 @@ describe("UpdatedCommand", () => { }); it("should list changes", done => { - child.execSync("git tag v1.0.0"); - child.execSync("touch " + path.join(testDir, "packages/package-2/random-file")); - child.execSync("git add -A"); - child.execSync("git commit -m 'Commit'"); + execSync("git tag v1.0.0"); + execSync("touch " + path.join(testDir, "packages/package-2/random-file")); + execSync("git add -A"); + execSync("git commit -m 'Commit'"); const updatedCommand = new UpdatedCommand([], {}); @@ -46,10 +49,10 @@ describe("UpdatedCommand", () => { }); it("should list changes with --force-publish *", done => { - child.execSync("git tag v1.0.0"); - child.execSync("touch " + path.join(testDir, "packages/package-2/random-file")); - child.execSync("git add -A"); - child.execSync("git commit -m 'Commit'"); + execSync("git tag v1.0.0"); + execSync("touch " + path.join(testDir, "packages/package-2/random-file")); + execSync("git add -A"); + execSync("git commit -m 'Commit'"); const updatedCommand = new UpdatedCommand([], { forcePublish: "*" @@ -71,10 +74,10 @@ describe("UpdatedCommand", () => { }); it("should list changes with --force-publish [package,package]", done => { - child.execSync("git tag v1.0.0"); - child.execSync("touch " + path.join(testDir, "packages/package-3/random-file")); - child.execSync("git add -A"); - child.execSync("git commit -m 'Commit'"); + execSync("git tag v1.0.0"); + execSync("touch " + path.join(testDir, "packages/package-3/random-file")); + execSync("git add -A"); + execSync("git commit -m 'Commit'"); const updatedCommand = new UpdatedCommand([], { forcePublish: "package-2,package-4" @@ -103,11 +106,11 @@ describe("UpdatedCommand", () => { }; fs.writeFileSync(lernaJsonLocation, JSON.stringify(lernaJson, null, 2)); - child.execSync("git tag v1.0.0"); - child.execSync("touch " + path.join(testDir, "packages/package-2/ignored-file")); - child.execSync("touch " + path.join(testDir, "packages/package-3/random-file")); - child.execSync("git add -A"); - child.execSync("git commit -m 'Commit'"); + execSync("git tag v1.0.0"); + execSync("touch " + path.join(testDir, "packages/package-2/ignored-file")); + execSync("touch " + path.join(testDir, "packages/package-3/random-file")); + execSync("git add -A"); + execSync("git commit -m 'Commit'"); const updatedCommand = new UpdatedCommand([], {}); @@ -139,10 +142,10 @@ describe("UpdatedCommand", () => { }); it("should list changes", done => { - child.execSync("git tag v1.0.0"); - child.execSync("touch " + path.join(testDir, "packages/package-3/random-file")); - child.execSync("git add -A"); - child.execSync("git commit -m 'Commit'"); + execSync("git tag v1.0.0"); + execSync("touch " + path.join(testDir, "packages/package-3/random-file")); + execSync("git add -A"); + execSync("git commit -m 'Commit'"); const updatedCommand = new UpdatedCommand([], {}); @@ -162,10 +165,10 @@ describe("UpdatedCommand", () => { }); it("should list changes with --force-publish *", done => { - child.execSync("git tag v1.0.0"); - child.execSync("touch " + path.join(testDir, "packages/package-2/random-file")); - child.execSync("git add -A"); - child.execSync("git commit -m 'Commit'"); + execSync("git tag v1.0.0"); + execSync("touch " + path.join(testDir, "packages/package-2/random-file")); + execSync("git add -A"); + execSync("git commit -m 'Commit'"); const updatedCommand = new UpdatedCommand([], { forcePublish: "*" @@ -187,10 +190,10 @@ describe("UpdatedCommand", () => { }); it("should list changes with --force-publish [package,package]", done => { - child.execSync("git tag v1.0.0"); - child.execSync("touch " + path.join(testDir, "packages/package-4/random-file")); - child.execSync("git add -A"); - child.execSync("git commit -m 'Commit'"); + execSync("git tag v1.0.0"); + execSync("touch " + path.join(testDir, "packages/package-4/random-file")); + execSync("git add -A"); + execSync("git commit -m 'Commit'"); const updatedCommand = new UpdatedCommand([], { forcePublish: "package-2" @@ -219,11 +222,11 @@ describe("UpdatedCommand", () => { }; fs.writeFileSync(lernaJsonLocation, JSON.stringify(lernaJson, null, 2)); - child.execSync("git tag v1.0.0"); - child.execSync("touch " + path.join(testDir, "packages/package-2/ignored-file")); - child.execSync("touch " + path.join(testDir, "packages/package-3/random-file")); - child.execSync("git add -A"); - child.execSync("git commit -m 'Commit'"); + execSync("git tag v1.0.0"); + execSync("touch " + path.join(testDir, "packages/package-2/ignored-file")); + execSync("touch " + path.join(testDir, "packages/package-3/random-file")); + execSync("git add -A"); + execSync("git commit -m 'Commit'"); const updatedCommand = new UpdatedCommand([], {}); diff --git a/test/_initExternalFixture.js b/test/_initExternalFixture.js index 1582a86147..3d34b458cd 100644 --- a/test/_initExternalFixture.js +++ b/test/_initExternalFixture.js @@ -1,5 +1,6 @@ import rimraf from "rimraf"; import child from "child_process"; +import syncExec from "sync-exec"; import path from "path"; import cpr from "cpr"; @@ -23,7 +24,7 @@ export default function initExternalFixture(fixturePath, callback) { confirm: true }, err => { if (err) return callback(err); - child.execSync("git init . && git add -A && git commit -m 'Init external commit'", { + (child.execSync || syncExec)("git init . && git add -A && git commit -m 'Init external commit'", { cwd: testDir }); callback(); diff --git a/test/_initFixture.js b/test/_initFixture.js index df6da11e94..f8d1f4c434 100644 --- a/test/_initFixture.js +++ b/test/_initFixture.js @@ -2,6 +2,7 @@ import rimraf from "rimraf"; import child from "child_process"; import path from "path"; import cpr from "cpr"; +import syncExec from "sync-exec"; const tmpDir = path.resolve(__dirname, "../tmp"); const originalCwd = process.cwd(); @@ -29,7 +30,7 @@ export default function initFixture(fixturePath, callback) { }, err => { if (err) return callback(err); process.chdir(testDir); - child.execSync("git init . && git add -A && git commit -m 'Init commit'"); + (child.execSync || syncExec)("git init . && git add -A && git commit -m 'Init commit'"); callback(); }); From bc11eaabb77231d64c0e32c2f0d21fabdae053da Mon Sep 17 00:00:00 2001 From: Henry Zhu Date: Fri, 24 Jun 2016 14:18:20 -0400 Subject: [PATCH 10/13] Add `onlyExplicitUpdates` flag so that only packages that have changed have version bumps rather than all packages that depend on the updated packages (#241) --- README.md | 13 +++++++++++++ src/UpdatedPackagesCollector.js | 2 +- test/UpdatedCommand.js | 25 +++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 69a3162af0..50adb72727 100644 --- a/README.md +++ b/README.md @@ -476,3 +476,16 @@ The `ignore` flag, when used with the `bootstrap` command, can also be set in `l > Hint: The glob is matched against the package name defined in `package.json`, > not the directory name the package lives in. + +#### --only-explicit-updates + +Only will bump versions for packages that have been updated explicitly rather than cross-dependencies. + +> This may not make sense for a major version bump since other packages that depend on the updated packages wouldn't be updated. + +```sh +$ lerna updated --only-explicit-updates +$ lerna publish --only-explicit-updates +``` + +Ex: in Babel, `babel-types` is depended upon by all packages in the monorepo (over 100). However, Babel uses `^` for most of it's dependencies so it isn't necessary to bump the versions of all packages if only `babel-types` is updated. This option allows only the packages that have been explicitly updated to make a new version. diff --git a/src/UpdatedPackagesCollector.js b/src/UpdatedPackagesCollector.js index c5b7eb4234..3023b5e43e 100644 --- a/src/UpdatedPackagesCollector.js +++ b/src/UpdatedPackagesCollector.js @@ -127,7 +127,7 @@ export default class UpdatedPackagesCollector { collectUpdates() { return this.packages.filter(pkg => { - return this.updatedPackages[pkg.name] || this.dependents[pkg.name] || this.flags.canary; + return this.updatedPackages[pkg.name] || (this.flags.onlyExplicitUpdates ? false : this.dependents[pkg.name]) || this.flags.canary; }).map(pkg => { return new Update(pkg); }); diff --git a/test/UpdatedCommand.js b/test/UpdatedCommand.js index 8925b15acd..d5987dd2e6 100644 --- a/test/UpdatedCommand.js +++ b/test/UpdatedCommand.js @@ -128,6 +128,31 @@ describe("UpdatedCommand", () => { updatedCommand.runCommand(exitWithCode(0, done)); }); + + it("should list changes for explicitly changed packages", done => { + child.execSync("git tag v1.0.0"); + child.execSync("touch " + path.join(testDir, "packages/package-2/random-file")); + child.execSync("git add -A"); + child.execSync("git commit -m 'Commit'"); + + const updatedCommand = new UpdatedCommand([], { + onlyExplicitUpdates: true + }); + + updatedCommand.runValidations(); + updatedCommand.runPreparations(); + + let calls = 0; + stub(logger, "info", message => { + if (calls === 0) assert.equal(message, "Checking for updated packages..."); + if (calls === 1) assert.equal(message, ""); + if (calls === 2) assert.equal(message, "- package-2"); + if (calls === 3) assert.equal(message, ""); + calls++; + }); + + updatedCommand.runCommand(exitWithCode(0, done)); + }); }); /** ========================================================================= From fc64217879be9b46b4e9eb4aa5e214a2b3e869c0 Mon Sep 17 00:00:00 2001 From: Henry Zhu Date: Fri, 24 Jun 2016 14:28:50 -0400 Subject: [PATCH 11/13] fix execSync use --- test/UpdatedCommand.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/UpdatedCommand.js b/test/UpdatedCommand.js index d5987dd2e6..cb342c43fb 100644 --- a/test/UpdatedCommand.js +++ b/test/UpdatedCommand.js @@ -130,10 +130,10 @@ describe("UpdatedCommand", () => { }); it("should list changes for explicitly changed packages", done => { - child.execSync("git tag v1.0.0"); - child.execSync("touch " + path.join(testDir, "packages/package-2/random-file")); - child.execSync("git add -A"); - child.execSync("git commit -m 'Commit'"); + execSync("git tag v1.0.0"); + execSync("touch " + path.join(testDir, "packages/package-2/random-file")); + execSync("git add -A"); + execSync("git commit -m 'Commit'"); const updatedCommand = new UpdatedCommand([], { onlyExplicitUpdates: true From 095249ae99b5c7c08f7a181dd545dd5c5616f2cb Mon Sep 17 00:00:00 2001 From: Henry Zhu Date: Fri, 24 Jun 2016 15:52:52 -0400 Subject: [PATCH 12/13] 2.0.0-beta.23 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0d3cbe0bbe..eea06c5071 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lerna", - "version": "2.0.0-beta.22", + "version": "2.0.0-beta.23", "description": "Tool for managing JavaScript projects with multiple packages", "main": "lib/index.js", "scripts": { From 00de51f7903769c395a0383ec49882e226b42fec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mahieu?= Date: Tue, 28 Jun 2016 12:23:55 +0200 Subject: [PATCH 13/13] Bootstrap: copy `main` property from package.json --- src/commands/BootstrapCommand.js | 4 +++- test/BootstrapCommand.js | 2 +- .../BootstrapCommand/basic/packages/package-2/package.json | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/commands/BootstrapCommand.js b/src/commands/BootstrapCommand.js index a02892ad37..f640b62eeb 100644 --- a/src/commands/BootstrapCommand.js +++ b/src/commands/BootstrapCommand.js @@ -76,10 +76,12 @@ export default class BootstrapCommand extends Command { const srcPackageJsonLocation = path.join(src, "package.json"); const destPackageJsonLocation = path.join(dest, "package.json"); const destIndexJsLocation = path.join(dest, "index.js"); + const pkg = require(srcPackageJsonLocation); const packageJsonFileContents = JSON.stringify({ name: name, - version: require(srcPackageJsonLocation).version + version: pkg.version, + main: pkg.main }, null, " "); const prefix = this.repository.linkedFiles.prefix || ""; diff --git a/test/BootstrapCommand.js b/test/BootstrapCommand.js index 922fb0c03e..7589965a3b 100644 --- a/test/BootstrapCommand.js +++ b/test/BootstrapCommand.js @@ -58,7 +58,7 @@ describe("BootstrapCommand", () => { assert.equal(fs.readFileSync(path.join(testDir, "packages/package-2/node_modules/package-1/package.json")).toString(), "{\n \"name\": \"package-1\",\n \"version\": \"1.0.0\"\n}\n"); assert.equal(fs.readFileSync(path.join(testDir, "packages/package-3/node_modules/package-2/index.js")).toString(), "/**\n * @prefix\n */\nmodule.exports = require(\"" + path.join(testDir, "packages/package-2") + "\");\n"); - assert.equal(fs.readFileSync(path.join(testDir, "packages/package-3/node_modules/package-2/package.json")).toString(), "{\n \"name\": \"package-2\",\n \"version\": \"1.0.0\"\n}\n"); + assert.equal(fs.readFileSync(path.join(testDir, "packages/package-3/node_modules/package-2/package.json")).toString(), "{\n \"name\": \"package-2\",\n \"version\": \"1.0.0\",\n \"main\": \"lib/index.js\"\n}\n"); done(); } catch (err) { diff --git a/test/fixtures/BootstrapCommand/basic/packages/package-2/package.json b/test/fixtures/BootstrapCommand/basic/packages/package-2/package.json index d7e806f1b1..40bd46f9cb 100644 --- a/test/fixtures/BootstrapCommand/basic/packages/package-2/package.json +++ b/test/fixtures/BootstrapCommand/basic/packages/package-2/package.json @@ -1,6 +1,7 @@ { "name": "package-2", "version": "1.0.0", + "main": "lib/index.js", "dependencies": { "package-1": "^1.0.0" }