mirror of
https://github.com/tiktok/sparo.git
synced 2024-11-14 19:35:12 -05:00
feat: startup banner shows verion info
This commit is contained in:
parent
4f38fcb58e
commit
07b5dd4c76
10 changed files with 114 additions and 15 deletions
|
@ -17,6 +17,7 @@
|
|||
"git-repo-info": "~2.1.1",
|
||||
"inversify": "~6.0.2",
|
||||
"reflect-metadata": "~0.2.1",
|
||||
"semver": "~7.6.0",
|
||||
"yargs": "~17.7.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -24,6 +25,7 @@
|
|||
"@rushstack/heft-node-rig": "2.4.5",
|
||||
"@types/heft-jest": "1.0.6",
|
||||
"@types/node": "20.11.16",
|
||||
"@types/semver": "7.5.7",
|
||||
"@types/yargs": "17.0.32",
|
||||
"eslint": "8.56.0",
|
||||
"typescript": "~5.3.3"
|
||||
|
|
|
@ -8,6 +8,7 @@ import { CIHelpCommand } from './commands/ci-help';
|
|||
import { GitVersionCompatibility } from '../logic/GitVersionCompatibility';
|
||||
import { TelemetryService } from '../services/TelemetryService';
|
||||
import { getCommandName } from './commands/util';
|
||||
import { SparoStartupBanner } from './SparoStartupBanner';
|
||||
import type { ILaunchOptions } from '../api/Sparo';
|
||||
|
||||
export class SparoCICommandLine {
|
||||
|
@ -16,13 +17,14 @@ export class SparoCICommandLine {
|
|||
private constructor() {}
|
||||
|
||||
public static async launchAsync(launchOptions: ILaunchOptions): Promise<void> {
|
||||
await GitVersionCompatibility.ensureGitVersionAsync();
|
||||
|
||||
if (launchOptions.collectTelemetryAsync) {
|
||||
const telemetryService: TelemetryService = await getFromContainerAsync(TelemetryService);
|
||||
telemetryService.setCollectTelemetryFunction(launchOptions.collectTelemetryAsync);
|
||||
}
|
||||
|
||||
GitVersionCompatibility.ensureGitVersion();
|
||||
SparoStartupBanner.logBanner();
|
||||
|
||||
const sparoCI: SparoCICommandLine = new SparoCICommandLine();
|
||||
await sparoCI.prepareCommandAsync();
|
||||
await sparoCI.runAsync();
|
||||
|
|
|
@ -9,6 +9,7 @@ import { ICommand } from './commands/base';
|
|||
import { GitVersionCompatibility } from '../logic/GitVersionCompatibility';
|
||||
import { TelemetryService } from '../services/TelemetryService';
|
||||
import { getCommandName } from './commands/util';
|
||||
import { SparoStartupBanner } from './SparoStartupBanner';
|
||||
import type { ILaunchOptions } from '../api/Sparo';
|
||||
|
||||
export class SparoCommandLine {
|
||||
|
@ -17,13 +18,14 @@ export class SparoCommandLine {
|
|||
private constructor() {}
|
||||
|
||||
public static async launchAsync(launchOptions: ILaunchOptions): Promise<void> {
|
||||
await GitVersionCompatibility.ensureGitVersionAsync();
|
||||
|
||||
if (launchOptions.collectTelemetryAsync) {
|
||||
const telemetryService: TelemetryService = await getFromContainerAsync(TelemetryService);
|
||||
telemetryService.setCollectTelemetryFunction(launchOptions.collectTelemetryAsync);
|
||||
}
|
||||
|
||||
GitVersionCompatibility.ensureGitVersion();
|
||||
SparoStartupBanner.logBanner();
|
||||
|
||||
const sparo: SparoCommandLine = new SparoCommandLine();
|
||||
await sparo.prepareCommandAsync();
|
||||
await sparo.runAsync();
|
||||
|
|
30
apps/sparo-lib/src/cli/SparoStartupBanner.ts
Normal file
30
apps/sparo-lib/src/cli/SparoStartupBanner.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
import * as semver from 'semver';
|
||||
import { Colorize } from '@rushstack/terminal';
|
||||
import { getFromContainer } from '../di/container';
|
||||
import { TerminalService } from '../services/TerminalService';
|
||||
import { SparoVersion } from '../logic/SparoVersion';
|
||||
import { GitVersionCompatibility } from '../logic/GitVersionCompatibility';
|
||||
|
||||
export class SparoStartupBanner {
|
||||
public static logBanner(): void {
|
||||
const sparoVersion: string = SparoVersion.version;
|
||||
const gitVersion: string = GitVersionCompatibility.getGitVersion().join('.');
|
||||
const nodeVersion: string = this._formatNodeVersion();
|
||||
const { terminal } = getFromContainer(TerminalService);
|
||||
|
||||
terminal.writeLine();
|
||||
terminal.writeLine(Colorize.bold(`Sparo accelerator for Git ${sparoVersion}`));
|
||||
terminal.writeLine(`Node.js version is ${nodeVersion}`);
|
||||
terminal.writeLine(`Git version is ${gitVersion}`);
|
||||
terminal.writeLine();
|
||||
}
|
||||
|
||||
private static _formatNodeVersion(): string {
|
||||
const nodeVersion: string = process.versions.node;
|
||||
const nodeMajorVersion: number = semver.major(nodeVersion);
|
||||
const isOddNumberedVersion: boolean = nodeMajorVersion % 2 !== 0;
|
||||
const isLtsVersion: boolean = !!process.release.lts;
|
||||
const nodeReleaseLabel: string = isOddNumberedVersion ? 'unstable' : isLtsVersion ? 'LTS' : 'pre-LTS';
|
||||
return `${nodeVersion} (${nodeReleaseLabel})`;
|
||||
}
|
||||
}
|
|
@ -50,6 +50,11 @@ export async function getFromContainerAsync<T>(clazz: Constructable<T>): Promise
|
|||
return instance as T;
|
||||
}
|
||||
|
||||
export function getFromContainer<T>(clazz: Constructable<T>): T {
|
||||
const instance: T = defaultContainer.get<T & IAppClassInterface>(clazz);
|
||||
return instance as T;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a class into dependency-injection container
|
||||
* @example
|
||||
|
|
|
@ -1,25 +1,33 @@
|
|||
import 'reflect-metadata';
|
||||
import { getFromContainerAsync } from '../di/container';
|
||||
import { getFromContainer } from '../di/container';
|
||||
import { GitService } from '../services/GitService';
|
||||
|
||||
/**
|
||||
* This class provides the useful function to check git version.
|
||||
*/
|
||||
export class GitVersionCompatibility {
|
||||
private static _gitVersion: [number, number, number] | undefined;
|
||||
|
||||
private constructor() {}
|
||||
|
||||
public static async ensureGitVersionAsync(): Promise<void> {
|
||||
const gitService: GitService = await getFromContainerAsync(GitService);
|
||||
const gitVersion: [number, number, number] | undefined = gitService.getGitVersion();
|
||||
if (!gitVersion) {
|
||||
throw new Error(`Fail to get git version`);
|
||||
}
|
||||
|
||||
const [major, minor, patch] = gitVersion;
|
||||
public static ensureGitVersion(): void {
|
||||
const [major, minor, patch] = GitVersionCompatibility.getGitVersion();
|
||||
if (major < 2 || minor < 32) {
|
||||
throw new Error(
|
||||
`git version is too low. The minimal git version is >=2.32.0. Your git version is ${major}.${minor}.${patch}. Please upgrade git.`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public static getGitVersion(): [number, number, number] {
|
||||
if (!GitVersionCompatibility._gitVersion) {
|
||||
const gitService: GitService = getFromContainer(GitService);
|
||||
const gitVersion: [number, number, number] | undefined = gitService.getGitVersion();
|
||||
if (!gitVersion) {
|
||||
throw new Error(`Fail to get git version`);
|
||||
}
|
||||
GitVersionCompatibility._gitVersion = gitVersion;
|
||||
}
|
||||
return GitVersionCompatibility._gitVersion as [number, number, number];
|
||||
}
|
||||
}
|
||||
|
|
42
apps/sparo-lib/src/logic/SparoVersion.ts
Normal file
42
apps/sparo-lib/src/logic/SparoVersion.ts
Normal file
|
@ -0,0 +1,42 @@
|
|||
import * as path from 'path';
|
||||
import { type IPackageJson, PackageJsonLookup } from '@rushstack/node-core-library';
|
||||
|
||||
export class SparoVersion {
|
||||
private static __sparoLibPackageJson: IPackageJson | undefined = undefined;
|
||||
private static __sparoLibPackageFolder: string | undefined = undefined;
|
||||
|
||||
private constructor() {}
|
||||
|
||||
/**
|
||||
* The currently executing version of the "sparo-lib" library.
|
||||
* This is the same as the Sparo tool version for that release.
|
||||
*/
|
||||
public static get version(): string {
|
||||
return this._sparoLibPackageJson.version;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public static get _sparoLibPackageJson(): IPackageJson {
|
||||
SparoVersion._ensureOwnPackageJsonIsLoaded();
|
||||
return SparoVersion.__sparoLibPackageJson!;
|
||||
}
|
||||
|
||||
public static get _sparoLibPackageFolder(): string {
|
||||
SparoVersion._ensureOwnPackageJsonIsLoaded();
|
||||
return SparoVersion.__sparoLibPackageFolder!;
|
||||
}
|
||||
|
||||
private static _ensureOwnPackageJsonIsLoaded(): void {
|
||||
if (!SparoVersion.__sparoLibPackageJson) {
|
||||
const packageJsonFilePath: string | undefined =
|
||||
PackageJsonLookup.instance.tryGetPackageJsonFilePathFor(__dirname);
|
||||
if (!packageJsonFilePath) {
|
||||
throw new Error('Unable to locate the package.json file for this module');
|
||||
}
|
||||
SparoVersion.__sparoLibPackageFolder = path.dirname(packageJsonFilePath);
|
||||
SparoVersion.__sparoLibPackageJson = PackageJsonLookup.instance.loadPackageJson(packageJsonFilePath);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,7 +21,9 @@ export class ArgvService {
|
|||
public async parseArgvAsync(): Promise<void> {
|
||||
this._parsed = await this.yargsArgv
|
||||
.help(false)
|
||||
// --debug
|
||||
.boolean('debug')
|
||||
// --verbose
|
||||
.boolean('verbose')
|
||||
.middleware([this._terminalMiddleware])
|
||||
.parseAsync();
|
||||
|
|
|
@ -17,12 +17,12 @@ export class TerminalService {
|
|||
|
||||
public setIsVerbose(value: boolean): void {
|
||||
this._terminalProvider.verboseEnabled = value;
|
||||
// verbose implies debug
|
||||
this._terminalProvider.debugEnabled = value;
|
||||
}
|
||||
|
||||
public setIsDebug(value: boolean): void {
|
||||
this._terminalProvider.debugEnabled = value;
|
||||
// debug implies verbose
|
||||
this._terminalProvider.verboseEnabled = value;
|
||||
}
|
||||
|
||||
public get terminal(): ITerminal {
|
||||
|
|
|
@ -50,6 +50,9 @@ importers:
|
|||
reflect-metadata:
|
||||
specifier: ~0.2.1
|
||||
version: 0.2.1
|
||||
semver:
|
||||
specifier: ~7.6.0
|
||||
version: 7.6.0
|
||||
yargs:
|
||||
specifier: ~17.7.2
|
||||
version: 17.7.2
|
||||
|
@ -66,6 +69,9 @@ importers:
|
|||
'@types/node':
|
||||
specifier: 20.11.16
|
||||
version: 20.11.16
|
||||
'@types/semver':
|
||||
specifier: 7.5.7
|
||||
version: 7.5.7
|
||||
'@types/yargs':
|
||||
specifier: 17.0.32
|
||||
version: 17.0.32
|
||||
|
|
Loading…
Reference in a new issue