18 releases

0.3.6 Jan 25, 2021
0.3.5 Nov 2, 2020
0.3.4 Aug 15, 2020
0.3.0 Jul 29, 2020
0.1.9 Jul 20, 2020

#241 in Build Utils

Download history 34/week @ 2024-03-30

52 downloads per month

MIT/Apache

220KB
5.5K SLoC

sht / short / 🩳

Crate status linux osx azure releases dicord

A concise cli launcher / project manager using env files.

The main goal it's readability and time saving with commands use in your project. Short it's command-line tool that allow to run program (usually sh script) with environment variables mapping from .env files. It is like to run eval $(.env_file) ./script.sh with more options.

short global workflow

Install

This product is in alpha but for personal use it is reasonably stable.

ArchLinux AUR : short-git

git clone https://aur.archlinux.org/short-git.git
cd short-git
makepkg -si

Homebrew (OSX,Linux)

brew install vincent-herlemont/tap/short

From sources

Require for compilation : libgit2, openssl.

cargo install short

Configure prompt

It's really recommended to configure the prompt. That allow to known every time which setup and
environment are selected. You can see the command show for more details.

✨ PS1 (BASH/ZSH)

Example with PS1 configure by .bashrc

export PS1="$(sht show -f):\w\$ "

Example with PS1 configure by .zshrc

⚠️ TODO ...
✨ starship

Example with custom pre-prompt : starship.

Here the custom script that starship run before display prompt.

#!/bin/bash

function blastoff(){
    sht show -f
}
starship_precmd_user_func=blastoff

Preview:

$> [my_setup:my_env] ~/your_project$

Quick start blank ✍️

Generate a simply sh script who display variables. You can use this base for what as you want. See generate for more details.

sht generate <setup_name> <environment_name> <file_kind:sh|bash>
$> sht init
$> sht generate setup_1 test sh -d
$> sht run

-d: create a sub directory (optional).

Quick start with template 🚀

🌱 Example with Node && ExpressJs

Generate a simply aws sam project base on this template node-express. See generate for more details.

Requirement : You have installed node and npm.

$> sht init
$> sht generate node-express -d -t
$> sht run

-t: generate from template. -d: create a sub directory (optional).

🌱 Example with AWS SAM

Generate a simply aws sam project base on this template aws-node-sam. See generate for more details.

Requirement : You have installed SAM and AWS_CLI.

$> sht init
$> sht generate aws-node-sam -d -t
$> sht run

-t: generate from template. -d: create a sub directory (optional).

You can list all templates available with sht generate -l and add a new one here.


Commands

init project.

Create an empty short.yaml configuration file. This one define the your project directory. All short command inside of this folder and child's folders take for references this configuration file.

$> sht init

short.yaml (generated)

setups: {}

generate setup.

Generate an empty setup or a setup from a project templates repository, this command can be also list all available project templates.

✍ Generate an empty setup ️
Arguments Required Description
<setup_name> yes Setup name
<env_name> yes Env name
<kind> yes File kind [sh,bash ...]
Options Allow empty* Default Description
-d , --directory yes <setup_name> Target directory.
-p , --private no false 🔒 Save to private directory. [conflict with "-d"]
-f , --file no run.sh Path script, create directory if they miss. [conflict with "-d"]
-e , --env-directory no . Public env directory. [conflict with "-d"]

Example : create a setup named my_setup with .test environment file and bash script.

$> sht generate my_setup test bash 

short.yaml (generated) : Configuration file.

setups:
  my_setup:
    file: run.sh
    array_vars:
      all:
        pattern: ".*"
        case: CamelCase
        format: "[{key}]='{value}'"
        delimiter: " "
    vars: []

.test (generated) : Environment file.

VAR1=VALUE1
VAR2=VALUE2

run.sh (generated) : Runnable file.

#!/bin/bash
declare -A all && eval all=($ALL)

declare -p all

The seconds line declare -A all && eval all=($ALL) allow to use bash associative array.

🌱 List all project templates
$> sht generate -l
🌱 Generate setup from projects template
Arguments Required Description
<setup_name/template> yes Setup name or <template> name with "-t" option left empty
Options Allow empty* Default Description
-t , --template yes <setup_name> Template name, can be founded in list template -l
-d , --directory yes <setup_name> Target directory.

Example : create a setup node-express with its associated envs.

$> sht generate node-express -t

👉 short.yaml (generated) and run.sh (generated) with generate from the following project template : node-express.

run setup

Run the runnable script.

📜 Details
Arguments Required Description
<args>... no All arguments will be pass to the runnable script as argument.
$> sht run

rename setup

Rename setup. e.g my_setup -> another_setup.

$> sht rename my_setup another_setup

new env

Create new env. e.g dev

$> sht new dev

Or private env. e.g prod

$> sht new dev -p

🔒 -p save the file in the private directory.

sync env

Sync all environment and ask you for each diff what to do.

$> sht sync

edit env

