diff --git a/__tests__/commands/install/integration.js b/__tests__/commands/install/integration.js index a0a1ac9bdb..4323995d82 100644 --- a/__tests__/commands/install/integration.js +++ b/__tests__/commands/install/integration.js @@ -868,3 +868,47 @@ test.concurrent('a allows dependency with [] in os cpu requirements', assert(await fs.exists(path.join(config.cwd, 'node_modules', 'feed'))); }); }); + +test.concurrent('should skip integrity check and do install when --skip-integrity-check flag is passed', + (): Promise => { + return runInstall({}, 'skip-integrity-check', async (config, reporter) => { + assert.equal(await fs.exists(path.join(config.cwd, 'node_modules', 'sub-dep')), true); + await fs.unlink(path.join(config.cwd, 'node_modules', 'sub-dep')); + + let lockContent = await fs.readFile( + path.join(config.cwd, 'yarn.lock'), + ); + lockContent += ` +# changed the file, integrity should be fine + `; + await fs.writeFile( + path.join(config.cwd, 'yarn.lock'), + lockContent, + ); + + let reinstall = new Install({}, config, reporter, await Lockfile.fromDirectory(config.cwd)); + await reinstall.init(); + + // reinstall will be successful but it won't reinstall anything + assert.equal(await fs.exists(path.join(config.cwd, 'node_modules', 'sub-dep')), false); + + reinstall = new Install({skipIntegrityCheck: true}, config, reporter, await Lockfile.fromDirectory(config.cwd)); + await reinstall.init(); + // reinstall will reinstall deps + assert.equal(await fs.exists(path.join(config.cwd, 'node_modules', 'sub-dep')), true); + + let newLockContent = await fs.readFile( + path.join(config.cwd, 'yarn.lock'), + ); + assert.equal(lockContent, newLockContent); + + reinstall = new Install({force: true}, config, reporter, await Lockfile.fromDirectory(config.cwd)); + await reinstall.init(); + // force rewrites lockfile + newLockContent = await fs.readFile( + path.join(config.cwd, 'yarn.lock'), + ); + assert.notEqual(lockContent, newLockContent); + + }); + }); diff --git a/__tests__/fixtures/install/skip-integrity-check/package.json b/__tests__/fixtures/install/skip-integrity-check/package.json new file mode 100644 index 0000000000..0e000202c5 --- /dev/null +++ b/__tests__/fixtures/install/skip-integrity-check/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "sub-dep": "file:sub-dep" + } +} diff --git a/__tests__/fixtures/install/skip-integrity-check/sub-dep/install.js b/__tests__/fixtures/install/skip-integrity-check/sub-dep/install.js new file mode 100644 index 0000000000..dcbbff6c93 --- /dev/null +++ b/__tests__/fixtures/install/skip-integrity-check/sub-dep/install.js @@ -0,0 +1 @@ +process.exit(0); diff --git a/__tests__/fixtures/install/skip-integrity-check/sub-dep/package.json b/__tests__/fixtures/install/skip-integrity-check/sub-dep/package.json new file mode 100644 index 0000000000..ceee1431ce --- /dev/null +++ b/__tests__/fixtures/install/skip-integrity-check/sub-dep/package.json @@ -0,0 +1,4 @@ +{ + "name": "sub-dep", + "version": "1.0.0" +} diff --git a/src/cli/commands/install.js b/src/cli/commands/install.js index 58b9569081..c3fd07ad9e 100644 --- a/src/cli/commands/install.js +++ b/src/cli/commands/install.js @@ -60,7 +60,7 @@ type Flags = { flat: boolean, lockfile: boolean, pureLockfile: boolean, - skipIntegrity: boolean, + skipIntegrityCheck: boolean, // add peer: boolean, @@ -127,7 +127,7 @@ function normalizeFlags(config: Config, rawFlags: Object): Flags { flat: !!rawFlags.flat, lockfile: rawFlags.lockfile !== false, pureLockfile: !!rawFlags.pureLockfile, - skipIntegrity: !!rawFlags.skipIntegrity, + skipIntegrityCheck: !!rawFlags.skipIntegrityCheck, frozenLockfile: !!rawFlags.frozenLockfile, linkDuplicates: !!rawFlags.linkDuplicates, @@ -301,14 +301,17 @@ export class Install { async bailout( patterns: Array, ): Promise { - const match = await this.matchesIntegrityHash(patterns); - const haveLockfile = await fs.exists(path.join(this.config.cwd, constants.LOCKFILE_FILENAME)); - if (this.flags.frozenLockfile && !this.lockFileInSync(patterns)) { throw new MessageError(this.reporter.lang('frozenLockfileError')); } + if (this.flags.skipIntegrityCheck || this.flags.force) { + return false; + } + + const match = await this.matchesIntegrityHash(patterns); + const haveLockfile = await fs.exists(path.join(this.config.cwd, constants.LOCKFILE_FILENAME)); - if (!this.flags.skipIntegrity && !this.flags.force && match.matches && haveLockfile) { + if (match.matches && haveLockfile) { this.reporter.success(this.reporter.lang('upToDate')); return true; } diff --git a/src/cli/index.js b/src/cli/index.js index 505afe325f..8a15761ce8 100644 --- a/src/cli/index.js +++ b/src/cli/index.js @@ -56,7 +56,8 @@ commander.option('--har', 'save HAR output of network traffic'); commander.option('--ignore-platform', 'ignore platform checks'); commander.option('--ignore-engines', 'ignore engines check'); commander.option('--ignore-optional', 'ignore optional dependencies'); -commander.option('--force', 'ignore all caches'); +commander.option('--force', 'install and build scripts even if they were built before, overwrite lockfile'); +commander.option('--skip-integrity-check', 'run install without checking if node_modules is installed'); commander.option('--no-bin-links', "don't generate bin links when setting up packages"); commander.option('--flat', 'only allow one version of a package'); commander.option('--prod, --production [prod]', '');