Skip to content

Commit

Permalink
feat: ✨ added --topology to use workspace dependencies for parallell …
Browse files Browse the repository at this point in the history
…commands other than "build"
  • Loading branch information
folke committed May 14, 2020
1 parent 6d88ab5 commit c19f807
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 52 deletions.
59 changes: 59 additions & 0 deletions src/concurrency.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import chalk from "chalk"
import { relative } from "path"
import { RunnerOptions } from "./options"
import { Command, CommandParser, CommandType } from "./parser"
import { Workspace } from "./workspace"

export function createCommand(
workspace: Workspace,
cmd: string,
options: RunnerOptions
) {
const useTopology = options.build || options.topology
const topoPromises = new Map<string | undefined, Promise<void>>()
const topoPackages = new Set<string>()

const command = new Command([], CommandType.script)

let hasScript = false
command.children = workspace
.getPackages(options.filter)
.map((pkg) => {
const command = new CommandParser(pkg, pkg.root)
.parse(cmd)
.setCwd(pkg.root)
command.name = `${chalk.cyanBright(pkg.name)} at ${chalk.grey(
relative(workspace.root, pkg.root)
)}`
command.type = CommandType.script
if (useTopology) {
topoPackages.add(pkg.name)
command.beforeRun = async () => {
topoPromises.set(
pkg.name,
new Promise((resolve) => {
command.afterRun = () => {
resolve()
}
})
)
await Promise.all(
workspace
.getDepTree(pkg.name)
.filter((dep) => topoPackages.has(dep))
.map((dep) => topoPromises.get(dep))
.filter((p) => p)
)
}
}
hasScript =
hasScript || command.children.some((c) => c.type == CommandType.script)
return command
})
// If we have some scripts, filter out the packages that don't have that script
.filter(
(c) => !hasScript || c.children.some((c) => c.type == CommandType.script)
)
command.concurrent = true
return command
}
6 changes: 6 additions & 0 deletions src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const defaults = {
rebuild: false,
list: false,
info: false,
topology: false,
build: false,
concurrency: 10,
debug: false,
Expand Down Expand Up @@ -49,6 +50,11 @@ export const RunnerOptionDefs: Record<keyof RunnerOptions, RunnerOptionDef> = {
description: "Run command in every workspace folder concurrently",
alias: "r",
},
topology: {
type: "boolean",
description:
"Run concurrently, automatically waiting for dependencies when needed. Defaults to 'true' for 'build'",
},
concurrency: {
type: "number",
description: "Set the maximum number of concurrency",
Expand Down
53 changes: 2 additions & 51 deletions src/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { Spawner } from "./spawn"
import { OutputSpinner, Spinner } from "./spinner"
import { getWorkspace, Workspace } from "./workspace"
import { WorkspaceProviderType } from "./workspace.providers"
import { createCommand } from "./concurrency"

export class Runner {
spinner = new OutputSpinner()
Expand Down Expand Up @@ -258,58 +259,8 @@ export class Runner {
throw new Error(
"Could not find packages in your workspace. Supported: yarn, pnpm, lerna"
)
const command = new Command([], CommandType.script)
const done = new Set<string>()
// setInterval(() => {
// console.log([...this.deps.keys()].filter(d => !done.has(d as string)))
// }, 2000)

let hasScript = false
const buildPackages = new Set<string>()
command.children = workspace
.getPackages(this.options.filter)
.map((pkg) => {
const command = new CommandParser(pkg, pkg.root)
.parse(cmd)
.setCwd(pkg.root)
command.name = `${chalk.cyanBright(pkg.name)} at ${chalk.grey(
relative(workspace.root, pkg.root)
)}`
command.type = CommandType.script
if (
this.options.build &&
command.children.some((c) => c.type == CommandType.script)
) {
buildPackages.add(pkg.name)
command.beforeRun = async () => {
this.deps.set(
pkg.name,
new Promise((resolve) => {
command.afterRun = () => {
done.add(pkg.name)
resolve()
}
})
)
await Promise.all(
workspace
.getDepTree(pkg.name)
.filter((dep) => buildPackages.has(dep))
.map((dep) => this.deps.get(dep))
.filter((p) => p)
)
}
}
hasScript =
hasScript ||
command.children.some((c) => c.type == CommandType.script)
return command
})
.filter(
(c) =>
!hasScript || c.children.some((c) => c.type == CommandType.script)
)
command.concurrent = true
const command = createCommand(workspace, cmd, this.options)
return await this._run(command, -1)
}

Expand Down
5 changes: 4 additions & 1 deletion src/yargs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ const program = yargs
.alias("h", "help")
.help(false)
.version(require(path.resolve(__dirname, "../package.json")).version)
.group(["recursive", "filter", "root", "concurrency", "serial"], "Workspace:")
.group(
["recursive", "filter", "root", "concurrency", "serial", "topology"],
"Workspace:"
)
.group(["info", "list", "monitor", "monitor-interval"], "Status:")
.group(["build", "rebuild"], "Build:")
.group(["pretty", "raw", "silent", "color"], "Formatting:")
Expand Down

0 comments on commit c19f807

Please sign in to comment.