From 55176f4961b7d0a313bb686e72014042c97ff135 Mon Sep 17 00:00:00 2001 From: Mathias Schreck Date: Thu, 24 Jun 2021 12:31:05 +0200 Subject: [PATCH 1/4] Remove deprecated TSLint TSLint has been deprecated in favor of @typescript-eslint. --- package.json | 4 - tslint.json | 381 --------------------------------------------------- 2 files changed, 385 deletions(-) delete mode 100644 tslint.json diff --git a/package.json b/package.json index 9a0b015..59e3573 100644 --- a/package.json +++ b/package.json @@ -28,11 +28,7 @@ "devDependencies": { "@types/node": "^13.7.0", "clean-publish": "~1.1.2", - "tslint": "5.20.1", - "tslint-eslint-rules": "~5.4.0", - "tslint-microsoft-contrib": "~6.2.0", "typescript": "3.7.2", - "vrsource-tslint-rules": "6.0.0" }, "scripts": { "clean": "rm index.js", diff --git a/tslint.json b/tslint.json deleted file mode 100644 index f1c234f..0000000 --- a/tslint.json +++ /dev/null @@ -1,381 +0,0 @@ -{ - "linterOptions": { - "format": "verbose" - }, - "rulesDirectory": [ - "node_modules/tslint-eslint-rules/dist/rules", - "node_modules/tslint-microsoft-contrib", - "node_modules/vrsource-tslint-rules/rules" - ], - "rules": { - "adjacent-overload-signatures": true, - "align": [ - true, - "parameters", - "arguments", - "statements" - ], - "array-type": [true, "array"], - "arrow-parens": true, - "arrow-return-shorthand": false, - "await-promise": false, - "ban": false, - "ban-comma-operator": true, - "ban-ts-ignore": true, - "ban-types": [ - true, - ["Object", "Avoid using the `Object` type. Did you mean `object`?"], - ["Function", "Avoid using the `Function` type. Prefer a specific function type, like `() => void`."], - ["Boolean", "Avoid using the `Boolean` type. Did you mean `boolean`?"], - ["Number", "Avoid using the `Number` type. Did you mean `number`?"], - ["String", "Avoid using the `String` type. Did you mean `string`?"], - ["Symbol", "Avoid using the `Symbol` type. Did you mean `symbol`?"] - ], - "binary-expression-operand-order": false, - "callable-types": true, - "class-name": true, - "comment-format": [true, "check-space"], - "comment-type": false, - "completed-docs": false, - "curly": true, - "cyclomatic-complexity": [true, 13], - "deprecation": true, - "encoding": true, - "eofline": true, - "file-header": false, - "file-name-casing": [true, "kebab-case"], - "forin": true, - "function-constructor": true, - "import-blacklist": [true, "rxjs", "lodash"], - "import-spacing": true, - "increment-decrement": false, - "indent": false, - "interface-name": [false, "never-prefix"], - "interface-over-type-literal": true, - "invalid-void": true, - "jsdoc-format": true, - "label-position": false, - "linebreak-style": false, - "match-default-export-name": true, - "max-classes-per-file": [true, 5], - "max-file-line-count": false, - "max-line-length": false, - "member-access": [ - true, - "check-accessor", - "check-constructor" - ], - "member-ordering": [ - true, - { - "order": [ - "public-static-field", - "protected-static-field", - "private-static-field", - "public-instance-field", - "protected-instance-field", - "private-instance-field", - "constructor", - "public-instance-method", - "public-static-method", - "protected-instance-method", - "protected-static-method", - "private-instance-method", - "private-static-method" - ] - } - ], - "new-parens": true, - "newline-before-return": false, - "newline-per-chained-call": false, - "no-angle-bracket-type-assertion": true, - "no-any": true, - "no-arg": true, - "no-async-without-await": true, - "no-bitwise": false, - "no-boolean-literal-compare": false, - "no-conditional-assignment": true, - "no-consecutive-blank-lines": true, - "no-console": false, - "no-construct": true, - "no-debugger": true, - "no-default-export": true, - "no-default-import": false, - "no-duplicate-imports": true, - "no-duplicate-super": true, - "no-duplicate-switch-case": true, - "no-duplicate-variable": true, - "no-dynamic-delete": false, - "no-empty": [true, "allow-empty-functions"], - "no-empty-interface": false, - "no-eval": true, - "no-floating-promises": false, - "no-for-in-array": true, - "no-for-in": true, - "no-implicit-dependencies": false, - "no-import-side-effect": false, - "no-inferrable-types": [true, "ignore-params", "ignore-properties"], - "no-inferred-empty-object-type": false, - "no-internal-module": true, - "no-invalid-template-strings": true, - "no-invalid-this": [false], - "no-irregular-whitespace": true, - "no-magic-numbers": false, - "no-mergeable-namespace": true, - "no-misused-new": true, - "no-namespace": false, - "no-non-null-assertion": true, - "no-null-keyword": false, - "no-null-undefined-union": false, - "no-object-literal-type-assertion": true, - "no-parameter-properties": true, - "no-parameter-reassignment": false, - "no-promise-as-boolean": false, - "no-redundant-jsdoc": true, - "no-reference": false, - "no-reference-import": true, - "no-require-imports": false, - "no-restricted-globals": false, - "no-return-await": true, - "no-shadowed-variable": [true, "temporalDeadZone"], - "no-string-literal": true, - "no-string-throw": true, - "no-submodule-imports": false, - "no-switch-case-fall-through": true, - "no-tautology-expression": true, - "no-this-assignment": true, - "no-trailing-whitespace": true, - "no-unbound-method": false, - "no-unnecessary-callback-wrapper": false, - "no-unnecessary-class": true, - "no-unnecessary-initializer": true, - "no-unnecessary-qualifier": true, - "no-unnecessary-type-assertion": true, - "no-unsafe-any": false, - "no-unsafe-finally": true, - "no-unused-expression": true, - "no-unused-variable": false, - "no-use-before-declare": false, - "no-var-keyword": true, - "no-var-requires": true, - "no-void-expression": false, - "non-literal-require": false, - "number-literal-format": true, - "object-literal-key-quotes": [true, "as-needed"], - "object-literal-shorthand": false, - "object-literal-sort-keys": false, - "one-line": [ - true, - "check-catch", - "check-else", - "check-finally", - "check-open-brace", - "check-whitespace" - ], - "one-variable-per-declaration": true, - "only-arrow-functions": [true, "allow-declarations"], - "prefer-conditional-expression": false, - "prefer-const": true, - "prefer-for-of": false, - "prefer-function-over-method": false, - "prefer-method-signature": false, - "prefer-object-spread": false, - "prefer-readonly": false, - "prefer-switch": false, - "prefer-template": false, - "prefer-while": true, - "promise-function-async": false, - "quotemark": [true, "single", "avoid-escape", "jsx-double"], - "radix": false, - "restrict-plus-operands": false, - "return-undefined": false, - "semicolon": [true, "always"], - "space-before-function-paren": [true, { "anonymous": "never", "named": "never" }], - "space-within-parens": [true, 0], - "static-this": true, - "strict-boolean-expressions": false, - "strict-string-expressions": false, - "strict-type-predicates": true, - "switch-default": false, - "switch-final-break": false, - "trailing-comma": [ - true, - { - "esSpecCompliant": true, - "singleline": "never", - "multiline": { - "arrays": "always", - "exports": "always", - "functions": "never", - "imports": "always", - "objects": "always", - "typeLiterals": "always" - } - } - ], - "triple-equals": [true, "allow-null-check"], - "type-literal-delimiter": true, - "typedef": [ - true, - "call-signature", - "parameter", - "arrow-parameter", - "property-declaration", - "member-variable-declaration" - ], - "typedef-whitespace": [ - true, - { - "call-signature": "nospace", - "index-signature": "nospace", - "parameter": "nospace", - "property-declaration": "nospace", - "variable-declaration": "nospace" - }, - { - "call-signature": "onespace", - "index-signature": "onespace", - "parameter": "onespace", - "property-declaration": "onespace", - "variable-declaration": "onespace" - } - ], - "unified-signatures": false, - "unnecessary-bind": true, - "unnecessary-constructor": true, - "unnecessary-else": false, - "use-default-type-parameter": false, - "use-isnan": true, - "variable-name": [ - true, - "ban-keywords", - "check-format", - "allow-pascal-case", - ], - "whitespace": [ - true, - "check-branch", - "check-decl", - "check-operator", - "check-module", - "check-separator", - "check-type", - "check-type-operator" - ], - - - "array-bracket-spacing": false, - "block-spacing": false, - "brace-style": [ - true, - "1tbs", - { - "allowSingleLine": true - } - ], - "handle-callback-err": false, - "no-empty-character-class": true, - "no-ex-assign": true, - "no-extra-boolean-cast": false, - "no-extra-semi": false, - "no-inner-declarations": true, - "no-multi-spaces": [ - true, - { - "exceptions": { - "BinaryExpression": true - } - } - ], - "no-unexpected-multiline": false, - "object-curly-spacing": false, - "sort-imports": false, - "space-in-parens": false, - "ter-arrow-body-style": false, - "ter-arrow-parens": false, - "ter-arrow-spacing": false, - "ter-func-call-spacing": false, - "ter-indent": [true, "tab", { "SwitchCase": 1, "VariableDeclarator": 1 }], - "ter-max-len": false, - "ter-no-irregular-whitespace": false, - "ter-no-self-compare": false, - "ter-no-sparse-arrays": false, - "ter-prefer-arrow-callback": false, - "valid-jsdoc": false, - - - "chai-prefer-contains-to-index-of": false, - "chai-vague-errors": false, - "export-name": false, - "import-name": false, - "insecure-random": false, - "jquery-deferred-must-complete": false, - "max-func-body-length": false, - "missing-optional-annotation": false, - "mocha-avoid-only": false, - "mocha-no-side-effect-code": false, - "mocha-unneeded-done": true, - "no-banned-terms": true, - "no-constant-condition": [true, { "checkLoops": false }], - "no-control-regex": false, - "no-cookies": false, - "no-disable-auto-sanitization": true, - "no-document-domain": true, - "no-document-write": false, - "no-duplicate-parameter-names": false, - "no-empty-line-after-opening-brace": true, - "no-exec-script": true, - "no-for-in": false, - "no-function-constructor-with-string-args": false, - "no-function-expression": false, - "no-http-string": [ - true, - "http://www.w3.org/2000/svg", - "http://schemas.xmlsoap.org/soap/envelope/" - ], - "no-increment-decrement": false, - "no-inner-html": false, - "no-invalid-regexp": true, - "no-jquery-raw-elements": false, - "no-missing-visibility-modifiers": false, - "no-multiline-string": false, - "no-multiple-var-decl": false, - "no-octal-literal": true, - "no-regex-spaces": true, - "no-relative-imports": false, - "no-single-line-block-comment": false, - "no-sparse-arrays": true, - "no-string-based-set-immediate": true, - "no-string-based-set-interval": true, - "no-string-based-set-timeout": true, - "no-suspicious-comment": false, - "no-typeof-undefined": true, - "no-unexternalized-strings": false, - "no-unnecessary-bind": false, - "no-unnecessary-local-variable": true, - "no-unnecessary-override": true, - "no-unnecessary-semicolons": true, - "no-unsupported-browser-code": [true, ["IE 11", "Firefox > 40", "Chrome >= 45"]], - "no-useless-files": false, - "no-with-statement": true, - "possible-timing-attack": false, - "underscore-consistent-invocation": false, - "use-named-parameter": false, - - - "conditional-expression-parens": false, - "ext-variable-name": false, - "literal-spacing": [ - true, - { - "array": ["never"], - "object": ["always"], - "import": ["always"] - } - ], - "max-params": [true, 6], - "multiline-arrow": false, - "prefer-case-blocks": false, - "prefer-literal": false - } -} From 3a03a89d1e21fbf5820463b824c0faab8c9455d5 Mon Sep 17 00:00:00 2001 From: Mathias Schreck Date: Thu, 24 Jun 2021 12:32:08 +0200 Subject: [PATCH 2/4] Upgrade typescript --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 59e3573..1abec7b 100644 --- a/package.json +++ b/package.json @@ -23,12 +23,12 @@ "node": ">=11.0.0" }, "dependencies": { - "typescript": ">=3.7.5" + "typescript": ">=4.3.4" }, "devDependencies": { "@types/node": "^13.7.0", "clean-publish": "~1.1.2", - "typescript": "3.7.2", + "typescript": "4.3.4" }, "scripts": { "clean": "rm index.js", From 4f9177f62b21f254cd5b53d376ccbdab82266d63 Mon Sep 17 00:00:00 2001 From: Mathias Schreck Date: Thu, 24 Jun 2021 12:32:32 +0200 Subject: [PATCH 3/4] Upgrade remaining dependencies --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 1abec7b..b433a63 100644 --- a/package.json +++ b/package.json @@ -26,8 +26,8 @@ "typescript": ">=4.3.4" }, "devDependencies": { - "@types/node": "^13.7.0", - "clean-publish": "~1.1.2", + "@types/node": "^15.12.4", + "clean-publish": "~2.2.0", "typescript": "4.3.4" }, "scripts": { From b0a11ed909113712fdfc17a2ecb27865031356fa Mon Sep 17 00:00:00 2001 From: Mathias Schreck Date: Thu, 24 Jun 2021 12:33:04 +0200 Subject: [PATCH 4/4] Use proper command line argument parser Before running `npx parallel-typescript --wrokers` did not work because `--workers` is placed as the third argument which is also used as the configurable `tscPath`. --- index.ts | 455 ++++++++++++++++++++++++++++++--------------------- package.json | 1 + 2 files changed, 273 insertions(+), 183 deletions(-) diff --git a/index.ts b/index.ts index ab1db97..6be9c14 100644 --- a/index.ts +++ b/index.ts @@ -1,212 +1,301 @@ #!/usr/bin/env node -import * as childProcess from 'child_process'; -import { Worker } from 'worker_threads'; -import * as path from 'path'; - -import * as ts from 'typescript'; +import * as childProcess from "child_process"; +import { Worker } from "worker_threads"; +import * as path from "path"; +import { command, run, string, boolean, flag, option } from "cmd-ts"; + +import * as ts from "typescript"; + +interface Args { + tscPath: string; + project: string; + useWorkers: boolean; + verbose: boolean; +} const enum ProjectState { - WaitForDeps, - ReadyToBuild, - Building, - Built, + WaitForDeps, + ReadyToBuild, + Building, + Built, } function assert(val: boolean, msg: string): void { - if (!val) { - console.error(msg); - process.exit(1); - } + if (!val) { + console.error(msg); + process.exit(1); + } } class ProjectsTree { - private projectsState = new Map(); - private dependenciesForProject = new Map(); - - public getBuildFlow(): number[] { - const copy = new ProjectsTree(); - copy.projectsState = new Map(this.projectsState); - copy.dependenciesForProject = new Map(this.dependenciesForProject); - - const result = []; - while (!copy.areAllProjectsBuilt()) { - const projectsToBuild = copy.takeProjectsReadyToBuild(); - result.push(projectsToBuild.length); - projectsToBuild.forEach(copy.setProjectBuilt, copy); - } - - return result; - } - - public projectsCount(): number { - return this.projectsState.size; - } - - public addProjectWithDeps(projectPath: string, projDeps: string[]): void { - this.dependenciesForProject.set(projectPath, projDeps.slice()); - this.updateProjectsState(); - } - - public validateState(): void { - this.dependenciesForProject.forEach((deps: string[], projectPath: string) => { - assert(this.projectsState.get(projectPath) !== undefined, `Cannot find state for ${projectPath}`); - - deps.forEach((depPath: string) => { - assert(this.projectsState.get(depPath) !== undefined, `Cannot find state for ${depPath}`); - }); - }); - } - - public takeProjectsReadyToBuild(): string[] { - this.updateProjectsState(); - const result: string[] = []; - this.projectsState.forEach((state: ProjectState, projectPath: string) => { - if (state === ProjectState.ReadyToBuild) { - result.push(projectPath); - } - }); - - for (const projectPath of result) { - this.projectsState.set(projectPath, ProjectState.Building); - } - - return result; - } - - public setProjectBuilt(projectPath: string): void { - assert(this.projectsState.get(projectPath) === ProjectState.Building, `State of ${projectPath} is not building`); - this.projectsState.set(projectPath, ProjectState.Built); - this.updateProjectsState(); - } - - public areAllProjectsBuilt(): boolean { - let result = true; - - this.projectsState.forEach((state: ProjectState) => { - result = result && state === ProjectState.Built; - }); - - return result; - } - - private updateProjectsState(): void { - this.dependenciesForProject.forEach((deps: string[], projectPath: string) => { - const currentState = this.projectsState.get(projectPath); - if (currentState === ProjectState.Built || currentState === ProjectState.Building) { - return; - } - - const allDepsAreBuilt = deps.every((depPath: string) => this.projectsState.get(depPath) === ProjectState.Built); - this.projectsState.set(projectPath, allDepsAreBuilt ? ProjectState.ReadyToBuild : ProjectState.WaitForDeps); - }); - } + private projectsState = new Map(); + private dependenciesForProject = new Map(); + + public getBuildFlow(): number[] { + const copy = new ProjectsTree(); + copy.projectsState = new Map(this.projectsState); + copy.dependenciesForProject = new Map(this.dependenciesForProject); + + const result = []; + while (!copy.areAllProjectsBuilt()) { + const projectsToBuild = copy.takeProjectsReadyToBuild(); + result.push(projectsToBuild.length); + projectsToBuild.forEach(copy.setProjectBuilt, copy); + } + + return result; + } + + public projectsCount(): number { + return this.projectsState.size; + } + + public addProjectWithDeps(projectPath: string, projDeps: string[]): void { + this.dependenciesForProject.set(projectPath, projDeps.slice()); + this.updateProjectsState(); + } + + public validateState(): void { + this.dependenciesForProject.forEach( + (deps: string[], projectPath: string) => { + assert( + this.projectsState.get(projectPath) !== undefined, + `Cannot find state for ${projectPath}` + ); + + deps.forEach((depPath: string) => { + assert( + this.projectsState.get(depPath) !== undefined, + `Cannot find state for ${depPath}` + ); + }); + } + ); + } + + public takeProjectsReadyToBuild(): string[] { + this.updateProjectsState(); + const result: string[] = []; + this.projectsState.forEach((state: ProjectState, projectPath: string) => { + if (state === ProjectState.ReadyToBuild) { + result.push(projectPath); + } + }); + + for (const projectPath of result) { + this.projectsState.set(projectPath, ProjectState.Building); + } + + return result; + } + + public setProjectBuilt(projectPath: string): void { + assert( + this.projectsState.get(projectPath) === ProjectState.Building, + `State of ${projectPath} is not building` + ); + this.projectsState.set(projectPath, ProjectState.Built); + this.updateProjectsState(); + } + + public areAllProjectsBuilt(): boolean { + let result = true; + + this.projectsState.forEach((state: ProjectState) => { + result = result && state === ProjectState.Built; + }); + + return result; + } + + private updateProjectsState(): void { + this.dependenciesForProject.forEach( + (deps: string[], projectPath: string) => { + const currentState = this.projectsState.get(projectPath); + if ( + currentState === ProjectState.Built || + currentState === ProjectState.Building + ) { + return; + } + + const allDepsAreBuilt = deps.every( + (depPath: string) => + this.projectsState.get(depPath) === ProjectState.Built + ); + this.projectsState.set( + projectPath, + allDepsAreBuilt ? ProjectState.ReadyToBuild : ProjectState.WaitForDeps + ); + } + ); + } } function durationToStr(durInMs: number): string { - return `${(durInMs / 1000).toFixed(2)}s`; + return `${(durInMs / 1000).toFixed(2)}s`; } -function buildInParallel(projectsTree: ProjectsTree, startTime: number): void { - if (projectsTree.areAllProjectsBuilt()) { - console.log(`${projectsTree.projectsCount()} projects are compiled successfully in ${durationToStr(Date.now() - startTime)}`); - return; - } - - const projectsToBuild = projectsTree.takeProjectsReadyToBuild(); - if (projectsToBuild.length === 0) { - return; - } - - for (const project of projectsToBuild) { - const projectStartTime = Date.now(); - console.log(`Running build for ${project}...`); - - const argv = [ - '-b', - project, - ]; - - if (process.argv.includes('--verbose')) { - argv.push('--verbose'); - } - - const tscPath = path.resolve(process.cwd(), process.argv[3] || 'node_modules/typescript/lib/tsc.js'); - - if (process.argv.includes('--workers')) { - const worker = new Worker(tscPath, { argv }); - - worker.on('exit', (code: number) => { - if (code !== 0) { - console.error(`ERROR: Cannot build ${project}`); - process.exit(1); - } - - console.log(` ${project} is built successfully in ${durationToStr(Date.now() - projectStartTime)}`); - - projectsTree.setProjectBuilt(project); - buildInParallel(projectsTree, startTime); - }); - } else { - childProcess.exec( - `node ${tscPath} ${argv.join(' ')}`, - (error: childProcess.ExecException | null, stdout: string, stderr: string) => { - if (error !== null) { - console.error(`Cannot build ${project}:\n${stderr || stdout}`); - process.exit(1); - } - - // console.log(stdout); - - console.log(` ${project} is built successfully in ${durationToStr(Date.now() - projectStartTime)}`); - - projectsTree.setProjectBuilt(project); - buildInParallel(projectsTree, startTime); - } - ); - } - } +function buildInParallel( + projectsTree: ProjectsTree, + startTime: number, + args: Args +): void { + if (projectsTree.areAllProjectsBuilt()) { + console.log( + `${projectsTree.projectsCount()} projects are compiled successfully in ${durationToStr( + Date.now() - startTime + )}` + ); + return; + } + + const projectsToBuild = projectsTree.takeProjectsReadyToBuild(); + if (projectsToBuild.length === 0) { + return; + } + + for (const project of projectsToBuild) { + const projectStartTime = Date.now(); + console.log(`Running build for ${project}...`); + + const argv = ["-b", project]; + + if (args.verbose) { + argv.push("--verbose"); + } + + const tscPath = path.resolve(process.cwd(), args.tscPath); + + if (args.useWorkers) { + const worker = new Worker(tscPath, { argv }); + + worker.on("exit", (code: number) => { + if (code !== 0) { + console.error(`ERROR: Cannot build ${project}`); + process.exit(1); + } + + console.log( + ` ${project} is built successfully in ${durationToStr( + Date.now() - projectStartTime + )}` + ); + + projectsTree.setProjectBuilt(project); + buildInParallel(projectsTree, startTime, args); + }); + } else { + childProcess.exec( + `node ${tscPath} ${argv.join(" ")}`, + ( + error: childProcess.ExecException | null, + stdout: string, + stderr: string + ) => { + if (error !== null) { + console.error(`Cannot build ${project}:\n${stderr || stdout}`); + process.exit(1); + } + + // console.log(stdout); + + console.log( + ` ${project} is built successfully in ${durationToStr( + Date.now() - projectStartTime + )}` + ); + + projectsTree.setProjectBuilt(project); + buildInParallel(projectsTree, startTime, args); + } + ); + } + } } -function main(): void { - let project = process.argv[2]; - if (project === undefined) { - project = path.resolve(process.cwd(), 'tsconfig.json'); - } else { - project = path.resolve(project); - } +function main(args: Args): void { + let project = args.project; - const host = ts.createSolutionBuilderHost(); - const builder = ts.createSolutionBuilder(host, [project], { incremental: true }) as any; + const host = ts.createSolutionBuilderHost(); + const builder = ts.createSolutionBuilder(host, [project], { + incremental: true, + }) as any; - // THIS IS PRIVATE API - // to force ts read all configs - void builder.getBuildOrder(); + // THIS IS PRIVATE API + // to force ts read all configs + void builder.getBuildOrder(); - // THIS IS PRIVATE API - // it isn't enough to know build order - // we need to know which one could be run in parallel - const parsedConfigs: any[] = builder.getAllParsedConfigs(); + // THIS IS PRIVATE API + // it isn't enough to know build order + // we need to know which one could be run in parallel + const parsedConfigs: any[] = builder.getAllParsedConfigs(); - const tree = new ProjectsTree(); + const tree = new ProjectsTree(); - for (const proj of parsedConfigs) { - const deps = proj.projectReferences && proj.projectReferences.map((x: any) => { - if (ts.sys.fileExists(x.path)) { - return x.path; - } + for (const proj of parsedConfigs) { + const deps = + proj.projectReferences && + proj.projectReferences.map((x: any) => { + if (ts.sys.fileExists(x.path)) { + return x.path; + } - return ts.findConfigFile(x.path, ts.sys.fileExists); - }); + return ts.findConfigFile(x.path, ts.sys.fileExists); + }); - tree.addProjectWithDeps(proj.options.configFilePath, deps ? deps : []); - } + tree.addProjectWithDeps(proj.options.configFilePath, deps ? deps : []); + } - tree.validateState(); + tree.validateState(); - console.log('build flow:', JSON.stringify(tree.getBuildFlow())); + console.log("build flow:", JSON.stringify(tree.getBuildFlow())); - buildInParallel(tree, Date.now()); + buildInParallel(tree, Date.now(), args); } -main(); +const app = command({ + name: "ptsc", + description: "Compile typescript projects in parallel.", + version: "0.0.1", + handler(args) { + main(args); + }, + args: { + tscPath: option({ + long: "tsc-path", + type: string, + defaultValue() { + return "node_modules/typescript/lib/tsc.js"; + }, + defaultValueIsSerializable: true, + }), + project: option({ + long: "project", + type: string, + defaultValue() { + return path.resolve(process.cwd(), "tsconfig.json"); + }, + defaultValueIsSerializable: true, + }), + useWorkers: flag({ + long: "workers", + type: boolean, + defaultValue() { + return false; + }, + defaultValueIsSerializable: true, + }), + verbose: flag({ + long: "verbose", + type: boolean, + defaultValue() { + return false; + }, + defaultValueIsSerializable: true, + }), + }, +}); + +run(app, process.argv.slice(2)); diff --git a/package.json b/package.json index b433a63..5f04486 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "node": ">=11.0.0" }, "dependencies": { + "cmd-ts": "^0.7.0", "typescript": ">=4.3.4" }, "devDependencies": {