Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Aug 11, 2022. It is now read-only.

Commit ba50bdb

Browse files
zkatiarna
authored andcommitted
feat(lockfile): add package-lock.json support
This implements #16441 as well as the auto-save behavior it needs in order to be kept up to date.
1 parent 35d0ea8 commit ba50bdb

File tree

6 files changed

+193
-126
lines changed

6 files changed

+193
-126
lines changed

lib/install.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -279,11 +279,9 @@ Installer.prototype.run = function (_cb) {
279279
[this, this.commit, staging, this.todo],
280280

281281
[this, this.runPostinstallTopLevelLifecycles],
282-
[this, this.finishTracker, 'runTopLevelLifecycles'])
283-
if (getSaveType(this.args)) {
284-
postInstallSteps.push(
285-
[this, this.saveToDependencies])
286-
}
282+
[this, this.finishTracker, 'runTopLevelLifecycles'],
283+
[this, this.saveToDependencies]
284+
)
287285
}
288286
postInstallSteps.push(
289287
[this, this.printWarnings],

lib/install/read-shrinkwrap.js

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,45 @@
11
'use strict'
2-
var path = require('path')
3-
var fs = require('graceful-fs')
4-
var iferr = require('iferr')
5-
var inflateShrinkwrap = require('./inflate-shrinkwrap.js')
6-
var parseJSON = require('../utils/parse-json.js')
72

8-
var readShrinkwrap = module.exports = function (child, next) {
3+
const BB = require('bluebird')
4+
5+
const fs = require('graceful-fs')
6+
const iferr = require('iferr')
7+
const inflateShrinkwrap = require('./inflate-shrinkwrap.js')
8+
const log = require('npmlog')
9+
const parseJSON = require('../utils/parse-json.js')
10+
const path = require('path')
11+
12+
const readFileAsync = BB.promisify(fs.readFile)
13+
14+
module.exports = readShrinkwrap
15+
function readShrinkwrap (child, next) {
916
if (child.package._shrinkwrap) return process.nextTick(next)
10-
fs.readFile(path.join(child.path, 'npm-shrinkwrap.json'), function (er, data) {
11-
if (er) {
12-
child.package._shrinkwrap = null
13-
return next()
17+
BB.join(
18+
readLockfile('npm-shrinkwrap.json', child),
19+
// Don't read non-root lockfiles
20+
!child.parent && readLockfile('package-lock.json', child),
21+
(shrinkwrap, lockfile) => {
22+
if (shrinkwrap && lockfile) {
23+
log.warn('read-shrinkwrap', 'Ignoring package-lock.json because there is already an npm-shrinkwrap.json. Please use only one of the two.')
24+
}
25+
if (shrinkwrap || lockfile) {
26+
try {
27+
child.package._shrinkwrap = parseJSON(shrinkwrap || lockfile)
28+
} catch (ex) {
29+
child.package._shrinkwrap = null
30+
throw ex
31+
}
32+
} else {
33+
child.package._shrinkwrap = null
34+
}
1435
}
15-
try {
16-
child.package._shrinkwrap = parseJSON(data)
17-
} catch (ex) {
18-
child.package._shrinkwrap = null
19-
return next(ex)
20-
}
21-
return next()
22-
})
36+
).then(() => next(), next)
37+
}
38+
39+
function readLockfile (name, child) {
40+
return readFileAsync(
41+
path.join(child.path, name)
42+
).catch({code: 'ENOENT'}, () => null)
2343
}
2444

2545
module.exports.andInflate = function (child, next) {

lib/install/save.js

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
'use strict'
2-
var fs = require('graceful-fs')
3-
var path = require('path')
4-
var writeFileAtomic = require('write-file-atomic')
5-
var log = require('npmlog')
6-
var iferr = require('iferr')
7-
var validate = require('aproba')
8-
var without = require('lodash.without')
9-
var npm = require('../npm.js')
10-
var deepSortObject = require('../utils/deep-sort-object.js')
11-
var parseJSON = require('../utils/parse-json.js')
12-
var moduleName = require('../utils/module-name.js')
13-
var isDevDep = require('./is-dev-dep.js')
14-
var createShrinkwrap = require('../shrinkwrap.js').createShrinkwrap
2+
3+
const BB = require('bluebird')
4+
5+
const createShrinkwrap = require('../shrinkwrap.js').createShrinkwrap
6+
const deepSortObject = require('../utils/deep-sort-object.js')
7+
const fs = BB.promisifyAll(require('graceful-fs'))
8+
const iferr = require('iferr')
9+
const isDevDep = require('./is-dev-dep.js')
10+
const log = require('npmlog')
11+
const moduleName = require('../utils/module-name.js')
12+
const npm = require('../npm.js')
13+
const parseJSON = require('../utils/parse-json.js')
14+
const path = require('path')
15+
const validate = require('aproba')
16+
const without = require('lodash.without')
17+
const writeFileAtomic = require('write-file-atomic')
1518

1619
// if the -S|--save option is specified, then write installed packages
1720
// as dependencies to a package.json file.
@@ -40,30 +43,28 @@ function andWarnErrors (cb) {
4043

4144
function saveShrinkwrap (tree, next) {
4245
validate('OF', arguments)
43-
var saveTarget = path.resolve(tree.path, 'npm-shrinkwrap.json')
44-
fs.stat(saveTarget, function (er, stat) {
45-
if (er) return next()
46-
var save = npm.config.get('save')
47-
var saveDev = npm.config.get('save-dev')
48-
var saveOptional = npm.config.get('save-optional')
49-
50-
var shrinkwrap = tree.package._shrinkwrap || {dependencies: {}}
51-
var shrinkwrapHasAnyDevOnlyDeps = tree.requires.some(function (dep) {
52-
var name = moduleName(dep)
53-
return isDevDep(tree, name) &&
54-
shrinkwrap.dependencies[name] != null
55-
})
46+
var save = npm.config.get('save')
47+
var saveDev = npm.config.get('save-dev')
48+
var saveOptional = npm.config.get('save-optional')
49+
50+
var shrinkwrap = tree.package._shrinkwrap || {dependencies: {}}
51+
var shrinkwrapHasAnyDevOnlyDeps = tree.requires.some(function (dep) {
52+
var name = moduleName(dep)
53+
return isDevDep(tree, name) &&
54+
shrinkwrap.dependencies[name] != null
55+
})
5656

57-
if (!saveOptional && saveDev && !shrinkwrapHasAnyDevOnlyDeps) return next()
58-
if (saveOptional || !(save || saveDev)) return next()
57+
if (!saveOptional && saveDev && !shrinkwrapHasAnyDevOnlyDeps) return next()
58+
if (saveOptional || !(save || saveDev)) return next()
5959

60-
var silent = false
61-
createShrinkwrap(tree.path, tree.package, shrinkwrapHasAnyDevOnlyDeps, silent, next)
62-
})
60+
var silent = false
61+
createShrinkwrap(tree.path, tree.package, shrinkwrapHasAnyDevOnlyDeps, silent, next)
6362
}
6463

6564
function savePackageJson (args, tree, next) {
6665
validate('AOF', arguments)
66+
if (!args || !args.length) { return next() }
67+
6768
var saveBundle = npm.config.get('save-bundle')
6869

6970
// each item in the tree is a top-level thing that should be saved

lib/shrinkwrap.js

Lines changed: 68 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,37 @@
1-
// emit JSON describing versions of all packages currently installed (for later
2-
// use with shrinkwrap install)
3-
4-
module.exports = exports = shrinkwrap
5-
6-
var path = require('path')
7-
var log = require('npmlog')
8-
var writeFileAtomic = require('write-file-atomic')
9-
var iferr = require('iferr')
10-
var readPackageJson = require('read-package-json')
11-
var readPackageTree = require('read-package-tree')
12-
var validate = require('aproba')
13-
var chain = require('slide').chain
14-
var npm = require('./npm.js')
15-
var recalculateMetadata = require('./install/deps.js').recalculateMetadata
16-
var validatePeerDeps = require('./install/deps.js').validatePeerDeps
17-
var isExtraneous = require('./install/is-extraneous.js')
18-
var packageId = require('./utils/package-id.js')
19-
var moduleName = require('./utils/module-name.js')
20-
var output = require('./utils/output.js')
21-
var lifecycle = require('./utils/lifecycle.js')
22-
var isDevDep = require('./install/is-dev-dep.js')
23-
var isProdDep = require('./install/is-prod-dep.js')
24-
var isOptDep = require('./install/is-opt-dep.js')
1+
'use strict'
2+
3+
const BB = require('bluebird')
4+
5+
const chain = require('slide').chain
6+
const iferr = require('iferr')
7+
const isDevDep = require('./install/is-dev-dep.js')
8+
const isExtraneous = require('./install/is-extraneous.js')
9+
const isOptDep = require('./install/is-opt-dep.js')
10+
const isProdDep = require('./install/is-prod-dep.js')
11+
const fs = BB.promisifyAll(require('graceful-fs'))
12+
const lifecycle = require('./utils/lifecycle.js')
13+
const log = require('npmlog')
14+
const moduleName = require('./utils/module-name.js')
15+
const move = require('move-concurrently')
16+
const npm = require('./npm.js')
17+
const packageId = require('./utils/package-id.js')
18+
const path = require('path')
19+
const readPackageJson = require('read-package-json')
20+
const readPackageTree = require('read-package-tree')
21+
const recalculateMetadata = require('./install/deps.js').recalculateMetadata
2522
const ssri = require('ssri')
23+
const validate = require('aproba')
24+
const validatePeerDeps = require('./install/deps.js').validatePeerDeps
25+
const writeFileAtomic = require('write-file-atomic')
26+
27+
const SHRINKWRAP = 'npm-shrinkwrap.json'
28+
const PKGLOCK = 'package-lock.json'
2629

30+
// emit JSON describing versions of all packages currently installed (for later
31+
// use with shrinkwrap install)
2732
shrinkwrap.usage = 'npm shrinkwrap'
2833

34+
module.exports = exports = shrinkwrap
2935
function shrinkwrap (args, silent, cb) {
3036
if (typeof cb !== 'function') {
3137
cb = silent
@@ -39,9 +45,18 @@ function shrinkwrap (args, silent, cb) {
3945
var packagePath = path.join(npm.localPrefix, 'package.json')
4046
var prod = npm.config.get('production') || /^prod/.test(npm.config.get('only'))
4147

42-
readPackageJson(packagePath, iferr(cb, function (pkg) {
43-
createShrinkwrap(npm.localPrefix, pkg, !prod, silent, cb)
44-
}))
48+
move(
49+
path.resolve(npm.prefix, PKGLOCK),
50+
path.resolve(npm.prefix, SHRINKWRAP),
51+
{ Promise: BB }
52+
).then(() => {
53+
log.notice('', `${PKGLOCK} has been renamed to ${SHRINKWRAP}. ${SHRINKWRAP} will be used for future installations.`)
54+
cb()
55+
}).catch({code: 'ENOENT'}, () => {
56+
readPackageJson(packagePath, iferr(cb, function (pkg) {
57+
createShrinkwrap(npm.localPrefix, pkg, !prod, silent, cb)
58+
}))
59+
})
4560
}
4661

4762
module.exports.createShrinkwrap = createShrinkwrap
@@ -101,10 +116,6 @@ function shrinkwrapDeps (dev, problems, deps, tree, seen) {
101116
})
102117
tree.children.sort(function (aa, bb) { return moduleName(aa).localeCompare(moduleName(bb)) }).forEach(function (child) {
103118
var childIsOnlyDev = isOnlyDev(child)
104-
if (!dev && childIsOnlyDev) {
105-
log.warn('shrinkwrap', 'Excluding devDependency: %s', child.location)
106-
return
107-
}
108119
var pkginfo = deps[moduleName(child)] = {}
109120
pkginfo.version = child.package.version
110121
if (child.package._inBundle) {
@@ -153,14 +164,33 @@ function save (pkginfo, silent, cb) {
153164
return cb(er)
154165
}
155166

156-
var file = path.resolve(npm.prefix, 'npm-shrinkwrap.json')
167+
BB.join(
168+
checkShrinkwrap(SHRINKWRAP),
169+
checkShrinkwrap(PKGLOCK),
170+
(shrinkwrap, lockfile) => {
171+
const file = (
172+
shrinkwrap ||
173+
lockfile ||
174+
path.resolve(npm.prefix, PKGLOCK)
175+
)
176+
writeFileAtomic(file, swdata, (err) => {
177+
if (err) return cb(err)
178+
if (silent) return cb(null, pkginfo)
179+
if (!shrinkwrap && !lockfile) {
180+
log.notice('', `created a lockfile as ${path.basename(file)}. You should commit this file.`)
181+
}
182+
cb(null, pkginfo)
183+
})
184+
}
185+
).then((file) => {
186+
}, cb)
187+
}
157188

158-
writeFileAtomic(file, swdata, function (er) {
159-
if (er) return cb(er)
160-
if (silent) return cb(null, pkginfo)
161-
output('wrote npm-shrinkwrap.json')
162-
cb(null, pkginfo)
163-
})
189+
function checkShrinkwrap (name) {
190+
const file = path.resolve(npm.prefix, name)
191+
return fs.lstatAsync(
192+
file
193+
).then(() => file).catch({code: 'ENOENT'}, () => {})
164194
}
165195

166196
// Returns true if the module `node` is only required direcctly as a dev

lib/utils/tar.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,9 @@ BundledPacker.prototype.applyIgnores = function (entry, partial, entryObj) {
124124
entry.match(/^\..*\.swp$/) ||
125125
entry === '.DS_Store' ||
126126
entry.match(/^\._/) ||
127-
entry.match(/^.*\.orig$/)
127+
entry.match(/^.*\.orig$/) ||
128+
// Package locks are never allowed in tarballs -- use shrinkwrap instead
129+
entry === 'package-lock.json'
128130
) {
129131
return false
130132
}

0 commit comments

Comments
 (0)