liftoff 0.1.1

Get your coding project off the ground fast. See repo
Documentation
<p align="center"> 
  <img src="./logo.png" width="350">
</p>
<p align="center"> <b> Get your coding project off the ground </b> </p>
<p align="center">
  <a href="https://circleci.com/gh/juliangaal/liftoff/tree/master"> <img src="https://img.shields.io/circleci/build/github/juliangaal/liftoff.svg?style=popout-square">  </a>
  <a href="https://github.com/juliangaal/liftoff/releases"> <img src="https://img.shields.io/badge/liftoff-v0.1.0-red.svg?style=popout-square"> </a>
</p>

Liftoff tries to resemble and is inspired by Rusts `cargo new foo --<some_option>` command and aims to get you up and running with coding as fast as possible, in any language.

#

* [Example]#Example
* [Install]#Install
* [How To]#How-To
    * [Usage and Options]#Usage-and-Options
    * [Licenses]#Licenses
* [Templates]#Templates
* [Writing Config Files]#Writing-Config-Files
    * [Top Level Variables]#Top-Level-Variables
    * [Files]#Files
    * [Directories]#Directories
    * [Variable Substitution]#Variable-Substitution
    * [Identifiers]#Identifiers
    * [CI]#CI
* [Building]#Building

### Example
Simple python project in folder `my_python_project`:
```bash
$ liftoff new my_python_project --config file/to/template.sane
```
generates this file tree
```bash
.
├── my_python_project
│  ├── __init__.py
│  ├── core.py
│  └── helpers.py
├── README.md
├── requirements.txt
├── LICENSE.txt
└── setup.py

```
from this config file:
```yaml
language = "python"
git = true
license = "Unlicense"

directories = [
    {
        name = "$(project)",
        files = [
            { name = "helpers.py" },
            { name = "core.py" },
            { name = "__init__.py" }
        ]
    },
]

files = [
    {
        name = "setup.py",
        template = "http://www.alink.com/a_file.py"
    },
    {
        name = "README.md",
        content = "# $(project)"
    },
    {
        name = "requirements.txt"
    },
]
```
# Install
with cargo
```bash
cargo install liftoff
```
binary releases are in the works...

After having a binary on your system, run 
```
liftoff install
```
*Disclaimer:* this will download template and license files to `~/.kick/`

# How To
## Usage and Options
### General
```bash
liftoff - get your coding project off the ground 

USAGE:
    liftoff [SUBCOMMAND]

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

SUBCOMMANDS:
    help         Prints this message or the help of the given subcommand(s)
    install      Installs liftoff files
    new          Create new project
    uninstall    Uninstalls liftoff files

```

### Create a new Project
```bash
USAGE:
    liftoff new [FLAGS] [OPTIONS] --config <FILE> [NAME]

FLAGS:
    -h, --help       Prints help information
        --nogit      Git will not be initialized in project
    -V, --version    Prints version information

OPTIONS:
    -a, --author <NAME>      Author. Needed for some licenses: MIT, BSD*
        --ci <CI_SERVICE>    Git will not be initialized in project
    -c, --config <FILE>      The config file from file path or template, e.g. "cpp" (template), "path/python.sane" (file
                             path)
    -l, --license <NAME>     License to be used
    -r, --root <PATH>        Root directory in which project <NAME> will be created. Default: $PWD

ARGS:
    <NAME>  
```
All *OPTIONS* can optionally be explicitly set in the config file itself. See [Working with Files](#Top-Level-Variables).

### Licenses
The following Licenses can be chosen from the command line `--license <Identifier>` or set in the config file `license = <Identifier>`

|Name| Identifier |Name|Identifier
|--|--|--|--|
|Unlicense |`unlicense` (Default) |Apache 2.0|`apache-2.0`|
|MIT|`mit`|EPL 2.0|`epl-2.0`|
|GPL 3.0|`gpl-3.0`|GPL 2.0|`gpl-2.0`|
|BSD 3.0|`bsd-3.0`|BSD 2.0|`bsd-2.0`|
|LGPL 2.1|`lgpl-2.1`|LGPL 3.0|`lgpl-3.0`|
|AGPL 3.0|`agpl-3.0`|MPL 2.0|`mpl-2.0`|

> Disclaimer: I am not responsible for legal damages due to license issues. Double check the generated license

### CI Options
The following Ci Services can be chosen from the command line `--ci <Identifier>` or set in the config file `ci = <Identifier>`.

|Name| Identifier |
|--|--|
|Travis CI|`travisci`|
|Circle CI|`circleci`|
|AppVeyor|`appveyor`|


# Templates
These [Templates](./files/configs) are available after installation. 

### Using default Templates
If you want to use a default template, just choose the base name of the config file (**without** the file extenstion) as the `--config <NAME>` parameter. E.g. 
```bash
 $ liftoff new myproject --config cpp
```
for [cpp.sane](./files/configs/cpp.sane)

### Custom Templates
If you are not happy with the templates given, you can do two things: 

a) quickly adapt a template
```bash
 $ liftoff prep <config_id> --name my_<config_id>.sane
```
with e.g. template [cpp](./files/configs/cpp.sane) copies base template cpp.sane to `$PWD/my_cpp.sane`, *edit it to your taste!*. Now simply run `liftoff` with the adapted template
```bash
 $ liftoff new a_project --config my_cpp.sane 
``` 
Want to save the adjusted config?
```bash
 $ liftoff save my_cpp.sane
``` 
The adjusted template will be placed to `$HOME/.liftoff/configs/` and can be used with `--config my_cpp` (*without* the file extension)

