Skip to content

Commit

Permalink
feat: help command for Paragon CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
monteri committed Sep 7, 2023
1 parent b8bdc7b commit c3ca114
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 8 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,16 @@ Usage on with `@edx/brand`:

Note that including fonts will affect performance. In some applications may choose not to load the custom font to keep it highly performant.

## Paragon CLI

The Paragon CLI (Command Line Interface) is a tool that provides various utility commands to automate actions within the Open edX environment.

### Available Commands

- `paragon install-theme [theme]`: Installs the specific @edx/brand package.

Use `paragon help` to see more information.

## Getting Help

Please reach out to the Paragon Working Group (PWG):
Expand Down
54 changes: 48 additions & 6 deletions bin/paragon-scripts.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,68 @@
#!/usr/bin/env node
/* eslint-disable no-console */
const chalk = require('chalk');
const themeCommand = require('../lib/install-theme');
const helpCommand = require('../lib/help');

// command: executor function
const COMMANDS = {
'install-theme': themeCommand,
// 'command-name': {
// executor: executorFunc,
//
// ********** Block for help command start **********
// description: 'Command description',
// parameters: [
// {
// name: 'paramName',
// description: 'paramDescription',
// defaultValue: 'paramDefaultValue',
// required: true/false,
// },
// ...
// ],
// options: [
// {
// name: '--optionName',
// description: 'optionDescription',
// },
// ...
// ],
// ********** Block for help command end **********
// },
'install-theme': {
executor: themeCommand,
description: 'Installs the specific @edx/brand package.',
parameters: [
{
name: 'theme',
description: 'The @edx/brand package to install.',
defaultValue: '@edx/brand-openedx@latest',
required: false,
},
],
},
help: {
executor: helpCommand,
description: 'Displays help for available commands.',
},
};

(async () => {
const [command] = process.argv.slice(2);
const executor = COMMANDS[command];

if (!executor) {
// eslint-disable-next-line no-console
console.log(chalk.red.bold('Unknown command. Usage: paragon <command>'));
console.log(chalk.red.bold('Unknown command. Usage: paragon <command>.'));
return;
}

if (command === 'help') {
helpCommand(COMMANDS);
return;
}

try {
await executor();
await executor.executor();
} catch (error) {
// eslint-disable-next-line no-console
console.error(chalk.red.bold('An error occurred:', error.message));
process.exit(1);
}
Expand Down
57 changes: 57 additions & 0 deletions lib/help.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/* eslint-disable no-console */
const chalk = require('chalk');

const DESCRIPTION_PAD = 20;

/**
* Pads a description string to align with a specified offset string.
*
* @param {string} description - The description to pad.
* @param {string} offsetString - The offset string that the description should align with.
* @returns {string} - The padded description.
*/
function padLeft(description, offsetString) {
// Calculate the necessary padding based on the offsetString length
const padding = ' '.repeat(Math.max(0, DESCRIPTION_PAD - offsetString.length));
return `${padding}${description}`;
}

/**
* Displays a help message for available commands, including descriptions, parameters, and options.
*
* @param {Object} commands - An object containing information about available commands.
*/
function helpCommand(commands) {
console.log(chalk.yellow.bold('Paragon Help'));
console.log();
console.log('Available commands:');
console.log();

Object.keys(commands).forEach(command => {
console.log(` ${chalk.green.bold(command)}`);
if (commands[command].description) {
console.log(` ${commands[command].description}`);
}

if (commands[command].parameters && commands[command].parameters.length > 0) {
console.log(` ${chalk.cyan('Parameters: ')}`);
commands[command].parameters.forEach(parameter => {
const requiredStatus = parameter.required ? 'Required' : 'Optional';
const formattedDescription = padLeft(parameter.description, parameter.name);
console.log(` ${parameter.name}${formattedDescription} (${requiredStatus}, Default: ${parameter.defaultValue || 'None'})`);
});
}

if (commands[command].options && commands[command].options.length > 0) {
console.log(` ${chalk.cyan('Options: ')}`);
commands[command].options.forEach(option => {
const formattedDescription = padLeft(option.description, option.name);
console.log(` ${option.name}${formattedDescription}`);
});
}

console.log();
});
}

module.exports = helpCommand;
25 changes: 23 additions & 2 deletions lib/install-theme.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
/* eslint-disable no-console */
const inquirer = require('inquirer');
const childProcess = require('child_process');

/**
* Prompts the user to enter the @edx/brand package they want to install.
*
* @returns {Promise<Object>} - A Promise that resolves to an object containing the user's input.
*/
function promptUserForTheme() {
return inquirer.prompt([
{
Expand All @@ -12,6 +18,11 @@ function promptUserForTheme() {
]);
}

/**
* Installs a specified @edx/brand package.
*
* @param {string} theme - The @edx/brand package to install.
*/
function installTheme(theme) {
const version = theme ? `npm:${theme}` : '';

Expand All @@ -20,9 +31,19 @@ function installTheme(theme) {
childProcess.execSync(installCommand, { stdio: 'inherit' });
}

/**
* Command handler for installing an @edx/brand package.
*/
async function themeCommand() {
const answers = await promptUserForTheme();
installTheme(answers.theme);
// Check if the user passed a theme parameter as a command-line argument
console.log('process.argv', process.argv);
if (process.argv.length === 4) {
const providedTheme = process.argv[3];
installTheme(providedTheme);
} else {
const answers = await promptUserForTheme();
installTheme(answers.theme);
}
}

module.exports = themeCommand;

0 comments on commit c3ca114

Please sign in to comment.