dreiup-cli
Requirements
- node >=10.0
- npm >=6
Installation
Install this package globally on your machine
npm i @dreipol/dreiup -g
Usage
All the available cli features can be listed using the following command
dreiup --help
Technologies
Core Modules
commander A library to create CLI subcommands and handles option parsing
Inquirer Handles user props. This way we can minimize the amount of options required for a command And give the user a simpler experience.
Testing Modules
Mocha Test runner module to execute our tests
Chai Assertion library that works with any testrunner
Commands
create <projectName>
dreiup create <projectName>
will create a new project. It will generate a sub folder in the current directory with
the given project name and install the template from dreiup-templates
from the master
branch.
In case you need another branch to be used, you can add the option -b <branchName>
or --branch <branchName>
.
Or you can specify a template source directory with -t <path>
or --template <path>
. This will not fetch any
data from the remote repo, but will use the given path as a template source folder and will then install it's content
into the projectName
subfolder
setup
dreiup setup
creates the ~/.dreiup.json
file in your home directory storing your private global variables.
Your ~/.dreiup.json
file will look something like:
{
"GITHUB_OAUTH_TOKEN": "1d5723BLABLABLA1a9c6c30"
}
Development
To see if everything behaves correctly you can link this repo with npm link
. This exposes the dreiup
cli command
that is then linked directly into this directory instead of the global module installation
Structure
Module Structure
- src
- commands
- cli
- test
-
src
core functionality used to "boot" the cli, load commands and config and so on. Logic shared between the commands can also be placed here. -
src/commands
contains all available commands -
src/util
helper functions that can be shared across several files -
src/index.js
Logic that is dedicated to the CLI boot is placed here. Like loading files & config and so on -
test
location to add the unittest for the files withinsrc
Command Structure
- commands
- <COMMAND_NAME>
- command.js
- index.spec.js
- prompt.js
- index.js
-
commands
Folder containing all available commands -
<COMMAND_NAME>
Folder containing a single command. This name should correspond to the name available in the cli -
command.js
The command initialisation. This file is autoloaded to expose the command and its description -
index.spec.js
Containing all unittests for the command logic withinindex.js
-
prompt.js
Prompts spawned by the command -
index.js
Contains the main logic of the command. All logic is here to make the command as testable as possible
Create a new Command
-
Create a new folder with the command name. In this case we will use
foo
-
Create the command file
index.command.js
which will register a new command. This file should export a function.import program from 'commander'; import foo from './index.js'; export default function() { program .command('foo <name>') .alias('f') .description('Example foo command') .action(async (name) => { await foo(name) }); };
-
Create the spec file
index.spec.js
. Within this file, the logic fromindex.js
will be tested -
Add the
index.js
. Within this file all the logic should be placed so theindex.command.js
only has to call one function from this file, pass all parameters and that's it.
inquirer
within a command
Use In order to let the user make more decisions, we simply wrap the main logic from index.js
into another function.
Example before
export default function foo(config, name) {
console.log(`Foo bar ${name}`);
};
Example with inquirer
import inquirer from 'inquirer';
function foo(config, name, gender) {
console.log(`Foo bar ${gender} ${name}`);
}
export default function (config, name) {
return inquirer
.prompt([
{
type: 'list',
name: 'gender',
message: 'Select gender',
choices: ['male', 'female']
}
])
.then(({gender}) => {
return foo(config, name, gender);
});
};