b) see next section 

# Writing Config Files

The config files follow the *sane* specification by [Bloom](https://bloom.sh/). Here's a quick [overview](https://gitlab.com/bloom42/sane/blob/master/versions/v1.0.0-beta.md) of the format. 

## Top Level Variables
All *OPTIONS* in `liftoff new -h` can be manually set in a file *OR* manually set with command line options (although command line options always **overwrite** file defaults)
The only top level variables, that **have to** exist are
* `language`: language identifier matching the [gitignore.io api names]gitignore.io

## Files
Individual files are described by
* `name`: a file name
* `template` (optional): a file template: web link or file path
* `content` (optional): a string that will be echoed into the file. If `template` AND `content` is set, the file will be overwritten by `content`!

**but must be wrapped into a Files list:**
```yaml
files = [
  { 
      name = "a_file_name", 
      template = "some_file", # optional, web link or file path
      content = "Hi there" # optional
  },
  ... # more files
]
```


## Directories
* `name`: a directory name
* file *or* list of files consisting of
    * `name`: a file name
    * `template` (optional): a file template: web link or file path
    * `content` (optional): a string that will be echoed into the file. If `template` AND `content` is set, the file will be overwritten by `content`!

**files in directory must be wrapped into a directories list:**
```yaml
directories = [
    {
        name = "$(project)", 
        files = [ # multiple files
            { 
                name = "helper.py",
                template = "/a/path/to/file.py"
            },
            { 
                name = "another_helper.py",
                content = "import numpy as np"
            },  
        ]
    },
    {
        {
            name = "$(project)_copy", 
            file = { # single file
                name = "helper_copy.py",
                template = "http://somewebsite.com"
            }
        },
    }
]
```


## Variable Substitution
You can set variables, enclosed in `$(<variable>)` in the config file. Supported substitutable variables are
* `project`
* `author` (if set)
* `language`
* `license`
* `date`
* `year`
* `month`
* `day`

E.g. config file
```yaml
language = "c++" 
git = false                                            
...
files = [
    { 
        name = "README_$(project).md", # just an example
        content = "# $(project)\n* in $(language)\n* with [liftoff](www.github.com/juliangaal/liftoff)"
    },
    ...
]
```
with liftoff command `liftoff new test_project --config /path/to/config.sane`
will be evaluated into `README_test_project.md` (***Note***: Markdown not rendered here)
```markdown
# test_project
* in c++
* with [liftoff]www.github.com/juliangaal/liftoff
```

## CI
Supported Services

|Name| Identifier |
|--|--|
|Travis CI|`travisci`|
|Circle CI|`circleci`|
|AppVeyor|`appveyor`|

A service is described by
* `name`: see *Identifier* above
* `template` (optional): web link or file path

```yaml
ci = {
    name = "circleci", # see support CI Services in section Options
    template = "some_file" # optional: web link or file path!
}
```

# Building
Requirements:
* rust >= 1.26.0 (fs::read\_to\_string())
* `libssl-dev`