Skip to content

Commit

Permalink
feat(watch): add optional stdin key to exit watch mode cleanly (#472)
Browse files Browse the repository at this point in the history
* feat(watch): add optional stdin key to exit watch mode cleanly
  • Loading branch information
ghiscoding committed Feb 4, 2023
1 parent 5387b4e commit d0cf2d9
Show file tree
Hide file tree
Showing 20 changed files with 73 additions and 5 deletions.
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
"pack-tarball": "lerna run pack-tarball",
"pack-tarball:nx": "lerna run pack-tarball --stream --use-nx",
"preview:build": "lerna run build --stream --include-dependents --scope=@lerna-lite/listable",
"preview:watch:build": "lerna watch --no-bail --scope=@lerna-lite/listable --include-dependents -- cross-env-shell lerna run build --stream --include-dependents --scope=$LERNA_PACKAGE_NAME",
"preview:watch:build:pnpm": "lerna watch --no-bail --scope=@lerna-lite/listable --include-dependents -- cross-env-shell pnpm run --stream --filter ...$LERNA_PACKAGE_NAME build",
"preview:watch:build": "lerna watch --no-bail --scope=@lerna-lite/listable --include-dependents -- cross-env-shell lerna run build:incremental --stream --include-dependents --scope=$LERNA_PACKAGE_NAME",
"preview:watch:build:pnpm": "lerna watch --no-bail --scope=@lerna-lite/listable --include-dependents -- cross-env-shell pnpm run --stream --filter ...$LERNA_PACKAGE_NAME build:incremental",
"postpreview:watch:build:pnpm": "echo clean exit",
"preview:watch:files": "lerna watch --glob=\"src/**/*.ts\" --scope=@lerna-lite/listable --include-dependents -- cross-env-shell echo $LERNA_FILE_CHANGES in package $LERNA_PACKAGE_NAME\"",
"preview:watch:all": "lerna watch --watch-all-events --scope {@lerna-lite/watch,@lerna-lite/exec} -- cross-env-shell echo \"Changed files $LERNA_FILE_CHANGES in package $LERNA_PACKAGE_NAME\"",
"preview:publish-alpha-dry-run": "lerna publish --dry-run --exact --include-merged-tags --preid alpha --dist-tag next prerelease",
Expand Down
1 change: 1 addition & 0 deletions packages/changed/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"scripts": {
"prebuild": "rimraf dist",
"build": "tsc --project tsconfig.bundle.json --newLine LF",
"build:incremental": "tsc --incremental --project tsconfig.bundle.json --newLine LF --sourceMap false --excludeDirectories dist",
"pack-tarball": "npm pack"
},
"license": "MIT",
Expand Down
1 change: 1 addition & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"scripts": {
"prebuild": "rimraf dist",
"build": "tsc --project tsconfig.bundle.json --newLine LF",
"build:incremental": "tsc --incremental --project tsconfig.bundle.json --newLine LF --sourceMap false --excludeDirectories dist",
"pack-tarball": "npm pack"
},
"license": "MIT",
Expand Down
1 change: 1 addition & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"scripts": {
"prebuild": "rimraf dist",
"build": "tsc --project tsconfig.bundle.json --newLine LF",
"build:incremental": "tsc --incremental --project tsconfig.bundle.json --newLine LF --sourceMap false --excludeDirectories dist",
"pack-tarball": "npm pack"
},
"license": "MIT",
Expand Down
1 change: 1 addition & 0 deletions packages/diff/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"scripts": {
"prebuild": "rimraf dist",
"build": "tsc --project tsconfig.bundle.json --newLine LF",
"build:incremental": "tsc --incremental --project tsconfig.bundle.json --newLine LF --sourceMap false --excludeDirectories dist",
"pack-tarball": "npm pack"
},
"license": "MIT",
Expand Down
1 change: 1 addition & 0 deletions packages/exec/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"scripts": {
"prebuild": "rimraf dist",
"build": "tsc --project tsconfig.bundle.json --newLine LF",
"build:incremental": "tsc --incremental --project tsconfig.bundle.json --newLine LF --sourceMap false --excludeDirectories dist",
"pack-tarball": "npm pack"
},
"license": "MIT",
Expand Down
1 change: 1 addition & 0 deletions packages/filter-packages/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"scripts": {
"prebuild": "rimraf dist",
"build": "tsc --project tsconfig.bundle.json --newLine LF",
"build:incremental": "tsc --incremental --project tsconfig.bundle.json --newLine LF --sourceMap false --excludeDirectories dist",
"pack-tarball": "npm pack"
},
"license": "MIT",
Expand Down
1 change: 1 addition & 0 deletions packages/info/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"scripts": {
"prebuild": "rimraf dist",
"build": "tsc --project tsconfig.bundle.json --newLine LF",
"build:incremental": "tsc --incremental --project tsconfig.bundle.json --newLine LF --sourceMap false --excludeDirectories dist",
"pack-tarball": "npm pack"
},
"license": "MIT",
Expand Down
1 change: 1 addition & 0 deletions packages/init/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"scripts": {
"prebuild": "rimraf dist",
"build": "tsc --project tsconfig.bundle.json --newLine LF",
"build:incremental": "tsc --incremental --project tsconfig.bundle.json --newLine LF --sourceMap false --excludeDirectories dist",
"pack-tarball": "npm pack"
},
"license": "MIT",
Expand Down
1 change: 1 addition & 0 deletions packages/list/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"scripts": {
"prebuild": "rimraf dist",
"build": "tsc --project tsconfig.bundle.json --newLine LF",
"build:incremental": "tsc --incremental --project tsconfig.bundle.json --newLine LF --sourceMap false --excludeDirectories dist",
"pack-tarball": "npm pack"
},
"license": "MIT",
Expand Down
1 change: 1 addition & 0 deletions packages/listable/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"scripts": {
"prebuild": "rimraf dist",
"build": "tsc --project tsconfig.bundle.json --newLine LF",
"build:incremental": "tsc --incremental --project tsconfig.bundle.json --newLine LF --sourceMap false --excludeDirectories dist",
"pack-tarball": "npm pack"
},
"license": "MIT",
Expand Down
1 change: 1 addition & 0 deletions packages/profiler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"scripts": {
"prebuild": "rimraf dist",
"build": "tsc --project tsconfig.bundle.json --newLine LF",
"build:incremental": "tsc --incremental --project tsconfig.bundle.json --newLine LF --sourceMap false --excludeDirectories dist",
"pack-tarball": "npm pack"
},
"license": "MIT",
Expand Down
1 change: 1 addition & 0 deletions packages/publish/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"scripts": {
"prebuild": "rimraf dist",
"build": "tsc --project tsconfig.bundle.json --newLine LF",
"build:incremental": "tsc --incremental --project tsconfig.bundle.json --newLine LF --sourceMap false --excludeDirectories dist",
"pack-tarball": "npm pack"
},
"license": "MIT",
Expand Down
1 change: 1 addition & 0 deletions packages/run/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"scripts": {
"prebuild": "rimraf dist",
"build": "tsc --project tsconfig.bundle.json --newLine LF",
"build:incremental": "tsc --incremental --project tsconfig.bundle.json --newLine LF --sourceMap false --excludeDirectories dist",
"pack-tarball": "npm pack"
},
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion packages/tsconfig.bundle.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@
"sourceMap": true,
"strict": true
},
"exclude": ["**/*.spec.ts", "**/*.test.js", "**/*.test.ts", "**/__fixtures__/**/*.*", "**/__mocks__/**/*.*"]
"exclude": ["**/dist/**", "**/__fixtures__/**/*.*", "**/__mocks__/**/*.*", "**/__tests__/**/*.*"]
}
1 change: 1 addition & 0 deletions packages/version/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"scripts": {
"prebuild": "rimraf dist",
"build": "tsc --project tsconfig.bundle.json --newLine LF",
"build:incremental": "tsc --incremental --project tsconfig.bundle.json --newLine LF --sourceMap false --excludeDirectories dist",
"pack-tarball": "npm pack"
},
"license": "MIT",
Expand Down
2 changes: 2 additions & 0 deletions packages/watch/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"scripts": {
"prebuild": "rimraf dist",
"build": "tsc --project tsconfig.bundle.json --newLine LF",
"build:incremental": "tsc --incremental --project tsconfig.bundle.json --newLine LF --sourceMap false --excludeDirectories dist",
"pack-tarball": "npm pack"
},
"license": "MIT",
Expand All @@ -38,6 +39,7 @@
"path": "^0.12.7"
},
"devDependencies": {
"mock-stdin": "^1.0.0",
"rimraf": "^3.0.2",
"yargs-parser": "^21.1.1"
}
Expand Down
30 changes: 30 additions & 0 deletions packages/watch/src/__tests__/watch-command.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ jest.mock('@lerna-lite/watch', () => jest.requireActual('../watch-command'));

