@gobstones/gobstones-scripts
Version:
Scripts to abstract away build configuration of Gobstones Project's libraries and modules.
149 lines (134 loc) • 5.46 kB
text/typescript
/*
* *****************************************************************************
* Copyright (C) National University of Quilmes 2018-2024
* Gobstones (TM) is a trademark of the National University of Quilmes.
*
* This program is free software distributed under the terms of the
* GNU Affero General Public License version 3.
* Additional terms added in compliance to section 7 of such license apply.
*
* You may read the full license at https://gobstones.github.io/gobstones-guidelines/LICENSE.
* *****************************************************************************
*/
/**
* ----------------------------------------------------
* @module CLI
* @author Alan Rodas Bonjour <alanrodas@gmail.com>
*
* @internal
* ----------------------------------------------------
*/
import fs from 'fs';
import path from 'path';
import process from 'process';
import colors from 'ansi-colors';
import figlet from 'figlet';
import { t } from '../@i18n';
import { config } from '../Config';
import { FileDefinitionWithTooling } from '../Config/config';
import { logger } from '../Helpers/Logger';
/**
* Returns the gobstones-scripts banner that will be printed in CLI.
*
* @returns The gobstones-script banner.
*/
export const banner = (): string => {
const text: string = figlet.textSync('gobstones-scripts', {
font: 'Standard',
horizontalLayout: 'fitted',
verticalLayout: 'default',
width: 120,
whitespaceBreak: true
});
return colors.red(text);
};
/**
* Returns the gobstones-scripts welcome message in the CLI.
*
* @returns The welcome message.
*/
export const welcome = (): string => t('cli:messages.welcome', { version: config.environment.toolVersion });
/**
* Display the welcome message of the gobstones-script tool
* and immediately after, the given message.
*
* @param message - The message to display after welcome.
*/
export const displayWelcomeForAction = (message: string): void => {
logger.log(banner());
logger.log(welcome());
logger.log('');
logger.log(message);
logger.log('');
};
/**
* Run a function and print an error message if it fails.
* The action is expected to be executed and produce an error with a given
* message in some cases. errorsAndMessages matches on those inner messages
* and outputs the associated message to the user in a style with red background.
*
* @param action - A function to be executed and catch on failure.
* @param errorsAndMessages - An object associating inner
* possible error messages as keys and messages to output to the user as values.
*/
export const runOrEnd = (action: () => void): void => {
try {
action();
} catch (e: unknown) {
const error = e as { message: string };
let message: string;
if (error.message === 'errors.emptyFolder') {
message = t('cli:errors.emptyFolder');
} else if (error.message === 'errors.undefinedTsConfig') {
message = t('cli:errors.undefinedTsConfig');
} else {
message = t('cli:errors.unexpected');
}
logger.on();
if (!config.executionEnvironment.debug) {
logger.error('ERROR: ' + message, 'bgRed');
process.exit(1);
}
throw e;
}
};
/**
* Print the currently used configuration when the options contain the argument.
*/
export const printConfiguration = (): void => {
logger.log(
t('cli:messages.configuration', {
projectType: colors.blue(config.executionEnvironment.projectType),
projectManager: colors.blue(config.executionEnvironment.packageManager),
isTestMode: colors.blue(config.executionEnvironment.test ? 'yes' : 'no'),
isDebugMode: colors.blue(config.executionEnvironment.debug ? 'yes' : 'no'),
usingLocalTsConfig: colors.blue(config.executionEnvironment.useLocalTsconfigJson ? 'yes' : 'no'),
usingFullPaths: colors.blue(config.executionEnvironment.useFullPaths ? 'yes' : 'no')
})
);
logger.log(
t('cli:messages.folders', {
rootFolder: colors.blue(config.locations.projectRoot),
gobstonesScriptsFolder: colors.blue(config.locations.gobstonesScriptsRoot)
})
);
const useAbsolute = config.executionEnvironment.useFullPaths;
let configFiles = config.projectTypeFilteredFiles.toolingFiles;
// Do not expose tsConfigJSON, but show it's file, if not auto-generated
// as the typescript one.
if (config.projectType.tsConfigJSON.toolingFile && fs.existsSync(config.projectType.tsConfigJSON.toolingFile)) {
config.projectType.typescript.toolingFile = config.projectType.tsConfigJSON.toolingFile;
}
configFiles = configFiles.filter((e) => e !== 'tsConfigJSON').sort();
logger.log(t('cli:messages.files', { pathType: useAbsolute ? '(full path)' : '(relative path)' }));
for (const fileName of configFiles) {
if (!(config.projectType[fileName] as FileDefinitionWithTooling).toolingFile) continue;
const filePath = useAbsolute
? path.resolve((config.projectType[fileName] as FileDefinitionWithTooling).toolingFile)
: path.relative(
config.locations.projectRoot,
(config.projectType[fileName] as FileDefinitionWithTooling).toolingFile
);
logger.log(`\t${fileName}: ${colors.blue(filePath)}`);
}
};