Skip to content

Commit

Permalink
cli: fix help message
Browse files Browse the repository at this point in the history
The CLI parsing logic is broken in `@theia/cli`. The help doesn't show
the right information.

The issue comes from using `yargs` at the script level in some places,
leading to corrupt global `yargs` state.

This commit refactors code around so that `--help` works as expected.
  • Loading branch information
paul-marechal committed Aug 4, 2021
1 parent cff1eda commit cdfb405
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 141 deletions.
47 changes: 32 additions & 15 deletions dev-packages/application-manager/src/application-package-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,38 @@ import * as cp from 'child_process';
import { ApplicationPackage, ApplicationPackageOptions } from '@theia/application-package';
import { WebpackGenerator, FrontendGenerator, BackendGenerator } from './generator';
import { ApplicationProcess } from './application-process';
import { GeneratorOptions } from './generator/abstract-generator';
import yargs = require('yargs');

export class ApplicationPackageManager {

// eslint-disable-next-line @typescript-eslint/tslint/config
static defineGeneratorOptions<T>(cli: yargs.Argv<T>): yargs.Argv<T & {
'mode': 'development' | 'production'
'split-frontend'?: boolean
}> {
return cli
.option('mode', {
description: 'Generation mode to use',
choices: ['development', 'production'],
default: 'production' as const,
})
.option('split-frontend', {
description: 'Split frontend modules into separate chunks. By default enabled in the `development` mode and disabled in the `production` mode.',
type: 'boolean'
});
}

readonly pck: ApplicationPackage;
/** application process */
readonly process: ApplicationProcess;
/** manager process */
protected readonly __process: ApplicationProcess;
protected readonly webpack: WebpackGenerator;
protected readonly backend: BackendGenerator;
protected readonly frontend: FrontendGenerator;

constructor(options: ApplicationPackageOptions) {
this.pck = new ApplicationPackage(options);
this.process = new ApplicationProcess(this.pck, options.projectPath);
this.__process = new ApplicationProcess(this.pck, path.join(__dirname, '..'));
this.webpack = new WebpackGenerator(this.pck);
this.backend = new BackendGenerator(this.pck);
this.frontend = new FrontendGenerator(this.pck);
}

protected async remove(fsPath: string): Promise<void> {
Expand All @@ -48,24 +61,28 @@ export class ApplicationPackageManager {
}

async clean(): Promise<void> {
await this.remove(this.pck.lib());
await this.remove(this.pck.srcGen());
await this.remove(this.webpack.genConfigPath);
await Promise.all([
this.remove(this.pck.lib()),
this.remove(this.pck.srcGen()),
this.remove(new WebpackGenerator(this.pck).genConfigPath)
]);
}

async generate(): Promise<void> {
await this.webpack.generate();
await this.backend.generate();
await this.frontend.generate();
async generate(options: GeneratorOptions = {}): Promise<void> {
await Promise.all([
new WebpackGenerator(this.pck, options).generate(),
new BackendGenerator(this.pck, options).generate(),
new FrontendGenerator(this.pck, options).generate(),
]);
}

async copy(): Promise<void> {
await fs.ensureDir(this.pck.lib());
await fs.copy(this.pck.frontend('index.html'), this.pck.lib('index.html'));
}

async build(args: string[] = []): Promise<void> {
await this.generate();
async build(args: string[] = [], options: GeneratorOptions = {}): Promise<void> {
await this.generate(options);
await this.copy();
return this.__process.run('webpack', args);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,22 @@

import * as os from 'os';
import * as fs from 'fs-extra';
import * as yargs from 'yargs';
import { ApplicationPackage } from '@theia/application-package';

const argv = yargs.option('mode', {
description: 'Mode to use',
choices: ['development', 'production'],
default: 'production' as 'development' | 'production',
}).option('split-frontend', {
description: 'Split frontend modules into separate chunks. By default enabled in the dev mode and disabled in the prod mode.',
type: 'boolean',
}).option('app-target', {
description: 'The target application type. Overrides ["theia.target"] in the application\'s package.json.',
choices: ['browser', 'electron'],
}).argv;
const splitFrontend: boolean = argv['split-frontend'] ?? argv.mode === 'development';
export interface GeneratorOptions {
mode?: 'development' | 'production'
splitFrontend?: boolean
}

export abstract class AbstractGenerator {

constructor(
protected readonly pck: ApplicationPackage
protected readonly pck: ApplicationPackage,
protected options: GeneratorOptions = {}
) { }

protected compileFrontendModuleImports(modules: Map<string, string>): string {
const splitFrontend = this.options.splitFrontend ?? this.options.mode !== 'production';
return this.compileModuleImports(modules, splitFrontend ? 'import' : 'require');
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@

/* eslint-disable @typescript-eslint/indent */

import { AbstractGenerator } from './abstract-generator';
import { AbstractGenerator, GeneratorOptions } from './abstract-generator';
import { existsSync, readFileSync } from 'fs';

export class FrontendGenerator extends AbstractGenerator {

async generate(): Promise<void> {
async generate(options: GeneratorOptions = {}): Promise<void> {
const frontendModules = this.pck.targetFrontendModules;
await this.write(this.pck.frontend('index.html'), this.compileIndexHtml(frontendModules));
await this.write(this.pck.frontend('index.js'), this.compileIndexJs(frontendModules));
Expand Down
Loading

0 comments on commit cdfb405

Please sign in to comment.