Skip to content

[rush] Add rush alert CLI #4844

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

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@microsoft/rush",
"comment": "Add rush alert CLI",
"type": "none"
}
],
"packageName": "@microsoft/rush"
}
6 changes: 5 additions & 1 deletion libraries/rush-lib/src/cli/RushCommandLineParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import { PhasedScriptAction } from './scriptActions/PhasedScriptAction';
import type { IBuiltInPluginConfiguration } from '../pluginFramework/PluginLoader/BuiltInPluginLoader';
import { InitSubspaceAction } from './actions/InitSubspaceAction';
import { RushAlerts } from '../utilities/RushAlerts';
import { AlertAction } from './actions/AlertAction';

/**
* Options for `RushCommandLineParser`.
Expand Down Expand Up @@ -236,7 +237,9 @@ export class RushCommandLineParser extends CommandLineParser {
terminal: this._terminal
});
if (await rushAlerts.isAlertsStateUpToDateAsync()) {
await rushAlerts.printAlertsAsync();
if (!(await rushAlerts.isSnoozeAsync())) {
await rushAlerts.printAlertsAsync();
}
} else {
await rushAlerts.retrieveAlertsAsync();
}
Expand Down Expand Up @@ -289,6 +292,7 @@ export class RushCommandLineParser extends CommandLineParser {
try {
// Alphabetical order
this.addAction(new AddAction(this));
this.addAction(new AlertAction(this));
this.addAction(new ChangeAction(this));
this.addAction(new CheckAction(this));
this.addAction(new DeployAction(this));
Expand Down
43 changes: 43 additions & 0 deletions libraries/rush-lib/src/cli/actions/AlertAction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.

import type { CommandLineFlagParameter } from '@rushstack/ts-command-line';

import { BaseRushAction } from './BaseRushAction';
import type { RushCommandLineParser } from '../RushCommandLineParser';
import { ConsoleTerminalProvider, Terminal } from '@rushstack/terminal';
import { RushAlerts } from '../../utilities/RushAlerts';
export class AlertAction extends BaseRushAction {
private readonly _snoozeParameter: CommandLineFlagParameter;
private readonly _rushAlerts: RushAlerts;

public constructor(parser: RushCommandLineParser) {
super({
actionName: 'alert',
summary: 'Use this command to interact with Rush alert feature',
documentation:
'The "rush alert" command is used to interact with Rush alert feature. For example,' +
' you can mute the alerts if you think they are annoying',
parser
});

this._snoozeParameter = this.defineFlagParameter({
parameterLongName: '--snooze',
description:
'Snooze the alerts for today.' +
' Please note, if you delete the `common/temp` folder, the snooze state will be reset. '
});

const terminal: Terminal = new Terminal(new ConsoleTerminalProvider());
this._rushAlerts = new RushAlerts({
rushConfiguration: this.rushConfiguration,
terminal
});
}

protected async runAsync(): Promise<void> {
if (this._snoozeParameter.value!) {
await this._rushAlerts.snoozeAlertsAsync();
}
}
}
43 changes: 42 additions & 1 deletion libraries/rush-lib/src/utilities/RushAlerts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ interface IRushAlertsConfigEntry {
}
interface IRushAlertsState {
lastUpdateTime: string;
snooze: boolean;
rushVersion: string;
alerts: Array<IRushAlertStateEntry>;
}
interface IRushAlertStateEntry {
Expand Down Expand Up @@ -60,7 +62,16 @@ export class RushAlerts {
public async isAlertsStateUpToDateAsync(): Promise<boolean> {
const rushAlertsState: IRushAlertsState | undefined = await this._loadRushAlertsStateAsync();

if (rushAlertsState === undefined || !rushAlertsState.lastUpdateTime) {
if (
rushAlertsState === undefined ||
!rushAlertsState.lastUpdateTime ||
rushAlertsState.rushVersion === undefined
) {
return false;
}

// if the state file is generated by another Rush version, also return false
if (rushAlertsState.rushVersion !== this._rushConfiguration.rushConfigurationJson.rushVersion) {
return false;
}

Expand Down Expand Up @@ -262,6 +273,8 @@ export class RushAlerts {
if (validAlerts.length > 0) {
const rushAlertsState: IRushAlertsState = {
lastUpdateTime: new Date().toISOString(),
snooze: false,
rushVersion: this._rushConfiguration.rushConfigurationJson.rushVersion,
alerts: validAlerts
};

Expand All @@ -276,4 +289,32 @@ export class RushAlerts {
await FileSystem.deleteFileAsync(this.rushAlertsStateFilePath);
}
}

public async snoozeAlertsAsync(): Promise<void> {
const rushAlertsState: IRushAlertsState | undefined = await this._loadRushAlertsStateAsync();

if (!rushAlertsState) {
return;
}

rushAlertsState.snooze = true;

await JsonFile.saveAsync(rushAlertsState, this.rushAlertsStateFilePath, {
ignoreUndefinedValues: true,
headerComment: '// THIS FILE IS MACHINE-GENERATED -- DO NOT MODIFY',
jsonSyntax: JsonSyntax.JsonWithComments
});

this._terminal.writeLine('Snoozing the rush alerts for today!');
}

public async isSnoozeAsync(): Promise<boolean> {
const rushAlertsState: IRushAlertsState | undefined = await this._loadRushAlertsStateAsync();

if (rushAlertsState === undefined || !rushAlertsState.snooze) {
return false;
}

return true;
}
}
Loading