Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
22 changes: 12 additions & 10 deletions .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
name: Node.js CI

on: [push, pull_request]
on:
push:
pull_request:

jobs:
build:
strategy:
matrix:
node-version: [10.x, 12.x, 14.x]
os: [ubuntu-latest, windows-latest, macOS-latest]
node-version: [22.x]
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm install
- run: npm test
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm install
- run: npm test
25 changes: 9 additions & 16 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,21 +57,14 @@ typings/
# dotenv environment variables file
.env

# bundleDependencies
!node_modules/fs-extra/*
!node_modules/gunzip-maybe/*
!node_modules/is-root/*
!node_modules/node-gyp/*
!node_modules/npm-package-arg/*
!node_modules/npm-path/*
!node_modules/promise-each/*
!node_modules/request/*
!node_modules/semver/*
!node_modules/tar-fs/*
!node_modules/tar-stream/*
!node_modules/update-notifier/*
!node_modules/which/*
!node_modules/yargs/*

# dep
__pycache__

# Standard cache
.cache/

# Tap test artifacts
.tap/

# Temporary home directory
.tmp-home
59 changes: 41 additions & 18 deletions bin/dep.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,61 @@

const semver = require('semver')
const yargs = require('yargs')
const updateNotifier = require('update-notifier')
const commands = {
install: require('../lib/install'),
lock: require('../lib/lock'),
run: require('../lib/run')
}
const pkgJSON = require('../package.json')
const notifier = updateNotifier({ pkg: pkgJSON })

if (!semver.satisfies(process.version, pkgJSON.engine.node)) {
process.stderr.write('dep works only on Node.js LTS versions\n')
process.stderr.write('See the schedule: https://github.com/nodejs/LTS#lts-schedule1\n')
const allowLegacyNode = ['1', 'true', 'yes'].includes((process.env.DEP_ALLOW_OLD_NODE || '').toLowerCase())

if (!allowLegacyNode && !semver.satisfies(process.version, pkgJSON.engine.node)) {
process.stderr.write(`dep requires Node.js ${pkgJSON.engine.node} (detected ${process.version})\n`)
process.stderr.write('Upgrade Node.js to continue.\n')
process.exit(1)
}

if (notifier.update) {
notifier.notify()
const loadUpdateNotifier = async () => {
try {
const mod = await import('update-notifier')
return mod.default ?? mod
} catch (error) {
if (!process.env.DEP_SILENCE_UPDATE_NOTIFIER_ERRORS && (process.env.DEBUG || process.env.NODE_ENV === 'test')) {
// Surface failures when debugging to ease troubleshooting
console.error('Failed to load update-notifier:', error.message)
}
return null
}
}

yargs.usage(pkgJSON.description)
const run = async () => {
const updateNotifier = await loadUpdateNotifier()
const notifier = updateNotifier ? updateNotifier({ pkg: pkgJSON }) : null

yargs.help('help')
.alias('help', 'h')
if (notifier?.update) {
notifier.notify()
}

yargs.version()
.alias('version', 'v')
.describe('version', 'Show version information')
yargs.usage(pkgJSON.description)

Object.keys(commands).forEach((i) => {
yargs.command(commands[i])
})
yargs.help('help')
.alias('help', 'h')

yargs.version()
.alias('version', 'v')
.describe('version', 'Show version information')

Object.keys(commands).forEach((i) => {
yargs.command(commands[i])
})

const argv = yargs.argv
const argv = yargs.argv

if (!argv._handled) yargs.showHelp()
if (!argv._handled) yargs.showHelp()
}

run().catch((error) => {
console.error(error)
process.exit(1)
})
4 changes: 2 additions & 2 deletions lib/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const install = (argv) => {
'devDependencies'
]
}
var deps = Object.assign({}, optionalDependencies)
const deps = Object.assign({}, optionalDependencies)
allDependencies[only].forEach((key) => {
if (!pkgJSON[key]) return
Object.assign(deps, pkgJSON[key])
Expand All @@ -53,7 +53,7 @@ const install = (argv) => {
global.nativeBuildQueue.forEach((cwd) => {
try {
process.stdout.write('Building dependencies\n')
nodeGyp({ cwd: cwd })
nodeGyp({ cwd })
} catch (e) {
// remove the pkg since the deps could be optional
fs.removeSync(cwd)
Expand Down
4 changes: 2 additions & 2 deletions lib/install/installer.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const installer = (dep, deps, base, resolve, reject) => {
fs.ensureDirSync(target)

const pkg = deps[dep]
var fetch
let fetch

switch (pkg.type) {
case 'git':
Expand Down Expand Up @@ -55,7 +55,7 @@ const installer = (dep, deps, base, resolve, reject) => {
if (!pkg.dependencies) return resolve()
const tasks = Object.keys(pkg.dependencies).map((item) => {
const list = pkg.dependencies
var keys = [].concat(base, dep)
const keys = [].concat(base, dep)
if (keys.length > 1) keys.splice(-1, 0, 'node_modules')
return new Promise((resolve, reject) => {
installer(item, list, keys, resolve, reject)
Expand Down
99 changes: 82 additions & 17 deletions lib/install/installer/bin.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,94 @@ const fs = require('fs-extra')
const path = require('path')
const nm = require('../../utils/nm')

const isWindows = process.platform === 'win32'
const removeIfExists = (filePath) => {
try {
fs.rmSync(filePath, { force: true })
} catch (error) {
if (error.code !== 'ENOENT') {
throw error
}
}
}

const makePosixLink = (source, dest) => {
removeIfExists(dest)
fs.symlinkSync(source, dest)
try {
fs.chmodSync(source, 0o755)
} catch (error) {
if (error.code !== 'ENOENT') throw error
}
}

const makeWindowsShims = (source, dest) => {
removeIfExists(dest)
let linked = false
try {
fs.symlinkSync(source, dest, 'file')
linked = true
} catch (error) {
if (!['EACCES', 'EPERM', 'UNKNOWN'].includes(error.code)) {
throw error
}
fs.copyFileSync(source, dest)
}

try {
fs.chmodSync(source, 0o755)
} catch (error) {
if (!['ENOENT', 'EPERM', 'EINVAL'].includes(error.code)) {
throw error
}
}

const nodePath = process.execPath
const cmdContent = `@ECHO OFF\r\n"${nodePath}" "${source}" %*\r\n`
const psContent = `& "${nodePath}" "${source}" $args\r\n`

removeIfExists(`${dest}.cmd`)
removeIfExists(`${dest}.ps1`)

fs.writeFileSync(`${dest}.cmd`, cmdContent, 'utf8')
fs.writeFileSync(`${dest}.ps1`, psContent, 'utf8')

return linked
}

const createBinEntry = (command, relativePath, targetDir) => {
const binDir = path.join(nm, '.bin')
const source = path.join(targetDir, relativePath)
const dest = path.join(binDir, command)

fs.ensureDirSync(binDir)

if (isWindows) {
makeWindowsShims(source, dest)
} else {
makePosixLink(source, dest)
}

if (!isWindows) return

try {
fs.chmodSync(dest, 0o755)
} catch (error) {
if (!['ENOENT', 'EPERM', 'EINVAL'].includes(error.code)) {
throw error
}
}
}

const bin = (key, target) => {
const pkgJSON = require(path.join(target, 'package.json'))
if (!pkgJSON.bin) return
fs.ensureDirSync(path.join(nm, '.bin'))

if (typeof pkgJSON.bin === 'string') {
try {
fs.unlinkSync(path.join(nm, '.bin', key))
} catch (e) {}
fs.symlinkSync(
path.join(target, pkgJSON.bin),
path.join(nm, '.bin', key)
)
fs.chmodSync(path.join(target, pkgJSON.bin), '0755')
createBinEntry(key, pkgJSON.bin, target)
} else if (typeof pkgJSON.bin === 'object') {
Object.keys(pkgJSON.bin).forEach((cmd) => {
try {
fs.unlinkSync(path.join(nm, '.bin', cmd))
} catch (e) {}
fs.symlinkSync(
path.join(target, pkgJSON.bin[cmd]),
path.join(nm, '.bin', cmd)
)
fs.chmodSync(path.join(target, pkgJSON.bin[cmd]), '0755')
createBinEntry(cmd, pkgJSON.bin[cmd], target)
})
}
}
Expand Down
6 changes: 3 additions & 3 deletions lib/install/installer/git.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ module.exports = (pkg, cwd) => {

git.sync(['clone', url, cwd, '--quiet'])
if (!fs.pathExistsSync(path.join(cwd, '.gitmodules'))) {
return git(['checkout', hash, '--quiet'], { cwd: cwd })
return git(['checkout', hash, '--quiet'], { cwd })
}
git.sync(['checkout', hash, '--quiet'], { cwd: cwd })
return git(['submodule', 'update', '--init', '--recursive', '--quiet'], { cwd: cwd })
git.sync(['checkout', hash, '--quiet'], { cwd })
return git(['submodule', 'update', '--init', '--recursive', '--quiet'], { cwd })
}
20 changes: 6 additions & 14 deletions lib/install/installer/registry.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,15 @@
const request = require('request')
const tar = require('tar-fs')
const gunzip = require('gunzip-maybe')
const npmrc = require('../../utils/npmrc')
const { pipeline } = require('node:stream/promises')
const { requestStream } = require('../../utils/http')

module.exports = (pkg, cwd) => {
const options = {
url: pkg.tarball,
module.exports = async (pkg, cwd) => {
const extract = tar.extract(cwd, { strip: 1 })
const { stream } = await requestStream(pkg.tarball, {
headers: {
'User-Agent': npmrc.userAgent
}
}
return new Promise((resolve, reject) => {
const extract = tar.extract(cwd, { strip: 1 })
extract.on('finish', () => {
resolve()
})
request.get(options)
.pipe(gunzip())
.pipe(extract)
.on('error', reject)
})
await pipeline(stream, gunzip(), extract)
}
20 changes: 6 additions & 14 deletions lib/install/installer/remote.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,15 @@
const request = require('request')
const tar = require('tar-fs')
const gunzip = require('gunzip-maybe')
const npmrc = require('../../utils/npmrc')
const { pipeline } = require('node:stream/promises')
const { requestStream } = require('../../utils/http')

module.exports = (pkg, cwd) => {
const options = {
url: pkg.url,
module.exports = async (pkg, cwd) => {
const extract = tar.extract(cwd, { strip: 1 })
const { stream } = await requestStream(pkg.url, {
headers: {
'User-Agent': npmrc.userAgent
}
}
return new Promise((resolve, reject) => {
const extract = tar.extract(cwd, { strip: 1 })
extract.on('finish', () => {
resolve()
})
request.get(options)
.pipe(gunzip())
.pipe(extract)
.on('error', reject)
})
await pipeline(stream, gunzip(), extract)
}
6 changes: 3 additions & 3 deletions lib/install/resolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ const resolver = (dep, deps, base, resolve, reject) => {
return resolve()
}
}
for (var i = 0; base.length > i; i += 2) {
var target = tree.getter(global.dependenciesTree, base.slice(0, i))
for (let i = 0; base.length > i; i += 2) {
const target = tree.getter(global.dependenciesTree, base.slice(0, i))
if (target && target[dep] && target[dep].version) {
if (semver.satisfies(target[dep].version, deps[dep])) {
return resolve()
Expand All @@ -30,7 +30,7 @@ const resolver = (dep, deps, base, resolve, reject) => {

const tasks = Object.keys(pkg.dependencies).map((item) => {
const list = pkg.dependencies
var keys = base.length === 0
const keys = base.length === 0
? [].concat(`${dep}@${pkg.version}`)
: [].concat(base, 'dependencies', `${dep}@${pkg.version}`)
return new Promise((resolve, reject) => {
Expand Down
Loading
Loading