Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(watch): Add
lerna watch
command (#3466)
- Loading branch information
Showing
21 changed files
with
874 additions
and
115 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# `lerna watch` | ||
|
||
> Watch for changes within packages and execute commands from the root of the repository | ||
Install [lerna](https://www.npmjs.com/package/lerna) for access to the `lerna` CLI. | ||
|
||
## Usage | ||
|
||
```sh | ||
$ lerna watch -- <command> | ||
``` | ||
|
||
The values `$LERNA_PACKAGE_NAME` and `$LERNA_FILE_CHANGES` will be replaced with the package and the file(s) that changed, respectively. If multiple file changes are detected in one cycle, then `$LERNA_FILE_CHANGES` will list them all, separated by spaces. | ||
|
||
> 💡 When using `$LERNA_PACKAGE_NAME` and `$LERNA_FILE_CHANGES`, you will need to escape the dollar sign with a backslash (`\`). See the [examples](#examples) below. | ||
### Examples | ||
|
||
Watch all packages and echo the package name and the files that changed: | ||
|
||
```sh | ||
$ lerna watch -- echo \$LERNA_PACKAGE_NAME \$LERNA_FILE_CHANGES | ||
``` | ||
|
||
Watch only packages "package-1", "package-3" and their dependencies: | ||
|
||
```sh | ||
$ lerna watch --scope "package-{1,3}" --include-dependencies -- echo \$LERNA_PACKAGE_NAME \$LERNA_FILE_CHANGES | ||
``` | ||
|
||
Watch only package "package-4" and its dependencies and run the `test` script for the package that changed: | ||
|
||
```sh | ||
$ lerna watch --scope="package-4" --include-dependencies -- lerna run test --scope=\$LERNA_PACKAGE_NAME | ||
``` | ||
|
||
When using `npx`, the `-c` option must be used if also providing variables for substitution: | ||
|
||
```sh | ||
$ npx -c 'lerna watch -- echo \$LERNA_PACKAGE_NAME \$LERNA_FILE_CHANGES' | ||
``` | ||
|
||
## Options | ||
|
||
`lerna watch` accepts all [filter flags](https://www.npmjs.com/package/@lerna/filter-options). Filter flags can be used to select specific packages to watch. See the [examples](#examples) above. | ||
|
||
### `--verbose` | ||
|
||
Run `lerna watch` in verbose mode, where commands are logged before execution. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// @ts-check | ||
|
||
"use strict"; | ||
|
||
const { filterOptions } = require("@lerna/filter-options"); | ||
|
||
/** | ||
* @see https://github.com/yargs/yargs/blob/master/docs/advanced.md#providing-a-command-module | ||
*/ | ||
exports.command = "watch"; | ||
|
||
exports.describe = "Runs a command whenever packages or their dependents change."; | ||
|
||
exports.builder = (yargs) => { | ||
yargs | ||
.parserConfiguration({ | ||
"populate--": true, | ||
"strip-dashed": true, | ||
}) | ||
.option("command", { type: "string", hidden: true }) | ||
.option("verbose", { | ||
type: "boolean", | ||
description: "Run watch mode in verbose mode, where commands are logged before execution.", | ||
}) | ||
.middleware((args) => { | ||
const { "--": doubleDash } = args; | ||
if (doubleDash && Array.isArray(doubleDash)) { | ||
// eslint-disable-next-line no-param-reassign | ||
args.command = doubleDash.join(" "); | ||
} | ||
}, true); | ||
|
||
return filterOptions(yargs); | ||
}; | ||
|
||
exports.handler = function handler(argv) { | ||
// eslint-disable-next-line global-require | ||
return require(".")(argv); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// @ts-check | ||
|
||
"use strict"; | ||
|
||
const { Command } = require("@lerna/command"); | ||
const { getFilteredPackages } = require("@lerna/filter-options"); | ||
const { ValidationError } = require("@lerna/validation-error"); | ||
const { watch } = require("nx/src/command-line/watch"); | ||
const { readNxJson } = require("nx/src/config/configuration"); | ||
|
||
module.exports = factory; | ||
|
||
const getNxProjectNamesFromLernaPackageNames = (packageNames) => { | ||
const nxJson = readNxJson(); | ||
const nxConfiguredNpmScope = nxJson.npmScope; | ||
|
||
return nxConfiguredNpmScope | ||
? packageNames.map((name) => name.replace(`@${nxConfiguredNpmScope}/`, "")) | ||
: packageNames; | ||
}; | ||
|
||
function factory(argv) { | ||
return new WatchCommand(argv); | ||
} | ||
|
||
class WatchCommand extends Command { | ||
get requiresGit() { | ||
return false; | ||
} | ||
|
||
async initialize() { | ||
if (!this.options.command) { | ||
throw new ValidationError("ENOCOMMAND", "A command to execute is required"); | ||
} | ||
|
||
this.filteredPackages = await getFilteredPackages(this.packageGraph, this.execOpts, this.options); | ||
|
||
this.count = this.filteredPackages.length; | ||
this.packagePlural = this.count === 1 ? "package" : "packages"; | ||
} | ||
|
||
async execute() { | ||
this.logger.info( | ||
"watch", | ||
"Executing command %j on changes in %d %s.", | ||
this.options.command, | ||
this.count, | ||
this.packagePlural | ||
); | ||
|
||
const projectNames = getNxProjectNamesFromLernaPackageNames(this.filteredPackages.map((p) => p.name)); | ||
|
||
await watch({ | ||
command: this.options.command, | ||
projectNameEnvName: "LERNA_PACKAGE_NAME", | ||
fileChangesEnvName: "LERNA_FILE_CHANGES", | ||
includeDependentProjects: false, // dependent projects are accounted for via lerna filter options | ||
projects: projectNames, | ||
verbose: this.options.verbose, | ||
}); | ||
} | ||
} | ||
|
||
module.exports.WatchCommand = WatchCommand; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"extends": ["../../.eslintrc.json"], | ||
"ignorePatterns": ["!**/*"], | ||
"overrides": [ | ||
{ | ||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"], | ||
"rules": {} | ||
}, | ||
{ | ||
"files": ["*.ts", "*.tsx"], | ||
"rules": {} | ||
}, | ||
{ | ||
"files": ["*.js", "*.jsx"], | ||
"rules": {} | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/* eslint-disable */ | ||
export default { | ||
displayName: "e2e-watch", | ||
preset: "../../jest.preset.js", | ||
globals: { | ||
"ts-jest": { | ||
tsconfig: "<rootDir>/tsconfig.spec.json", | ||
}, | ||
}, | ||
transform: { | ||
"^.+\\.[tj]s$": "ts-jest", | ||
}, | ||
moduleFileExtensions: ["ts", "js", "html"], | ||
coverageDirectory: "../../coverage/e2e/watch", | ||
maxWorkers: 1, | ||
testTimeout: 60000, | ||
setupFiles: ["<rootDir>/src/test-setup.ts"], | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
{ | ||
"name": "e2e-watch", | ||
"$schema": "../../node_modules/nx/schemas/project-schema.json", | ||
"tags": [], | ||
"targets": { | ||
"e2e": { | ||
"executor": "nx:run-commands", | ||
"options": { | ||
"commands": [ | ||
{ | ||
"command": "npm run e2e-start-local-registry" | ||
}, | ||
{ | ||
"command": "npm run e2e-build-package-publish" | ||
}, | ||
{ | ||
"command": "E2E_ROOT=$(npx ts-node scripts/set-e2e-root.ts) nx run-e2e-tests e2e-watch" | ||
} | ||
], | ||
"parallel": false | ||
} | ||
}, | ||
"run-e2e-tests-process": { | ||
"executor": "nx:run-commands", | ||
"options": { | ||
"commands": [ | ||
{ | ||
"command": "E2E_ROOT=$(npx ts-node scripts/set-e2e-root.ts) nx run-e2e-tests e2e-watch", | ||
"description": "This additional wrapper target exists so that we can ensure that the e2e tests run in a dedicated process with enough memory" | ||
} | ||
], | ||
"parallel": false | ||
} | ||
}, | ||
"run-e2e-tests": { | ||
"executor": "@nrwl/jest:jest", | ||
"options": { | ||
"jestConfig": "e2e/watch/jest.config.ts", | ||
"passWithNoTests": true, | ||
"runInBand": true | ||
}, | ||
"outputs": ["{workspaceRoot}/coverage/e2e/watch"] | ||
}, | ||
"lint": { | ||
"executor": "@nrwl/linter:eslint", | ||
"outputs": ["{options.outputFile}"], | ||
"options": { | ||
"lintFilePatterns": ["e2e/watch/**/*.ts"] | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
jest.retryTimes(3); |
Oops, something went wrong.