Skip to content

Commit

Permalink
Make --quiet flags more consistent
Browse files Browse the repository at this point in the history
  • Loading branch information
elliot-nelson committed Mar 21, 2022
1 parent f69df47 commit cc6ca36
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 45 deletions.
3 changes: 1 addition & 2 deletions apps/rush-lib/src/api/Rush.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { RushCommandLineParser } from '../cli/RushCommandLineParser';
import { RushStartupBanner } from '../cli/RushStartupBanner';
import { RushXCommandLine } from '../cli/RushXCommandLine';
import { CommandLineMigrationAdvisor } from '../cli/CommandLineMigrationAdvisor';
import { Utilities } from '../utilities/Utilities';
import { EnvironmentVariableNames } from './EnvironmentConfiguration';
import { IBuiltInPluginConfiguration } from '../pluginFramework/PluginLoader/BuiltInPluginLoader';

Expand Down Expand Up @@ -62,7 +61,7 @@ export class Rush {
public static launch(launcherVersion: string, arg: ILaunchOptions): void {
const options: ILaunchOptions = Rush._normalizeLaunchOptions(arg);

if (!Utilities.shouldRestrictConsoleOutput()) {
if (!RushCommandLineParser.shouldRestrictConsoleOutput()) {
RushStartupBanner.logBanner(Rush.version, options.isManaged);
}

Expand Down
37 changes: 34 additions & 3 deletions apps/rush-lib/src/cli/RushCommandLineParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import colors from 'colors/safe';
import * as os from 'os';
import * as path from 'path';

import { CommandLineParser, CommandLineFlagParameter } from '@rushstack/ts-command-line';
import { CommandLineParser, CommandLineFlagParameter, CommandLineHelper } from '@rushstack/ts-command-line';
import {
InternalError,
AlreadyReportedError,
Expand All @@ -22,7 +22,6 @@ import {
IGlobalCommandConfig,
IPhasedCommandConfig
} from '../api/CommandLineConfiguration';
import { Utilities } from '../utilities/Utilities';

import { AddAction } from './actions/AddAction';
import { ChangeAction } from './actions/ChangeAction';
Expand Down Expand Up @@ -72,6 +71,7 @@ export class RushCommandLineParser extends CommandLineParser {
public readonly pluginManager: PluginManager;

private _debugParameter!: CommandLineFlagParameter;
private _quietParameter!: CommandLineFlagParameter;
private readonly _rushOptions: IRushCommandLineParserOptions;
private readonly _terminalProvider: ConsoleTerminalProvider;
private readonly _terminal: Terminal;
Expand All @@ -98,7 +98,7 @@ export class RushCommandLineParser extends CommandLineParser {
try {
const rushJsonFilename: string | undefined = RushConfiguration.tryFindRushJsonLocation({
startingFolder: this._rushOptions.cwd,
showVerbose: !Utilities.shouldRestrictConsoleOutput()
showVerbose: !RushCommandLineParser.shouldRestrictConsoleOutput()
});
if (rushJsonFilename) {
this.rushConfiguration = RushConfiguration.loadFromConfigurationFile(rushJsonFilename);
Expand Down Expand Up @@ -145,6 +145,31 @@ export class RushCommandLineParser extends CommandLineParser {
return this._debugParameter.value;
}

public get isQuiet(): boolean {
return this._quietParameter.value;
}

/**
* Peek at the -q/--quiet mode flag, before the command line parser is executed.
*
* Used during Rush startup.
*/
public static peekIsQuiet(): boolean {
const flags: string[] = process.argv.slice(2);
return flags.includes('-q') || flags.includes('--quiet');
}

/**
* Utility to determine if the app should restrict writing to the console.
*/
public static shouldRestrictConsoleOutput(): boolean {
return (
CommandLineHelper.isTabCompletionActionRequest(process.argv) ||
RushCommandLineParser.peekIsQuiet() ||
process.argv.indexOf('--json') !== -1
);
}

public flushTelemetry(): void {
if (this.telemetry) {
this.telemetry.flush();
Expand All @@ -165,6 +190,12 @@ export class RushCommandLineParser extends CommandLineParser {
parameterShortName: '-d',
description: 'Show the full call stack if an error occurs while executing the tool'
});

this._quietParameter = this.defineFlagParameter({
parameterLongName: '--quiet',
parameterShortName: '-q',
description: 'Hide rush startup information'
});
}

protected async onExecute(): Promise<void> {
Expand Down
2 changes: 1 addition & 1 deletion apps/rush-lib/src/cli/actions/BaseRushAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export abstract class BaseConfiglessRushAction extends CommandLineAction impleme
}
}

if (!Utilities.shouldRestrictConsoleOutput()) {
if (!RushCommandLineParser.shouldRestrictConsoleOutput()) {
console.log(`Starting "rush ${this.actionName}"${os.EOL}`);
}
return this.runAsync();
Expand Down
39 changes: 31 additions & 8 deletions apps/rush-lib/src/scripts/install-run-rush.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,17 @@ import {
installAndRun,
findRushJsonFolder,
RUSH_JSON_FILENAME,
runWithErrorAndStatusCode
runWithErrorAndStatusCode,
ILogger
} from './install-run';

const PACKAGE_NAME: string = '@microsoft/rush';
const RUSH_PREVIEW_VERSION: string = 'RUSH_PREVIEW_VERSION';

function _getRushVersion(): string {
function _getRushVersion(logger: ILogger): string {
const rushPreviewVersion: string | undefined = process.env[RUSH_PREVIEW_VERSION];
if (rushPreviewVersion !== undefined) {
console.log(`Using Rush version from environment variable ${RUSH_PREVIEW_VERSION}=${rushPreviewVersion}`);
logger.info(`Using Rush version from environment variable ${RUSH_PREVIEW_VERSION}=${rushPreviewVersion}`);
return rushPreviewVersion;
}

Expand Down Expand Up @@ -66,7 +67,29 @@ function _run(): void {
throw new Error('Unexpected exception: could not detect node path or script path');
}

if (process.argv.length < 3) {
let commandFound: boolean = false;
let logger: ILogger = { info: console.log, error: console.error };

for (const arg of packageBinArgs) {
if (arg === '-q' || arg === '--quiet') {
// The -q/--quiet flag is supported by both `rush` and `rushx`, and will suppress
// any normal informational/diagnostic information printed during startup.
//
// To maintain the same user experience, the install-run* scripts pass along this
// flag but also use it to suppress any diagnostic information normally printed
// to stdout.
logger = {
info: () => {},
error: console.error
};
}
if (!arg.startsWith('-')) {
commandFound = true;
break;
}
}

if (!commandFound) {
console.log(`Usage: ${scriptName} <command> [args...]`);
if (scriptName === 'install-run-rush.js') {
console.log(`Example: ${scriptName} build --to myproject`);
Expand All @@ -76,11 +99,11 @@ function _run(): void {
process.exit(1);
}

runWithErrorAndStatusCode(() => {
const version: string = _getRushVersion();
console.log(`The rush.json configuration requests Rush version ${version}`);
runWithErrorAndStatusCode(logger, () => {
const version: string = _getRushVersion(logger);
logger.info(`The rush.json configuration requests Rush version ${version}`);

return installAndRun(PACKAGE_NAME, version, bin, packageBinArgs);
return installAndRun(logger, PACKAGE_NAME, version, bin, packageBinArgs);
});
}

Expand Down
55 changes: 36 additions & 19 deletions apps/rush-lib/src/scripts/install-run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ const INSTALLED_FLAG_FILENAME: string = 'installed.flag';
const NODE_MODULES_FOLDER_NAME: string = 'node_modules';
const PACKAGE_JSON_FILENAME: string = 'package.json';

export interface ILogger {
info: (string: string) => void;
error: (string: string) => void;
}

/**
* Parse a package specifier (in the form of name\@version) into name and version parts.
*/
Expand Down Expand Up @@ -64,9 +69,9 @@ function _parsePackageSpecifier(rawPackageSpecifier: string): IPackageSpecifier
*
* IMPORTANT: THIS CODE SHOULD BE KEPT UP TO DATE WITH Utilities.copyAndTrimNpmrcFile()
*/
function _copyAndTrimNpmrcFile(sourceNpmrcPath: string, targetNpmrcPath: string): void {
console.log(`Transforming ${sourceNpmrcPath}`); // Verbose
console.log(` --> "${targetNpmrcPath}"`);
function _copyAndTrimNpmrcFile(logger: ILogger, sourceNpmrcPath: string, targetNpmrcPath: string): void {
logger.info(`Transforming ${sourceNpmrcPath}`); // Verbose
logger.info(` --> "${targetNpmrcPath}"`);
let npmrcFileLines: string[] = fs.readFileSync(sourceNpmrcPath).toString().split('\n');
npmrcFileLines = npmrcFileLines.map((line) => (line || '').trim());
const resultLines: string[] = [];
Expand Down Expand Up @@ -117,18 +122,23 @@ function _copyAndTrimNpmrcFile(sourceNpmrcPath: string, targetNpmrcPath: string)
*
* IMPORTANT: THIS CODE SHOULD BE KEPT UP TO DATE WITH Utilities._syncNpmrc()
*/
function _syncNpmrc(sourceNpmrcFolder: string, targetNpmrcFolder: string, useNpmrcPublish?: boolean): void {
function _syncNpmrc(
logger: ILogger,
sourceNpmrcFolder: string,
targetNpmrcFolder: string,
useNpmrcPublish?: boolean
): void {
const sourceNpmrcPath: string = path.join(
sourceNpmrcFolder,
!useNpmrcPublish ? '.npmrc' : '.npmrc-publish'
);
const targetNpmrcPath: string = path.join(targetNpmrcFolder, '.npmrc');
try {
if (fs.existsSync(sourceNpmrcPath)) {
_copyAndTrimNpmrcFile(sourceNpmrcPath, targetNpmrcPath);
_copyAndTrimNpmrcFile(logger, sourceNpmrcPath, targetNpmrcPath);
} else if (fs.existsSync(targetNpmrcPath)) {
// If the source .npmrc doesn't exist and there is one in the target, delete the one in the target
console.log(`Deleting ${targetNpmrcPath}`); // Verbose
logger.info(`Deleting ${targetNpmrcPath}`); // Verbose
fs.unlinkSync(targetNpmrcPath);
}
} catch (e) {
Expand Down Expand Up @@ -220,7 +230,11 @@ export interface IPackageSpecifier {
/**
* Resolve a package specifier to a static version
*/
function _resolvePackageVersion(rushCommonFolder: string, { name, version }: IPackageSpecifier): string {
function _resolvePackageVersion(
logger: ILogger,
rushCommonFolder: string,
{ name, version }: IPackageSpecifier
): string {
if (!version) {
version = '*'; // If no version is specified, use the latest version
}
Expand All @@ -235,7 +249,7 @@ function _resolvePackageVersion(rushCommonFolder: string, { name, version }: IPa
const rushTempFolder: string = _getRushTempFolder(rushCommonFolder);
const sourceNpmrcFolder: string = path.join(rushCommonFolder, 'config', 'rush');

_syncNpmrc(sourceNpmrcFolder, rushTempFolder);
_syncNpmrc(logger, sourceNpmrcFolder, rushTempFolder);

const npmPath: string = getNpmPath();

Expand Down Expand Up @@ -372,9 +386,9 @@ function _createPackageJson(packageInstallFolder: string, name: string, version:
/**
* Run "npm install" in the package install folder.
*/
function _installPackage(packageInstallFolder: string, name: string, version: string): void {
function _installPackage(logger: ILogger, packageInstallFolder: string, name: string, version: string): void {
try {
console.log(`Installing ${name}...`);
logger.info(`Installing ${name}...`);
const npmPath: string = getNpmPath();
const result: childProcess.SpawnSyncReturns<Buffer> = childProcess.spawnSync(npmPath, ['install'], {
stdio: 'inherit',
Expand All @@ -386,7 +400,7 @@ function _installPackage(packageInstallFolder: string, name: string, version: st
throw new Error('"npm install" encountered an error');
}

console.log(`Successfully installed ${name}@${version}`);
logger.info(`Successfully installed ${name}@${version}`);
} catch (e) {
throw new Error(`Unable to install package: ${e}`);
}
Expand Down Expand Up @@ -414,6 +428,7 @@ function _writeFlagFile(packageInstallFolder: string): void {
}

export function installAndRun(
logger: ILogger,
packageName: string,
packageVersion: string,
packageBinName: string,
Expand All @@ -433,16 +448,16 @@ export function installAndRun(
_cleanInstallFolder(rushTempFolder, packageInstallFolder);

const sourceNpmrcFolder: string = path.join(rushCommonFolder, 'config', 'rush');
_syncNpmrc(sourceNpmrcFolder, packageInstallFolder);
_syncNpmrc(logger, sourceNpmrcFolder, packageInstallFolder);

_createPackageJson(packageInstallFolder, packageName, packageVersion);
_installPackage(packageInstallFolder, packageName, packageVersion);
_installPackage(logger, packageInstallFolder, packageName, packageVersion);
_writeFlagFile(packageInstallFolder);
}

const statusMessage: string = `Invoking "${packageBinName} ${packageBinArgs.join(' ')}"`;
const statusMessageLine: string = new Array(statusMessage.length + 1).join('-');
console.log(os.EOL + statusMessage + os.EOL + statusMessageLine + os.EOL);
logger.info(os.EOL + statusMessage + os.EOL + statusMessageLine + os.EOL);

const binPath: string = _getBinPath(packageInstallFolder, packageBinName);
const binFolderPath: string = path.resolve(packageInstallFolder, NODE_MODULES_FOLDER_NAME, '.bin');
Expand Down Expand Up @@ -475,14 +490,14 @@ export function installAndRun(
}
}

export function runWithErrorAndStatusCode(fn: () => number): void {
export function runWithErrorAndStatusCode(logger: ILogger, fn: () => number): void {
process.exitCode = 1;

try {
const exitCode: number = fn();
process.exitCode = exitCode;
} catch (e) {
console.error(os.EOL + os.EOL + (e as Error).toString() + os.EOL + os.EOL);
logger.error(os.EOL + os.EOL + (e as Error).toString() + os.EOL + os.EOL);
}
}

Expand Down Expand Up @@ -512,19 +527,21 @@ function _run(): void {
process.exit(1);
}

runWithErrorAndStatusCode(() => {
const logger: ILogger = { info: console.log, error: console.error };

runWithErrorAndStatusCode(logger, () => {
const rushJsonFolder: string = findRushJsonFolder();
const rushCommonFolder: string = _ensureAndJoinPath(rushJsonFolder, 'common');

const packageSpecifier: IPackageSpecifier = _parsePackageSpecifier(rawPackageSpecifier);
const name: string = packageSpecifier.name;
const version: string = _resolvePackageVersion(rushCommonFolder, packageSpecifier);
const version: string = _resolvePackageVersion(logger, rushCommonFolder, packageSpecifier);

if (packageSpecifier.version !== version) {
console.log(`Resolved to ${name}@${version}`);
}

return installAndRun(name, version, packageBinName, packageBinArgs);
return installAndRun(logger, name, version, packageBinName, packageBinArgs);
});
}

Expand Down
10 changes: 0 additions & 10 deletions apps/rush-lib/src/utilities/Utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
FileSystemStats
} from '@rushstack/node-core-library';
import type * as stream from 'stream';
import { CommandLineHelper } from '@rushstack/ts-command-line';

import { RushConfiguration } from '../api/RushConfiguration';

Expand Down Expand Up @@ -426,15 +425,6 @@ export class Utilities {
return Utilities._executeLifecycleCommandInternal(command, child_process.spawn, options);
}

/**
* Utility to determine if the app should restrict writing to the console.
*/
public static shouldRestrictConsoleOutput(): boolean {
return (
CommandLineHelper.isTabCompletionActionRequest(process.argv) || process.argv.indexOf('--json') !== -1
);
}

/**
* For strings passed to a shell command, this adds appropriate escaping
* to avoid misinterpretation of spaces or special characters.
Expand Down
4 changes: 2 additions & 2 deletions apps/rush/src/MinimalRushConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import * as path from 'path';
import { JsonFile } from '@rushstack/node-core-library';
import { RushConfiguration } from '@microsoft/rush-lib';
import { RushConstants } from '@microsoft/rush-lib/lib/logic/RushConstants';
import { Utilities } from '@microsoft/rush-lib/lib/utilities/Utilities';
import { RushCommandLineParser } from '@microsoft/rush-lib/lib/cli/RushCommandLineParser';

interface IMinimalRushConfigurationJson {
rushMinimumVersion: string;
Expand Down Expand Up @@ -34,7 +34,7 @@ export class MinimalRushConfiguration {

public static loadFromDefaultLocation(): MinimalRushConfiguration | undefined {
const rushJsonLocation: string | undefined = RushConfiguration.tryFindRushJsonLocation({
showVerbose: !Utilities.shouldRestrictConsoleOutput()
showVerbose: !RushCommandLineParser.shouldRestrictConsoleOutput()
});
if (rushJsonLocation) {
return MinimalRushConfiguration._loadFromConfigurationFile(rushJsonLocation);
Expand Down

0 comments on commit cc6ca36

Please sign in to comment.