// jest.useFakeTimers({ timerLimit: 100 });

import mockStdin from 'mock-stdin';
import path from 'path';
import yargParser from 'yargs-parser';

Expand Down Expand Up @@ -87,7 +88,18 @@ const createArgv = (cwd: string, ...args: string[]) => {
};

describe('Watch Command', () => {
const stdinIsTTY = process.stdin.isTTY;
const stdoutIsTTY = process.stdout.isTTY;
const stdin = mockStdin.stdin();

beforeEach(() => {
process.stdin.isTTY = true;
process.stdout.isTTY = true;
});

afterEach(() => {
process.stdin.isTTY = stdinIsTTY;
process.stdout.isTTY = stdoutIsTTY;
process.exitCode = undefined;
});

Expand Down Expand Up @@ -494,5 +506,23 @@ describe('Watch Command', () => {
shell: true,
});
});

it('should execute watch add callback and stop the watch process when typing "x" in the shell', async () => {
const mockExit = jest.spyOn(process, 'exit').mockImplementation((number) => {
throw new Error('process.exit: ' + number);
});

try {
// prettier-ignore
await lernaWatch(testDir)('--emit-changes-delay', '0', '--scope', 'package-2', '--', 'echo $LERNA_PACKAGE_NAME');
const promise = watchAddHandler('add', path.join(testDir, 'packages/package-2/some-file.ts'));
stdin.send('x');
stdin.end();
await promise;
} catch (e) {
expect(mockExit).toHaveBeenCalled();
mockExit.mockRestore();
}
});
});
});
19 changes: 17 additions & 2 deletions packages/watch/src/watch-command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import chokidar from 'chokidar';
import path from 'path';

