Skip to content
This repository was archived by the owner on May 10, 2021. It is now read-only.
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: npm/libcipm
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 2fd8651322982b7b9305de90dd8236ecc93a0278
Choose a base ref
...
head repository: npm/libcipm
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: ef52f1e8ef5fd1b14de7b8b4938f45ef9e14f4e1
Choose a head ref

Commits on Aug 31, 2018

  1. feat(config): switch to modern, figgy-pudding configuration (#57)

    * updates to pacote@9
    * switches to figgy-pudding for config handling
    * removes config/pacote-opts and config/lifecycle-opts
    * all config is in opts itself. `opts.config` is no longer used
    * adds support for auth config reading to npmConfig() utility
    
    BREAKING CHANGE: this updates cipm to use pacote@9, which consumes npm-style config objects, not pacoteOpts()-style objects.
    zkat authored Aug 31, 2018
    Copy the full SHA
    161f6b2 View commit details
  2. chore(release): 3.0.0

    zkat committed Aug 31, 2018
    Copy the full SHA
    e81484c View commit details
  3. Copy the full SHA
    64db490 View commit details
  4. chore(release): 3.0.1

    zkat committed Aug 31, 2018
    Copy the full SHA
    02cdffa View commit details
  5. fix(worker): missed a spot

    zkat committed Aug 31, 2018
    Copy the full SHA
    4371558 View commit details
  6. chore(release): 3.0.2

    zkat committed Aug 31, 2018
    Copy the full SHA
    193d74e View commit details

Commits on Jan 22, 2019

  1. Copy the full SHA
    018df27 View commit details
  2. chore(release): 3.0.3

    zkat committed Jan 22, 2019
    Copy the full SHA
    109cbaa View commit details

Commits on Jun 26, 2019

  1. fix(lifecycle): remove warning from bluebird (#59)

    Fixes: #58
    jehy authored and zkat committed Jun 26, 2019
    Copy the full SHA
    7af39e6 View commit details

Commits on Jul 10, 2019

  1. npm-lifecycle@3.0.0

    BREAKING CHANGE: requires updating node-gyp in npm/cli
    isaacs committed Jul 10, 2019
    Copy the full SHA
    84b8d7e View commit details
  2. chore(release): 4.0.0

    isaacs committed Jul 10, 2019
    Copy the full SHA
    21efbcc View commit details

Commits on Aug 12, 2019

  1. fix: respect and retain all configs passed in

    This is part 1 of fixing the issue where npm ci does not share
    npmrc values with lifecycle scripts
    isaacs committed Aug 12, 2019
    Copy the full SHA
    20b7372 View commit details
  2. chore(release): 4.0.1

    isaacs committed Aug 12, 2019
    Copy the full SHA
    1623565 View commit details
  3. Copy the full SHA
    7166364 View commit details
  4. chore(release): 4.0.2

    isaacs committed Aug 12, 2019
    Copy the full SHA
    9f2bfa9 View commit details
  5. Copy the full SHA
    46b2101 View commit details
  6. chore: update travis yml

    isaacs committed Aug 12, 2019
    Copy the full SHA
    250808c View commit details
  7. chore(release): 4.0.3

    isaacs committed Aug 12, 2019
    Copy the full SHA
    3fa8efb View commit details

Commits on Sep 24, 2019

  1. respect no-optional argument

    PR-URL: #2
    Credit: @cruzdanilo
    Close: #2
    Reviewed-by: @isaacs
    cruzdanilo authored and isaacs committed Sep 24, 2019
    Copy the full SHA
    8c11b6d View commit details
  2. fix: pack git directories properly

    - add dirPacker to options
    - set dirPacker to null on lifecycle options
    
    PR-URL: #4
    Credit: @claudiahdz
    Close: #4
    Reviewed-by: @isaacs
    claudiahdz authored and isaacs committed Sep 24, 2019
    Copy the full SHA
    576ab36 View commit details
  3. chore(release): 4.0.4

    isaacs committed Sep 24, 2019
    Copy the full SHA
    3394de0 View commit details

Commits on Oct 9, 2019

  1. chore: delete node_modules contents but keep the dir itself

    PR-URL: #1
    Credit: @tareqhs
    Close: #1
    Reviewed-by: @claudiahdz
    tareksha authored and claudiahdz committed Oct 9, 2019
    Copy the full SHA
    f668181 View commit details
  2. test: deletes node_modules contents but keep the dir itself

    PR-URL: #1
    Credit: @tareqhs
    Close: #1
    Reviewed-by: @claudiahdz
    tareksha authored and claudiahdz committed Oct 9, 2019
    Copy the full SHA
    189980e View commit details
  3. chore(release): 4.0.7

    claudiahdz committed Oct 9, 2019
    Copy the full SHA
    b66d520 View commit details

Commits on Jan 17, 2020

  1. Copy the full SHA
    ed2d735 View commit details

Commits on Mar 25, 2020

  1. Copy the full SHA
    85cfff4 View commit details
  2. chore(release): 4.0.8

    isaacs committed Mar 25, 2020
    Copy the full SHA
    ef52f1e View commit details
Showing with 786 additions and 1,347 deletions.
  1. +1 −0 .github/CODEOWNERS
  2. +2 −0 .github/settings.yml
  3. +94 −0 .github/workflows/ci.yml
  4. +13 −8 .travis.yml
  5. +206 −90 CHANGELOG.md
  6. +0 −151 CODE_OF_CONDUCT.md
  7. +0 −256 CONTRIBUTING.md
  8. +0 −7 ISSUE_TEMPLATE
  9. +16 −4 LICENSE.md
  10. +0 −7 PULL_REQUEST_TEMPLATE
  11. +7 −12 README.md
  12. +0 −23 appveyor.yml
  13. +2 −5 bin/cli.js
  14. +2 −1 bin/package.json
  15. +51 −24 index.js
  16. +0 −29 lib/config/lifecycle-opts.js
  17. +42 −30 lib/config/npm-config.js
  18. +0 −135 lib/config/pacote-opts.js
  19. +32 −20 lib/extract.js
  20. +3 −3 lib/worker.js
  21. +205 −474 package-lock.json
  22. +9 −12 package.json
  23. +82 −9 test/specs/index.js
  24. +5 −12 test/specs/lib/config.js
  25. +14 −0 test/specs/lib/extract.js
  26. +0 −35 test/specs/lib/pacote-opts.js
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @npm/cli-team
2 changes: 2 additions & 0 deletions .github/settings.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
_extends: 'open-source-project-boilerplate'
94 changes: 94 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
---
################################################################################
# Template - Node CI
#
# Description:
# This contains the basic information to: install dependencies, run tests,
# get coverage, and run linting on a nodejs project. This template will run
# over the MxN matrix of all operating systems, and all current LTS versions
# of NodeJS.
#
# Dependencies:
# This template assumes that your project is using the `tap` module for
# testing. If you're not using this module, then the step that runs your
# coverage will need to be adjusted.
#
################################################################################
name: Node CI

on: [push, pull_request]

jobs:
build:
strategy:
fail-fast: false
matrix:
node-version: [10.x, 12.x, 13.x]
os: [ubuntu-latest, windows-latest, macOS-latest]

runs-on: ${{ matrix.os }}

steps:
# Checkout the repository
- uses: actions/checkout@v2
# Installs the specific version of Node.js
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}

################################################################################
# Install Dependencies
#
# ASSUMPTIONS:
# - The project has a package-lock.json file
#
# Simply run the tests for the project.
################################################################################
- name: Install dependencies
run: npm ci

################################################################################
# Run Testing
#
# ASSUMPTIONS:
# - The project has `tap` as a devDependency
# - There is a script called "test" in the package.json
#
# Simply run the tests for the project.
################################################################################
- name: Run tests
run: npm test

################################################################################
# Run coverage check
#
# ASSUMPTIONS:
# - The project has `tap` as a devDependency
# - There is a script called "coverage" in the package.json
#
# Coverage should only be posted once, we are choosing the latest LTS of
# node, and ubuntu as the matrix point to post coverage from. We limit
# to the 'push' event so that coverage ins't posted twice from the
# pull-request event, and push event (line 3).
################################################################################
- name: Run coverage report
if: github.event_name == 'push' && matrix.node-version == '12.x' && matrix.os == 'ubuntu-latest'
run: npm run coverage
env:
# The environment variable name is leveraged by `tap`
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}

