Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: pnpm update -r --prod #2305

Merged
merged 4 commits into from
Feb 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
190 changes: 6 additions & 184 deletions packages/plugin-commands-installation/src/install.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,14 @@
import {
createLatestSpecs,
docsUrl,
getPinnedVersion,
getSaveType,
readProjectManifestOnly,
tryReadProjectManifest,
updateToLatestSpecsFromManifest,
} from '@pnpm/cli-utils'
import { FILTERING, OPTIONS, UNIVERSAL_OPTIONS } from '@pnpm/common-cli-options-help'
import { Config, types as allTypes } from '@pnpm/config'
import { WANTED_LOCKFILE } from '@pnpm/constants'
import PnpmError from '@pnpm/error'
import { filterPkgsBySelectorObjects } from '@pnpm/filter-workspace-packages'
import findWorkspacePackages, { arrayOfWorkspacePackagesToMap } from '@pnpm/find-workspace-packages'
import matcher from '@pnpm/matcher'
import { rebuild } from '@pnpm/plugin-commands-rebuild/lib/implementation'
import { requireHooks } from '@pnpm/pnpmfile'
import { createOrConnectStoreController, CreateStoreControllerOptions } from '@pnpm/store-connection-manager'
import { CreateStoreControllerOptions } from '@pnpm/store-connection-manager'
import { oneLine } from 'common-tags'
import R = require('ramda')
import renderHelp = require('render-help')
import {
install,
mutateModules,
} from 'supi'
import recursive, { matchDependencies } from './recursive'
import { createWorkspaceSpecs, updateToWorkspacePackagesFromManifest } from './updateWorkspaceDependencies'

const OVERWRITE_UPDATE_OPTIONS = {
allowNew: true,
update: false,
}
import installDeps from './installDeps'

export const rcOptionsTypes = cliOptionsTypes

Expand Down Expand Up @@ -301,179 +279,23 @@ export type InstallCommandOptions = Pick<Config,
argv: {
original: string[],
},
allowNew?: boolean,
latest?: boolean,
update?: boolean,
useBetaCli?: boolean,
recursive?: boolean,
workspace?: boolean,
}

