feat: deploy command (#4933)

close #4378
This commit is contained in:
Zoltan Kochan
2022-06-27 19:58:29 +03:00
committed by GitHub
parent 148a104da8
commit 7922d63145
43 changed files with 598 additions and 61 deletions

View File

@@ -0,0 +1,12 @@
---
"@pnpm/plugin-commands-deploy": major
"pnpm": minor
---
A new experimental command added: `pnpm deploy`. The deploy command takes copies a project from a workspace and installs all of its production dependencies (even if some of those dependencies are other projects from the workspace).
For example, the new command will deploy the project named `foo` to the `dist` directory in the root of the workspace:
```
pnpm --filter=foo deploy dist
```

View File

@@ -0,0 +1,6 @@
---
"@pnpm/core": patch
"pnpm": patch
---
Don't link local dev dependencies, when prod dependencies should only be installed.

View File

@@ -0,0 +1,5 @@
---
"@pnpm/fs.indexed-pkg-importer": major
---
Initial release.

View File

@@ -137,6 +137,7 @@ async function updateManifest (workspaceDir: string, manifest: ProjectManifest,
case '@pnpm/plugin-commands-rebuild':
case '@pnpm/plugin-commands-script-runners':
case '@pnpm/plugin-commands-store':
case '@pnpm/plugin-commands-deploy':
case CLI_PKG_NAME:
case '@pnpm/core': {
// @pnpm/core tests currently works only with port 4873 due to the usage of

View File

@@ -812,6 +812,33 @@ const _installInContext: InstallFunction = async (projects, ctx, opts) => {
patchedDependencies: opts.patchedDependencies,
}
)
if (!opts.include.optionalDependencies || !opts.include.devDependencies || !opts.include.dependencies) {
for (const projectId of Object.keys(linkedDependenciesByProjectId ?? {})) {
linkedDependenciesByProjectId[projectId] = linkedDependenciesByProjectId[projectId].filter((linkedDep) =>
!(
linkedDep.dev && !opts.include.devDependencies ||
linkedDep.optional && !opts.include.optionalDependencies ||
!linkedDep.dev && !linkedDep.optional && !opts.include.dependencies
)
)
}
for (const { id, manifest } of projects) {
dependenciesByProjectId[id] = fromPairs(
Object.entries(dependenciesByProjectId[id])
.filter(([, depPath]) => {
const dep = dependenciesGraph[depPath]
if (!dep) return false
const isDev = Boolean(manifest.devDependencies?.[dep.name])
const isOptional = Boolean(manifest.optionalDependencies?.[dep.name])
return !(
isDev && !opts.include.devDependencies ||
isOptional && !opts.include.optionalDependencies ||
!isDev && !isOptional && !opts.include.dependencies
)
})
)
}
}
stageLogger.debug({
prefix: ctx.lockfileDir,

View File

@@ -165,17 +165,12 @@ export default async function linkPackages (
.map(([rootAlias, depPath]) => ({ rootAlias, depGraphNode: depGraph[depPath] }))
.filter(({ depGraphNode }) => depGraphNode)
.map(async ({ rootAlias, depGraphNode }) => {
const isDev = Boolean(manifest.devDependencies?.[depGraphNode.name])
const isOptional = Boolean(manifest.optionalDependencies?.[depGraphNode.name])
if (
isDev && !opts.include.devDependencies ||
isOptional && !opts.include.optionalDependencies ||
!isDev && !isOptional && !opts.include.dependencies
) return
if (
(await symlinkDependency(depGraphNode.dir, modulesDir, rootAlias)).reused
) return
const isDev = Boolean(manifest.devDependencies?.[depGraphNode.name])
const isOptional = Boolean(manifest.optionalDependencies?.[depGraphNode.name])
rootLogger.debug({
added: {
dependencyType: isDev && 'dev' || isOptional && 'optional' || 'prod',

View File

@@ -16,17 +16,11 @@
},
"dependencies": {
"@pnpm/cafs": "workspace:4.0.7",
"@pnpm/core-loggers": "workspace:7.0.5",
"@pnpm/fetcher-base": "workspace:13.0.1",
"@pnpm/fs.indexed-pkg-importer": "workspace:0.0.0",
"@pnpm/store-controller-types": "workspace:14.0.1",
"@zkochan/rimraf": "^2.1.2",
"make-empty-dir": "^2.0.0",
"mem": "^8.0.0",
"p-limit": "^3.1.0",
"path-exists": "^4.0.0",
"path-temp": "^2.0.0",
"rename-overwrite": "^4.0.2",
"sanitize-filename": "^1.6.3"
"path-temp": "^2.0.0"
},
"devDependencies": {
"@pnpm/create-cafs-store": "workspace:2.0.1",
@@ -55,10 +49,8 @@
"scripts": {
"start": "tsc --watch",
"fix": "tslint -c tslint.json src/**/*.ts test/**/*.ts --fix",
"lint": "eslint src/**/*.ts test/**/*.ts",
"pretest": "rimraf .tmp",
"_test": "pnpm pretest && jest",
"test": "pnpm run compile && pnpm run _test",
"lint": "eslint src/**/*.ts",
"test": "pnpm run compile",
"prepublishOnly": "pnpm run compile",
"compile": "tsc --build && pnpm run lint --fix"
},

View File

@@ -4,13 +4,13 @@ import createCafs, {
getFilePathByModeInCafs,
} from '@pnpm/cafs'
import { PackageFilesResponse } from '@pnpm/fetcher-base'
import { createIndexedPkgImporter } from '@pnpm/fs.indexed-pkg-importer'
import {
ImportPackageFunction,
PackageFileInfo,
} from '@pnpm/store-controller-types'
import memoize from 'mem'
import pathTemp from 'path-temp'
import createImportPackage from './createImportPackage'
function createPackageImporter (
opts: {
@@ -18,7 +18,7 @@ function createPackageImporter (
cafsDir: string
}
): ImportPackageFunction {
const cachedImporterCreator = memoize(createImportPackage)
const cachedImporterCreator = memoize(createIndexedPkgImporter)
const packageImportMethod = opts.packageImportMethod
const gfm = getFlatMap.bind(null, opts.cafsDir)
return async (to, opts) => {

View File

@@ -16,10 +16,10 @@
"path": "../cafs"
},
{
"path": "../core-loggers"
"path": "../fetcher-base"
},
{
"path": "../fetcher-base"
"path": "../fs.indexed-pkg-importer"
},
{
"path": "../store-controller-types"

View File

@@ -0,0 +1,13 @@
# @pnpm/create-cafs-store
> Replicates indexed directories using hard links, copies, or cloning
## Installation
```
pnpm add @pnpm/create-cafs-store
```
## License
[MIT](LICENSE)

View File

@@ -0,0 +1,3 @@
const config = require('../../jest.config.js');
module.exports = Object.assign({}, config, {});

View File

@@ -0,0 +1,65 @@
{
"name": "@pnpm/fs.indexed-pkg-importer",
"description": "Replicates indexed directories using hard links, copies, or cloning",
"version": "0.0.0",
"bugs": {
"url": "https://github.com/pnpm/pnpm/issues"
},
"main": "lib/index.js",
"types": "lib/index.d.ts",
"files": [
"lib",
"!*.map"
],
"peerDependencies": {
"@pnpm/logger": "^4.0.0"
},
"dependencies": {
"@pnpm/core-loggers": "workspace:7.0.5",
"@zkochan/rimraf": "^2.1.2",
"make-empty-dir": "^2.0.0",
"p-limit": "^3.1.0",
"path-exists": "^4.0.0",
"path-temp": "^2.0.0",
"rename-overwrite": "^4.0.2",
"sanitize-filename": "^1.6.3"
},
"devDependencies": {
"@pnpm/fs.indexed-pkg-importer": "workspace:0.0.0",
"@pnpm/logger": "^4.0.0",
"@pnpm/prepare": "workspace:*"
},
"directories": {
"test": "test"
},
"homepage": "https://github.com/pnpm/pnpm/blob/main/packages/fs.indexed-pkg-importer#readme",
"keywords": [
"pnpm7",
"store",
"storage",
"global store",
"maching store",
"central storage",
"cache",
"packages"
],
"license": "MIT",
"engines": {
"node": ">=14.6"
},
"repository": "https://github.com/pnpm/pnpm/blob/main/packages/fs.indexed-pkg-importer",
"scripts": {
"start": "tsc --watch",
"fix": "tslint -c tslint.json src/**/*.ts test/**/*.ts --fix",
"lint": "eslint src/**/*.ts test/**/*.ts",
"pretest": "rimraf .tmp",
"_test": "pnpm pretest && jest",
"test": "pnpm run compile && pnpm run _test",
"prepublishOnly": "pnpm run compile",
"compile": "tsc --build && pnpm run lint --fix"
},
"funding": "https://opencollective.com/pnpm",
"exports": {
".": "./lib/index.js"
}
}

View File

@@ -18,9 +18,9 @@ interface ImportOptions {
type ImportFunction = (to: string, opts: ImportOptions) => Promise<string | undefined>
export default (
export function createIndexedPkgImporter (
packageImportMethod?: 'auto' | 'hardlink' | 'copy' | 'clone' | 'clone-or-copy'
): ImportFunction => {
): ImportFunction {
const importPackage = createImportPackage(packageImportMethod)
return async (to, opts) => limitLinking(async () => importPackage(to, opts))
}

View File

@@ -19,10 +19,10 @@ baseLogger['globalWarn'] = globalWarn
jest.mock('@pnpm/logger', () => baseLogger)
// eslint-disable-next-line
import createImportPackage from '../lib/createImportPackage'
import { createIndexedPkgImporter } from '@pnpm/fs.indexed-pkg-importer'
test('packageImportMethod=auto: clone files by default', async () => {
const importPackage = createImportPackage('auto')
const importPackage = createIndexedPkgImporter('auto')
fsMock.promises.copyFile = jest.fn()
fsMock.promises.rename = jest.fn()
expect(await importPackage('project/package', {
@@ -46,7 +46,7 @@ test('packageImportMethod=auto: clone files by default', async () => {
})
test('packageImportMethod=auto: link files if cloning fails', async () => {
const importPackage = createImportPackage('auto')
const importPackage = createIndexedPkgImporter('auto')
fsMock.promises.copyFile = jest.fn(() => {
throw new Error('This file system does not support cloning')
})
@@ -80,7 +80,7 @@ test('packageImportMethod=auto: link files if cloning fails', async () => {
})
test('packageImportMethod=auto: link files if cloning fails and even hard linking fails but not with EXDEV error', async () => {
const importPackage = createImportPackage('auto')
const importPackage = createIndexedPkgImporter('auto')
fsMock.promises.copyFile = jest.fn(() => {
throw new Error('This file system does not support cloning')
})
@@ -105,7 +105,7 @@ test('packageImportMethod=auto: link files if cloning fails and even hard linkin
})
test('packageImportMethod=auto: chooses copying if cloning and hard linking is not possible', async () => {
const importPackage = createImportPackage('auto')
const importPackage = createIndexedPkgImporter('auto')
fsMock.promises.copyFile = jest.fn((src: string, dest: string, flags?: number) => {
if (flags === fsMock.constants.COPYFILE_FICLONE_FORCE) {
throw new Error('This file system does not support cloning')
@@ -127,7 +127,7 @@ test('packageImportMethod=auto: chooses copying if cloning and hard linking is n
})
test('packageImportMethod=hardlink: fall back to copying if hardlinking fails', async () => {
const importPackage = createImportPackage('hardlink')
const importPackage = createIndexedPkgImporter('hardlink')
fsMock.promises.link = jest.fn((src: string, dest: string) => {
if (dest.endsWith('license')) {
const err = new Error('')
@@ -153,7 +153,7 @@ test('packageImportMethod=hardlink: fall back to copying if hardlinking fails',
})
test('packageImportMethod=hardlink does not relink package from store if package.json is linked from the store', async () => {
const importPackage = createImportPackage('hardlink')
const importPackage = createIndexedPkgImporter('hardlink')
fsMock.promises.copyFile = jest.fn()
fsMock.promises.rename = jest.fn()
fsMock.promises.stat = jest.fn(() => ({ ino: 1 }))
@@ -169,7 +169,7 @@ test('packageImportMethod=hardlink does not relink package from store if package
test('packageImportMethod=hardlink relinks package from store if package.json is not linked from the store', async () => {
globalInfo.mockReset()
const importPackage = createImportPackage('hardlink')
const importPackage = createIndexedPkgImporter('hardlink')
fsMock.promises.copyFile = jest.fn()
fsMock.promises.rename = jest.fn()
let ino = 0
@@ -186,7 +186,7 @@ test('packageImportMethod=hardlink relinks package from store if package.json is
})
test('packageImportMethod=hardlink does not relink package from store if package.json is not present in the store', async () => {
const importPackage = createImportPackage('hardlink')
const importPackage = createIndexedPkgImporter('hardlink')
fsMock.promises.copyFile = jest.fn()
fsMock.promises.rename = jest.fn()
fsMock.promises.stat = jest.fn((file) => {
@@ -204,7 +204,7 @@ test('packageImportMethod=hardlink does not relink package from store if package
test('packageImportMethod=hardlink links packages when they are not found', async () => {
globalInfo.mockReset()
const importPackage = createImportPackage('hardlink')
const importPackage = createIndexedPkgImporter('hardlink')
fsMock.promises.copyFile = jest.fn()
fsMock.promises.rename = jest.fn()
fsMock.promises.stat = jest.fn((file) => {

View File

@@ -1,11 +1,11 @@
import { promises as fs } from 'fs'
import path from 'path'
import { prepareEmpty } from '@pnpm/prepare'
import createImportPackage from '../lib/createImportPackage'
import { createIndexedPkgImporter } from '@pnpm/fs.indexed-pkg-importer'
test('importing a package with invalid files', async () => {
prepareEmpty()
const importPackage = createImportPackage('copy')
const importPackage = createIndexedPkgImporter('copy')
const target = path.resolve('target')
await importPackage(target, {
filesMap: {

View File

@@ -0,0 +1,19 @@
{
"extends": "@pnpm/tsconfig",
"compilerOptions": {
"outDir": "lib",
"rootDir": "src"
},
"include": [
"src/**/*.ts",
"../../typings/**/*.d.ts"
],
"references": [
{
"path": "../../privatePackages/prepare"
},
{
"path": "../core-loggers"
}
]
}

View File

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

View File

@@ -55,7 +55,7 @@ export default async function (lockfileDir: string, projectDir: string) {
'install',
'--frozen-lockfile',
'--lockfile-dir=.',
'--lockfile-only',
'--fix-lockfile',
'--filter=.',
'--no-link-workspace-packages',
], {

View File

@@ -1,3 +1,4 @@
import fs from 'fs'
import path from 'path'
import { readWantedLockfile } from '@pnpm/lockfile-file'
import fixtures from '@pnpm/test-fixtures'
@@ -7,6 +8,7 @@ const f = fixtures(__dirname)
test('makeDedicatedLockfile()', async () => {
const tmp = f.prepare('fixture')
fs.writeFileSync('.npmrc', 'store-dir=store\ncache-dir=cache', 'utf8')
const projectDir = path.join(tmp, 'packages/is-negative')
await makeDedicatedLockfile(tmp, projectDir)

View File

@@ -0,0 +1,15 @@
# @pnpm/plugin-commands-deploy
> Commands for deploy
[![npm version](https://img.shields.io/npm/v/@pnpm/plugin-commands-deploy.svg)](https://www.npmjs.com/package/@pnpm/plugin-commands-deploy)
## deploy
```sh
pnpm add @pnpm/plugin-commands-deploy
```
## License
MIT

View File

@@ -0,0 +1 @@
module.exports = require('../../jest.config.js')

View File

@@ -0,0 +1,60 @@
{
"name": "@pnpm/plugin-commands-deploy",
"version": "0.0.0",
"description": "Commands for deploy",
"funding": "https://opencollective.com/pnpm",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"files": [
"lib",
"!*.map"
],
"exports": {
".": "./lib/index.js"
},
"engines": {
"node": ">=14.6"
},
"scripts": {
"start": "tsc --watch",
"lint": "eslint src/**/*.ts test/**/*.ts",
"registry-mock": "registry-mock",
"test:jest": "jest",
"test:e2e": "registry-mock prepare && run-p -r registry-mock test:jest",
"_test": "cross-env PNPM_REGISTRY_MOCK_PORT=7773 pnpm run test:e2e",
"test": "pnpm run compile && pnpm run _test",
"prepublishOnly": "pnpm run compile",
"compile": "tsc --build && pnpm run lint --fix"
},
"repository": "https://github.com/pnpm/pnpm/blob/main/packages/plugin-commands-deploy",
"keywords": [
"pnpm7",
"pnpm"
],
"license": "MIT",
"bugs": {
"url": "https://github.com/pnpm/pnpm/issues"
},
"homepage": "https://github.com/pnpm/pnpm/blob/main/packages/plugin-commands-deploy#readme",
"devDependencies": {
"@pnpm/assert-project": "workspace:*",
"@pnpm/filter-workspace-packages": "workspace:5.0.16",
"@pnpm/lockfile-types": "workspace:4.2.0",
"@pnpm/logger": "^4.0.0",
"@pnpm/plugin-commands-deploy": "workspace:0.0.0",
"@pnpm/prepare": "workspace:*",
"@pnpm/registry-mock": "2.20.0"
},
"dependencies": {
"@pnpm/cli-utils": "workspace:0.7.16",
"@pnpm/directory-fetcher": "workspace:3.0.6",
"@pnpm/error": "workspace:3.0.1",
"@pnpm/fs.indexed-pkg-importer": "workspace:0.0.0",
"@pnpm/plugin-commands-installation": "workspace:10.3.2",
"@zkochan/rimraf": "^2.1.2",
"render-help": "^1.0.1"
},
"peerDependencies": {
"@pnpm/logger": "^4.0.0"
}
}

View File

@@ -0,0 +1,86 @@
import fs from 'fs'
import path from 'path'
import { docsUrl } from '@pnpm/cli-utils'
import { fetchFromDir } from '@pnpm/directory-fetcher'
import { createIndexedPkgImporter } from '@pnpm/fs.indexed-pkg-importer'
import { install } from '@pnpm/plugin-commands-installation'
import PnpmError from '@pnpm/error'
import rimraf from '@zkochan/rimraf'
import renderHelp from 'render-help'
export function rcOptionsTypes () {
return install.rcOptionsTypes()
}
export function cliOptionsTypes () {
return install.cliOptionsTypes()
}
export const commandNames = ['deploy']
export function help () {
return renderHelp({
description: 'Experimental! Deploy a package from a workspace',
descriptionLists: [],
url: docsUrl('deploy'),
usages: ['pnpm --filter=<deployed project name> deploy <target directory>'],
})
}
export async function handler (
opts: install.InstallCommandOptions,
params: string[]
) {
if (!opts.workspaceDir) {
throw new PnpmError('CANNOT_DEPLOY', 'A deploy is only possible from inside a workspace')
}
const selectedDirs = Object.keys(opts.selectedProjectsGraph ?? {})
if (selectedDirs.length === 0) {
throw new PnpmError('NOTHING_TO_DEPLOY', 'No project was selected for deployment')
}
if (selectedDirs.length > 1) {
throw new PnpmError('CANNOT_DEPLOY_MANY', 'Cannot deploy more than 1 project')
}
if (params.length !== 1) {
throw new PnpmError('INVALID_DEPLOY_TARGET', 'This command requires one parameter')
}
const deployedDir = selectedDirs[0]
const deployDir = path.join(opts.workspaceDir, params[0])
await rimraf(deployDir)
await fs.promises.mkdir(deployDir)
await copyProject(deployedDir, deployDir)
const readPackageHook = opts.hooks?.readPackage
// eslint-disable-next-line
const newReadPackageHook = readPackageHook ? (async (pkg: any, context: any) => deployHook(await readPackageHook(pkg, context))) : deployHook
await install.handler({
...opts,
depth: Infinity,
hooks: {
...opts.hooks,
readPackage: newReadPackageHook,
},
frozenLockfile: false,
preferFrozenLockfile: false,
dev: false,
virtualStoreDir: path.join(deployDir, 'node_modules/.pnpm'),
modulesDir: path.relative(deployedDir, path.join(deployDir, 'node_modules')),
})
}
async function copyProject (src: string, dest: string) {
const { filesIndex } = await fetchFromDir(src, { includeOnlyPackageFiles: true })
const importPkg = createIndexedPkgImporter('clone-or-copy')
await importPkg(dest, { filesMap: filesIndex, force: true, fromStore: true })
}
function deployHook (pkg: any) { // eslint-disable-line
pkg.dependenciesMeta = pkg.dependenciesMeta || {}
for (const [depName, depVersion] of Object.entries(pkg.dependencies ?? {})) {
if ((depVersion as string).startsWith('workspace:')) {
pkg.dependenciesMeta[depName] = {
injected: true,
}
}
}
return pkg
}

View File

@@ -0,0 +1,3 @@
import * as deploy from './deploy'
export { deploy }

View File

@@ -0,0 +1,63 @@
import fs from 'fs'
import path from 'path'
import { deploy } from '@pnpm/plugin-commands-deploy'
import assertProject from '@pnpm/assert-project'
import { preparePackages } from '@pnpm/prepare'
import { readProjects } from '@pnpm/filter-workspace-packages'
import { DEFAULT_OPTS } from './utils'
test('deploy', async () => {
preparePackages([
{
name: 'project-1',
version: '1.0.0',
files: ['index.js'],
dependencies: {
'project-2': 'workspace:*',
'is-positive': '1.0.0',
},
devDependencies: {
'project-3': 'workspace:*',
'is-negative': '1.0.0',
},
},
{
name: 'project-2',
version: '2.0.0',
dependencies: {
'project-3': 'workspace:*',
'is-odd': '1.0.0',
},
},
{
name: 'project-3',
version: '2.0.0',
dependencies: {
'project-3': 'workspace:*',
'is-odd': '1.0.0',
},
},
])
fs.writeFileSync('project-1/test.js', '', 'utf8')
fs.writeFileSync('project-1/index.js', '', 'utf8')
const { allProjects, selectedProjectsGraph } = await readProjects(process.cwd(), [{ namePattern: 'project-1' }])
await deploy.handler({
...DEFAULT_OPTS,
allProjects,
dir: process.cwd(),
recursive: true,
selectedProjectsGraph,
workspaceDir: process.cwd(),
}, ['deploy'])
const project = assertProject(path.resolve('deploy'))
await project.has('project-2')
await project.has('is-positive')
await project.hasNot('project-3')
await project.hasNot('is-negative')
expect(fs.existsSync('deploy/index.js')).toBeTruthy()
expect(fs.existsSync('deploy/test.js')).toBeFalsy()
})

View File

@@ -0,0 +1,50 @@
import { REGISTRY_MOCK_PORT } from '@pnpm/registry-mock'
const REGISTRY = `http://localhost:${REGISTRY_MOCK_PORT}`
export const DEFAULT_OPTS = {
alwaysAuth: false,
argv: {
original: [],
},
bail: true,
bin: 'node_modules/.bin',
ca: undefined,
cacheDir: '../cache',
cert: undefined,
cliOptions: {},
fetchRetries: 2,
fetchRetryFactor: 90,
fetchRetryMaxtimeout: 90,
fetchRetryMintimeout: 10,
filter: [] as string[],
httpsProxy: undefined,
include: {
dependencies: true,
devDependencies: true,
optionalDependencies: true,
},
key: undefined,
linkWorkspacePackages: true,
localAddress: undefined,
lock: false,
lockStaleDuration: 90,
networkConcurrency: 16,
offline: false,
pending: false,
pnpmfile: './.pnpmfile.cjs',
pnpmHomeDir: '',
proxy: undefined,
rawConfig: { registry: REGISTRY },
rawLocalConfig: {},
registries: { default: REGISTRY },
registry: REGISTRY,
sort: true,
storeDir: '../store',
strictSsl: false,
userAgent: 'pnpm',
userConfig: {},
useRunningStoreServer: false,
useStoreServer: false,
workspaceConcurrency: 4,
}

View File

@@ -0,0 +1,40 @@
{
"extends": "@pnpm/tsconfig",
"compilerOptions": {
"outDir": "lib",
"rootDir": "src"
},
"include": [
"src/**/*.ts",
"../../typings/**/*.d.ts"
],
"references": [
{
"path": "../../privatePackages/assert-project"
},
{
"path": "../../privatePackages/prepare"
},
{
"path": "../cli-utils"
},
{
"path": "../directory-fetcher"
},
{
"path": "../error"
},
{
"path": "../filter-workspace-packages"
},
{
"path": "../fs.indexed-pkg-importer"
},
{
"path": "../lockfile-types"
},
{
"path": "../plugin-commands-installation"
}
]
}

View File

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

View File

@@ -17,7 +17,7 @@
"registry-mock": "registry-mock",
"test:jest": "jest",
"test:e2e": "registry-mock prepare && run-p -r registry-mock test:jest",
"_test": "cross-env PNPM_REGISTRY_MOCK_PORT=7773 pnpm run test:e2e",
"_test": "cross-env PNPM_REGISTRY_MOCK_PORT=7774 pnpm run test:e2e",
"test": "pnpm run compile && pnpm run _test",
"prepublishOnly": "pnpm run compile",
"compile": "tsc --build && pnpm run lint --fix"

View File

@@ -245,6 +245,7 @@ export type InstallCommandOptions = Pick<Config,
| 'depth'
| 'dev'
| 'engineStrict'
| 'frozenLockfile'
| 'global'
| 'globalPnpmfile'
| 'hooks'
@@ -254,7 +255,9 @@ export type InstallCommandOptions = Pick<Config,
| 'rawLocalConfig'
| 'lockfileDir'
| 'lockfileOnly'
| 'modulesDir'
| 'pnpmfile'
| 'preferFrozenLockfile'
| 'production'
| 'registries'
| 'save'
@@ -272,6 +275,7 @@ export type InstallCommandOptions = Pick<Config,
| 'sharedWorkspaceLockfile'
| 'tag'
| 'optional'
| 'virtualStoreDir'
| 'workspaceConcurrency'
| 'workspaceDir'
> & CreateStoreControllerOptions & {

View File

@@ -16,7 +16,7 @@
"registry-mock": "registry-mock",
"test:jest": "jest",
"test:e2e": "registry-mock prepare && run-p -r registry-mock test:jest",
"_test": "cross-env PNPM_REGISTRY_MOCK_PORT=7774 pnpm run test:e2e",
"_test": "cross-env PNPM_REGISTRY_MOCK_PORT=7775 pnpm run test:e2e",
"test": "pnpm run compile && pnpm run _test",
"prepublishOnly": "pnpm run compile",
"compile": "tsc --build && pnpm run lint --fix"

View File

@@ -16,7 +16,7 @@
"registry-mock": "registry-mock",
"test:jest": "jest",
"test:e2e": "registry-mock prepare && run-p -r registry-mock test:jest",
"_test": "cross-env PNPM_REGISTRY_MOCK_PORT=7775 pnpm run test:e2e",
"_test": "cross-env PNPM_REGISTRY_MOCK_PORT=7776 pnpm run test:e2e",
"test": "pnpm run compile && pnpm run _test",
"prepublishOnly": "pnpm run compile",
"compile": "tsc --build && pnpm run lint --fix"

View File

@@ -16,7 +16,7 @@
"registry-mock": "registry-mock",
"test:jest": "jest",
"test:e2e": "registry-mock prepare && run-p -r registry-mock test:jest",
"_test": "cross-env PNPM_REGISTRY_MOCK_PORT=7776 pnpm run test:e2e",
"_test": "cross-env PNPM_REGISTRY_MOCK_PORT=7777 pnpm run test:e2e",
"test": "pnpm run compile && pnpm run _test",
"prepublishOnly": "pnpm run compile",
"compile": "tsc --build && pnpm run lint --fix"

View File

@@ -17,7 +17,7 @@
"registry-mock": "registry-mock",
"test:jest": "jest",
"test:e2e": "registry-mock prepare && run-p -r registry-mock test:jest",
"_test": "cross-env PNPM_REGISTRY_MOCK_PORT=7777 pnpm run test:e2e",
"_test": "cross-env PNPM_REGISTRY_MOCK_PORT=7778 pnpm run test:e2e",
"test": "pnpm run compile && pnpm run _test",
"prepublishOnly": "pnpm run compile",
"compile": "tsc --build && pnpm run lint --fix"

View File

@@ -16,7 +16,7 @@
"registry-mock": "registry-mock",
"test:jest": "jest",
"test:e2e": "registry-mock prepare && run-p -r registry-mock test:jest",
"_test": "cross-env PNPM_REGISTRY_MOCK_PORT=7778 pnpm run test:e2e",
"_test": "cross-env PNPM_REGISTRY_MOCK_PORT=7779 pnpm run test:e2e",
"test": "pnpm run compile && pnpm run _test",
"prepublishOnly": "pnpm run compile",
"compile": "tsc --build && pnpm run lint --fix"

View File

@@ -16,7 +16,7 @@
"registry-mock": "registry-mock",
"test:jest": "jest",
"test:e2e": "registry-mock prepare && run-p -r registry-mock test:jest",
"_test": "cross-env PNPM_REGISTRY_MOCK_PORT=7779 pnpm run test:e2e",
"_test": "cross-env PNPM_REGISTRY_MOCK_PORT=7780 pnpm run test:e2e",
"test": "pnpm run compile && pnpm run _test",
"prepublishOnly": "pnpm run compile",
"start": "tsc --watch",

View File

@@ -16,7 +16,7 @@
"registry-mock": "registry-mock",
"test:jest": "jest",
"test:e2e": "registry-mock prepare && run-p -r registry-mock test:jest",
"_test": "cross-env PNPM_REGISTRY_MOCK_PORT=7780 pnpm run test:e2e",
"_test": "cross-env PNPM_REGISTRY_MOCK_PORT=7781 pnpm run test:e2e",
"test": "pnpm run compile && pnpm run _test",
"prepublishOnly": "pnpm run compile",
"compile": "tsc --build && pnpm run lint --fix"

View File

@@ -42,6 +42,7 @@
"@pnpm/pick-registry-for-package": "workspace:3.0.5",
"@pnpm/plugin-commands-audit": "workspace:6.0.16",
"@pnpm/plugin-commands-env": "workspace:2.1.15",
"@pnpm/plugin-commands-deploy": "workspace:0.0.0",
"@pnpm/plugin-commands-init": "workspace:1.0.16",
"@pnpm/plugin-commands-installation": "workspace:10.3.2",
"@pnpm/plugin-commands-listing": "workspace:5.0.16",
@@ -154,7 +155,7 @@
"test:jest": "jest",
"pretest:e2e": "rimraf node_modules/.bin/pnpm",
"test:e2e": "registry-mock prepare && run-p -r registry-mock test:jest",
"_test": "cross-env PNPM_REGISTRY_MOCK_PORT=7781 pnpm run test:e2e",
"_test": "cross-env PNPM_REGISTRY_MOCK_PORT=7782 pnpm run test:e2e",
"test": "pnpm run compile && pnpm run _test",
"prepublishOnly": "pnpm compile && npm cache clear --force && publish-packed --prune --npm-client=pnpm --dest=dist",
"postpublish": "publish-packed",

View File

@@ -2,6 +2,7 @@ import { CompletionFunc } from '@pnpm/command'
import { types as allTypes } from '@pnpm/config'
import { audit } from '@pnpm/plugin-commands-audit'
import { env } from '@pnpm/plugin-commands-env'
import { deploy } from '@pnpm/plugin-commands-deploy'
import { add, fetch, install, link, prune, remove, unlink, update, importCommand } from '@pnpm/plugin-commands-installation'
import { list, ll, why } from '@pnpm/plugin-commands-listing'
import { outdated } from '@pnpm/plugin-commands-outdated'
@@ -97,6 +98,7 @@ const commands: CommandDefinition[] = [
audit,
bin,
create,
deploy,
dlx,
env,
exec,

View File

@@ -75,6 +75,9 @@
{
"path": "../plugin-commands-audit"
},
{
"path": "../plugin-commands-deploy"
},
{
"path": "../plugin-commands-env"
},

View File

@@ -75,6 +75,7 @@ export interface BaseManifest {
directories?: {
bin?: string
}
files?: string[]
dependencies?: Dependencies
devDependencies?: Dependencies
optionalDependencies?: Dependencies

80
pnpm-lock.yaml generated
View File

@@ -27,6 +27,8 @@ overrides:
packageExtensionsChecksum: 1373aa954ee01713eb42037cfa3725eb
patchedDependencies: {}
importers:
.:
@@ -583,33 +585,21 @@ importers:
packages/create-cafs-store:
specifiers:
'@pnpm/cafs': workspace:4.0.7
'@pnpm/core-loggers': workspace:7.0.5
'@pnpm/create-cafs-store': workspace:2.0.1
'@pnpm/fetcher-base': workspace:13.0.1
'@pnpm/fs.indexed-pkg-importer': workspace:0.0.0
'@pnpm/logger': ^4.0.0
'@pnpm/prepare': workspace:*
'@pnpm/store-controller-types': workspace:14.0.1
'@zkochan/rimraf': ^2.1.2
make-empty-dir: ^2.0.0
mem: ^8.0.0
p-limit: ^3.1.0
path-exists: ^4.0.0
path-temp: ^2.0.0
rename-overwrite: ^4.0.2
sanitize-filename: ^1.6.3
dependencies:
'@pnpm/cafs': link:../cafs
'@pnpm/core-loggers': link:../core-loggers
'@pnpm/fetcher-base': link:../fetcher-base
'@pnpm/fs.indexed-pkg-importer': link:../fs.indexed-pkg-importer
'@pnpm/store-controller-types': link:../store-controller-types
'@zkochan/rimraf': 2.1.2
make-empty-dir: 2.0.0
mem: 8.1.1
p-limit: 3.1.0
path-exists: 4.0.0
path-temp: 2.0.0
rename-overwrite: 4.0.2
sanitize-filename: 1.6.3
devDependencies:
'@pnpm/create-cafs-store': 'link:'
'@pnpm/logger': 4.0.0
@@ -1013,6 +1003,33 @@ importers:
devDependencies:
'@pnpm/find-workspace-packages': 'link:'
packages/fs.indexed-pkg-importer:
specifiers:
'@pnpm/core-loggers': workspace:7.0.5
'@pnpm/fs.indexed-pkg-importer': workspace:0.0.0
'@pnpm/logger': ^4.0.0
'@pnpm/prepare': workspace:*
'@zkochan/rimraf': ^2.1.2
make-empty-dir: ^2.0.0
p-limit: ^3.1.0
path-exists: ^4.0.0
path-temp: ^2.0.0
rename-overwrite: ^4.0.2
sanitize-filename: ^1.6.3
dependencies:
'@pnpm/core-loggers': link:../core-loggers
'@zkochan/rimraf': 2.1.2
make-empty-dir: 2.0.0
p-limit: 3.1.0
path-exists: 4.0.0
path-temp: 2.0.0
rename-overwrite: 4.0.2
sanitize-filename: 1.6.3
devDependencies:
'@pnpm/fs.indexed-pkg-importer': 'link:'
'@pnpm/logger': 4.0.0
'@pnpm/prepare': link:../../privatePackages/prepare
packages/get-context:
specifiers:
'@pnpm/constants': workspace:6.1.0
@@ -2146,6 +2163,39 @@ importers:
strip-ansi: 6.0.1
tempy: 1.0.1
packages/plugin-commands-deploy:
specifiers:
'@pnpm/assert-project': workspace:*
'@pnpm/cli-utils': workspace:0.7.16
'@pnpm/directory-fetcher': workspace:3.0.6
'@pnpm/error': workspace:3.0.1
'@pnpm/filter-workspace-packages': workspace:5.0.16
'@pnpm/fs.indexed-pkg-importer': workspace:0.0.0
'@pnpm/lockfile-types': workspace:4.2.0
'@pnpm/logger': ^4.0.0
'@pnpm/plugin-commands-deploy': workspace:0.0.0
'@pnpm/plugin-commands-installation': workspace:10.3.2
'@pnpm/prepare': workspace:*
'@pnpm/registry-mock': 2.20.0
'@zkochan/rimraf': ^2.1.2
render-help: ^1.0.1
dependencies:
'@pnpm/cli-utils': link:../cli-utils
'@pnpm/directory-fetcher': link:../directory-fetcher
'@pnpm/error': link:../error
'@pnpm/fs.indexed-pkg-importer': link:../fs.indexed-pkg-importer
'@pnpm/plugin-commands-installation': link:../plugin-commands-installation
'@zkochan/rimraf': 2.1.2
render-help: 1.0.2
devDependencies:
'@pnpm/assert-project': link:../../privatePackages/assert-project
'@pnpm/filter-workspace-packages': link:../filter-workspace-packages
'@pnpm/lockfile-types': link:../lockfile-types
'@pnpm/logger': 4.0.0
'@pnpm/plugin-commands-deploy': 'link:'
'@pnpm/prepare': link:../../privatePackages/prepare
'@pnpm/registry-mock': 2.20.0
packages/plugin-commands-env:
specifiers:
'@pnpm/cli-utils': workspace:0.7.16
@@ -2924,6 +2974,7 @@ importers:
'@pnpm/parse-cli-args': workspace:5.0.2
'@pnpm/pick-registry-for-package': workspace:3.0.5
'@pnpm/plugin-commands-audit': workspace:6.0.16
'@pnpm/plugin-commands-deploy': workspace:0.0.0
'@pnpm/plugin-commands-env': workspace:2.1.15
'@pnpm/plugin-commands-init': workspace:1.0.16
'@pnpm/plugin-commands-installation': workspace:10.3.2
@@ -3013,6 +3064,7 @@ importers:
'@pnpm/parse-cli-args': link:../parse-cli-args
'@pnpm/pick-registry-for-package': link:../pick-registry-for-package
'@pnpm/plugin-commands-audit': link:../plugin-commands-audit
'@pnpm/plugin-commands-deploy': link:../plugin-commands-deploy
'@pnpm/plugin-commands-env': link:../plugin-commands-env
'@pnpm/plugin-commands-init': link:../plugin-commands-init
'@pnpm/plugin-commands-installation': link:../plugin-commands-installation