################################################################################
# Run linting
#
# ASSUMPTIONS:
# - There is a script called "lint" in the package.json
#
# We run linting AFTER we run testing and coverage checks, because if a step
# fails in an GitHub Action, all other steps are not run. We don't want to
# fail to run tests or coverage because of linting. It should be the lowest
# priority of all the steps.
################################################################################
- name: Run linter
run: npm run lint
21 changes: 13 additions & 8 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
# cipm currently relies on npm >5.4.0 to retrieve config
before_install:
- npm i -g npm@>5.4.0
language: node_js
sudo: false

node_js:
- "10"
- "9"
- "8"
- "6"
- node
- 12
- 10
- 8
- 6

cache:
directories:
- $HOME/.npm

notifications:
email: false
296 changes: 206 additions & 90 deletions CHANGELOG.md

Large diffs are not rendered by default.

151 changes: 0 additions & 151 deletions CODE_OF_CONDUCT.md

This file was deleted.

256 changes: 0 additions & 256 deletions CONTRIBUTING.md

This file was deleted.

7 changes: 0 additions & 7 deletions ISSUE_TEMPLATE

This file was deleted.

20 changes: 16 additions & 4 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
Copyright 2017 Kat Marchán and Contributors
Copyright npm, Inc., Kat Marchán, and Contributors

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
7 changes: 0 additions & 7 deletions PULL_REQUEST_TEMPLATE