export async function handler (
export function handler (
input: string[],
opts: InstallCommandOptions,
) {
if (opts.workspace) {
if (opts.latest) {
throw new PnpmError('BAD_OPTIONS', 'Cannot use --latest with --workspace simultaneously')
}
if (!opts.workspaceDir) {
throw new PnpmError('WORKSPACE_OPTION_OUTSIDE_WORKSPACE', '--workspace can only be used inside a workspace')
}
if (!opts.linkWorkspacePackages && !opts.saveWorkspaceProtocol) {
if (opts.rawLocalConfig['save-workspace-protocol'] === false) {
throw new PnpmError('BAD_OPTIONS', oneLine`This workspace has link-workspace-packages turned off,
so dependencies are linked from the workspace only when the workspace protocol is used.
Either set link-workspace-packages to true or don't use the --no-save-workspace-protocol option
when running add/update with the --workspace option`)
} else {
opts.saveWorkspaceProtocol = true
}
}
opts['preserveWorkspaceProtocol'] = !opts.linkWorkspacePackages
}
const include = {
dependencies: opts.production !== false,
devDependencies: opts.dev !== false,
optionalDependencies: opts.optional !== false,
}
if (opts.recursive && opts.allProjects && opts.selectedProjectsGraph && opts.workspaceDir) {
await recursive(opts.allProjects,
input,
{
...opts,
include,
selectedProjectsGraph: opts.selectedProjectsGraph!,
workspaceDir: opts.workspaceDir!,
},
opts.update ? 'update' : (input.length === 0 ? 'install' : 'add'),
)
return
}
// `pnpm install ""` is going to be just `pnpm install`
input = input.filter(Boolean)

const dir = opts.dir || process.cwd()
let allProjects = opts.allProjects
let workspacePackages = undefined

if (opts.workspaceDir) {
allProjects = allProjects ?? await findWorkspacePackages(opts.workspaceDir, opts)
workspacePackages = arrayOfWorkspacePackagesToMap(allProjects)
}

const store = await createOrConnectStoreController(opts)
const installOpts = {
return installDeps(input, {
...opts,
// In case installation is done in a multi-package repository
// The dependencies should be built first,
// so ignoring scripts for now
ignoreScripts: !!workspacePackages || opts.ignoreScripts,
include,
sideEffectsCacheRead: opts.sideEffectsCache || opts.sideEffectsCacheReadonly,
sideEffectsCacheWrite: opts.sideEffectsCache,
storeController: store.ctrl,
storeDir: store.dir,
workspacePackages,

forceHoistPattern: typeof opts.rawLocalConfig['hoist-pattern'] !== 'undefined' || typeof opts.rawLocalConfig['hoist'] !== 'undefined',
forceIndependentLeaves: typeof opts.rawLocalConfig['independent-leaves'] !== 'undefined',
forceShamefullyHoist: typeof opts.rawLocalConfig['shamefully-hoist'] !== 'undefined',
}
if (!opts.ignorePnpmfile) {
installOpts['hooks'] = requireHooks(opts.lockfileDir || dir, opts)
}

let { manifest, writeProjectManifest } = await tryReadProjectManifest(opts.dir, opts)
if (manifest === null) {
if (opts.update) {
throw new PnpmError('NO_IMPORTER_MANIFEST', 'No package.json found')
}
manifest = {}
}

const [patternedInput, unpatternedInput] = R.partition(R.includes('*'), input)
const updateMatch = opts.update && patternedInput.length ? matcher(patternedInput) : null
if (updateMatch) {
input = [
...unpatternedInput,
...matchDependencies(updateMatch, manifest, include),
]
}

if (opts.update && opts.latest) {
if (!input || !input.length) {
input = updateToLatestSpecsFromManifest(manifest, include)
} else {
input = createLatestSpecs(input, manifest)
}
delete installOpts.include
}
if (opts.workspace) {
if (!input || !input.length) {
input = updateToWorkspacePackagesFromManifest(manifest, include, workspacePackages!)
} else {
input = createWorkspaceSpecs(input, workspacePackages!)
}
}
if (!input || !input.length) {
const updatedManifest = await install(manifest, installOpts)
if (opts.update === true && opts.save !== false) {
await writeProjectManifest(updatedManifest)
}
} else {
const [updatedImporter] = await mutateModules([
{
allowNew: opts.allowNew,
binsDir: installOpts.bin,
dependencySelectors: input,
manifest,
mutation: 'installSome',
peer: opts.savePeer,
pinnedVersion: getPinnedVersion(opts),
rootDir: installOpts.dir,
targetDependenciesField: getSaveType(installOpts),
},
], installOpts)
if (opts.save !== false) {
await writeProjectManifest(updatedImporter.manifest)
}
}

if (opts.linkWorkspacePackages && opts.workspaceDir) {
allProjects = allProjects ?? await findWorkspacePackages(opts.workspaceDir, opts)
const selectedProjectsGraph = await filterPkgsBySelectorObjects(allProjects, [
{
excludeSelf: true,
includeDependencies: true,
parentDir: dir,
},
], {
workspaceDir: opts.workspaceDir,
})
await recursive(allProjects, [], {
...opts,
...OVERWRITE_UPDATE_OPTIONS,
include,
selectedProjectsGraph,
workspaceDir: opts.workspaceDir, // Otherwise TypeScript doesn't understant that is is not undefined
}, 'install')

if (opts.ignoreScripts) return

await rebuild(
[
{
buildIndex: 0,
manifest: await readProjectManifestOnly(opts.dir, opts),
rootDir: opts.dir,
},
], {
...opts,
pending: true,
storeController: store.ctrl,
storeDir: store.dir,
},
)
}
includeDirect: include,
})
}