import { CHOKIDAR_AVAILABLE_OPTIONS, EMIT_CHANGES_DELAY, FILE_DELIMITER } from './constants';
import { ChangesStructure, ChokidarEventType } from './models';
import { ChangesStructure } from './models';

export function factory(argv: WatchCommandOption) {
return new WatchCommand(argv);
Expand Down Expand Up @@ -64,6 +64,19 @@ export class WatchCommand extends Command<WatchCommandOption & FilterOptions> {

this._count = this._filteredPackages.length;
this._packagePlural = this._count === 1 ? 'package' : 'packages';

// optional keystroke to exit the watch cleanly
if (process.stdin.isTTY) {
this.logger.info('watch', 'Press "x" to exit watch mode.');
process.stdin.setRawMode(true);
process.stdin.resume();
process.stdin.on('data', (key) => {
if (key.toString().toLowerCase() === 'x') {
this.logger.info('watch', 'Exiting the watch...');
process.exit(0);
}
});
}
}

async execute() {
Expand Down Expand Up @@ -142,6 +155,8 @@ export class WatchCommand extends Command<WatchCommandOption & FilterOptions> {
}

protected executeCommandCallback() {
const debounceDelay = this.options.emitChangesDelay ?? EMIT_CHANGES_DELAY;

return new Promise((resolve) => {
// once we reached emit change stability threshold, we'll fire events for each packages & events while the file paths array will be merged
if (this._timer) clearTimeout(this._timer as NodeJS.Timeout);
Expand Down Expand Up @@ -190,7 +205,7 @@ export class WatchCommand extends Command<WatchCommandOption & FilterOptions> {
resolve({ changedPkg, mergedFiles: changedFilesCsv });
}
}
}, this.options.emitChangesDelay ?? EMIT_CHANGES_DELAY);
}, debounceDelay);
});
}

Expand Down
6 changes: 6 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit d0cf2d9

Please sign in to comment.