feat: support package.yaml and package.json5

PR #1799
close #1100
This commit is contained in:
Zoltan Kochan
2019-05-02 00:19:46 +03:00
committed by GitHub
parent 82f9176651
commit a955f715d3
71 changed files with 1745 additions and 147 deletions

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2017-2019 Zoltan Kochan
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.

View File

@@ -0,0 +1,51 @@
# find-packages
> Find all packages inside a directory
<!--@shields('npm')-->
[![npm version](https://img.shields.io/npm/v/find-packages.svg)](https://www.npmjs.com/package/find-packages)
<!--/@-->
## Installation
```sh
<npm|yarn|pnpm> add find-packages
```
## Usage
```js
const path = require('path')
const findPkgs = require('find-packages')
findPkgs(path.join(__dirname, 'test', 'fixture'))
.then(pkgs => console.log(pkgs))
.catch(err => console.error(err))
//> [ { path: '/home/zkochan/src/find-packages/test/fixture/pkg',
// manifest: { name: 'foo', version: '1.0.0' },
// writeImporterManifest: [AsyncFunction] } ]
```
## API
### `findPackages(dir, [opts])`
#### `dir`
The directory in which to search for packages.
#### `opts`
Parameters normally passed to [glob](https://www.npmjs.com/package/glob)
#### `opts.patterns`
Array of globs to use as package locations. For example: `['packages/**', 'utils/**']`.
#### `opts.ignore`
Patterns to ignore when searching for packages. By default: `**/node_modules/**`, `**/bower_components/**`, `**/test/**`, `**/tests/**`.
## License
[MIT](./LICENSE) © [Zoltan Kochan](https://www.kochan.io)

View File

@@ -0,0 +1,6 @@
const path = require('path')
const findPkgs = require('find-packages')
findPkgs(path.join(__dirname, 'test/fixtures/one-pkg'))
.then(pkgs => console.log(pkgs))
.catch(err => console.error(err))

View File

@@ -0,0 +1,60 @@
{
"name": "find-packages",
"version": "4.0.1",
"description": "Find all packages inside a directory",
"main": "lib/index.js",
"files": [
"lib"
],
"typings": "lib/index.d.ts",
"scripts": {
"lint": "tslint -c tslint.json src/**/*.ts test/**/*.ts",
"test": "npm run tsc && npm run lint && ts-node test --type-check",
"tsc": "tsc",
"prepublishOnly": "npm run tsc",
"md": "mos"
},
"repository": "https://github.com/pnpm/pnpm/blob/master/packages/find-packages",
"keywords": [
"find",
"package"
],
"mos": {
"plugins": [
"readme"
],
"installation": {
"useShortAlias": true
}
},
"author": {
"name": "Zoltan Kochan",
"email": "z@kochan.io",
"url": "https://www.kochan.io"
},
"engines": {
"node": ">=8.15"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/pnpm/pnpm/issues"
},
"homepage": "https://github.com/pnpm/pnpm/blob/master/packages/find-packages#readme",
"devDependencies": {
"@pnpm/tslint-config": "0.0.0",
"@types/tape": "^4.2.29",
"find-packages": "link:",
"mos": "^2.0.0-alpha.3",
"mos-plugin-readme": "^1.0.4",
"tape": "^4.6.3",
"ts-node": "^8.0.1",
"tslint": "^5.0.0",
"typescript": "^3.0.0"
},
"dependencies": {
"@pnpm/read-importer-manifest": "0.0.0",
"@types/node": "^10.12.18",
"fast-glob": "^2.0.4",
"p-filter": "^2.0.0"
}
}

View File

@@ -0,0 +1,57 @@
import { readExactImporterManifest } from '@pnpm/read-importer-manifest'
import fastGlob = require('fast-glob')
import pFilter = require('p-filter')
import path = require('path')
const DEFAULT_IGNORE = [
'**/node_modules/**',
'**/bower_components/**',
'**/test/**',
'**/tests/**',
]
async function findPkgs (
root: string,
opts?: {
ignore?: string[],
patterns?: string[],
},
) {
opts = opts || {}
const globOpts = { ...opts, cwd: root }
globOpts.ignore = opts.ignore || DEFAULT_IGNORE
globOpts.patterns = opts.patterns
? normalizePatterns(opts.patterns)
: ['**/package.{json,yaml,json5}']
const paths: string[] = await fastGlob(globOpts.patterns, globOpts)
return pFilter(
paths
.sort()
.map((manifestPath) => path.join(root, manifestPath))
.map(async (manifestPath) => {
try {
return {
path: path.dirname(manifestPath),
...await readExactImporterManifest(manifestPath),
}
} catch (err) {
if (err.code === 'ENOENT') {
return null
}
throw err
}
}),
Boolean,
)
}
function normalizePatterns (patterns: string[]) {
return patterns.map((pattern) => pattern.replace(/\/?$/, '/package.{json,yaml,json5}'))
}
// for backward compatibility
findPkgs['default'] = findPkgs // tslint:disable-line
export = findPkgs

View File

@@ -0,0 +1,2 @@
name: component-1
version: 1.0.0

View File

@@ -0,0 +1,4 @@
{
name: 'component-2',
version: '1.0.0',
}

View File

@@ -0,0 +1,4 @@
{
"name": "foo",
"version": "1.0.0"
}

View File

@@ -0,0 +1,4 @@
{
"name": "component-1",
"version": "1.0.0"
}

View File

@@ -0,0 +1,4 @@
{
"name": "component-2",
"version": "1.0.0"
}

View File

@@ -0,0 +1,4 @@
{
"name": "foo",
"version": "1.0.0"
}

View File

@@ -0,0 +1,4 @@
{
"name": "foo",
"version": "1.0.0"
}

View File

@@ -0,0 +1,55 @@
import findPackages from 'find-packages'
import path = require('path')
import test = require('tape')
const fixtures = path.join(__dirname, 'fixtures')
test('finds package', async t => {
const root = path.join(fixtures, 'one-pkg')
const pkgs = await findPackages(root)
t.equal(pkgs.length, 1)
t.ok(pkgs[0].path)
t.ok(pkgs[0].manifest)
t.end()
})
test('finds packages by patterns', async t => {
const root = path.join(fixtures, 'many-pkgs')
const pkgs = await findPackages(root, { patterns: ['components/**'] })
t.equal(pkgs.length, 2)
t.ok(pkgs[0].path)
t.ok(pkgs[0].manifest)
t.ok(pkgs[1].path)
t.ok(pkgs[1].manifest)
t.deepEqual([pkgs[0].manifest.name, pkgs[1].manifest.name].sort(), ['component-1', 'component-2'])
t.end()
})
test('ignore packages by patterns', async t => {
const root = path.join(fixtures, 'many-pkgs')
const pkgs = await findPackages(root, { patterns: ['**', '!libs/**'] })
t.equal(pkgs.length, 2)
t.ok(pkgs[0].path)
t.ok(pkgs[0].manifest)
t.ok(pkgs[1].path)
t.ok(pkgs[1].manifest)
t.deepEqual([pkgs[0].manifest.name, pkgs[1].manifest.name].sort(), ['component-1', 'component-2'])
t.end()
})
test('json and yaml manifests are also found', async t => {
const root = path.join(fixtures, 'many-pkgs-with-different-manifest-types')
const pkgs = await findPackages(root)
t.equal(pkgs.length, 3)
t.ok(pkgs[0].path)
t.equal(pkgs[0].manifest.name, 'component-1')
t.ok(pkgs[1].path)
t.equal(pkgs[1].manifest.name, 'component-2')
t.ok(pkgs[2].path)
t.equal(pkgs[2].manifest.name, 'foo')
t.end()
})

View File

@@ -0,0 +1,10 @@
{
"extends": "../../utils/tsconfig.json",
"compilerOptions": {
"outDir": "lib"
},
"include": [
"src/**/*.ts",
"typings/**/*.d.ts"
]
}

View File

@@ -0,0 +1,3 @@
{
"extends": "@pnpm/tslint-config"
}

View File

@@ -0,0 +1,14 @@
declare module 'fast-glob' {
const anything: any;
export = anything;
}
declare module 'read-pkg' {
const anything: any;
export = anything;
}
declare module 'p-filter' {
const anything: any;
export = anything;
}

View File

@@ -36,6 +36,7 @@
},
"homepage": "https://github.com/pnpm/pnpm/blob/master/packages/list#readme",
"dependencies": {
"@pnpm/read-importer-manifest": "0.0.0",
"@pnpm/read-package-json": "2.0.1",
"@pnpm/types": "3.2.0",
"@types/archy": "0.0.31",

View File

@@ -1,11 +1,10 @@
import { readImporterManifestOnly } from '@pnpm/read-importer-manifest'
import { Registries } from '@pnpm/types'
import npa = require('@zkochan/npm-package-arg')
import dh, {
forPackages as dhForPackages,
PackageSelector,
} from 'dependencies-hierarchy'
import path = require('path')
import readPkg from './readPkg'
import renderParseable from './renderParseable'
import renderTree from './renderTree'
@@ -55,7 +54,7 @@ export async function forPackages (
})
const print = getPrinter(opts.parseable)
const entryPkg = await readPkg(path.resolve(projectPath, 'package.json'))
const entryPkg = await readImporterManifestOnly(projectPath)
return print({
name: entryPkg.name,
path: projectPath,
@@ -90,7 +89,7 @@ export default async function (
})
const print = getPrinter(opts.parseable)
const entryPkg = await readPkg(path.resolve(projectPath, 'package.json'))
const entryPkg = await readImporterManifestOnly(projectPath)
return print({
name: entryPkg.name,
path: projectPath,

View File

@@ -5,8 +5,8 @@ const sortPackages = R.sortBy(R.prop('name'))
export default async function (
project: {
name: string,
version: string,
name?: string,
version?: string,
path: string,
},
tree: PackageNode[],

View File

@@ -9,8 +9,8 @@ const sortPackages = R.sortBy(R.path(['pkg', 'name']) as (pkg: object) => R.Ord)
export default async function (
project: {
name: string,
version: string,
name?: string,
version?: string,
path: string,
},
tree: PackageNode[],

View File

@@ -31,7 +31,7 @@
},
"homepage": "https://github.com/pnpm/pnpm/blob/master/packages/local-resolver#readme",
"dependencies": {
"@pnpm/read-package-json": "2.0.1",
"@pnpm/read-importer-manifest": "0.0.0",
"@pnpm/resolver-base": "3.1.2",
"@pnpm/types": "3.2.0",
"@types/graceful-fs": "4.1.3",

View File

@@ -1,4 +1,4 @@
import readPackageJson from '@pnpm/read-package-json'
import { readImporterManifestOnly } from '@pnpm/read-importer-manifest'
import {
DirectoryResolution,
ResolveResult,
@@ -6,7 +6,6 @@ import {
} from '@pnpm/resolver-base'
import { DependencyManifest } from '@pnpm/types'
import fs = require('graceful-fs')
import path = require('path')
import ssri = require('ssri')
import parsePref from './parsePref'
@@ -44,9 +43,9 @@ export default async function resolveLocal (
}
}
let localPkg!: DependencyManifest
let localDependencyManifest!: DependencyManifest
try {
localPkg = await readPackageJson(path.join(spec.fetchSpec, 'package.json')) as DependencyManifest
localDependencyManifest = await readImporterManifestOnly(spec.fetchSpec) as DependencyManifest
} catch (internalErr) {
switch (internalErr.code) {
case 'ENOTDIR': {
@@ -67,7 +66,7 @@ export default async function resolveLocal (
return {
id: spec.id,
normalizedPref: spec.normalizedPref,
package: localPkg,
package: localDependencyManifest,
resolution: {
directory: spec.dependencyPath,
type: 'directory',

View File

@@ -105,7 +105,7 @@ test('fail when resolving from not existing directory', async t => {
t.fail()
} catch (err) {
t.ok(err)
t.equal(err.code, 'ERR_PNPM_DIRECTORY_HAS_NO_PACKAGE_JSON')
t.equal(err.code, 'ERR_PNPM_NO_IMPORTER_MANIFEST_FOUND')
t.end()
}
})

View File

@@ -43,7 +43,7 @@
"@pnpm/constants": "1.0.0",
"@pnpm/lockfile-file": "1.0.4",
"@pnpm/npm-resolver": "3.0.7",
"@pnpm/read-package-json": "2.0.1",
"@pnpm/read-importer-manifest": "0.0.0",
"@pnpm/store-path": "1.0.4",
"@pnpm/types": "3.2.0",
"@pnpm/utils": "0.10.4",

View File

@@ -5,9 +5,9 @@ import {
readWantedLockfile,
} from '@pnpm/lockfile-file'
import createResolver from '@pnpm/npm-resolver'
import { fromDir as readPackageFromDir } from '@pnpm/read-package-json'
import { readImporterManifestOnly } from '@pnpm/read-importer-manifest'
import resolveStore from '@pnpm/store-path'
import { DEPENDENCIES_FIELDS, Registries } from '@pnpm/types'
import { DEPENDENCIES_FIELDS, ImporterManifest, Registries } from '@pnpm/types'
import { normalizeRegistries } from '@pnpm/utils'
import * as dp from 'dependency-path'
@@ -103,8 +103,8 @@ async function _outdated (
): Promise<OutdatedPackage[]> {
const registries = normalizeRegistries(opts.registries)
const lockfileDirectory = opts.lockfileDirectory || pkgPath
const pkg = await readPackageFromDir(pkgPath)
if (packageHasNoDeps(pkg)) return []
const manifest = await readImporterManifestOnly(pkgPath)
if (packageHasNoDeps(manifest)) return []
const wantedLockfile = await readWantedLockfile(lockfileDirectory, { ignoreIncompatible: false })
|| await readCurrentLockfile(lockfileDirectory, { ignoreIncompatible: false })
if (!wantedLockfile) {
@@ -211,11 +211,10 @@ async function _outdated (
return outdated.sort((pkg1, pkg2) => pkg1.packageName.localeCompare(pkg2.packageName))
}
// tslint:disable-next-line:no-any
function packageHasNoDeps (pkg: any) {
return (!pkg.dependencies || isEmpty(pkg.dependencies))
&& (!pkg.devDependencies || isEmpty(pkg.devDependencies))
&& (!pkg.optionalDependencies || isEmpty(pkg.optionalDependencies))
function packageHasNoDeps (manifest: ImporterManifest) {
return (!manifest.dependencies || isEmpty(manifest.dependencies))
&& (!manifest.devDependencies || isEmpty(manifest.devDependencies))
&& (!manifest.optionalDependencies || isEmpty(manifest.optionalDependencies))
}
function isEmpty (obj: object) {

View File

@@ -108,11 +108,6 @@ declare module '@zkochan/cmd-shim' {
export = anything;
}
declare module 'write-pkg' {
const anything: any;
export = anything;
}
declare module 'is-windows' {
function isWindows(): boolean;
export = isWindows;

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017-present Zoltan Kochan
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.

View File

@@ -0,0 +1,67 @@
# pkgs-graph
> Create a graph from an array of packages
[![npm version](https://img.shields.io/npm/v/pkgs-graph.svg)](https://www.npmjs.com/package/pkgs-graph)
## Installation
```
<npm|yarn|pnpm> add pkgs-graph
```
## Usage
```js
import createPkgsGraph from 'pkgs-graph'
const {graph} = createPkgsGraph([
{
manifest: {
name: 'foo',
version: '1.0.0',
dependencies: {
bar: '^1.0.0',
},
},
path: '/home/zkochan/src/foo',
},
{
manifest: {
name: 'bar',
version: '1.1.0',
},
path: '/home/zkochan/src/bar',
}
])
console.log(graph)
//> {
// '/home/zkochan/src/foo': {
// dependencies: ['/home/zkochan/src/bar'],
// manifest: {
// name: 'foo',
// version: '1.0.0',
// dependencies: {
// bar: '^1.0.0',
// },
// },
// },
// '/home/zkochan/src/bar': {
// dependencies: [],
// manifest: {
// name: 'bar',
// version: '1.1.0',
// },
// },
// }
```
## Related
* [find-packages](https://github.com/zkochan/find-packages) - Find all packages inside a directory
* [sort-pkgs](https://github.com/zkochan/sort-pkgs) - Sort packages. Dependents first.
## License
[MIT](LICENSE) © [Zoltan Kochan](https://www.kochan.io)

View File

@@ -0,0 +1,48 @@
{
"name": "pkgs-graph",
"version": "3.0.0",
"description": "Create a graph from an array of packages",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"files": [
"lib"
],
"scripts": {
"lint": "tslint -c tslint.json src/**/*.ts test/**/*.ts",
"test": "npm run tsc && pnpm run lint && ts-node test --type-check",
"tsc": "tsc",
"prepublishOnly": "npm run tsc"
},
"repository": "https://github.com/pnpm/pnpm/blob/master/packages/pkgs-graph",
"author": {
"name": "Zoltan Kochan",
"email": "z@kochan.io",
"url": "https://www.kochan.io/"
},
"license": "MIT",
"engines": {
"node": ">=8.15"
},
"bugs": {
"url": "https://github.com/pnpm/pnpm/issues"
},
"homepage": "https://github.com/pnpm/pnpm/blob/master/packages/pkgs-graph#readme",
"devDependencies": {
"@pnpm/tslint-config": "0.0.0",
"@types/tape": "^4.2.29",
"better-path-resolve": "1.0.0",
"pkgs-graph": "link:",
"tape": "^4.6.3",
"ts-node": "^8.0.3",
"tslint": "5.16.0",
"typescript": "^3.0.0"
},
"dependencies": {
"@types/node": "*",
"@types/ramda": "^0.26.0",
"@types/semver": "^5.3.31",
"@zkochan/npm-package-arg": "^1.0.0",
"ramda": "^0.26.0",
"semver": "^6.0.0"
}
}

View File

@@ -0,0 +1,102 @@
///<reference path="../typings/index.d.ts"/>
import npa = require('@zkochan/npm-package-arg')
import path = require('path')
import R = require('ramda')
import semver = require('semver')
export type Manifest = {
name: string,
version: string,
dependencies?: {
[name: string]: string,
},
devDependencies?: {
[name: string]: string,
},
optionalDependencies?: {
[name: string]: string,
},
}
export type Package = {
manifest: Manifest,
path: string,
}
export type PackageNode<T> = {
package: Package & T,
dependencies: string[],
}
export default function<T> (pkgs: Array<Package & T>): {
graph: {[id: string]: PackageNode<T>},
unmatched: Array<{pkgName: string, range: string}>,
} {
const pkgMap = createPkgMap(pkgs)
const unmatched: Array<{pkgName: string, range: string}> = []
const graph = Object.keys(pkgMap)
.reduce((acc, pkgSpec) => {
acc[pkgSpec] = {
dependencies: createNode(pkgMap[pkgSpec]),
package: pkgMap[pkgSpec],
}
return acc
}, {})
return { graph, unmatched }
function createNode (pkg: Package): string[] {
const dependencies = Object.assign({},
pkg.manifest.devDependencies,
pkg.manifest.optionalDependencies,
pkg.manifest.dependencies)
return Object.keys(dependencies)
.map(depName => {
let spec!: { fetchSpec: string, type: string }
try {
spec = npa.resolve(depName, dependencies[depName], pkg.path)
} catch (err) {
return ''
}
if (spec.type === 'directory') {
const matchedPkg = R.values(pkgMap).find(pkg => path.relative(pkg.path, spec.fetchSpec) === '')
if (!matchedPkg) {
return ''
}
return matchedPkg!.path
}
if (spec.type !== 'version' && spec.type !== 'range') return ''
const range = dependencies[depName]
const pkgs = R.values(pkgMap).filter(pkg => pkg.manifest.name === depName)
if (!pkgs.length) return ''
const versions = pkgs.map(pkg => pkg.manifest.version)
if (versions.indexOf(range) !== -1) {
const matchedPkg = pkgs.find(pkg => pkg.manifest.name === depName && pkg.manifest.version === range)
return matchedPkg!.path
}
const matched = semver.maxSatisfying(versions, range)
if (!matched) {
unmatched.push({ pkgName: depName, range })
return ''
}
const matchedPkg = pkgs.find(pkg => pkg.manifest.name === depName && pkg.manifest.version === matched)
return matchedPkg!.path
})
.filter(Boolean)
}
}
function createPkgMap (pkgs: Package[]): {
[pkgId: string]: Package
} {
const pkgMap = {}
for (let pkg of pkgs) {
pkgMap[pkg.path] = pkg
}
return pkgMap
}

View File

@@ -0,0 +1,216 @@
import pathResolve = require('better-path-resolve')
import createPkgGraph from 'pkgs-graph'
import test = require('tape')
const BAR1_PATH = pathResolve('/zkochan/src/bar')
const FOO1_PATH = pathResolve('/zkochan/src/foo')
const BAR2_PATH = pathResolve('/zkochan/src/bar@2')
const FOO2_PATH = pathResolve('/zkochan/src/foo@2')
test('create package graph', t => {
const result = createPkgGraph([
{
manifest: {
name: 'bar',
version: '1.0.0',
dependencies: {
'foo': '^1.0.0',
'is-positive': '1.0.0',
}
},
path: BAR1_PATH,
},
{
manifest: {
name: 'foo',
version: '1.0.0',
dependencies: {
bar: '^10.0.0'
}
},
path: FOO1_PATH,
},
{
manifest: {
name: 'bar',
version: '2.0.0',
dependencies: {
foo: '^2.0.0'
}
},
path: BAR2_PATH,
},
{
manifest: {
name: 'foo',
version: '2.0.0',
},
path: FOO2_PATH,
},
])
t.deepEqual(result.unmatched, [{ pkgName: 'bar', range: '^10.0.0' }])
t.deepEqual(result.graph, {
[BAR1_PATH]: {
dependencies: [FOO1_PATH],
package: {
manifest: {
name: 'bar',
version: '1.0.0',
dependencies: {
'foo': '^1.0.0',
'is-positive': '1.0.0',
}
},
path: BAR1_PATH,
},
},
[FOO1_PATH]: {
dependencies: [],
package: {
manifest: {
name: 'foo',
version: '1.0.0',
dependencies: {
bar: '^10.0.0'
}
},
path: FOO1_PATH,
},
},
[BAR2_PATH]: {
dependencies: [FOO2_PATH],
package: {
manifest: {
name: 'bar',
version: '2.0.0',
dependencies: {
foo: '^2.0.0',
},
},
path: BAR2_PATH,
},
},
[FOO2_PATH]: {
dependencies: [],
package: {
manifest: {
name: 'foo',
version: '2.0.0',
},
path: FOO2_PATH,
},
},
})
t.end()
})
test('create package graph for local directory dependencies', t => {
const result = createPkgGraph([
{
manifest: {
name: 'bar',
version: '1.0.0',
dependencies: {
'foo': '../foo',
'is-positive': '1.0.0',
'weird-dep': ':aaaaa', // weird deps are skipped
},
},
path: BAR1_PATH,
},
{
manifest: {
name: 'foo',
version: '1.0.0',
dependencies: {
bar: '^10.0.0',
},
},
path: FOO1_PATH,
},
{
manifest: {
name: 'bar',
version: '2.0.0',
dependencies: {
foo: 'file:../foo@2',
},
},
path: BAR2_PATH,
},
{
manifest: {
name: 'foo',
version: '2.0.0',
},
path: FOO2_PATH,
},
])
t.deepEqual(result.unmatched, [{ pkgName: 'bar', range: '^10.0.0' }])
t.deepEqual(result.graph, {
[BAR1_PATH]: {
dependencies: [FOO1_PATH],
package: {
manifest: {
name: 'bar',
version: '1.0.0',
dependencies: {
'foo': '../foo',
'is-positive': '1.0.0',
'weird-dep': ':aaaaa',
},
},
path: BAR1_PATH,
},
},
[FOO1_PATH]: {
dependencies: [],
package: {
manifest: {
name: 'foo',
version: '1.0.0',
dependencies: {
bar: '^10.0.0',
},
},
path: FOO1_PATH,
},
},
[BAR2_PATH]: {
dependencies: [FOO2_PATH],
package: {
manifest: {
name: 'bar',
version: '2.0.0',
dependencies: {
foo: 'file:../foo@2'
},
},
path: BAR2_PATH,
},
},
[FOO2_PATH]: {
dependencies: [],
package: {
manifest: {
name: 'foo',
version: '2.0.0',
},
path: FOO2_PATH,
},
},
})
t.end()
})

View File

@@ -0,0 +1,10 @@
{
"extends": "../../utils/tsconfig.json",
"compilerOptions": {
"outDir": "lib"
},
"include": [
"src/**/*.ts",
"typings/**/*.d.ts"
]
}

View File

@@ -0,0 +1,3 @@
{
"extends": "@pnpm/tslint-config"
}

View File

@@ -0,0 +1,9 @@
declare module '@zkochan/npm-package-arg' {
const anything: any;
export = anything;
}
declare module 'better-path-resolve' {
const anything: any;
export = anything;
}

View File

@@ -32,6 +32,7 @@
"@pnpm/logger": "2.1.0",
"@pnpm/outdated": "2.0.8",
"@pnpm/package-store": "4.0.6",
"@pnpm/read-importer-manifest": "0.0.0",
"@pnpm/server": "3.0.3",
"@pnpm/store-controller-types": "3.0.3",
"@pnpm/store-path": "1.0.4",
@@ -92,6 +93,7 @@
"@pnpm/prepare": "0.0.0",
"@pnpm/read-package-json": "2.0.1",
"@pnpm/tslint-config": "0.0.0",
"@pnpm/write-importer-manifest": "0.0.0",
"@types/byline": "4.2.31",
"@types/common-tags": "1.8.0",
"@types/mkdirp": "0.5.2",

View File

@@ -1,10 +1,10 @@
import { WANTED_LOCKFILE } from '@pnpm/constants'
import { readImporterManifestOnly } from '@pnpm/read-importer-manifest'
import loadJsonFile = require('load-json-file')
import path = require('path')
import rimraf = require('rimraf-then')
import { install } from 'supi'
import createStoreController from '../createStoreController'
import { readImporterManifestFromDir } from '../readImporterManifest'
import { PnpmOptions } from '../types'
export default async function installCmd (
@@ -26,7 +26,7 @@ export default async function installCmd (
store: store.path,
storeController: store.ctrl,
}
await install(await readImporterManifestFromDir(opts.prefix), installOpts)
await install(await readImporterManifestOnly(opts.prefix), installOpts)
}
async function readNpmLockfile (prefix: string) {

View File

@@ -1,14 +1,13 @@
import { readImporterManifestOnly, tryReadImporterManifest } from '@pnpm/read-importer-manifest'
import { getSaveType } from '@pnpm/utils'
import {
install,
mutateModules,
rebuild,
} from 'supi'
import writePkg = require('write-pkg')
import createStoreController from '../createStoreController'
import findWorkspacePackages, { arrayOfLocalPackagesToMap } from '../findWorkspacePackages'
import getPinnedVersion from '../getPinnedVersion'
import { readImporterManifestFromDir, safeReadImporterManifestFromDir } from '../readImporterManifest'
import requireHooks from '../requireHooks'
import { PnpmOptions } from '../types'
import updateToLatestSpecsFromManifest, { createLatestSpecs } from '../updateToLatestSpecsFromManifest'
@@ -54,7 +53,7 @@ export default async function installCmd (
storeController: store.ctrl,
}
let manifest = await safeReadImporterManifestFromDir(opts.prefix)
let { manifest, writeImporterManifest } = await tryReadImporterManifest(opts.prefix)
if (manifest === null) {
if (opts.update) {
const err = new Error('No package.json found')
@@ -87,7 +86,7 @@ export default async function installCmd (
targetDependenciesField: getSaveType(installOpts),
},
], installOpts)
await writePkg(opts.prefix, updatedImporter.manifest)
await writeImporterManifest(updatedImporter.manifest)
}
if (opts.linkWorkspacePackages && opts.workspacePrefix) {
@@ -113,7 +112,7 @@ export default async function installCmd (
[
{
buildIndex: 0,
manifest: await readImporterManifestFromDir(opts.prefix),
manifest: await readImporterManifestOnly(opts.prefix),
prefix: opts.prefix,
},
], {

View File

@@ -1,5 +1,8 @@
import { StoreController } from '@pnpm/package-store'
import { safeReadPackageFromDir } from '@pnpm/utils'
import readImporterManifest, {
readImporterManifestOnly,
tryReadImporterManifest,
} from '@pnpm/read-importer-manifest'
import pLimit = require('p-limit')
import path = require('path')
import pathAbsolute = require('path-absolute')
@@ -11,11 +14,9 @@ import {
linkToGlobal,
LocalPackages,
} from 'supi'
import writePkg = require('write-pkg')
import { cached as createStoreController } from '../createStoreController'
import findWorkspacePackages, { arrayOfLocalPackagesToMap } from '../findWorkspacePackages'
import getConfigs from '../getConfigs'
import { readImporterManifestFromDir } from '../readImporterManifest'
import { PnpmOptions } from '../types'
const installLimit = pLimit(4)
@@ -45,12 +46,12 @@ export default async (
// pnpm link
if (!input || !input.length) {
const manifest = await safeReadPackageFromDir(opts.globalPrefix) || {}
const { manifest, writeImporterManifest } = await tryReadImporterManifest(opts.globalPrefix)
const newManifest = await linkToGlobal(cwd, {
...linkOpts,
manifest,
manifest: manifest || {},
})
await writePkg(opts.globalPrefix, newManifest)
await writeImporterManifest(newManifest)
return
}
@@ -80,7 +81,7 @@ export default async (
pkgPaths.map((prefix) => installLimit(async () => {
const s = await createStoreController(storeControllerCache, opts)
await install(
await readImporterManifestFromDir(prefix), {
await readImporterManifestOnly(prefix), {
...await getConfigs(
{ ...opts.cliArgs, prefix },
{
@@ -95,12 +96,12 @@ export default async (
)
})),
)
const currentManifest = await readImporterManifestFromDir(cwd)
const { manifest, writeImporterManifest } = await readImporterManifest(cwd)
const newManifest = await link(pkgPaths, path.join(cwd, 'node_modules'), {
...linkOpts,
manifest: currentManifest,
manifest,
})
await writePkg(cwd, newManifest)
await writeImporterManifest(newManifest)
await Promise.all(
Array.from(storeControllerCache.values())

View File

@@ -1,6 +1,6 @@
import { readImporterManifestOnly } from '@pnpm/read-importer-manifest'
import { InstallOptions, mutateModules } from 'supi'
import createStoreController from '../createStoreController'
import { readImporterManifestFromDir } from '../readImporterManifest'
import { PnpmOptions } from '../types'
export default async (input: string[], opts: PnpmOptions) => {
@@ -8,7 +8,7 @@ export default async (input: string[], opts: PnpmOptions) => {
return mutateModules([
{
buildIndex: 0,
manifest: await readImporterManifestFromDir(process.cwd()),
manifest: await readImporterManifestOnly(process.cwd()),
mutation: 'install',
prefix: process.cwd(),
pruneDirectDependencies: true,

View File

@@ -1,9 +1,9 @@
import { readImporterManifestOnly } from '@pnpm/read-importer-manifest'
import {
rebuild,
rebuildPkgs,
} from 'supi'
import createStoreController from '../createStoreController'
import { readImporterManifestFromDir } from '../readImporterManifest'
import { PnpmOptions } from '../types'
export default async function (
@@ -22,7 +22,7 @@ export default async function (
[
{
buildIndex: 0,
manifest: await readImporterManifestFromDir(rebuildOpts.prefix),
manifest: await readImporterManifestOnly(rebuildOpts.prefix),
prefix: rebuildOpts.prefix,
},
],
@@ -32,7 +32,7 @@ export default async function (
await rebuildPkgs(
[
{
manifest: await readImporterManifestFromDir(rebuildOpts.prefix),
manifest: await readImporterManifestOnly(rebuildOpts.prefix),
prefix: rebuildOpts.prefix,
},
],

View File

@@ -4,9 +4,9 @@ import pLimit = require('p-limit')
import { PackageNode } from 'pkgs-graph'
import RecursiveSummary from './recursiveSummary'
export default async (
export default async <T> (
packageChunks: string[][],
graph: {[id: string]: PackageNode},
graph: {[id: string]: PackageNode<T>},
args: string[],
cmd: string,
opts: {
@@ -31,7 +31,7 @@ export default async (
cwd: prefix,
env: {
...process.env,
PNPM_PACKAGE_NAME: graph[prefix].manifest.name,
PNPM_PACKAGE_NAME: graph[prefix].package.manifest.name,
},
stdio: 'inherit',
})

View File

@@ -4,18 +4,18 @@ import { PackageNode } from 'pkgs-graph'
import R = require('ramda')
import { PackageSelector } from '../../parsePackageSelectors'
interface PackageGraph {
[id: string]: PackageNode,
interface PackageGraph<T> {
[id: string]: PackageNode<T>,
}
interface Graph {
[nodeId: string]: string[],
}
export function filterGraph (
pkgGraph: PackageGraph,
export function filterGraph<T> (
pkgGraph: PackageGraph<T>,
packageSelectors: PackageSelector[],
): PackageGraph {
): PackageGraph<T> {
const cherryPickedPackages = [] as string[]
const walkedDependencies = new Set<string>()
const walkedDependents = new Set<string>()
@@ -46,7 +46,7 @@ export function filterGraph (
return R.pick(Array.from(walked), pkgGraph)
}
function pkgGraphToGraph (pkgGraph: PackageGraph): Graph {
function pkgGraphToGraph<T> (pkgGraph: PackageGraph<T>): Graph {
const graph: Graph = {}
Object.keys(pkgGraph).forEach((nodeId) => {
graph[nodeId] = pkgGraph[nodeId].dependencies
@@ -68,15 +68,15 @@ function reverseGraph (graph: Graph): Graph {
return reversedGraph
}
function matchPackages (
graph: PackageGraph,
function matchPackages<T> (
graph: PackageGraph<T>,
pattern: string,
) {
return R.keys(graph).filter((id) => graph[id].manifest.name && minimatch(graph[id].manifest.name, pattern))
return R.keys(graph).filter((id) => graph[id].package.manifest.name && minimatch(graph[id].package.manifest.name, pattern))
}
function matchPackagesByPath (
graph: PackageGraph,
function matchPackagesByPath<T> (
graph: PackageGraph<T>,
pathStartsWith: string,
) {
return R.keys(graph).filter((location) => isSubdir(pathStartsWith, location))

View File

@@ -22,14 +22,12 @@ import {
rebuildPkgs,
uninstall,
} from 'supi'
import writePkg = require('write-pkg')
import createStoreController from '../../createStoreController'
import findWorkspacePackages, { arrayOfLocalPackagesToMap } from '../../findWorkspacePackages'
import getCommandFullName from '../../getCommandFullName'
import getPinnedVersion from '../../getPinnedVersion'
import { scopeLogger } from '../../loggers'
import parsePackageSelector, { PackageSelector } from '../../parsePackageSelectors'
import { readImporterManifestFromDir } from '../../readImporterManifest'
import requireHooks from '../../requireHooks'
import { PnpmOptions } from '../../types'
import updateToLatestSpecsFromManifest, { createLatestSpecs } from '../../updateToLatestSpecsFromManifest'
@@ -101,7 +99,7 @@ export default async (
}
export async function recursive (
allPkgs: Array<{path: string, manifest: DependencyManifest}>,
allPkgs: Array<{path: string, manifest: DependencyManifest, writeImporterManifest: (manifest: ImporterManifest) => Promise<void>}>,
input: string[],
opts: PnpmOptions & {
allowNew?: boolean,
@@ -117,7 +115,7 @@ export async function recursive (
}
const pkgGraphResult = createPkgGraph(allPkgs)
let pkgs: Array<{path: string, manifest: ImporterManifest}>
let pkgs: Array<{path: string, manifest: ImporterManifest, writeImporterManifest: (manifest: ImporterManifest) => Promise<void> }>
if (opts.packageSelectors && opts.packageSelectors.length) {
pkgGraphResult.graph = filterGraph(pkgGraphResult.graph, opts.packageSelectors)
pkgs = allPkgs.filter((pkg: {path: string}) => pkgGraphResult.graph[pkg.path])
@@ -128,6 +126,13 @@ export async function recursive (
if (pkgs.length === 0) {
return false
}
const manifestsByPath: { [path: string]: { manifest: ImporterManifest, writeImporterManifest: (manifest: ImporterManifest) => Promise<void> } } = {}
for (const pkg of pkgs) {
manifestsByPath[pkg.path] = {
manifest: pkg.manifest,
writeImporterManifest: pkg.writeImporterManifest,
}
}
scopeLogger.debug({
selected: pkgs.length,
@@ -208,7 +213,7 @@ export async function recursive (
prefixes.map(async (prefix) => {
importers.push({
buildIndex,
manifest: await readImporterManifestFromDir(prefix),
manifest: manifestsByPath[prefix].manifest,
prefix,
})
})
@@ -224,6 +229,7 @@ export async function recursive (
}
if (cmdFullName !== 'rebuild') {
// For a workspace with shared lockfile
if (opts.lockfileDirectory && ['install', 'uninstall', 'update'].includes(cmdFullName)) {
let importers = await getImporters()
const isFromWorkspace = isSubdir.bind(null, opts.lockfileDirectory)
@@ -231,9 +237,11 @@ export async function recursive (
if (importers.length === 0) return true
const hooks = opts.ignorePnpmfile ? {} : requireHooks(opts.lockfileDirectory, opts)
const mutation = cmdFullName === 'uninstall' ? 'uninstallSome' : (input.length === 0 && !updateToLatest ? 'install' : 'installSome')
const mutatedImporters = await Promise.all<MutatedImporter>(importers.map(async ({ buildIndex, prefix }) => {
const writeImporterManifests = [] as Array<(manifest: ImporterManifest) => Promise<void>>
const mutatedImporters = await Promise.all<MutatedImporter>(importers.map(async ({ buildIndex, prefix }, index) => {
const localConfigs = await memReadLocalConfigs(prefix)
const manifest = await readImporterManifestFromDir(prefix)
const { manifest, writeImporterManifest } = manifestsByPath[prefix]
writeImporterManifests[index] = writeImporterManifest
const shamefullyFlatten = typeof localConfigs.shamefullyFlatten === 'boolean'
? localConfigs.shamefullyFlatten
: opts.shamefullyFlatten
@@ -288,7 +296,7 @@ export async function recursive (
await Promise.all(
mutatedPkgs
.filter((mutatedPkg, index) => mutatedImporters[index].mutation !== 'install')
.map(({ manifest, prefix }) => writePkg(prefix, manifest))
.map(({ manifest, prefix }, index) => writeImporterManifests[index](manifest))
)
return true
}
@@ -306,7 +314,7 @@ export async function recursive (
return
}
const manifest = await readImporterManifestFromDir(prefix)
const { manifest, writeImporterManifest } = manifestsByPath[prefix]
let currentInput = [...input]
if (updateToLatest) {
if (!currentInput || !currentInput.length) {
@@ -330,7 +338,7 @@ export async function recursive (
}
const localConfigs = await memReadLocalConfigs(prefix)
const newPkg = await action(
const newManifest = await action(
manifest,
{
...installOpts,
@@ -347,7 +355,7 @@ export async function recursive (
},
)
if (action !== install) {
await writePkg(prefix, newPkg)
await writeImporterManifest(newManifest)
}
result.passes++
} catch (err) {
@@ -404,7 +412,7 @@ export async function recursive (
[
{
buildIndex: 0,
manifest: await readImporterManifestFromDir(prefix),
manifest: manifestsByPath[prefix].manifest,
prefix,
},
],
@@ -473,7 +481,7 @@ async function unlinkPkgs (dependencyNames: string[], manifest: ImporterManifest
)
}
function sortPackages (pkgGraph: {[nodeId: string]: PackageNode}): string[][] {
function sortPackages<T> (pkgGraph: {[nodeId: string]: PackageNode<T>}): string[][] {
const keys = Object.keys(pkgGraph)
const setOfKeys = new Set(keys)
const graph = new Map(

View File

@@ -6,9 +6,9 @@ import pLimit = require('p-limit')
import { PackageNode } from 'pkgs-graph'
import RecursiveSummary from './recursiveSummary'
export default async (
export default async <T> (
packageChunks: string[][],
graph: {[id: string]: PackageNode},
graph: {[id: string]: PackageNode<T>},
args: string[],
cmd: string,
opts: {
@@ -35,8 +35,8 @@ export default async (
for (const chunk of packageChunks) {
await Promise.all(chunk.map((prefix: string) =>
limitRun(async () => {
const pkg = graph[prefix] as {manifest: PackageJson, path: string}
if (!pkg.manifest.scripts || !pkg.manifest.scripts[scriptName]) {
const pkg = graph[prefix] as {package: {manifest: PackageJson, path: string}}
if (!pkg.package.manifest.scripts || !pkg.package.manifest.scripts[scriptName]) {
return
}
hasCommand++
@@ -49,12 +49,12 @@ export default async (
stdio,
unsafePerm: true, // when running scripts explicitly, assume that they're trusted.
}
if (pkg.manifest.scripts[`pre${scriptName}`]) {
await runLifecycleHooks(`pre${scriptName}`, pkg.manifest, lifecycleOpts)
if (pkg.package.manifest.scripts[`pre${scriptName}`]) {
await runLifecycleHooks(`pre${scriptName}`, pkg.package.manifest, lifecycleOpts)
}
await runLifecycleHooks(scriptName, pkg.manifest, lifecycleOpts)
if (pkg.manifest.scripts[`post${scriptName}`]) {
await runLifecycleHooks(`post${scriptName}`, pkg.manifest, lifecycleOpts)
await runLifecycleHooks(scriptName, pkg.package.manifest, lifecycleOpts)
if (pkg.package.manifest.scripts[`post${scriptName}`]) {
await runLifecycleHooks(`post${scriptName}`, pkg.package.manifest, lifecycleOpts)
}
result.passes++
} catch (err) {

View File

@@ -1,11 +1,10 @@
import readImporterManifest from '@pnpm/read-importer-manifest'
import {
mutateModules,
uninstall,
} from 'supi'
import writePkg = require('write-pkg')
import createStoreController from '../createStoreController'
import findWorkspacePackages, { arrayOfLocalPackagesToMap } from '../findWorkspacePackages'
import { readImporterManifestFromDir } from '../readImporterManifest'
import { PnpmOptions } from '../types'
export default async function uninstallCmd (
@@ -18,24 +17,26 @@ export default async function uninstallCmd (
storeController: store.ctrl,
})
if (opts.lockfileDirectory === opts.prefix) {
const manifest = await uninstall(await readImporterManifestFromDir(opts.prefix), input, uninstallOpts)
await writePkg(opts.prefix, manifest)
const { manifest, writeImporterManifest } = await readImporterManifest(opts.prefix)
const newManifest = await uninstall(manifest, input, uninstallOpts)
await writeImporterManifest(newManifest)
return
}
uninstallOpts['localPackages'] = opts.linkWorkspacePackages && opts.workspacePrefix
? arrayOfLocalPackagesToMap(await findWorkspacePackages(opts.workspacePrefix))
: undefined
const [{ manifest }] = await mutateModules(
const currentManifest = await readImporterManifest(opts.prefix)
const [mutationResult] = await mutateModules(
[
{
bin: opts.bin,
dependencyNames: input,
manifest: await readImporterManifestFromDir(opts.prefix),
manifest: currentManifest.manifest,
mutation: 'uninstallSome',
prefix: opts.prefix,
},
],
uninstallOpts,
)
await writePkg(opts.prefix, manifest)
await currentManifest.writeImporterManifest(mutationResult.manifest)
}

View File

@@ -1,6 +1,6 @@
import { readImporterManifestOnly } from '@pnpm/read-importer-manifest'
import { mutateModules } from 'supi'
import createStoreController from '../createStoreController'
import { readImporterManifestFromDir } from '../readImporterManifest'
import { PnpmOptions } from '../types'
export default async function (input: string[], opts: PnpmOptions) {
@@ -14,7 +14,7 @@ export default async function (input: string[], opts: PnpmOptions) {
return mutateModules([
{
dependencyNames: input,
manifest: await readImporterManifestFromDir(opts.prefix),
manifest: await readImporterManifestOnly(opts.prefix),
mutation: 'unlinkSome',
prefix: opts.prefix,
},
@@ -22,7 +22,7 @@ export default async function (input: string[], opts: PnpmOptions) {
}
return mutateModules([
{
manifest: await readImporterManifestFromDir(opts.prefix),
manifest: await readImporterManifestOnly(opts.prefix),
mutation: 'unlink',
prefix: opts.prefix,
},

View File

@@ -1,10 +1,10 @@
import { WORKSPACE_MANIFEST_FILENAME } from '@pnpm/constants'
import { DependencyManifest } from '@pnpm/types'
import { DependencyManifest, ImporterManifest } from '@pnpm/types'
import findPackages from 'find-packages'
import path = require('path')
import readYamlFile from 'read-yaml-file'
export default async (workspaceRoot: string): Promise<Array<{path: string, manifest: DependencyManifest}>> => {
export default async (workspaceRoot: string): Promise<Array<{path: string, manifest: DependencyManifest, writeImporterManifest: (manifest: ImporterManifest) => Promise<void>}>> => {
const packagesManifest = await requirePackagesManifest(workspaceRoot)
const pkgs = await findPackages(workspaceRoot, {
ignore: [

View File

@@ -1,12 +1,13 @@
import { WANTED_LOCKFILE } from '@pnpm/constants'
import { Lockfile } from '@pnpm/lockfile-types'
import prepare, { prepareEmpty } from '@pnpm/prepare'
import readImporterManifest from '@pnpm/read-importer-manifest'
import { fromDir as readPackageJsonFromDir } from '@pnpm/read-package-json'
import writeImporterManifest from '@pnpm/write-importer-manifest'
import crossSpawn = require('cross-spawn')
import delay = require('delay')
import dirIsCaseSensitive from 'dir-is-case-sensitive'
import fs = require('fs')
import isWindows = require('is-windows')
import loadJsonFile = require('load-json-file')
import path = require('path')
import exists = require('path-exists')
@@ -122,6 +123,20 @@ test('install --save-exact', async (t: tape.Test) => {
t.deepEqual(pkg.devDependencies, { 'is-positive': '3.1.0' })
})
test('install to a project that uses package.yaml', async (t: tape.Test) => {
const project = prepareEmpty(t)
await writeImporterManifest(path.resolve('package.yaml'), { name: 'foo', version: '1.0.0' })
await execPnpm('install', 'is-positive@3.1.0', '--save-exact', '--save-dev')
await project.has('is-positive')
const { manifest } = await readImporterManifest(process.cwd())
t.deepEqual(manifest && manifest.devDependencies, { 'is-positive': '3.1.0' })
})
test('install save new dep with the specified spec', async (t: tape.Test) => {
const project = prepare(t)

View File

@@ -173,11 +173,6 @@ declare module 'pnpm-registry-mock' {
export = anything;
}
declare module 'read-package-json' {
const anything: any;
export = anything;
}
declare module 'ssri' {
const anything: any;
export = anything;

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2018-2019 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.

View File

@@ -0,0 +1,25 @@
# @pnpm/read-importer-manifest
> Read an importer manifest (called package.json in most cases)
<!--@shields('npm')-->
[![npm version](https://img.shields.io/npm/v/@pnpm/read-importer-manifest.svg)](https://www.npmjs.com/package/@pnpm/read-importer-manifest)
<!--/@-->
## Installation
```sh
<npm|yarn|pnpm> add @pnpm/read-importer-manifest
```
## Usage
```ts
import readImporterManifest from '@pnpm/read-importer-manifest'
const { manifest, fileName } = await readImporterManifest(process.cwd())
```
## License
[MIT](./LICENSE) © [Zoltan Kochan](https://www.kochan.io/)

View File

@@ -0,0 +1,71 @@
{
"name": "@pnpm/read-importer-manifest",
"version": "0.0.0",
"description": "Read an importer manifest (called package.json in most cases)",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
"engines": {
"node": ">=8.15"
},
"files": [
"lib"
],
"scripts": {
"lint": "tslint -c tslint.json src/**/*.ts test/**/*.ts",
"test": "npm run lint && npm run tsc && ts-node test --type-check",
"prepublishOnly": "tsc",
"tsc": "tsc",
"md": "mos"
},
"repository": "https://github.com/pnpm/pnpm/blob/master/packages/read-importer-manifest",
"keywords": [
"pnpm",
"outdated"
],
"author": {
"name": "Zoltan Kochan",
"email": "z@kochan.io",
"url": "https://www.kochan.io/",
"twitter": "ZoltanKochan"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/pnpm/pnpm/issues"
},
"homepage": "https://github.com/pnpm/pnpm/blob/master/packages/read-importer-manifest#readme",
"dependencies": {
"@pnpm/types": "^3.0.0",
"@pnpm/write-importer-manifest": "0.0.0",
"@types/detect-indent": "5.0.0",
"detect-indent": "5.0.0",
"graceful-fs": "4.1.15",
"is-windows": "1.0.2",
"json5": "2.1.0",
"read-yaml-file": "1.1.0",
"strip-bom": "4.0.0"
},
"devDependencies": {
"@pnpm/read-importer-manifest": "link:",
"@pnpm/tslint-config": "0.0.0",
"@types/graceful-fs": "4.1.3",
"@types/is-windows": "0.2.0",
"@types/json5": "0.0.30",
"@types/node": "^10.3.2",
"@types/tape": "^4.2.31",
"mos": "^2.0.0-alpha.3",
"mos-plugin-readme": "^1.0.4",
"tape": "^4.8.0",
"tempy": "0.3.0",
"ts-node": "8.1.0",
"tslint": "^5.8.0",
"typescript": "3.4.5"
},
"mos": {
"plugins": [
"readme"
],
"installation": {
"useShortAlias": true
}
}
}

View File

@@ -0,0 +1,158 @@
import { ImporterManifest } from '@pnpm/types'
import writeImporterManifest from '@pnpm/write-importer-manifest'
import detectIndent = require('detect-indent')
import fs = require('fs')
import { Stats } from 'fs'
import isWindows = require('is-windows')
import path = require('path')
import readYamlFile from 'read-yaml-file'
import { promisify } from 'util'
import {
readJson5File,
readJsonFile,
} from './readFile'
const stat = promisify(fs.stat)
export default async function readImporterManifest (importerDir: string): Promise<{
manifest: ImporterManifest
writeImporterManifest: (manifest: ImporterManifest) => Promise<void>
}> {
const result = await tryReadImporterManifest(importerDir)
if (result.manifest !== null) {
return result as {
manifest: ImporterManifest
writeImporterManifest: (manifest: ImporterManifest) => Promise<void>
}
}
const err = new Error(`No package.json (or package.yaml, or package.json5) was found in "${importerDir}".`)
err['code'] = 'ERR_PNPM_NO_IMPORTER_MANIFEST_FOUND'
throw err
}
export async function readImporterManifestOnly (importerDir: string): Promise<ImporterManifest> {
const { manifest } = await readImporterManifest(importerDir)
return manifest
}
export async function tryReadImporterManifest (importerDir: string): Promise<{
manifest: ImporterManifest | null
writeImporterManifest: (manifest: ImporterManifest) => Promise<void>
}> {
try {
const manifestPath = path.join(importerDir, 'package.json')
const { data, text } = await readJsonFile(manifestPath)
const { indent } = detectIndent(text)
return {
manifest: data,
writeImporterManifest: createManifestWriter({
indent,
initialManifest: data,
manifestPath,
}),
}
} catch (err) {
if (err.code !== 'ENOENT') throw err
}
try {
const manifestPath = path.join(importerDir, 'package.json5')
const { data, text } = await readJson5File(manifestPath)
const { indent } = detectIndent(text)
return {
manifest: data,
writeImporterManifest: createManifestWriter({
indent,
initialManifest: data,
manifestPath,
}),
}
} catch (err) {
if (err.code !== 'ENOENT') throw err
}
try {
const manifestPath = path.join(importerDir, 'package.yaml')
const manifest = await readPackageYaml(manifestPath)
return {
manifest,
writeImporterManifest: createManifestWriter({ initialManifest: manifest, manifestPath }),
}
} catch (err) {
if (err.code !== 'ENOENT') throw err
}
if (isWindows()) {
// ENOTDIR isn't used on Windows, but pnpm expects it.
let s: Stats | undefined
try {
s = await stat(importerDir)
} catch (err) {
// Ignore
}
if (s && !s.isDirectory()) {
const err = new Error(`"${importerDir}" is not a directory`)
err['code'] = 'ENOTDIR' // tslint:disable-line
throw err
}
}
const filePath = path.join(importerDir, 'package.json')
return {
manifest: null,
writeImporterManifest: writeImporterManifest.bind(null, filePath),
}
}
export async function readExactImporterManifest (manifestPath: string) {
const base = path.basename(manifestPath).toLowerCase()
switch (base) {
case 'package.json': {
const { data, text } = await readJsonFile(manifestPath)
const { indent } = detectIndent(text)
return {
manifest: data,
writeImporterManifest: createManifestWriter({
indent,
initialManifest: data,
manifestPath,
}),
}
}
case 'package.json5': {
const { data, text } = await readJson5File(manifestPath)
const { indent } = detectIndent(text)
return {
manifest: data,
writeImporterManifest: createManifestWriter({
indent,
initialManifest: data,
manifestPath,
}),
}
}
case 'package.yaml': {
const manifest = await readPackageYaml(manifestPath)
return {
manifest,
writeImporterManifest: createManifestWriter({ initialManifest: manifest, manifestPath }),
}
}
}
throw new Error(`Not supported manifest name "${base}"`)
}
function readPackageYaml (filePath: string) {
return readYamlFile<ImporterManifest>(filePath)
}
function createManifestWriter (
opts: {
initialManifest: ImporterManifest,
indent?: string | number | null | undefined,
manifestPath: string,
},
): ((manifest: ImporterManifest) => Promise<void>) {
const stringifiedInitialManifest = JSON.stringify(opts.initialManifest)
return async (updatedManifest: ImporterManifest) => {
if (stringifiedInitialManifest !== JSON.stringify(updatedManifest)) {
return writeImporterManifest(opts.manifestPath, updatedManifest, { indent: opts.indent })
}
}
}

View File

@@ -0,0 +1,26 @@
import { ImporterManifest } from '@pnpm/types'
import fs = require('graceful-fs')
import JSON5 = require('json5')
import stripBom = require('strip-bom')
import { promisify } from 'util'
const readFile = promisify(fs.readFile)
export async function readJson5File (filePath: string) {
const text = await readFileWithoutBom(filePath)
return {
data: JSON5.parse(text) as ImporterManifest,
text,
}
}
export async function readJsonFile (filePath: string) {
const text = await readFileWithoutBom(filePath)
return {
data: JSON.parse(text) as ImporterManifest,
text,
}
}
async function readFileWithoutBom (path: string) {
return stripBom(await readFile(path, 'utf8'))
}

View File

@@ -0,0 +1,4 @@
{
"name": "foo",
"version": "1.0.0"
}

View File

@@ -0,0 +1,4 @@
{
name: 'foo',
version: '1.0.0',
}

View File

@@ -0,0 +1,2 @@
name: foo
version: 1.0.0

View File

@@ -0,0 +1,110 @@
import readImporterManifest, { tryReadImporterManifest } from '@pnpm/read-importer-manifest'
import fs = require('graceful-fs')
import path = require('path')
import test = require('tape')
import tempy = require('tempy')
import { promisify } from 'util'
const writeFile = promisify(fs.writeFile)
const readFile = promisify(fs.readFile)
const stat = promisify(fs.stat)
const fixtures = path.join(__dirname, 'fixtures')
test('readImporterManifest()', async (t) => {
t.deepEqual(
(await tryReadImporterManifest(path.join(fixtures, 'package-json'))).manifest,
{ name: 'foo', version: '1.0.0' },
)
t.deepEqual(
(await tryReadImporterManifest(path.join(fixtures, 'package-json5'))).manifest,
{ name: 'foo', version: '1.0.0' },
)
t.deepEqual(
(await tryReadImporterManifest(path.join(fixtures, 'package-yaml'))).manifest,
{ name: 'foo', version: '1.0.0' },
)
t.deepEqual(
(await tryReadImporterManifest(fixtures)).manifest,
null,
)
t.end()
})
test('preserve tab indentation in json file', async (t) => {
process.chdir(tempy.directory())
await writeFile('package.json', '{\n\t"name": "foo"\n}\n', 'utf8')
const { manifest, writeImporterManifest } = await readImporterManifest(process.cwd())
await writeImporterManifest({ ...manifest, dependencies: { bar: '1.0.0' } })
const rawManifest = await readFile('package.json', 'utf8')
t.equal(rawManifest, '{\n\t"name": "foo",\n\t"dependencies": {\n\t\t"bar": "1.0.0"\n\t}\n}\n')
t.end()
})
test('preserve space indentation in json file', async (t) => {
process.chdir(tempy.directory())
await writeFile('package.json', '{\n "name": "foo"\n}\n', 'utf8')
const { manifest, writeImporterManifest } = await readImporterManifest(process.cwd())
await writeImporterManifest({ ...manifest, dependencies: { bar: '1.0.0' } })
const rawManifest = await readFile('package.json', 'utf8')
t.equal(rawManifest, '{\n "name": "foo",\n "dependencies": {\n "bar": "1.0.0"\n }\n}\n')
t.end()
})
test('preserve tab indentation in json5 file', async (t) => {
process.chdir(tempy.directory())
await writeFile('package.json5', "{\n\tname: 'foo',\n}\n", 'utf8')
const { manifest, writeImporterManifest } = await readImporterManifest(process.cwd())
await writeImporterManifest({ ...manifest, dependencies: { bar: '1.0.0' } })
const rawManifest = await readFile('package.json5', 'utf8')
t.equal(rawManifest, "{\n\tname: 'foo',\n\tdependencies: {\n\t\tbar: '1.0.0',\n\t},\n}\n")
t.end()
})
test('preserve space indentation in json5 file', async (t) => {
process.chdir(tempy.directory())
await writeFile('package.json5', "{\n name: 'foo'\n}\n", 'utf8')
const { manifest, writeImporterManifest } = await readImporterManifest(process.cwd())
await writeImporterManifest({ ...manifest, dependencies: { bar: '1.0.0' } })
const rawManifest = await readFile('package.json5', 'utf8')
t.equal(rawManifest, "{\n name: 'foo',\n dependencies: {\n bar: '1.0.0',\n },\n}\n")
t.end()
})
test('do not save manifest if it had no changes', async (t) => {
process.chdir(tempy.directory())
await writeFile('package.json5', JSON.stringify({ dependencies: { foo: '*', bar: '*' } }), 'utf8')
const { manifest, writeImporterManifest } = await readImporterManifest(process.cwd())
const stat1 = await stat('package.json5')
await writeImporterManifest(manifest)
const stat2 = await stat('package.json5')
t.deepEqual(stat1.ino, stat2.ino, 'manifest was not resaved')
t.end()
})

View File

@@ -0,0 +1,11 @@
{
"extends": "../../utils/tsconfig.json",
"compilerOptions": {
"outDir": "lib"
},
"include": [
"src/**/*.ts",
"typings/**/*.d.ts",
"test/typings/**/*.d.ts"
]
}

View File

@@ -0,0 +1,3 @@
{
"extends": "@pnpm/tslint-config"
}

View File

@@ -35,6 +35,7 @@
"@pnpm/package-requester": "7.0.6",
"@pnpm/pkgid-to-filename": "2.0.0",
"@pnpm/prune-lockfile": "1.0.4",
"@pnpm/read-importer-manifest": "0.0.0",
"@pnpm/read-importers-context": "1.0.1",
"@pnpm/read-modules-dir": "2.0.0",
"@pnpm/read-package-json": "2.0.1",

View File

@@ -11,6 +11,7 @@ import {
import logger, { streamParser } from '@pnpm/logger'
import { prune } from '@pnpm/modules-cleaner'
import { pruneSharedLockfile } from '@pnpm/prune-lockfile'
import readImporterManifest from '@pnpm/read-importer-manifest'
import { symlinkDirectRootDependency } from '@pnpm/symlink-dependency'
import {
DEPENDENCIES_FIELDS,
@@ -21,7 +22,6 @@ import {
import {
getSaveType,
} from '@pnpm/utils'
import loadJsonFile = require('load-json-file')
import normalize = require('normalize-path')
import path = require('path')
import pathAbsolute = require('path-absolute')
@@ -66,18 +66,18 @@ export default async function link (
linkFromPath = linkFrom.path
linkFromAlias = linkFrom.alias
}
const linkedPkg = await loadJsonFile<DependencyManifest>(path.join(linkFromPath, 'package.json'))
const { manifest } = await readImporterManifest(linkFromPath) as { manifest: DependencyManifest }
specsToUpsert.push({
name: linkedPkg.name,
pref: getPref(linkedPkg.name, linkedPkg.name, linkedPkg.version, {
name: manifest.name,
pref: getPref(manifest.name, manifest.name, manifest.version, {
pinnedVersion: opts.pinnedVersion,
}),
saveType: (saveType || ctx.manifest && guessDependencyType(linkedPkg.name, ctx.manifest)) as DependenciesField,
saveType: (saveType || ctx.manifest && guessDependencyType(manifest.name, ctx.manifest)) as DependenciesField,
})
const packagePath = normalize(path.relative(opts.prefix, linkFromPath))
const addLinkOpts = {
linkedPkgName: linkFromAlias || linkedPkg.name,
linkedPkgName: linkFromAlias || manifest.name,
manifest: ctx.manifest,
packagePath,
}
@@ -85,8 +85,8 @@ export default async function link (
addLinkToLockfile(ctx.wantedLockfile.importers[importerId], addLinkOpts)
linkedPkgs.push({
alias: linkFromAlias || linkedPkg.name,
manifest: linkedPkg,
alias: linkFromAlias || manifest.name,
manifest,
path: linkFromPath,
})
}

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2018-2019 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.

View File

@@ -0,0 +1,26 @@
# @pnpm/write-importer-manifest
> Write an importer manifest (called package.json in most cases)
<!--@shields('npm')-->
[![npm version](https://img.shields.io/npm/v/@pnpm/write-importer-manifest.svg)](https://www.npmjs.com/package/@pnpm/write-importer-manifest)
<!--/@-->
## Installation
```sh
<npm|yarn|pnpm> add @pnpm/write-importer-manifest
```
## Usage
```ts
import writeImporterManifest from '@pnpm/write-importer-manifest'
import path = require('path')
(async () => await writeImporterManifest(path.resolve('package.yaml'), { name: 'foo', version: '1.0.0' }))()
```
## License
[MIT](./LICENSE) © [Zoltan Kochan](https://www.kochan.io/)

View File

@@ -0,0 +1,64 @@
{
"name": "@pnpm/write-importer-manifest",
"version": "0.0.0",
"description": "Write an importer manifest (called package.json in most cases)",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
"engines": {
"node": ">=8.15"
},
"files": [
"lib"
],
"scripts": {
"lint": "tslint -c tslint.json src/**/*.ts test/**/*.ts",
"test": "npm run lint && npm run tsc && ts-node test --type-check",
"prepublishOnly": "tsc",
"tsc": "tsc",
"md": "mos"
},
"repository": "https://github.com/pnpm/pnpm/blob/master/packages/write-importer-manifest",
"keywords": [
"pnpm",
"outdated"
],
"author": {
"name": "Zoltan Kochan",
"email": "z@kochan.io",
"url": "https://www.kochan.io/",
"twitter": "ZoltanKochan"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/pnpm/pnpm/issues"
},
"homepage": "https://github.com/pnpm/pnpm/blob/master/packages/write-importer-manifest#readme",
"dependencies": {
"@pnpm/types": "^3.0.0",
"sort-keys": "2.0.0",
"write-json-file": "3.2.0",
"write-json5-file": "2.0.0",
"write-yaml-file": "2.0.0"
},
"devDependencies": {
"@pnpm/tslint-config": "0.0.0",
"@pnpm/write-importer-manifest": "link:",
"@types/node": "^10.3.2",
"@types/tape": "^4.2.31",
"mos": "^2.0.0-alpha.3",
"mos-plugin-readme": "^1.0.4",
"tape": "^4.8.0",
"tempy": "0.3.0",
"ts-node": "8.1.0",
"tslint": "^5.8.0",
"typescript": "3.4.5"
},
"mos": {
"plugins": [
"readme"
],
"installation": {
"useShortAlias": true
}
}
}

View File

@@ -0,0 +1,44 @@
import { ImporterManifest } from '@pnpm/types'
import sortKeys = require('sort-keys')
import writeJsonFile = require('write-json-file')
import writeJson5File = require('write-json5-file')
import writeYamlFile = require('write-yaml-file')
// TODO: normalize before save + preserve indent
export default function writeImporterManifest (
filePath: string,
manifest: ImporterManifest,
opts?: { indent?: string | number | null },
): Promise<void> {
manifest = normalize(manifest)
switch (filePath.substr(filePath.lastIndexOf('.') + 1).toLowerCase()) {
case 'json5':
return writeJson5File(filePath, manifest, opts)
case 'yaml':
return writeYamlFile(filePath, manifest)
case 'json':
default:
return writeJsonFile(filePath, manifest, opts)
}
}
const dependencyKeys = new Set([
'dependencies',
'devDependencies',
'optionalDependencies',
'peerDependencies',
])
function normalize (manifest: ImporterManifest) {
const result = {}
for (const key of Object.keys(manifest)) {
if (!dependencyKeys.has(key)) {
result[key] = manifest[key]
} else if (Object.keys(manifest[key]).length !== 0) {
result[key] = sortKeys(manifest[key])
}
}
return result
}

View File

@@ -0,0 +1,23 @@
import writeImporterManifest from '@pnpm/write-importer-manifest'
import fs = require('fs')
import path = require('path')
import test = require('tape')
import tempy = require('tempy')
import { promisify } from 'util'
const readFile = promisify(fs.readFile)
test('writeImporterManifest()', async (t) => {
const dir = tempy.directory()
await writeImporterManifest(path.join(dir, 'package.json'), { name: 'foo', version: '1.0.0' })
t.equal(await readFile(path.join(dir, 'package.json'), 'utf8'), '{\n\t"name": "foo",\n\t"version": "1.0.0"\n}\n')
await writeImporterManifest(path.join(dir, 'package.json5'), { name: 'foo', version: '1.0.0' })
t.equal(await readFile(path.join(dir, 'package.json5'), 'utf8'), "{\n\tname: 'foo',\n\tversion: '1.0.0',\n}\n")
await writeImporterManifest(path.join(dir, 'package.yaml'), { name: 'foo', version: '1.0.0' })
t.equal(await readFile(path.join(dir, 'package.yaml'), 'utf8'), 'name: foo\nversion: 1.0.0\n')
t.end()
})

View File

@@ -0,0 +1,11 @@
{
"extends": "../../utils/tsconfig.json",
"compilerOptions": {
"outDir": "lib"
},
"include": [
"src/**/*.ts",
"typings/**/*.d.ts",
"test/typings/**/*.d.ts"
]
}

View File

@@ -0,0 +1,3 @@
{
"extends": "@pnpm/tslint-config"
}

View File

@@ -0,0 +1,4 @@
declare module 'sort-keys' {
const anything: any;
export = anything;
}

239
pnpm-lock.yaml generated
View File

@@ -461,6 +461,36 @@ importers:
typescript: 3.4.5
write-yaml-file: 2.0.0
yaml-tag: 1.1.0
packages/find-packages:
dependencies:
'@pnpm/read-importer-manifest': 'link:../read-importer-manifest'
'@types/node': 10.14.6
fast-glob: 2.2.6
p-filter: 2.1.0
devDependencies:
'@pnpm/tslint-config': 'link:../../utils/tslint-config'
'@types/tape': 4.2.33
find-packages: 'link:'
mos: 2.0.0-alpha.3
mos-plugin-readme: 1.0.4
tape: 4.10.1
ts-node: 8.1.0_typescript@3.4.5
tslint: 5.16.0_typescript@3.4.5
typescript: 3.4.5
specifiers:
'@pnpm/read-importer-manifest': 0.0.0
'@pnpm/tslint-config': 0.0.0
'@types/node': ^10.12.18
'@types/tape': ^4.2.29
fast-glob: ^2.0.4
find-packages: 'link:'
mos: ^2.0.0-alpha.3
mos-plugin-readme: ^1.0.4
p-filter: ^2.0.0
tape: ^4.6.3
ts-node: ^8.0.1
tslint: ^5.0.0
typescript: ^3.0.0
packages/git-fetcher:
dependencies:
'@types/node': 11.13.8
@@ -695,6 +725,7 @@ importers:
typescript: 3.4.5
packages/list:
dependencies:
'@pnpm/read-importer-manifest': 'link:../read-importer-manifest'
'@pnpm/read-package-json': 'link:../read-package-json'
'@pnpm/types': 'link:../types'
'@types/archy': 0.0.31
@@ -722,6 +753,7 @@ importers:
specifiers:
'@pnpm/list': 'link:'
'@pnpm/logger': 2.1.0
'@pnpm/read-importer-manifest': 0.0.0
'@pnpm/read-package-json': 2.0.1
'@pnpm/tslint-config': 0.0.0
'@pnpm/types': 3.2.0
@@ -745,7 +777,7 @@ importers:
typescript: 3.4.5
packages/local-resolver:
dependencies:
'@pnpm/read-package-json': 'link:../read-package-json'
'@pnpm/read-importer-manifest': 'link:../read-importer-manifest'
'@pnpm/resolver-base': 'link:../resolver-base'
'@pnpm/types': 'link:../types'
'@types/graceful-fs': 4.1.3
@@ -765,7 +797,7 @@ importers:
typescript: 3.4.5
specifiers:
'@pnpm/local-resolver': 'link:'
'@pnpm/read-package-json': 2.0.1
'@pnpm/read-importer-manifest': 0.0.0
'@pnpm/resolver-base': 3.1.2
'@pnpm/tslint-config': 0.0.0
'@pnpm/types': 3.2.0
@@ -1024,7 +1056,7 @@ importers:
'@pnpm/logger': 2.1.0
'@pnpm/npm-resolver': 'link:'
'@pnpm/tslint-config': 'link:../../utils/tslint-config'
'@types/nock': 10.0.0
'@types/nock': 10.0.1
'@types/normalize-path': 3.0.0
'@types/path-exists': 3.0.0
'@types/ssri': 6.0.1
@@ -1079,7 +1111,7 @@ importers:
'@pnpm/constants': 'link:../constants'
'@pnpm/lockfile-file': 'link:../lockfile-file'
'@pnpm/npm-resolver': 'link:../npm-resolver'
'@pnpm/read-package-json': 'link:../read-package-json'
'@pnpm/read-importer-manifest': 'link:../read-importer-manifest'
'@pnpm/store-path': 1.0.4
'@pnpm/types': 'link:../types'
'@pnpm/utils': 'link:../utils'
@@ -1104,7 +1136,7 @@ importers:
'@pnpm/logger': 2.1.0
'@pnpm/npm-resolver': 3.0.7
'@pnpm/outdated': 'link:'
'@pnpm/read-package-json': 2.0.1
'@pnpm/read-importer-manifest': 0.0.0
'@pnpm/store-path': 1.0.4
'@pnpm/tslint-config': 0.0.0
'@pnpm/types': 3.2.0
@@ -1318,6 +1350,38 @@ importers:
tslint: 5.16.0
typescript: 3.4.5
write-json-file: 3.2.0
packages/pkgs-graph:
dependencies:
'@types/node': 11.13.8
'@types/ramda': 0.26.8
'@types/semver': 5.5.0
'@zkochan/npm-package-arg': 1.0.2
ramda: 0.26.1
semver: 6.0.0
devDependencies:
'@pnpm/tslint-config': 'link:../../utils/tslint-config'
'@types/tape': 4.2.33
better-path-resolve: 1.0.0
pkgs-graph: 'link:'
tape: 4.10.1
ts-node: 8.1.0_typescript@3.4.5
tslint: 5.16.0_typescript@3.4.5
typescript: 3.4.5
specifiers:
'@pnpm/tslint-config': 0.0.0
'@types/node': '*'
'@types/ramda': ^0.26.0
'@types/semver': ^5.3.31
'@types/tape': ^4.2.29
'@zkochan/npm-package-arg': ^1.0.0
better-path-resolve: 1.0.0
pkgs-graph: 'link:'
ramda: ^0.26.0
semver: ^6.0.0
tape: ^4.6.3
ts-node: ^8.0.3
tslint: 5.16.0
typescript: ^3.0.0
packages/pnpm:
dependencies:
'@pnpm/config': 'link:../config'
@@ -1331,6 +1395,7 @@ importers:
'@pnpm/logger': 2.1.0
'@pnpm/outdated': 'link:../outdated'
'@pnpm/package-store': 'link:../package-store'
'@pnpm/read-importer-manifest': 'link:../read-importer-manifest'
'@pnpm/server': 'link:../server'
'@pnpm/store-controller-types': 'link:../store-controller-types'
'@pnpm/store-path': 1.0.4
@@ -1351,7 +1416,7 @@ importers:
diable: 4.0.2
dir-is-case-sensitive: 1.0.0
execa: 1.0.0
find-packages: 4.0.1
find-packages: 'link:../find-packages'
get-port: 5.0.0
graceful-fs: 4.1.15
graph-sequencer: 2.0.0
@@ -1370,7 +1435,7 @@ importers:
p-limit: 2.2.0
path-absolute: 1.0.1
path-name: 1.0.0
pkgs-graph: 3.0.0
pkgs-graph: 'link:../pkgs-graph'
pnpm-file-reporter: 0.1.0
process-exists: 3.1.0
ramda: 0.26.1
@@ -1390,6 +1455,7 @@ importers:
'@pnpm/prepare': 'link:../../privatePackages/prepare'
'@pnpm/read-package-json': 'link:../read-package-json'
'@pnpm/tslint-config': 'link:../../utils/tslint-config'
'@pnpm/write-importer-manifest': 'link:../write-importer-manifest'
'@types/byline': 4.2.31
'@types/common-tags': 1.8.0
'@types/mkdirp': 0.5.2
@@ -1442,6 +1508,7 @@ importers:
'@pnpm/outdated': 2.0.8
'@pnpm/package-store': 4.0.6
'@pnpm/prepare': 0.0.0
'@pnpm/read-importer-manifest': 0.0.0
'@pnpm/read-package-json': 2.0.1
'@pnpm/server': 3.0.3
'@pnpm/store-controller-types': 3.0.3
@@ -1449,6 +1516,7 @@ importers:
'@pnpm/tslint-config': 0.0.0
'@pnpm/types': 3.2.0
'@pnpm/utils': 0.10.4
'@pnpm/write-importer-manifest': 0.0.0
'@types/archy': 0.0.31
'@types/byline': 4.2.31
'@types/common-tags': 1.8.0
@@ -1566,6 +1634,56 @@ importers:
tslint: 5.16.0
typescript: 3.4.5
yaml-tag: 1.1.0
packages/read-importer-manifest:
dependencies:
'@pnpm/types': 'link:../types'
'@pnpm/write-importer-manifest': 'link:../write-importer-manifest'
'@types/detect-indent': 5.0.0
detect-indent: 5.0.0
graceful-fs: 4.1.15
is-windows: 1.0.2
json5: 2.1.0
read-yaml-file: 1.1.0
strip-bom: 4.0.0
devDependencies:
'@pnpm/read-importer-manifest': 'link:'
'@pnpm/tslint-config': 'link:../../utils/tslint-config'
'@types/graceful-fs': 4.1.3
'@types/is-windows': 0.2.0
'@types/json5': 0.0.30
'@types/node': 10.14.6
'@types/tape': 4.2.33
mos: 2.0.0-alpha.3
mos-plugin-readme: 1.0.4
tape: 4.10.1
tempy: 0.3.0
ts-node: 8.1.0_typescript@3.4.5
tslint: 5.16.0_typescript@3.4.5
typescript: 3.4.5
specifiers:
'@pnpm/read-importer-manifest': 'link:'
'@pnpm/tslint-config': 0.0.0
'@pnpm/types': ^3.0.0
'@pnpm/write-importer-manifest': 0.0.0
'@types/detect-indent': 5.0.0
'@types/graceful-fs': 4.1.3
'@types/is-windows': 0.2.0
'@types/json5': 0.0.30
'@types/node': ^10.3.2
'@types/tape': ^4.2.31
detect-indent: 5.0.0
graceful-fs: 4.1.15
is-windows: 1.0.2
json5: 2.1.0
mos: ^2.0.0-alpha.3
mos-plugin-readme: ^1.0.4
read-yaml-file: 1.1.0
strip-bom: 4.0.0
tape: ^4.8.0
tempy: 0.3.0
ts-node: 8.1.0
tslint: ^5.8.0
typescript: 3.4.5
packages/read-importers-context:
dependencies:
'@pnpm/lockfile-file': 'link:../lockfile-file'
@@ -1836,6 +1954,7 @@ importers:
'@pnpm/package-requester': 'link:../package-requester'
'@pnpm/pkgid-to-filename': 2.0.0
'@pnpm/prune-lockfile': 'link:../prune-lockfile'
'@pnpm/read-importer-manifest': 'link:../read-importer-manifest'
'@pnpm/read-importers-context': 'link:../read-importers-context'
'@pnpm/read-modules-dir': 'link:../read-modules-dir'
'@pnpm/read-package-json': 'link:../read-package-json'
@@ -1944,6 +2063,7 @@ importers:
'@pnpm/pkgid-to-filename': 2.0.0
'@pnpm/prepare': 0.0.0
'@pnpm/prune-lockfile': 1.0.4
'@pnpm/read-importer-manifest': 0.0.0
'@pnpm/read-importers-context': 1.0.1
'@pnpm/read-modules-dir': 2.0.0
'@pnpm/read-package-json': 2.0.1
@@ -2179,6 +2299,42 @@ importers:
rimraf: 2.6.3
tslint: 5.16.0
typescript: 3.4.5
packages/write-importer-manifest:
dependencies:
'@pnpm/types': 'link:../types'
sort-keys: 2.0.0
write-json-file: 3.2.0
write-json5-file: 2.0.0
write-yaml-file: 2.0.0
devDependencies:
'@pnpm/tslint-config': 'link:../../utils/tslint-config'
'@pnpm/write-importer-manifest': 'link:'
'@types/node': 10.14.6
'@types/tape': 4.2.33
mos: 2.0.0-alpha.3
mos-plugin-readme: 1.0.4
tape: 4.10.1
tempy: 0.3.0
ts-node: 8.1.0_typescript@3.4.5
tslint: 5.16.0_typescript@3.4.5
typescript: 3.4.5
specifiers:
'@pnpm/tslint-config': 0.0.0
'@pnpm/types': ^3.0.0
'@pnpm/write-importer-manifest': 'link:'
'@types/node': ^10.3.2
'@types/tape': ^4.2.31
mos: ^2.0.0-alpha.3
mos-plugin-readme: ^1.0.4
sort-keys: 2.0.0
tape: ^4.8.0
tempy: 0.3.0
ts-node: 8.1.0
tslint: ^5.8.0
typescript: 3.4.5
write-json-file: 3.2.0
write-json5-file: 2.0.0
write-yaml-file: 2.0.0
privatePackages/assert-project:
dependencies:
'@pnpm/assert-store': 'link:../assert-store'
@@ -2543,7 +2699,7 @@ packages:
'@pnpm/types': 3.2.0
'@types/mz': 0.0.32
'@types/node': 11.13.8
'@types/ramda': 0.26.8
'@types/ramda': 0.26.6
'@zkochan/cmd-shim': 3.1.0
arr-flatten: 1.1.0
is-subdir: 1.0.3
@@ -2654,6 +2810,10 @@ packages:
/@types/common-tags/1.8.0:
resolution:
integrity: sha512-htRqZr5qn8EzMelhX/Xmx142z218lLyGaeZ3YR8jlze4TATRU9huKKvuBmAJEW4LCC4pnY1N6JAm6p85fMHjhg==
/@types/detect-indent/5.0.0:
dev: false
resolution:
integrity: sha512-eOFBOFCqusnH0i1s9XoURksqTZbsv5vbMMgOBKgSt67TsOw6ViaHO0Ii5DMhRoiU5TJ51uf9NsOpnxXsN96ywg==
/@types/events/3.0.0:
resolution:
integrity: sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==
@@ -2672,7 +2832,7 @@ packages:
integrity: sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==
/@types/graceful-fs/4.1.3:
dependencies:
'@types/node': 11.13.8
'@types/node': 10.14.6
resolution:
integrity: sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ==
/@types/http-proxy-agent/2.0.1:
@@ -2689,6 +2849,10 @@ packages:
dev: false
resolution:
integrity: sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==
/@types/json5/0.0.30:
dev: true
resolution:
integrity: sha512-sqm9g7mHlPY/43fcSNrCYfOeX9zkTTK+euO5E6+CVijSMm5tTjkVdwdqRkY3ljjIAf8679vps5jKUoJBCLsMDA==
/@types/lru-cache/5.1.0:
dev: false
resolution:
@@ -2718,6 +2882,12 @@ packages:
dev: true
resolution:
integrity: sha512-DJM4sOEUeGzqjDkMtCubuN8zQ9gUxzPC+WVMzK2X4q6Kc5pnRFWcm8gkk4JNsDs7Zs6jjVf+dNYbNOii8fzPLA==
/@types/nock/10.0.1:
dependencies:
'@types/node': 11.13.8
dev: true
resolution:
integrity: sha512-3Dbkj/f0HxuvyYfInbQCHLASFyjnNUcidabwrbhJDMZOXXznNyQpzsBgZnY2K+c43OekqWvZ+tDjGsGTKm1d5g==
/@types/node-fetch/2.3.3:
dependencies:
'@types/node': 11.13.8
@@ -5051,17 +5221,6 @@ packages:
node: '>= 0.8'
resolution:
integrity: sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==
/find-packages/4.0.1:
dependencies:
'@pnpm/read-package-json': 2.0.1
'@types/node': 10.14.6
fast-glob: 2.2.6
p-filter: 2.1.0
dev: false
engines:
node: '>=8'
resolution:
integrity: sha512-1qtGZL3BATaXYhYvH80CDgdy+5vVXLFGXMvJsJq00/E+/sIYd6BM/2V+hOq2VyR8Fe02k/v3pdl32TuLgyvSFg==
/find-up/1.1.2:
dependencies:
path-exists: 2.1.0
@@ -6262,6 +6421,15 @@ packages:
hasBin: true
resolution:
integrity: sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=
/json5/2.1.0:
dependencies:
minimist: 1.2.0
dev: false
engines:
node: '>=6'
hasBin: true
resolution:
integrity: sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==
/jsondiffpatch/0.1.43:
bundledDependencies: []
dependencies:
@@ -7932,19 +8100,6 @@ packages:
node: '>= 0.4.0'
resolution:
integrity: sha1-tUGO8EOd5UJfxJlQQtztFPsqhP8=
/pkgs-graph/3.0.0:
dependencies:
'@types/node': 11.13.8
'@types/ramda': 0.26.8
'@types/semver': 5.5.0
'@zkochan/npm-package-arg': 1.0.2
ramda: 0.26.1
semver: 6.0.0
dev: false
engines:
node: '>=8'
resolution:
integrity: sha512-GHjcGMs15Q3FtX9/aggZZuntrJpxSRXMYJNLsIveoaAZDGU89y7MBdaJr8PL9Qut71najIIzkfUHGmQZkWRWLA==
/please-upgrade-node/3.1.1:
dependencies:
semver-compare: 1.0.0
@@ -9222,6 +9377,12 @@ packages:
node: '>=4'
resolution:
integrity: sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=
/strip-bom/4.0.0:
dev: false
engines:
node: '>=8'
resolution:
integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==
/strip-color/0.1.0:
dev: false
engines:
@@ -10112,6 +10273,18 @@ packages:
node: '>=6'
resolution:
integrity: sha512-3xZqT7Byc2uORAatYiP3DHUUAVEkNOswEWNs9H5KXiicRTvzYzYqKjYc4G7p+8pltvAw641lVByKVtMpf+4sYQ==
/write-json5-file/2.0.0:
dependencies:
graceful-fs: 4.1.15
json5: 2.1.0
mkdirp: 0.5.1
sort-keys: 2.0.0
write-file-atomic: 2.4.2
dev: false
engines:
node: '>=8.15'
resolution:
integrity: sha512-/HE7Pf9lu94TWA8lAweK57xeNARpclDRNqOFeMfZto8VipnCB8IHnFF72aJocpjFsBRcVOgOe4KcrRyawAQ07A==
/write-pkg/1.0.0:
dependencies:
write-json-file: 1.2.0