Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(bit-cli-server), fix command help pages, "bit -v" and "bit new" #9080

Merged
merged 5 commits into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions scopes/harmony/api-server/cli-raw.route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CLIMain, CLIParser } from '@teambit/cli';
import { CLIMain, CLIParser, YargsExitWorkaround } from '@teambit/cli';
import chalk from 'chalk';
import { Route, Request, Response } from '@teambit/express';
import { Logger } from '@teambit/logger';
Expand Down Expand Up @@ -40,12 +40,17 @@ export class CLIRawRoute implements Route {
await this.apiForIDE.logFinishCmdHistory(cmdStrLog, 0);
res.json(result);
} catch (err: any) {
await this.apiForIDE.logFinishCmdHistory(cmdStrLog, 1);
res.status(500);
res.jsonp({
message: err.message,
error: err,
});
if (err instanceof YargsExitWorkaround) {
res.json({ data: err.helpMsg, exitCode: err.exitCode });
} else {
this.logger.error(`cli-raw server: got an error for ${command}`, err);
await this.apiForIDE.logFinishCmdHistory(cmdStrLog, 1);
res.status(500);
res.jsonp({
message: err.message,
error: err,
});
}
} finally {
this.logger.clearStatusLine();
// change chalk back to false, otherwise, the IDE will have colors. (this is a global setting)
Expand Down
2 changes: 1 addition & 1 deletion scopes/harmony/bit/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ function warnIfRunningAsRoot() {
}
}