Edit an environment file with your default text editor. You can choose different editor with --editor <editor> or EDITOR env vars.

$> sht edit

dir env directory

Set or unset env directory.

$> sht dir ./envs/
$> sht dir --unset

pdir env private directory

Set or unset env directory.

$> sht pdir ../private_envs/
$> sht pdir --unset

use select/switch your setup/environment

📜 Details
Arguments Required Description
<setup/environment> yes The setup name or environment name if another one is already specified.
<environment> no The environment name.

In this example we have two setups named my_setup_1, my_setup_2 and two environment files named dev, prod. We have to select the setup and the environment dev and we switch of to prod environment.

e.g. Select my_setup_1 with dev environment.

$> sht use my_setup_1 dev

e.g. Switch from dev to prod environment.

$> sht use prod

👉 If a setup and environment if already selected, you can avoid to provide the setup and just indicate the environment that you want.

Now we switch to the second setup my_setup_2. For that we must to specified the setup and the environment.

e.g. Switch from my_setup_1 to my_setup_2 keeping prod environment.

$> sht use my_setup_2 prod

show your current setup / environment

📜 Details
Options Default Description
-f, --format [{setup}:{env}] Display format
$> sht show
💁 your current setup is `my_setup`:`dev`

👉 This command can be use for display the current setup / env in prompt part of the shell. So you can use the option -f (format). This option remove the return line, and you can format the format as you wanted. By default the value it's [{setup}:{env}].

  • {setup} will be replace by the current setup name.
  • {env} will be replace by the current environment name.
Full example

In this example we have one setup named my_setup and two environment files named dev and prod. We have to select the setup and the environment dev and we switch of to prod environment.

$> sht use my_setup dev
$> sht show
💁 your current setup is `my_setup`:`dev`
$> sht use prod
$> sht show
💁 your current setup is `my_setup`:`prod`

ls list all setups and environments

List all setups / environments and indicated the current one like sht show.

$> sht ls
  my_project (run.sh)
     prod (.prod)
     dev (.dev)
  my_sub_project_1 (my_sub_project_1/run.sh)
     prod (sub_env/.prod)
     staging (sub_env/.staging)
     test (sub_env/.test)
  my_sub_project_2 (my_sub_project_2/run.sh)
>    prod (sub_env/.prod)
     staging (sub_env/.staging)
     test (sub_env/.test)

vars display/compare mapping environment variables

As you can see with the variables explanation. There is two displays environment variables (UPPER_CASE) and variables (lower_case).

<variable> | <ENVIRONMENT_VARIABLE> | <value>
    ..     |           ..           |   ..

When variable are an array this will be displayed like this.

<variable> | <ENVIRONMENT_VARIABLE> (<pattern>) `case`
           | <IN_ARRAY_ENVIRONMENT_VARIABLE> | <value>
           |           ..                    |    ..

e.g. Display variables mapping of test current environment

$> sht vars
                           | test
 all         | ALL (.*)
             | VAR1        | VALUE1
             | VAR2        | VALUE2
 var1        | VAR1        | VALUE1
 var2        | VAR2        | VALUE2
 short_setup | SHORT_SETUP | my_sub_project_2
 short_env   | SHORT_ENV   | test

e.g Compare variables mapping of test and prod environment

$> sht vars -e prod test
                           | prod             | test
 all         | ALL (.*)
             | VAR1        | VALUE1           | VALUE1
             | VAR2        | VALUE2_OF_PROD   | VALUE2
 var1        | VAR1        | VALUE1           | VALUE1
 var2        | VAR2        | VALUE2_OF_PROD   | VALUE2
 short_setup | SHORT_SETUP | my_sub_project_2 | my_sub_project_2
 short_env   | SHORT_ENV   | prod             | test

envs display/compare environment variables

e.g. Display variables of test current environment

$> sht vars
      | test
 VAR1 | VALUE1
 VAR2 | VALUE2

e.g. Compare variables of test and prod environment

$> sht vars -e prod test
      | prod           | test
 VAR1 | VALUE1         | VALUE1
 VAR2 | VALUE2_OF_PROD | VALUE2

Configuration file short.yaml

setups:
  <setup_name>: # Setup.name : String
    file: run.sh # Setup.file : Path - Required
    public_env_dir: env/ # Setup.public_env_dir : Path - Optional
    array_vars: # Map<ArrayVar.name,ArrayVar|Regex> : Optional
      <group1>: ".*" # String, It's a short way to set only ArrayVar.pattern.
      <group2>:      # ArrayVar
        pattern: PREFIX_.*           # ArrayVar.pattern : Regex - Required
        case: CamelCase              # ArrayVar.case : Enum<Case> - Optional
        format: "[{key}]='{value}'"  # ArrayVar.format : String - Optional
        delimiter: " "               # ArrayVar.delimiter : String - Optional
    vars: []       # Vars

<...> means that you can put any attribute name as you want.

Setup.name

Setup name

Setup.file

Path to the a runnable script.

Setup.public_env_dir

Path towards the project subdirectory.

