Skip to content

Commit

Permalink
feat(cli), introduce "wait" handler for commands that never exit (#8625)
Browse files Browse the repository at this point in the history
Some commands should never exit. Such as `bit watch` or `bit server`
that helps IDE to communicate with bit.
Instead of hacking the `report` handler by waiting for the promise
forever, this PR adds a new handler `wait`, which never exits the
process.
  • Loading branch information
davidfirst authored Mar 5, 2024
1 parent 1e1bcbb commit e0c4b0e
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 4 deletions.
2 changes: 1 addition & 1 deletion scopes/harmony/api-server/api-server.main.runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,13 @@ export class ApiServerMain {
const port = options.port || 3000;
const server = await this.express.listen(port);

// never ending promise to not exit the process (is there a better way?)
return new Promise((resolve, reject) => {
server.on('error', (err) => {
reject(err);
});
server.on('listening', () => {
this.logger.consoleSuccess(`Bit Server is listening on port ${port}`);
resolve(true);
});
});
}
Expand Down
3 changes: 1 addition & 2 deletions scopes/harmony/api-server/server.cmd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ export class ServerCmd implements Command {

constructor(private apiServer: ApiServerMain) {}

async report(args, options: { port: number; compile: boolean }): Promise<string> {
async wait(args, options: { port: number; compile: boolean }) {
await this.apiServer.runApiServer(options);
return 'server is running successfully'; // should never get here, the previous line is blocking
}
}
8 changes: 8 additions & 0 deletions scopes/harmony/cli/command-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ export class CommandRunner {
if (this.command.report) {
return await this.runReportHandler();
}
if (this.command.wait) {
return await this.runWaitHandler();
}
} catch (err: any) {
return handleErrorAndExit(err, this.commandName);
}
Expand Down Expand Up @@ -95,6 +98,11 @@ export class CommandRunner {
return this.writeAndExit(`${data}\n`, exitCode);
}

private async runWaitHandler() {
if (!this.command.wait) throw new Error('runReportHandler expects command.wait to be implemented');
await this.command.wait(this.args, this.flags);
}

/**
* the loader and logger.console write output to the console during the command execution.
* for internals commands, such as, _put, _fetch, the command.loader = false.
Expand Down
10 changes: 9 additions & 1 deletion src/cli/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,21 @@ export interface Command {
render?(args: CLIArgs, flags: Flags): Promise<RenderResult | React.ReactElement>;

/**
* Command handler which is called for legacy commands or when process.isTTY is false
* Command handler which prints the return value to the console and exits.
* If the command has both, `render` and `report`, this one will be called when process.isTTY is false.
* @param args - arguments object as defined in name.
* @param flags - command flags as described in options.
* @return - Report object. The Report.data is printed to the stdout as is.
*/
report?(args: CLIArgs, flags: Flags): Promise<string | Report>;

/**
* Command handler which never exits the process
* @param args - arguments object as defined in name.
* @param flags - command flags as described in options.
*/
wait?(args: CLIArgs, flags: Flags): Promise<void>;

/**
* Optional handler to provide a raw result of the command.
* Will be go called if '-j'/'--json' option is provided by user.
Expand Down

0 comments on commit e0c4b0e

Please sign in to comment.