refactor: move @pnpm/lifecycle to monorepo
This commit is contained in:
commit
358034bd3d
19 files changed
+4104
No files matched your search
@@ -0,0 +1,11 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
insert_final_newline = true
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
end_of_line = lf
|
||||
|
||||
[*.{ts,js,json}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
@@ -0,0 +1,3 @@
|
||||
* text eol=lf
|
||||
|
||||
*.tgz binary
|
||||
@@ -0,0 +1,20 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
|
||||
# Dependency directory
|
||||
node_modules
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
.tmp
|
||||
_docpress
|
||||
|
||||
lib
|
||||
|
||||
# Visual Studio Code configs
|
||||
.vscode/
|
||||
|
||||
.store
|
||||
@@ -0,0 +1,2 @@
|
||||
tag-version-prefix =
|
||||
message = chore(release): %s
|
||||
@@ -0,0 +1,14 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 6
|
||||
- 8
|
||||
- 10
|
||||
sudo: false
|
||||
before_install:
|
||||
- curl -L https://unpkg.com/@pnpm/self-installer | node
|
||||
install:
|
||||
- pnpm install
|
||||
script:
|
||||
- npm test
|
||||
notifications:
|
||||
email: false
|
||||
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 Zoltan Kochan <z@kochan.io>
|
||||
|
||||
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 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.
|
||||
@@ -0,0 +1,50 @@
|
||||
# @pnpm/lifecycle
|
||||
|
||||
> Package lifecycle hook runner
|
||||
|
||||
<!--@shields('npm', 'travis')-->
|
||||
[](https://www.npmjs.com/package/@pnpm/lifecycle) [](https://travis-ci.org/pnpm/lifecycle)
|
||||
<!--/@-->
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
npm i -S @pnpm/logger @pnpm/lifecycle
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```ts
|
||||
import runLifecycleHook, {runPostinstallHooks} from '@pnpm/lifecycle'
|
||||
|
||||
const targetPkgRoot = path.resolve('node_modules/target-pkg')
|
||||
const pkg = require(path.join(targetPkgRoot, 'package.json'))
|
||||
|
||||
// Run a specific hook
|
||||
await runLifecycleHook('preinstall', pkg, {
|
||||
pkgId: 'target-pkg/1.0.0',
|
||||
pkgRoot: targetPkgRoot,
|
||||
rawNpmConfig: {},
|
||||
rootNodeModulesDir: path.resolve('node_modules'),
|
||||
unsafePerm: true,
|
||||
})
|
||||
|
||||
// Run all install hooks
|
||||
await runPostinstallHooks({
|
||||
pkgId: 'target-pkg/1.0.0',
|
||||
pkgRoot: targetPkgRoot,
|
||||
rawNpmConfig: {},
|
||||
rootNodeModulesDir: path.resolve('node_modules'),
|
||||
unsafePerm: true,
|
||||
})
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### `runLifecycleHook(stage, packageJson, opts): Promise<void>`
|
||||
|
||||
### `runPostinstallHooks(opts): Promise<void>`
|
||||
|
||||
## License
|
||||
|
||||
[MIT](./LICENSE) © [Zoltan Kochan](https://www.kochan.io/)
|
||||
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"name": "@pnpm/lifecycle",
|
||||
"version": "3.0.2",
|
||||
"description": "Package lifecycle hook runner",
|
||||
"main": "lib/index.js",
|
||||
"typings": "lib/index.d.ts",
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "tslint -c tslint.json --project .",
|
||||
"tsc": "rimraf lib && tsc",
|
||||
"test": "npm run lint && preview && ts-node test --type-check && mos t",
|
||||
"md": "mos",
|
||||
"prepublishOnly": "npm run tsc",
|
||||
"fix": "tslint -c tslint.json --project . --fix"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/pnpm/lifecycle.git"
|
||||
},
|
||||
"keywords": [
|
||||
"pnpm",
|
||||
"lifecycle",
|
||||
"scripts"
|
||||
],
|
||||
"author": "Zoltan Kochan <z@kochan.io> (https://www.kochan.io/)",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/pnpm/lifecycle/issues"
|
||||
},
|
||||
"homepage": "https://github.com/pnpm/lifecycle#readme",
|
||||
"peerDependencies": {
|
||||
"@pnpm/logger": "^1.0.0 || ^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@pnpm/read-package-json": "^1.0.0",
|
||||
"@pnpm/types": "^2.0.0",
|
||||
"@zkochan/npm-lifecycle": "2.1.1",
|
||||
"path-exists": "^3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@pnpm/logger": "2.1.0",
|
||||
"@types/load-json-file": "2.0.7",
|
||||
"@types/node": "10.12.3",
|
||||
"@types/rimraf": "2.0.2",
|
||||
"@types/tape": "4.2.32",
|
||||
"json-append": "1.1.1",
|
||||
"load-json-file": "5.1.0",
|
||||
"mos": "2.0.0-alpha.3",
|
||||
"mos-plugin-readme": "1.0.4",
|
||||
"package-preview": "2.0.0",
|
||||
"rimraf": "2.6.2",
|
||||
"tape": "4.9.1",
|
||||
"ts-node": "7.0.1",
|
||||
"tslint": "5.11.0",
|
||||
"typescript": "3.2.1"
|
||||
},
|
||||
"mos": {
|
||||
"plugins": [
|
||||
"readme"
|
||||
],
|
||||
"installation": {
|
||||
"useShortAlias": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": [
|
||||
"config:base"
|
||||
],
|
||||
"rangeStrategy": "auto"
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,125 @@
|
||||
import {fromDir as readPackageJsonFromDir} from '@pnpm/read-package-json'
|
||||
import {PackageJson} from '@pnpm/types'
|
||||
import lifecycle = require('@zkochan/npm-lifecycle')
|
||||
import path = require('path')
|
||||
import exists = require('path-exists')
|
||||
import {LifecycleLog, lifecycleLogger} from './logger'
|
||||
|
||||
function noop () {} // tslint:disable-line:no-empty
|
||||
|
||||
export {LifecycleLog}
|
||||
|
||||
export async function runPostinstallHooks (
|
||||
opts: {
|
||||
depPath: string,
|
||||
rootNodeModulesDir: string,
|
||||
rawNpmConfig: object,
|
||||
pkgRoot: string,
|
||||
prepare?: boolean,
|
||||
unsafePerm: boolean,
|
||||
},
|
||||
): Promise<boolean> {
|
||||
const pkg = await readPackageJsonFromDir(opts.pkgRoot)
|
||||
const scripts = pkg && pkg.scripts || {}
|
||||
|
||||
if (!scripts.install) {
|
||||
await checkBindingGyp(opts.pkgRoot, scripts)
|
||||
}
|
||||
|
||||
if (scripts.preinstall) {
|
||||
await runLifecycleHook('preinstall', pkg, opts)
|
||||
}
|
||||
if (scripts.install) {
|
||||
await runLifecycleHook('install', pkg, opts)
|
||||
}
|
||||
if (scripts.postinstall) {
|
||||
await runLifecycleHook('postinstall', pkg, opts)
|
||||
}
|
||||
|
||||
if (opts.prepare && scripts.prepare) {
|
||||
await runLifecycleHook('prepare', pkg, opts)
|
||||
}
|
||||
|
||||
return !!scripts.preinstall || !!scripts.install || !!scripts.postinstall
|
||||
}
|
||||
|
||||
export default async function runLifecycleHook (
|
||||
stage: string,
|
||||
pkg: PackageJson,
|
||||
opts: {
|
||||
depPath: string,
|
||||
rootNodeModulesDir: string,
|
||||
rawNpmConfig: object,
|
||||
pkgRoot: string,
|
||||
stdio?: string,
|
||||
unsafePerm: boolean,
|
||||
},
|
||||
) {
|
||||
if (opts.stdio !== 'inherit') {
|
||||
lifecycleLogger.debug({
|
||||
depPath: opts.depPath,
|
||||
script: pkg!.scripts![stage],
|
||||
stage,
|
||||
wd: opts.pkgRoot,
|
||||
})
|
||||
}
|
||||
|
||||
return lifecycle(pkg, stage, opts.pkgRoot, {
|
||||
config: opts.rawNpmConfig,
|
||||
dir: opts.rootNodeModulesDir,
|
||||
log: {
|
||||
clearProgress: noop,
|
||||
info: noop,
|
||||
level: opts.stdio === 'inherit' ? undefined : 'silent',
|
||||
pause: noop,
|
||||
resume: noop,
|
||||
showProgress: noop,
|
||||
silly: npmLog,
|
||||
verbose: npmLog,
|
||||
warn: noop,
|
||||
},
|
||||
stdio: opts.stdio || 'pipe',
|
||||
unsafePerm: opts.unsafePerm,
|
||||
})
|
||||
|
||||
function npmLog (prefix: string, logid: string, stdtype: string, line: string) {
|
||||
switch (stdtype) {
|
||||
case 'stdout':
|
||||
case 'stderr':
|
||||
lifecycleLogger.debug({
|
||||
depPath: opts.depPath,
|
||||
line: line.toString(),
|
||||
stage,
|
||||
stdio: stdtype,
|
||||
wd: opts.pkgRoot,
|
||||
})
|
||||
return
|
||||
case 'Returned: code:':
|
||||
if (opts.stdio === 'inherit') {
|
||||
// Preventing the pnpm reporter from overriding the project's script output
|
||||
return
|
||||
}
|
||||
const code = arguments[3]
|
||||
lifecycleLogger.debug({
|
||||
depPath: opts.depPath,
|
||||
exitCode: code,
|
||||
stage,
|
||||
wd: opts.pkgRoot,
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run node-gyp when binding.gyp is available. Only do this when there's no
|
||||
* `install` script (see `npm help scripts`).
|
||||
*/
|
||||
async function checkBindingGyp (
|
||||
root: string,
|
||||
scripts: {},
|
||||
) {
|
||||
if (await exists(path.join(root, 'binding.gyp'))) {
|
||||
scripts['install'] = 'node-gyp rebuild' // tslint:disable-line:no-string-literal
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import baseLogger, {
|
||||
LogBase,
|
||||
Logger,
|
||||
} from '@pnpm/logger'
|
||||
|
||||
export const lifecycleLogger = baseLogger('lifecycle') as Logger<LifecycleMessage>
|
||||
|
||||
// TODO: make depPath optional
|
||||
export type LifecycleMessage = {
|
||||
depPath: string,
|
||||
stage: string,
|
||||
wd: string,
|
||||
} & ({
|
||||
line: string,
|
||||
stdio: 'stdout' | 'stderr',
|
||||
} | {
|
||||
exitCode: number,
|
||||
} | {
|
||||
script: string,
|
||||
})
|
||||
|
||||
export type LifecycleLog = {name: 'pnpm:lifecycle'} & LogBase & LifecycleMessage
|
||||
@@ -0,0 +1 @@
|
||||
output.json
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "simple",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"postinstall": "rimraf output.json && node -e \"process.stdout.write('install')\" | json-append output.json"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "with-many-scripts",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"prepare": "node -e \"process.stdout.write('prepare')\" | json-append output.json",
|
||||
"preinstall": "node -e \"process.stdout.write('preinstall')\" | json-append output.json",
|
||||
"install": "node -e \"process.stdout.write('install')\" | json-append output.json",
|
||||
"postinstall": "node -e \"process.stdout.write('postinstall')\" | json-append output.json"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import test = require('tape')
|
||||
import runLifecycleHook, {runPostinstallHooks} from '@pnpm/lifecycle'
|
||||
import path = require('path')
|
||||
import rimraf = require('rimraf')
|
||||
import loadJsonFile = require('load-json-file')
|
||||
|
||||
const fixtures = path.join(__dirname, 'fixtures')
|
||||
const rootNodeModulesDir = path.join(__dirname, '..', 'node_modules')
|
||||
|
||||
test('runLifecycleHook()', async (t) => {
|
||||
const pkgRoot = path.join(fixtures, 'simple')
|
||||
const pkg = require(path.join(pkgRoot, 'package.json'))
|
||||
await runLifecycleHook('postinstall', pkg, {
|
||||
rootNodeModulesDir,
|
||||
depPath: '/simple/1.0.0',
|
||||
rawNpmConfig: {},
|
||||
pkgRoot,
|
||||
unsafePerm: true,
|
||||
})
|
||||
|
||||
t.deepEqual(require(path.join(pkgRoot, 'output.json')), ['install'])
|
||||
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('runPostinstallHooks()', async (t) => {
|
||||
const pkgRoot = path.join(fixtures, 'with-many-scripts')
|
||||
const pkg = require(path.join(pkgRoot, 'package.json'))
|
||||
rimraf.sync(path.join(pkgRoot, 'output.json'))
|
||||
await runPostinstallHooks({
|
||||
rootNodeModulesDir,
|
||||
depPath: '/with-many-scripts/1.0.0',
|
||||
rawNpmConfig: {},
|
||||
pkgRoot,
|
||||
unsafePerm: true,
|
||||
})
|
||||
|
||||
t.deepEqual(loadJsonFile.sync(path.join(pkgRoot, 'output.json')), ['preinstall', 'install', 'postinstall'])
|
||||
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('runPostinstallHooks() with prepare = true', async (t) => {
|
||||
const pkgRoot = path.join(fixtures, 'with-many-scripts')
|
||||
const pkg = require(path.join(pkgRoot, 'package.json'))
|
||||
rimraf.sync(path.join(pkgRoot, 'output.json'))
|
||||
await runPostinstallHooks({
|
||||
rootNodeModulesDir,
|
||||
depPath: '/with-many-scripts/1.0.0',
|
||||
rawNpmConfig: {},
|
||||
prepare: true,
|
||||
pkgRoot,
|
||||
unsafePerm: true,
|
||||
})
|
||||
|
||||
t.deepEqual(loadJsonFile.sync(path.join(pkgRoot, 'output.json')), ['preinstall', 'install', 'postinstall', 'prepare'])
|
||||
|
||||
t.end()
|
||||
})
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"removeComments": false,
|
||||
"preserveConstEnums": true,
|
||||
"sourceMap": true,
|
||||
"declaration": true,
|
||||
"noImplicitAny": true,
|
||||
"noImplicitReturns": true,
|
||||
"suppressImplicitAnyIndexErrors": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"strictNullChecks": true,
|
||||
"target": "es6",
|
||||
"outDir": "lib",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"typings/**/*.d.ts"
|
||||
],
|
||||
"atom": {
|
||||
"rewriteTsconfig": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"extends": "tslint:recommended",
|
||||
"rules": {
|
||||
"curly": false,
|
||||
"eofline": false,
|
||||
"align": [true, "parameters"],
|
||||
"class-name": true,
|
||||
"indent": [true, "spaces"],
|
||||
"max-line-length": false,
|
||||
"no-any": true,
|
||||
"no-consecutive-blank-lines": true,
|
||||
"no-trailing-whitespace": true,
|
||||
"no-duplicate-variable": true,
|
||||
"no-var-keyword": true,
|
||||
"no-unused-expression": true,
|
||||
"no-use-before-declare": true,
|
||||
"no-var-requires": true,
|
||||
"no-require-imports": false,
|
||||
"space-before-function-paren": [true, "always"],
|
||||
"interface-name": [true, "never-prefix"],
|
||||
"no-console": false,
|
||||
"one-line": [true,
|
||||
"check-else",
|
||||
"check-whitespace",
|
||||
"check-open-brace"],
|
||||
"quotemark": [true,
|
||||
"single",
|
||||
"avoid-escape"],
|
||||
"semicolon": false,
|
||||
"typedef-whitespace": [true, {
|
||||
"call-signature": "nospace",
|
||||
"index-signature": "nospace",
|
||||
"parameter": "nospace",
|
||||
"property-declaration": "nospace",
|
||||
"variable-declaration": "nospace"
|
||||
}],
|
||||
"whitespace": [true,
|
||||
"check-branch",
|
||||
"check-decl",
|
||||
"check-operator",
|
||||
"check-separator",
|
||||
"check-type"]
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
declare module '@zkochan/npm-lifecycle' {
|
||||
const anything: any;
|
||||
export = anything;
|
||||
}
|
||||
|
||||
declare module 'path-exists' {
|
||||
const anything: any;
|
||||
export = anything;
|
||||
}
|
||||
|
||||
declare module 'read-package-json' {
|
||||
const anything: any;
|
||||
export = anything;
|
||||
}
|
||||
|
||||
declare module 'util.promisify' {
|
||||
const anything: any;
|
||||
export = anything;
|
||||
}
|
||||
Reference in new issue
Block a user