ArrayVars

This configuration allow to group and apply custom format and mapping in one environment variables.

Environment file

VAR1=VALUE1
VAR2=VALUE2
PREFIX_VAR1=P_VALUE1
PREFIX_VAR2=P_VALUE2

Environment variable will be injected, see ArrayVar.format for more details.

GROUP1 => VAR1:VALUE1,VAR2:VALUE2,PREFIX_VAR1:P_VALUE1,PREFIX_VAR2:P_VALUE2
GROUP2 => [PrefixVar1]='P_VALUE1' [PrefixVar2]='P_VALUE2'

ArrayVar.pattern (Regex)

All variables match with this pattern will be grouped.

For more indications see the lib(regex)* that it's used.

ArrayVar.case

Apply a case for each variables.

Available cases
CamelCase
snake_case
SHOUTY_SNAKE_CASE
mixedCase
Title Case

For more indications see the lib(heck)* that it's used.

ArrayVar.format

Format that it's apply on each variables and that will be concatenated in a string. There is two data who can used : {key} and {value}.

👉 By default (sh) the format {key}:{value} it's applied.

👉 By default (bash) it apply a format bash associative array format [{key}]='{value}' (doc).

ArrayVar.delimiter

A string that it's injected between each variables of the array.

👉 By default it's one space " ".

Vars[var]

Variables as set here, are selected for injection.

👉 Must match with environment variables.

👉 If it's no specified, all variables are selected.

👉 If it's empty like vars: [], any variables are selected.

Help

USAGE:
    sht [SUBCOMMAND]

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

SUBCOMMANDS:
    init        Init project, create an empty "short.yaml" configuration file.
    generate    Generate empty setup or from project template repository.
    run         Run setup [ARGS...].
    rename      Rename setup.
    new         Create env file ".<env>", in public directory by default.
    sync        Sync env files.
    edit        Edit env file.
    dir         Public env directory, [.] by default.
    pdir        Private env directory, unset by default.
    use         Switch of current setup or/and environment.
    show        Show your current setup.
    ls          Display setups and environments available.
    vars        Display/Diff mapping environment variables.
    envs        Display/Diff environment variables.
    help        Prints this message or the help of the given subcommand(s)

Concepts

Project short.yaml

It's a directory with the configuration file short.yaml inside it : that defined the project root.
All short commands inside of this folder and his child's folders take for references this configuration file.

  • For create/init a project see init command.

Setup

Setup it's is main concept of short. The setup configuration is describe in short.yaml and you can add more than once. It take a name, a runnable file, public env directory and mapping options. This is how short gets an easily way to simplify run command.

👉 Each setup one and only one runnable file.

  • For create/generate a setup see generate
  • For list all setups see ls command.
  • For display mapping of the setups see vars command.

Directories (public/private)

These directories store .<env> files. Env files presents in this directories will be synchronised to each other. if these set to the same setup.

Public directory

This directory must be inside of your project (The default value it's the root folder of the project). That can be a sub folder like ./env/ see setup configuration for more details. So if you had configured git or another code versioning solution, public directory allow to save with your code no critical configuration files like an example configuration file.

.
└── project
    ├── envs # public env directory
    │   └── .dev
    ├── ...
    └── short.yaml
  • For set/unset public directory see dir command.

Private directory 🔒

This directory must be outside of your project. The path of the private directory will be not store in project configuration ✅ ! So if you had configured git or another code versioning solution that will be never commit with your code and any clues of your private directory will be appear to the short configuration short.yaml.

.
├── envs # private env directory
│   └── .dev
└── project
    ├── run.sh
    └── short.yaml
  • For set/unset private directory see pdir command.

Environment file .<environment_name>

Each environment file define one environment in order to the environment name come from the file name like .<my_env> environment file => my_env environment name.

👉 The prefix . is mandatory.

The file formatting must be follow the RFC 2 – .env file guide line.

# Comment

VAR1=VALUE1
VAR2=VALUE2

Each environment inside on the same setup (public environment directory/private environment directory), are synchronised to each other. So value can be changed but, variables,variables order,spaces, comments will be the sames.

  • For create a new environment file see new command.
  • For list all environment files see ls command.
  • For display the content of environment file see envs command.
  • For edit en environment file see edit command.

Variables

Variables can be come from the environment file or specified in the configuration file : array_vars and vars.

👉 Injected to script as an environment variables, variables name will be converted to UPPER_CASE. (See also vars command).

👉 Represented as an variables, they always be converted to lower_case. (See also vars command). This display is used only for the cli output readability, like commands as vars

Option allow empty

Option like -d who can found in sht generate my_template my_env -d can have three state.

  1. Deactivate you not specified the option : e.g. sht generate my_template my_env
  2. Activate; take the value by default : e.g. sht generate my_template my_env -d The value of -d is my_template.
  3. Activate with value : e.g. sht generate my_template my_env -d foo. The value of -d is foo.

Dependencies

~23–39MB
~652K SLoC