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 commandssrc/util
helper functions that can be shared across several filessrc/index.js
Logic that is dedicated to the CLI boot is placed here. Like loading files & config and so ontest
location to add the unittest for the files within src
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 within index.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 from index.js
will be tested
-
Add the index.js
. Within this file all the logic should be placed so the index.command.js
only has to call
one function from this file, pass all parameters and that's it.
Use inquirer
within a command
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);
});
};