dreiup-cli
===

[![NPM version][npm-version-image]][npm-url]
[![NPM downloads][npm-downloads-image]][npm-url]
[![CircleCI][ci-image]][ci-link]
[![Maintainability][codeclimate-maintainability-image]][codeclimate-maintainability-link]
[![Test Coverage][coverage-image]][coverage-link]

## Requirements
  1. node >=10.0
  1. npm >=6

## Installation

Install this package globally on your machine

```sh
npm i @dreipol/dreiup -g
```

## Usage

All the available cli features can be listed using the following command

```
dreiup --help
```

## Technologies

**Core Modules**

[commander](https://www.npmjs.com/package/commander) 
A library to create CLI subcommands and handles option parsing

[Inquirer](https://www.npmjs.com/package/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](https://www.npmjs.com/package/mocha)
Test runner module to execute our tests

[Chai](https://www.npmjs.com/package/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:

```json
{
	"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 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
  1. Create a new folder with the command name.
In this case we will use `foo`

  1. Create the command file `index.command.js` which will register a new command. This file should export a function.

        ```javascript
        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)
                });
        };
        ```

  1. Create the spec file `index.spec.js`. Within this file, the logic from `index.js` will be tested
  1. 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

```javascript
export default function foo(config, name) {
    console.log(`Foo bar ${name}`);
};

```

Example with inquirer
```javascript
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);
        });
};

```

[npm-version-image]:https://img.shields.io/npm/v/@dreipol/dreiup.svg?style=flat-square
[npm-downloads-image]:https://img.shields.io/npm/dm/@dreipol/dreiup.svg?style=flat-square
[npm-url]:https://npmjs.org/package/@dreipol/dreiup

[codeclimate-maintainability-image]:https://api.codeclimate.com/v1/badges/7c255193d04e6a5a163d/maintainability
[codeclimate-maintainability-link]:https://codeclimate.com/repos/5ce3f60727870b6af500360b/maintainability

[coverage-image]:https://api.codeclimate.com/v1/badges/7c255193d04e6a5a163d/test_coverage
[coverage-link]:https://codeclimate.com/repos/5ce3f60727870b6af500360b/test_coverage

[ci-image]:https://github.com/dreipol/dreiup-cli/workflows/CI/badge.svg
[ci-link]:https://github.com/dreipol/dreiup-cli/actions?query=workflow%3ACI