This file was deleted.

19 changes: 7 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
[![npm](https://img.shields.io/npm/v/libcipm.svg)](https://npm.im/libcipm) [![license](https://img.shields.io/npm/l/libcipm.svg)](https://npm.im/libcipm) [![Travis](https://img.shields.io/travis/zkat/cipm.svg)](https://travis-ci.org/zkat/cipm) [![AppVeyor](https://ci.appveyor.com/api/projects/status/github/zkat/cipm?svg=true)](https://ci.appveyor.com/project/zkat/cipm) [![Coverage Status](https://coveralls.io/repos/github/zkat/cipm/badge.svg?branch=latest)](https://coveralls.io/github/zkat/cipm?branch=latest)
# Note: pending imminent deprecation

[`libcipm`](https://github.com/zkat/cipm) installs npm projects in a way that's
**This module will be deprecated once npm v7 is released. Please do not rely
on it more than absolutely necessary.**

----

[`libcipm`](https://github.com/npm/libcipm) installs npm projects in a way that's
optimized for continuous integration/deployment/etc scenarios. It gives up
the ability to build its own trees or install packages individually, as well
as other user-oriented features, in exchange for speed, and being more strict
@@ -16,7 +21,6 @@ For documentation about the associated command-line tool, see
## Table of Contents

* [Features](#features)
* [Contributing](#contributing)
* [API](#api)

### Features
@@ -26,12 +30,3 @@ For documentation about the associated command-line tool, see
* blazing fast
* npm-compatible caching
* errors if `package.json` and `package-lock.json` are out of sync, instead of fixing it like npm does. Essentially provides a `--frozen` install.

### Contributing

The libcipm team enthusiastically welcomes contributions and project
participation! There's a bunch of things you can do if you want to contribute!
The [Contributor Guide](CONTRIBUTING.md) has all the information you need for
everything from reporting bugs to contributing entire new features. Please don't
hesitate to jump in if you'd like to, or even ask us questions if something
isn't clear.
23 changes: 0 additions & 23 deletions appveyor.yml

This file was deleted.

7 changes: 2 additions & 5 deletions bin/cli.js
Original file line number Diff line number Diff line change
@@ -17,11 +17,8 @@ function cliMain () {
const log = require('npmlog')
return fromNpm(process.argv)
.then(c => {
log.level = c.get('loglevel')
return new Installer({
config: c,
log
})
log.level = c.loglevel
return new Installer(c.concat({log}))
})
.then(cipm => cipm.run())
.then(
3 changes: 2 additions & 1 deletion bin/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"name": "cipm",
"version": "2.0.0",
"repository": "https://github.com/npm/libcipm",
"version": "2.0.1",
"description": "a standalone ci-oriented package installer for npm projects",
"bin": "./cli.js",
"main": "./cli.js",
75 changes: 51 additions & 24 deletions index.js
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@ const BB = require('bluebird')
const binLink = require('bin-links')
const buildLogicalTree = require('npm-logical-tree')
const extract = require('./lib/extract.js')
const figgyPudding = require('figgy-pudding')
const fs = require('graceful-fs')
const getPrefix = require('find-npm-prefix')
const lifecycle = require('npm-lifecycle')
@@ -20,10 +21,26 @@ const statAsync = BB.promisify(fs.stat)
const symlinkAsync = BB.promisify(fs.symlink)
const writeFileAsync = BB.promisify(fs.writeFile)

const LifecycleOpts = figgyPudding({
config: {},
'script-shell': {},
scriptShell: 'script-shell',
'ignore-scripts': {},
ignoreScripts: 'ignore-scripts',
'ignore-prepublish': {},
ignorePrepublish: 'ignore-prepublish',
'scripts-prepend-node-path': {},
scriptsPrependNodePath: 'scripts-prepend-node-path',
'unsafe-perm': {},
unsafePerm: 'unsafe-perm',
prefix: {},
dir: 'prefix',
failOk: { default: false }
}, { other () { return true } })

class Installer {
constructor (opts) {
this.opts = opts
this.config = opts.config

// Stats
this.startTime = Date.now()
@@ -80,17 +97,17 @@ class Installer {

prepare () {
this.log.info('prepare', 'initializing installer')
this.log.level = this.config.get('loglevel')
this.log.level = this.opts.loglevel
this.log.verbose('prepare', 'starting workers')
extract.startWorkers()

return (
this.config.get('prefix') && this.config.get('global')
? BB.resolve(this.config.get('prefix'))
this.opts.prefix && this.opts.global
? BB.resolve(this.opts.prefix)
// There's some Special™ logic around the `--prefix` config when it
// comes from a config file or env vs when it comes from the CLI
: process.argv.some(arg => arg.match(/^\s*--prefix\s*/i))
? BB.resolve(this.config.get('prefix'))
? BB.resolve(this.opts.prefix)
: getPrefix(process.cwd())
)
.then(prefix => {
@@ -120,7 +137,7 @@ class Installer {
)
return BB.join(
this.checkLock(),
stat && rimraf(path.join(this.prefix, 'node_modules'))
stat && rimraf(path.join(this.prefix, 'node_modules/*'))
)
}).then(() => {
// This needs to happen -after- we've done checkLock()
@@ -203,7 +220,7 @@ class Installer {
return next()
} else {
return BB.resolve(extract.child(
dep.name, dep, depPath, this.config, this.opts
dep.name, dep, depPath, this.opts
))
.then(() => cg.completeWork(1))
.then(() => { this.pkgCount++ })
@@ -218,16 +235,19 @@ class Installer {
checkDepEnv (dep) {
const includeDev = (
// Covers --dev and --development (from npm config itself)
this.config.get('dev') ||
this.opts.dev ||
(
!/^prod(uction)?$/.test(this.config.get('only')) &&
!this.config.get('production')
!/^prod(uction)?$/.test(this.opts.only) &&
!this.opts.production
) ||
/^dev(elopment)?$/.test(this.config.get('only')) ||
/^dev(elopment)?$/.test(this.config.get('also'))
/^dev(elopment)?$/.test(this.opts.only) ||
/^dev(elopment)?$/.test(this.opts.also)
)
const includeProd = !/^dev(elopment)?$/.test(this.config.get('only'))
return (dep.dev && includeDev) || (!dep.dev && includeProd)
const includeProd = !/^dev(elopment)?$/.test(this.opts.only)
const includeOptional = includeProd && this.opts.optional
return (dep.dev && includeDev) ||
(dep.optional && includeOptional) ||
(!dep.dev && !dep.optional && includeProd)
}

updateJson (tree) {
@@ -274,14 +294,14 @@ class Installer {
}
return readPkgJson(path.join(depPath, 'package.json'))
.then(pkg => binLink(pkg, depPath, false, {
force: this.config.get('force'),
ignoreScripts: this.config.get('ignore-scripts'),
force: this.opts.force,
ignoreScripts: this.opts['ignore-scripts'],
log: Object.assign({}, this.log, { info: () => {} }),
name: pkg.name,
pkgId: pkg.name + '@' + pkg.version,
prefix: this.prefix,
prefixes: [this.prefix],
umask: this.config.get('umask')
umask: this.opts.umask
}), e => {
this.log.verbose('buildTree', `error linking ${spec}: ${e.message} ${e.stack}`)
})
@@ -312,7 +332,7 @@ class Installer {
.then(from => npa.resolve(dep.name, from))
.then(from => { pkg._from = from.toString() })
.then(() => writeFileAsync(depPkgPath, JSON.stringify(pkg, null, 2)))
.then(pkg)
.then(() => pkg)
}

updateInstallScript (dep, pkg) {
@@ -327,7 +347,7 @@ class Installer {
pkg.scripts.install = 'node-gyp rebuild'
}
})
.then(pkg)
.then(() => pkg)
}

// A cute little mark-and-sweep collector!
@@ -346,18 +366,25 @@ class Installer {

runScript (stage, pkg, pkgPath) {
const start = Date.now()
if (!this.config.get('ignore-scripts')) {
if (!this.opts['ignore-scripts']) {
// TODO(mikesherov): remove pkg._id when npm-lifecycle no longer relies on it
pkg._id = pkg.name + '@' + pkg.version
const opts = this.config.toLifecycle()
return BB.resolve(lifecycle(pkg, stage, pkgPath, opts))
.tap(() => { this.timings.scripts += Date.now() - start })
return BB.resolve(lifecycle(
pkg, stage, pkgPath, LifecycleOpts(this.opts).concat({
// TODO: can be removed once npm-lifecycle is updated to modern
// config practices.
config: Object.assign({}, this.opts, {
log: null,
dirPacker: null
}),
dir: this.prefix
}))
).tap(() => { this.timings.scripts += Date.now() - start })
}
return BB.resolve()
}
}
module.exports = Installer
module.exports.CipmConfig = require('./lib/config/npm-config.js').CipmConfig

function mark (tree, failed) {
const liveDeps = new Set()
29 changes: 0 additions & 29 deletions lib/config/lifecycle-opts.js

This file was deleted.

72 changes: 42 additions & 30 deletions lib/config/npm-config.js
Original file line number Diff line number Diff line change
@@ -1,40 +1,22 @@
'use strict'

const BB = require('bluebird')
const lifecycleOpts = require('./lifecycle-opts.js')
const pacoteOpts = require('./pacote-opts.js')
const protoduck = require('protoduck')
const spawn = require('child_process').spawn

class NpmConfig extends Map {}
const fs = require('fs')
const figgyPudding = require('figgy-pudding')
const ini = require('ini')
const path = require('path')
const spawn = require('child_process').spawn

const CipmConfig = protoduck.define({
get: [],
set: [],
toPacote: [],
toLifecycle: []
}, {
name: 'CipmConfig'
})
module.exports.CipmConfig = CipmConfig
const readFileAsync = BB.promisify(fs.readFile)

CipmConfig.impl(NpmConfig, {
get: Map.prototype.get,
set: Map.prototype.set,
toPacote (opts) {
return pacoteOpts(this, opts)
},
toLifecycle () {
return lifecycleOpts(this)
}
const NpmConfig = figgyPudding({
cache: { default: '' },
then: {},
userconfig: {}
})

module.exports.fromObject = fromObj
function fromObj (obj) {
const map = new NpmConfig()
Object.keys(obj).forEach(k => map.set(k, obj[k]))
return map
}
module.exports = NpmConfig

module.exports.fromNpm = getNpmConfig
function getNpmConfig (argv) {
@@ -62,11 +44,41 @@ function getNpmConfig (argv) {
reject(new Error('`npm` command not found. Please ensure you have npm@5.4.0 or later installed.'))
} else {
try {
resolve(fromObj(JSON.parse(stdout)))
resolve(JSON.parse(stdout))
} catch (e) {
reject(new Error('`npm config ls --json` failed to output json. Please ensure you have npm@5.4.0 or later installed.'))
}
}
})
}).then(opts => {
return BB.all(
process.cwd().split(path.sep).reduce((acc, next) => {
acc.path = path.join(acc.path, next)
acc.promises.push(maybeReadIni(path.join(acc.path, '.npmrc')))
acc.promises.push(maybeReadIni(path.join(acc.path, 'npmrc')))
return acc
}, {
path: '',
promises: []
}).promises.concat(
opts.userconfig ? maybeReadIni(opts.userconfig) : {}
)
).then(configs => NpmConfig(...configs, opts))
}).then(opts => {
if (opts.cache) {
return opts.concat({ cache: path.join(opts.cache, '_cacache') })
} else {
return opts
}
})
}

function maybeReadIni (f) {
return readFileAsync(f, 'utf8').catch(err => {
if (err.code === 'ENOENT') {
return ''
} else {
throw err
}
}).then(ini.parse)
}
135 changes: 0 additions & 135 deletions lib/config/pacote-opts.js

This file was deleted.

52 changes: 32 additions & 20 deletions lib/extract.js
Original file line number Diff line number Diff line change
@@ -2,45 +2,57 @@

const BB = require('bluebird')

const npa = require('npm-package-arg')
const workerFarm = require('worker-farm')

const extractionWorker = require('./worker.js')
const figgyPudding = require('figgy-pudding')
const npa = require('npm-package-arg')
const WORKER_PATH = require.resolve('./worker.js')
let workerFarm

// Broken for now, cause too many issues on some systems.
const ENABLE_WORKERS = false

const ExtractOpts = figgyPudding({
log: {},
dirPacker: {}
})

module.exports = {
startWorkers () {
this._workers = workerFarm({
maxConcurrentCallsPerWorker: 20,
maxRetries: 1
}, WORKER_PATH)
if (ENABLE_WORKERS) {
if (!workerFarm) { workerFarm = require('worker-farm') }
this._workers = workerFarm({
maxConcurrentCallsPerWorker: 20,
maxRetries: 1
}, WORKER_PATH)
}
},

stopWorkers () {
workerFarm.end(this._workers)
if (ENABLE_WORKERS) {
if (!workerFarm) { workerFarm = require('worker-farm') }
workerFarm.end(this._workers)
}
},

child (name, child, childPath, config, opts) {
child (name, child, childPath, opts) {
opts = ExtractOpts(opts)
const spec = npa.resolve(name, child.version)
const additionalToPacoteOpts = {}
if (typeof opts.dirPacker !== 'undefined') {
additionalToPacoteOpts.dirPacker = opts.dirPacker
}
const childOpts = config.toPacote(Object.assign({
let childOpts = opts.concat({
integrity: child.integrity,
resolved: child.resolved
}, additionalToPacoteOpts))
})
const args = [spec, childPath, childOpts]
return BB.fromNode((cb) => {
let launcher = extractionWorker
let msg = args
const spec = typeof args[0] === 'string' ? npa(args[0]) : args[0]
childOpts.loglevel = opts.log.level
if (spec.registry || spec.type === 'remote') {
if (ENABLE_WORKERS && (spec.registry || spec.type === 'remote')) {
if (!workerFarm) { workerFarm = require('worker-farm') }
// We can't serialize these options
childOpts.config = null
childOpts.log = null
childOpts.dirPacker = null
childOpts = childOpts.concat({
log: null,
dirPacker: null
})
// workers will run things in parallel!
launcher = this._workers
try {
6 changes: 3 additions & 3 deletions lib/worker.js
Original file line number Diff line number Diff line change
@@ -2,15 +2,15 @@

const BB = require('bluebird')

const log = require('npmlog')
// const log = require('npmlog')
const pacote = require('pacote')

module.exports = (args, cb) => {
const parsed = typeof args === 'string' ? JSON.parse(args) : args
const spec = parsed[0]
const extractTo = parsed[1]
const opts = parsed[2]
opts.log = log
log.level = opts.loglevel
// opts.log = log
// log.level = opts.loglevel
return BB.resolve(pacote.extract(spec, extractTo, opts)).nodeify(cb)
}
679 changes: 205 additions & 474 deletions package-lock.json

Large diffs are not rendered by default.

21 changes: 9 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "libcipm",
"version": "2.0.2",
"version": "4.0.8",
"description": "programmatic API for cipm: a ci-oriented package installer for npm",
"main": "index.js",
"files": [
@@ -12,11 +12,9 @@
"postrelease": "npm publish && git push --follow-tags",
"pretest": "standard",
"release": "standard-version -s",
"test": "tap -J --nyc-arg=--all --coverage test/specs",
"update-coc": "weallbehave -o . && git add CODE_OF_CONDUCT.md && git commit -m 'docs(coc): updated CODE_OF_CONDUCT.md'",
"update-contrib": "weallcontribute -o . && git add CONTRIBUTING.md && git commit -m 'docs(contributing): updated CONTRIBUTING.md'"
"test": "tap -J --nyc-arg=--all --coverage test/specs"
},
"repository": "https://github.com/zkat/cipm",
"repository": "https://github.com/npm/libcipm",
"keywords": [
"npm",
"package manager",
@@ -32,15 +30,16 @@
"dependencies": {
"bin-links": "^1.1.2",
"bluebird": "^3.5.1",
"figgy-pudding": "^3.5.1",
"find-npm-prefix": "^1.0.2",
"graceful-fs": "^4.1.11",
"lock-verify": "^2.0.2",
"ini": "^1.3.5",
"lock-verify": "^2.1.0",
"mkdirp": "^0.5.1",
"npm-lifecycle": "^2.0.3",
"npm-lifecycle": "^3.0.0",
"npm-logical-tree": "^1.2.1",
"npm-package-arg": "^6.1.0",
"pacote": "^8.1.6",
"protoduck": "^5.0.0",
"pacote": "^9.1.0",
"read-package-json": "^2.0.13",
"rimraf": "^2.6.2",
"worker-farm": "^1.6.0"
@@ -52,9 +51,7 @@
"standard": "^11.0.1",
"standard-version": "^4.4.0",
"tacks": "^1.2.6",
"tap": "^12.0.1",
"weallbehave": "^1.2.0",
"weallcontribute": "^1.0.8"
"tap": "^12.0.1"
},
"config": {
"nyc": {
91 changes: 82 additions & 9 deletions test/specs/index.js
Original file line number Diff line number Diff line change
@@ -2,7 +2,6 @@

const BB = require('bluebird')

const npmConfig = require('../../lib/config/npm-config.js')
const npmlog = require('npmlog')
const fixtureHelper = require('../lib/fixtureHelper.js')
const fs = BB.promisifyAll(require('fs'))
@@ -37,15 +36,13 @@ const Installer = requireInject('../../index.js', {
})

function run (moreOpts) {
return new Installer({
return new Installer(Object.assign({
log: npmlog,
config: npmConfig.fromObject(Object.assign({}, {
global: true,
prefix,
'unsafe-perm': true, // this is the default when running non-root
loglevel: process.env.LOGLEVEL || 'error'
}, moreOpts || {}))
}).run()
global: true,
prefix,
'unsafe-perm': true, // this is the default when running non-root
loglevel: process.env.LOGLEVEL || 'error'
}, moreOpts || {})).run()
}

test('throws error when no package.json is found', t => {
@@ -171,6 +168,45 @@ test('handles dependency list with only shallow subdeps', t => {
})
})

test('deletes node_modules/ contents, without deleting node_modules/ itself', t => {
const fixture = new Tacks(Dir({
'node_modules': Dir({
'stale-dependency': Dir({
'package.json': File({
name: 'stale-dependency',
version: '1.0.0'
})
})
}),
'package.json': File({
name: pkgName,
version: pkgVersion
}),
'package-lock.json': File({
dependencies: {},
lockfileVersion: 1
})
}))
fixture.create(prefix)

let notNodeModulesDeleted = true
const nodeModulesDir = path.join(prefix, 'node_modules')
const watcher = fs.watch(nodeModulesDir, () => {
if (!fs.existsSync(nodeModulesDir)) {
notNodeModulesDeleted = false
}
})

return run().then(() => {
t.ok(
!fs.existsSync(path.join(nodeModulesDir, 'stale-dependency')),
'node_modules/ contents were deleted'
)
watcher.close()
t.ok(notNodeModulesDeleted, 'node_modules/ itself was not deleted')
})
})

test('handles dependency list with only deep subdeps', t => {
const fixture = new Tacks(Dir({
'package.json': File({
@@ -535,6 +571,43 @@ test('removes failed optional dependencies', t => {
})
})

test('don\'t install optional dependencies with no-optional argument', t => {
const fixture = new Tacks(Dir({
'package.json': File({
name: pkgName,
version: pkgVersion,
dependencies: { a: '^1' },
optionalDependencies: { b: '^1' }
}),
'package-lock.json': File({
lockfileVersion: 1,
dependencies: {
a: { version: '1.0.0' },
b: { version: '1.0.0', optional: true }
}
})
}))
fixture.create(prefix)

extract = (name, child, childPath, opts) => {
const files = new Tacks(Dir({
'package.json': File({
name,
version: '1.0.0'
})
}))
files.create(childPath)
}

return run({ optional: false }).then(details => {
t.equal(details.pkgCount, 1, 'only prod deps counted')
t.ok(fs.statSync(path.join(prefix, 'node_modules', 'a')), 'dep a is there')
t.throws(() => {
fs.statSync(path.join(prefix, 'node_modules', 'b'))
}, 'optional dep b is not there')
})
})

test('runs lifecycle hooks of packages with env variables', t => {
const originalConsoleLog = console.log
console.log = () => {}
17 changes: 5 additions & 12 deletions test/specs/lib/config.js
Original file line number Diff line number Diff line change
@@ -56,19 +56,12 @@ test('config: errors if npm errors for any reason', t => {
test('config: parses configs from npm', t => {
cleanup()

const expectedConfig = { a: 1, b: 2 }

config().then(config => {
const objConf = {}
for (const k of config.keys()) {
objConf[k] = config.get(k)
}
t.deepEqual(objConf, expectedConfig, 'configs match')
t.end()
})

child.stdout.emit('data', JSON.stringify(expectedConfig))
const c = config()
child.stdout.emit('data', JSON.stringify({cache: 'foo'}))
child.emit('close', 0)
return c.then(config => {
t.match(config.cache, /^foo[/\\]_cacache$/, 'configs match')
})
})

test('config: cleanup', t => {
14 changes: 14 additions & 0 deletions test/specs/lib/extract.js
Original file line number Diff line number Diff line change
@@ -10,6 +10,20 @@ const extract = requireInject('../../../lib/extract.js', {
}
})

test('extract.child() ensures dirPacker is defined', t => {
const name = 'name'
const child = { version: '0.0.0', integrity: 'integrity', resolved: 'resolved' }
const childPath = './path'

const opts = { log: { level: 'level' }, dirPacker: {} }
const a = extract.child(name, child, childPath, opts)

a.then(b => {
t.ok('dirPacker' in b[2], 'dirPacker is defined')
t.end()
})
})

test('extract.child() only overwrites dirPacker when opts.dirPacker is defined', t => {
const name = 'name'
const child = { version: '0.0.0', integrity: 'integrity', resolved: 'resolved' }
35 changes: 0 additions & 35 deletions test/specs/lib/pacote-opts.js

This file was deleted.