function printBitVersionIfAsked() {
export function printBitVersionIfAsked() {
if (process.argv[2]) {
if (['-V', '-v', '--version'].includes(process.argv[2])) {
const harmonyVersion = getBitVersionGracefully();
Expand Down
19 changes: 13 additions & 6 deletions scopes/harmony/bit/server-commander.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import EventSource from 'eventsource';
import { findScopePath } from '@teambit/scope.modules.find-scope-path';
import chalk from 'chalk';
import loader from '@teambit/legacy/dist/cli/loader';
import { printBitVersionIfAsked } from './bootstrap';

export class ServerPortFileNotFound extends Error {
constructor(filePath: string) {
Expand All @@ -16,6 +17,11 @@ export class ServerNotFound extends Error {
super(`bit server is not running on port ${port}`);
}
}
export class ScopeNotFound extends Error {
constructor(scopePath: string) {
super(`scope not found at ${scopePath}`);
}
}

type CommandResult = { data: any; exitCode: number };

Expand All @@ -34,14 +40,16 @@ export class ServerCommander {

process.exit(0);
} catch (err: any) {
if (err instanceof ServerPortFileNotFound || err instanceof ServerNotFound) throw err;
if (err instanceof ServerPortFileNotFound || err instanceof ServerNotFound || err instanceof ScopeNotFound)
throw err;
// eslint-disable-next-line no-console
console.error(chalk.red(err.message));
process.exit(1);
}
}

async runCommandWithHttpServer(): Promise<CommandResult | undefined> {
printBitVersionIfAsked();
const port = await this.getExistingUsedPort();
const url = `http://localhost:${port}/api`;
this.initSSE(url);
Expand Down Expand Up @@ -125,18 +133,17 @@ export class ServerCommander {
private getServerPortFilePath() {
const scopePath = findScopePath(process.cwd());
if (!scopePath) {
throw new Error(`scope not found at ${process.cwd()}`);
throw new ScopeNotFound(process.cwd());
}
return join(scopePath, 'server-port.txt');
}
}

export function shouldUseBitServer() {
const commandsToSkip = ['start', 'run', 'watch', 'init', 'server'];
const commandsToSkip = ['start', 'run', 'watch', 'server'];
const hasFlag = process.env.BIT_CLI_SERVER === 'true' || process.env.BIT_CLI_SERVER === '1';
return (
process.env.BIT_CLI_SERVER &&
!process.argv.includes('--help') &&
!process.argv.includes('-h') &&
hasFlag &&
process.argv.length > 2 && // if it has no args, it shows the help
!commandsToSkip.includes(process.argv[2])
);
Expand Down
34 changes: 26 additions & 8 deletions scopes/harmony/cli/cli-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { GLOBAL_GROUP, STANDARD_GROUP, YargsAdapter } from './yargs-adapter';
import { CommandNotFound } from './exceptions/command-not-found';
import { OnCommandStartSlot } from './cli.main.runtime';
import { CommandRunner } from './command-runner';
import { YargsExitWorkaround } from './exceptions/yargs-exit-workaround';

export class CLIParser {
public parser = yargs;
Expand Down Expand Up @@ -42,6 +43,7 @@ export class CLIParser {
this.setHelpMiddleware();
this.handleCommandFailure();
this.configureCompletion();
// yargs.showHelpOnFail(false); // doesn't help. it still shows the help on failure.
yargs.strict(); // don't allow non-exist flags and non-exist commands

yargs
Expand All @@ -51,7 +53,12 @@ export class CLIParser {
await yargs.parse();

const currentYargsCommand = this.yargsCommands.find((y) => y.commandRunner);
if (!currentYargsCommand) throw new Error(`unable to find the matched yargs command`);
if (!currentYargsCommand) {
// this happens when the args/flags are wrong. in this case, it prints the help of the command and in most cases
// exits the process before reaching this line. however, in case logger.isDaemon is true, which is for bit-cli-server,
// it doesn't exits the process, so we need to return undefined here.
throw new Error(`yargs failed to parse the command "${args.join(' ')}" and also failed to catch it properly`);
}
return currentYargsCommand.commandRunner as CommandRunner;
}

Expand All @@ -72,7 +79,7 @@ export class CLIParser {
loader.off(); // stop the "loading bit..." before showing help if needed
// this is a command help page
yargs.showHelp(this.logCommandHelp.bind(this));
if (!logger.isDaemon) process.exit(0);
process.exit(0);
}
}, true);
}
Expand All @@ -83,16 +90,27 @@ export class CLIParser {
if (err) {
throw err;
}
yargs.showHelp(this.logCommandHelp.bind(this));
const args = process.argv.slice(2);
const isHelpFlagEntered = args.includes('--help') || args.includes('-h');
let msgForDaemon = '';
try {
yargs.showHelp(this.logCommandHelp.bind(this));
} catch (error: any) {
if (error instanceof YargsExitWorkaround) {
msgForDaemon = error.helpMsg;
} else {
throw error;
}
}
const isMsgAboutMissingArgs = msg.startsWith('Not enough non-option arguments');
// avoid showing the "Not enough non-option arguments" message when the user is trying to get the command help
if (!isMsgAboutMissingArgs || !isHelpFlagEntered) {
// eslint-disable-next-line no-console
console.log(`\n${chalk.yellow(msg)}`);
msgForDaemon += `\n${chalk.yellow(msg)}`;
}
if (!logger.isDaemon) process.exit(1);
if (logger.isDaemon) throw new YargsExitWorkaround(1, msgForDaemon);
process.exit(1);
});
}

Expand Down Expand Up @@ -125,8 +143,8 @@ export class CLIParser {

private printHelp(shouldShowInternalCommands = false) {
const help = formatHelp(this.commands, this.groups, shouldShowInternalCommands);
// eslint-disable-next-line no-console
console.log(help);
if (logger.isDaemon) throw new YargsExitWorkaround(0, help);
else console.log(help); // eslint-disable-line no-console
}

private configureParser() {
Expand Down Expand Up @@ -281,8 +299,8 @@ ${argumentsStr}${subCommandsStr}${optionsStr}${examplesStr}
${GLOBAL_GROUP}
${globalOptionsStr}`;

// eslint-disable-next-line no-console
console.log(finalOutput);
if (logger.isDaemon) throw new YargsExitWorkaround(0, finalOutput);
else console.log(finalOutput); // eslint-disable-line no-console
}
}

Expand Down
1 change: 1 addition & 0 deletions scopes/harmony/cli/exceptions/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { AlreadyExistsError } from './already-exists';
export { YargsExitWorkaround } from './yargs-exit-workaround';
7 changes: 7 additions & 0 deletions scopes/harmony/cli/exceptions/yargs-exit-workaround.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { BitError } from '@teambit/bit-error';

export class YargsExitWorkaround extends BitError {
constructor(public exitCode: number, public helpMsg: string) {
super('Workaround for yargs exit issue');
}
}
3 changes: 2 additions & 1 deletion src/logger/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { CFG_LOG_JSON_FORMAT, CFG_LOG_LEVEL, CFG_NO_WARNINGS } from '../constant
import { getWinstonLogger } from './winston-logger';
import { getPinoLogger } from './pino-logger';
import { Profiler } from './profiler';
import loader from '../cli/loader';

export { Level as LoggerLevel };

Expand Down Expand Up @@ -152,7 +153,7 @@ class BitLogger implements IBitLogger {
this.trace('a wrong color provided to logger.console method');
}
}
console.log(messageStr); // eslint-disable-line no-console
loader.stopAndPersist({ text: messageStr });
}

/**
Expand Down