Skip to content

Commit

Permalink
feat(recursive): --no-sort flag to not sort packages topologically
Browse files Browse the repository at this point in the history
  • Loading branch information
zkochan committed Aug 24, 2018
1 parent 0abc1aa commit 0029163
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 42 deletions.
1 change: 1 addition & 0 deletions packages/config/src/PnpmConfigs.ts
Expand Up @@ -69,4 +69,5 @@ export interface PnpmConfigs extends Record<string, any> { // tslint:disable-lin
workspacePrefix?: string,
reporter?: string,
linkWorkspacePackages: boolean,
sort: boolean,
}
2 changes: 2 additions & 0 deletions packages/config/src/index.ts
Expand Up @@ -49,6 +49,7 @@ export const types = Object.assign({
'shrinkwrap-only': Boolean,
'side-effects-cache': Boolean,
'side-effects-cache-readonly': Boolean,
'sort': Boolean,
'store': path,
'use-running-store-server': Boolean,
'use-store-server': Boolean,
Expand Down Expand Up @@ -100,6 +101,7 @@ export default async (
'prefix': npmDefaults.prefix,
'registry': npmDefaults.registry,
'shrinkwrap': npmDefaults.shrinkwrap,
'sort': true,
'unsafe-perm': npmDefaults['unsafe-perm'],
'userconfig': npmDefaults.userconfig,
'workspace-concurrency': 4,
Expand Down
1 change: 1 addition & 0 deletions packages/pnpm/src/cmd/help.ts
Expand Up @@ -279,6 +279,7 @@ function getHelpText (command: string) {
--workspace-concurrency set the maximum number of concurrency. Default is 4. For unlimited concurrency use Infinity.
--link-workspace-packages locally available packages are linked to node_modules instead of being downloaded from the registry.
Convenient to use in a multi-package repository.
--sort sort packages topologically (dependencies before dependents). Pass --no-sort to disable.
`

default:
Expand Down
18 changes: 0 additions & 18 deletions packages/pnpm/src/cmd/recursive/dividePackagesToChunks.ts

This file was deleted.

8 changes: 2 additions & 6 deletions packages/pnpm/src/cmd/recursive/exec.ts
@@ -1,12 +1,10 @@
import logger from '@pnpm/logger'
import {PackageJson} from '@pnpm/types'
import execa = require('execa')
import pLimit = require('p-limit')
import dividePackagesToChunks from './dividePackagesToChunks'
import RecursiveSummary from './recursiveSummary'

export default async (
pkgs: Array<{path: string, manifest: PackageJson}>,
packageChunks: string[][],
args: string[],
cmd: string,
opts: {
Expand All @@ -16,16 +14,14 @@ export default async (
rawNpmConfig: object,
},
): Promise<RecursiveSummary> => {
const {chunks} = dividePackagesToChunks(pkgs)

const limitRun = pLimit(opts.workspaceConcurrency)

const result = {
fails: [],
passes: 0,
} as RecursiveSummary

for (const chunk of chunks) {
for (const chunk of packageChunks) {
await Promise.all(chunk.map((prefix: string) =>
limitRun(async () => {
try {
Expand Down
37 changes: 23 additions & 14 deletions packages/pnpm/src/cmd/recursive/index.ts
Expand Up @@ -3,9 +3,8 @@ import {PackageJson} from '@pnpm/types'
import camelcaseKeys = require('camelcase-keys')
import graphSequencer = require('graph-sequencer')
import pLimit = require('p-limit')
import { StoreController } from 'package-store'
import path = require('path')
import createPkgGraph from 'pkgs-graph'
import createPkgGraph, {PackageNode} from 'pkgs-graph'
import readIniFile = require('read-ini-file')
import {
install,
Expand Down Expand Up @@ -111,17 +110,24 @@ export async function recursive (
case 'outdated':
await outdated(pkgs, input, cmd, opts as any) // tslint:disable-line:no-any
return
}

const chunks = opts.sort
? sortPackages(pkgGraphResult.graph)
: [Object.keys(pkgGraphResult.graph).sort()]

switch (cmdFullName) {
case 'test':
throwOnFail(await run(pkgs, ['test', ...input], cmd, opts as any)) // tslint:disable-line:no-any
throwOnFail(await run(chunks, pkgGraphResult.graph, ['test', ...input], cmd, opts as any)) // tslint:disable-line:no-any
return
case 'run':
throwOnFail(await run(pkgs, input, cmd, opts as any)) // tslint:disable-line:no-any
throwOnFail(await run(chunks, pkgGraphResult.graph, input, cmd, opts as any)) // tslint:disable-line:no-any
return
case 'update':
opts = {...opts, update: true, allowNew: false} as any // tslint:disable-line:no-any
break
case 'exec':
throwOnFail(await exec(pkgs, input, cmd, opts as any)) // tslint:disable-line:no-any
throwOnFail(await exec(chunks, input, cmd, opts as any)) // tslint:disable-line:no-any
return
}

Expand All @@ -137,15 +143,6 @@ export async function recursive (
saveState: async () => undefined,
}

const graph = new Map(
Object.keys(pkgGraphResult.graph).map((pkgPath) => [pkgPath, pkgGraphResult.graph[pkgPath].dependencies]) as Array<[string, string[]]>,
)
const graphSequencerResult = graphSequencer({
graph,
groups: [Object.keys(pkgGraphResult.graph)],
})
const chunks = graphSequencerResult.chunks

if (cmdFullName === 'link' && opts.linkWorkspacePackages) {
const err = new Error('"pnpm recursive link" is deprecated with link-workspace-packages = true. Please use "pnpm recursive install" instead')
err['code'] = 'ERR_PNPM_RECURSIVE_LINK_DEPRECATED' // tslint:disable-line:no-string-literal
Expand Down Expand Up @@ -229,6 +226,18 @@ export async function recursive (
throwOnFail(result)
}

function sortPackages (pkgGraph: {[nodeId: string]: PackageNode}): string[][] {
const keys = Object.keys(pkgGraph)
const graph = new Map(
keys.map((pkgPath) => [pkgPath, pkgGraph[pkgPath].dependencies]) as Array<[string, string[]]>,
)
const graphSequencerResult = graphSequencer({
graph,
groups: [keys],
})
return graphSequencerResult.chunks
}

async function readLocalConfigs (prefix: string) {
try {
const ini = await readIniFile(path.join(prefix, '.npmrc'))
Expand Down
8 changes: 4 additions & 4 deletions packages/pnpm/src/cmd/recursive/run.ts
Expand Up @@ -3,11 +3,12 @@ import logger from '@pnpm/logger'
import {PackageJson} from '@pnpm/types'
import {realNodeModulesDir} from '@pnpm/utils'
import pLimit = require('p-limit')
import dividePackagesToChunks from './dividePackagesToChunks'
import {PackageNode} from 'pkgs-graph'
import RecursiveSummary from './recursiveSummary'

export default async (
pkgs: Array<{path: string, manifest: PackageJson}>,
packageChunks: string[][],
graph: {[id: string]: PackageNode},
args: string[],
cmd: string,
opts: {
Expand All @@ -18,7 +19,6 @@ export default async (
},
) => {
const scriptName = args[0]
const {chunks, graph} = dividePackagesToChunks(pkgs)
let hasCommand = 0

const result = {
Expand All @@ -29,7 +29,7 @@ export default async (
const limitRun = pLimit(opts.workspaceConcurrency)
const stdio = opts.workspaceConcurrency === 1 ? 'inherit' : 'pipe'

for (const chunk of chunks) {
for (const chunk of packageChunks) {
await Promise.all(chunk.map((prefix: string) =>
limitRun(async () => {
const pkg = graph[prefix] as {manifest: PackageJson, path: string}
Expand Down
1 change: 1 addition & 0 deletions packages/pnpm/src/types.ts
Expand Up @@ -76,6 +76,7 @@ export interface PnpmOptions {
workspaceConcurrency: number,
workspacePrefix?: string,
linkWorkspacePackages: boolean,
sort: boolean,

// cannot be specified via configs
update?: boolean,
Expand Down
33 changes: 33 additions & 0 deletions packages/pnpm/test/recursive/exec.ts
Expand Up @@ -122,3 +122,36 @@ test('testing the bail config with "pnpm recursive exec"', async (t: tape.Test)

t.ok(failed, 'recursive exec failed with --bail')
})

test('pnpm recursive exec --no-sort', async (t: tape.Test) => {
const projects = preparePackages(t, [
{
name: 'a-dependent',
version: '1.0.0',
dependencies: {
'b-dependency': '1.0.0',
'json-append': '1',
},
scripts: {
build: `node -e "process.stdout.write('a-dependent')" | json-append ../output.json`,
},
},
{
name: 'b-dependency',
version: '1.0.0',
dependencies: {
'json-append': '1',
},
scripts: {
build: `node -e "process.stdout.write('b-dependency')" | json-append ../output.json`,
},
},
])

await execPnpm('recursive', 'install', '--link-workspace-packages')
await execPnpm('recursive', 'exec', 'npm', 'run', 'build', '--no-sort', '--workspace-concurrency', '1')

const outputs = await import(path.resolve('output.json')) as string[]

t.deepEqual(outputs, ['a-dependent', 'b-dependency'])
})

0 comments on commit 0029163

Please sign in to comment.