Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: pass appropriate configs for file/dir modes #243

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 23 additions & 3 deletions lib/ci.js
Expand Up @@ -2,22 +2,42 @@

const npm = require('./npm.js')
const Installer = require('libcipm')
const npmlog = require('npmlog')
const log = require('npmlog')
const path = require('path')

ci.usage = 'npm ci'

ci.completion = (cb) => cb(null, [])

module.exports = ci
function ci (args, cb) {
const opts = Object.create({ log: npmlog })
const opts = {
// Add some non-npm-config opts by hand.
cache: path.join(npm.config.get('cache'), '_cacache'),
// NOTE: npm has some magic logic around color distinct from the config
// value, so we have to override it here
color: !!npm.color,
hashAlgorithm: 'sha1',
includeDeprecated: false,
log,
'npm-session': npm.session,
'project-scope': npm.projectScope,
refer: npm.referer,
dmode: npm.modes.exec,
fmode: npm.modes.file,
umask: npm.modes.umask,
npmVersion: npm.version,
tmp: npm.tmp
}

for (const key in npm.config.list[0]) {
if (key !== 'log') {
opts[key] = npm.config.list[0][key]
}
}

return new Installer(opts).run().then(details => {
npmlog.disableProgress()
log.disableProgress()
console.log(`added ${details.pkgCount} packages in ${
details.runTime / 1000
}s`)
Expand Down
2 changes: 1 addition & 1 deletion lib/config/figgy-config.js
Expand Up @@ -9,7 +9,7 @@ const npm = require('../npm.js')
const pack = require('../pack.js')
const path = require('path')

const npmSession = crypto.randomBytes(8).toString('hex')
const npmSession = npm.session = crypto.randomBytes(8).toString('hex')
log.verbose('npm-session', npmSession)

const SCOPE_REGISTRY_REGEX = /@.*:registry$/gi
Expand Down
53 changes: 53 additions & 0 deletions test/tap/ci-permissions.js
@@ -0,0 +1,53 @@
const t = require('tap')
const tar = require('tar')
const common = require('../common-tap.js')
const pkg = common.pkg
const rimraf = require('rimraf')
const { writeFileSync, statSync, chmodSync } = require('fs')
const { resolve } = require('path')
const mkdirp = require('mkdirp')

t.test('setup', t => {
mkdirp.sync(resolve(pkg, 'package'))
const pj = resolve(pkg, 'package', 'package.json')
writeFileSync(pj, JSON.stringify({
name: 'foo',
version: '1.2.3'
}))
chmodSync(pj, 0o640)
tar.c({
sync: true,
file: resolve(pkg, 'foo.tgz'),
gzip: true,
cwd: pkg
}, ['package'])
writeFileSync(resolve(pkg, 'package.json'), JSON.stringify({
name: 'root',
version: '1.2.3',
dependencies: {
foo: 'file:foo.tgz'
}
}))
t.end()
})

t.test('run install to generate package-lock', t =>
common.npm(['install'], { cwd: pkg }).then(([code]) => t.equal(code, 0)))

t.test('remove node_modules', t => rimraf(resolve(pkg, 'node_modules'), t.end))

t.test('run ci and check modes', t =>
common.npm(['ci'], { cwd: pkg, stdio: 'inherit' }).then(([code]) => {
t.equal(code, 0)
const file = resolve(pkg, 'node_modules', 'foo', 'package.json')
// bitwise AND against 0o705 so that we can detect whether
// the file is world-readable.
// Typical unix systems would leave the file 0o644
// Travis-ci and some other Linux systems will be 0o664
// Windows is 0o666
// The regression this is detecting (ie, the default in the tarball)
// leaves the file as 0o640.
// Bitwise-AND 0o705 should always result in 0o604, and never 0o600
const mode = statSync(file).mode & 0o705
t.equal(mode, 0o604)
}))