keats/kickstart

A CLI tool to easily get a new project up and running by using pre-made...

A rust cross platform rust boilerplate template to get up and running quickly

kickstart

. This is a slightly more powerful version of an equivalent tool in Python, cookiecutter. It is an alternative to NodeJS projects such as Yeoman or Slush.

Installation

kickstart is available only through crates.io:

$ cargo install kickstart

Or as a pre-built binary on the Releases page.

Run kickstart --help for a full listing of the available commands and their flags/options.

Features

  • Cross-platform: Windows, Mac and Linux supported
  • Single binary: no need to install a virtualenv or anything else
  • Simple to use
  • Directory names and filenames can be templated: {{ repo_name }}/{{author}}.md is a valid path
  • All templating done through Tera - a template engine inspired by Jinja2
  • Choose your own adventure: it supports conditional questions based on previous answers
  • It can load templates from a local directory or from a Git repository
  • It has conditional cleanup to not let irrelevant files in the output directory after generation
  • Templates can be made for any kind of projects/languages

The main drawback compared to cookiecutter is the lack of hook scripts support, which can be mitigated a bit by the conditional cleanup.

Lastly, since Windows does not allow | in file paths, you may use a tera built-in filter by using the $$ separator instead.

Note that, in file templates, you should keep using | for filtering, as the $$ syntax is only for files and directories. Keep in mind the characters () are not allowed on Windows so do not use filter parameters if you want to be cross-platform.

Try it out

# From the root of this repo
$ kickstart examples/super-basic
$ kickstart examples/complex -o Hello
# Anywhere
$ kickstart https://github.com/Keats/kickstart -s examples/super-basic
$ kickstart https://github.com/Keats/kickstart-sample -o sample

Creating your own template

Creating a template is fairly simple: create files and then just add a template.toml in the root folder. Here is a description of all the fields available in it:

# Required, name of the template
name = "Django"
# Optional, longer form description
description = "A fully-featured Django template"
# Required, the version of the kickstart schema, currently only `1` is used
kickstart_version = 1
# Optional, the URL of the template
url = "https://google.com"
# Optional, a list of authors for this template
authors = [

]
# Optional, a list of keywords for this template
keywords = [

]
# Optional, those files will NOT be copied over when generating the template
# Use it to remove template-specific like its CI or its README/docs
ignore = [
    "README.md",
    "CONTRIBUTING.md",
    ".travis.yml",
    "docs",
]
# If this is set, kickstart will use this directory as a base for the template instead of
# the root directory. This is useful when your template has its own documentation/CI/etc and you don't want
# to ignore it.
directory = "some-directory"
# Optional, a list of patterns. All files matching one of the patterns will
# be copied over without going through Tera.
# Use it for files that contain syntax similar to Tera for example
copy_without_render = [
    "*.html",
]

# Optional, a list of cleanup actions to do.
# All paths listed will be deleted if the `name` has the value `value` after
# the questions have been answered and the project generated.
cleanup = [
    { name = "spa", value = true, paths = ["{{ project_name }}/templates/"]},
    { name = "auth_method", value = "none", paths = ["{{ project_name }}/docs/auth.md"]},
]

# A list of variables, the schema is explained in detail below
[[variables]]
name = "project_name"
default = "my-project"
prompt = "What is the name of this project?"
validation = "^([a-zA-Z][a-zA-Z0-9_-]+)$"

[[variables]]
name = "database"
default = "postgres"
prompt = "Which database do you want to use?"
choices = ["postgres", "mysql", "sqlite"]

[[variables]]
name = "pg_version"
default = "10.4"
prompt = "Which version of Postgres?"
choices =  [
    "10.4",
    "10.3",
    "10.2",
    "10.1",
    "9.6",
    "9.5",
    "9.4",
    "9.3",
]
only_if = { name = "database", value = "postgres" }

[[variables]]
name = "auth_method"
default = "jwt"
prompt = "How are users going to be authenticated?"
choices = ["jwt", "sessions", "none"]

[[variables]]
name = "sentry"
default = true
prompt = "Do you want to add Sentry integration?"

[[variables]]
name = "spa"
default = false
prompt = "Is the frontend a SPA?"

[[variables]]
name = "js_framework"
default = "React"
prompt = "Which JS framework do you want to setup?"
choices =  [
    "React",
    "Angular",
    "Vue",
    "None",
]
only_if = { name = "spa", value = true }

[[variables]]
name = "typescript"
default = true
prompt = "Do you want to use TypeScript?"
only_if = { name = "spa", value = true }

A variable has the following required fields:

  • name: the name of the variable in Tera context
  • default: the default value for that question, kickstart uses that to deduce the type of that value (only string, bool and integer are currently supported)
  • prompt: the text to display to the user

And three more optional fields:

  • choices: a list of potential values, kickstart will make the user pick one
  • only_if: this question will only be asked if the variable name has the value value
  • validation: a Regex pattern to check when getting a string value

List of templates

  • Rust CLI application

Changelog

0.3.0 (unreleased)

  • Update dependencies

0.2.1 (2020-02-07)

  • Allow using $$ for filters in filenames/directories

0.2.0 (2020-01-09)

  • Update all dependencies
  • Add the directory field to change the template directory away from the current one
  • VCS files are not automatically ignored anymore

0.1.8 (2018-09-30)

  • Allow loading templates from a subdirectory

0.1.7 (2018-08-09)

  • Work with Git aliases
  • The crate now works as a library as well as a binary

0.1.6 (2018-08-02)

  • Add a --no-input flag to the main command to generate a template from defaults
  • Validate that a template only uses allowed TOML types (String, integer and boolean) in validate command
  • Better question UI

0.1.5 (2018-07-31)

  • Fix git clone command

0.1.4 (2018-07-31)

  • Fix missing error display impl
  • Fix TOML error not showing up
  • Fix multi-layered questions being asked when they shouldn't

0.1.3 (2018-07-31)

  • Add pattern to match in the question when there is on

0.1.2 (2018-07-31)

  • Add optional validation field to validate a string against a regex
  • Add colours and boldness to CLI
  • Use git command rather than git2 crate to avoid some build issues
  • Add cleanup field to template definition for post-generation cleanup
  • Add validate command to diagnose errors in a template.toml file
Issues

Collection of the latest Issues

moimikey

moimikey

Comment Icon1

Would it be worth a PR to introduce a postKickstart or whatever naming convention directive, to run commands after all the kickstart questions? i have a scenario where i'd like to run npm install and a few other commands to save time.

chevdor

chevdor

documentation
Comment Icon2

Trying to escape #51, I tested to see if the --sub-dir could help.

I tested a very basic template and the following works:

Using --subdir however never worked although I provide a sub dir of the template

The error is:

We know the template is not missing and valid since the first test did work fine.

chevdor

chevdor

Comment Icon2

As I understand it, if put your template under a "template" folder (for instance) and add directory = "template" to your template.toml, template should become the root of the scaffold.

However, when using the example above with kickstart . -o OUTPUT, we end up with the following:

whereas I would expect:

chevdor

chevdor

Comment Icon2

The ability to pass the variables using an input file would be great.

That means a user could run (for instance):

or

where in this example https://gist.github.com/chevdor/050df6...c6e4207 points to a file containing all the fields. This could be a local file or a url.

Since the template is defined in toml, a first implementation could use toml as well. json can be helpful thanks to the pre/re-processing that can be done using jq.

That allows for instance, storing several sets of values in a single json map for instance:

where the json file could be something like:

That allows one-liners to bootstrap projects without any user input and with more flexibility than just using the default values from the template.

chevdor

chevdor

Comment Icon6

Loading the ENV to the Tera context is convenient in 2 locations:

template

The template.toml itself could go thru a first transformation pass. That would allow for instance:

or something richer such as:

scaffolding

I could imagine templates that can be controlled by ENV. For instance, calling MY_MODE=prod kickstart --env . would generate a diferent output than MY_MODE=dev kickstart --env .. What happens exactly is left to the template.

I would suggest NOT loading the ENV by default for security reasons. I would also suggest supporting a --env-key some_key or similarly named option that loads the ENV under the some_key key. Not only it allows accessing the ENV as a key/value but it also allows escaping potential collisions where both your template and your ENV could have a greeting_recipient (for instance).

chevdor

chevdor

Comment Icon5

It would be nice having a homebrew binary package for MacOS users. Scaffolding is especially useful for beginner users and they may not have the rust toolchain installed.

I did just that for the https://github.com/chevdor/tera-cli project and use... Tera to do the work :)

The template is rather simple: https://github.com/chevdor/tera-cli/blob/master/templates/formula.rb The CI doing that part is located here: https://github.com/chevdor/tera-cli/blob/master/.github/workflows/release.yml#L94

NOTE: I am using using a specific feature of chevdor/tera-cli in this CI: that is the support for ENV. For (probably too little) details, see:

aexvir

aexvir

Comment Icon3

Nice project!

It actually seems to be doing some nice things that I wanted cookiecutter to do and I was developing on my own 😅️

What do you think about allowing to populate the choices option dynamically via some API call? My use case at the moment is that we already have existing resources that we'd like to make references to in templated files, like k8s definitions and vcs projects.

I imagine this being set up somewhat like this:

what kickstart would do in this case would be an API call to the endpoint, with the specified headers and will query the result using JSONPath for both values and labels and zip them together, showing the labels to the users but saving the value when the user accepts

I think that allowing to template headers from env vars or cli flag should be enough to support most auth methods, and for basic auth the credentials can be templated in the endpoint part

so headers should be optional

and labels as well, for when the info displayed to the user can be used also as value

choices can accept a list of this inline tables and make one request per configured endpoint, merging all the results in the end... not sure if this would be needed at some point, otherwise it can be limited to one only, or maybe moved outside of choices

either way... this is just a suggestion implementation, I'm more interested in if you'd be up for adding this feature to kickstart and if you'd be ok with getting and reviewing a contribution on this 🙂️

Arteneko

Arteneko

Comment Icon3

What do you think about providing your tool as installable through the winget windows package manager?

I would think that it'd be awesome

Arteneko

Arteneko

Comment Icon2

What do you think about including man pages with the tool / releases (or alongside the release binaries)?

I wrote some for a project for a linux tool, and I find it really useful to have the tool / configuration documentation right on my computer, in a format I can use in my terminal, on a centralized place.

whitfin

whitfin

enhancement
Comment Icon4

Hi! Stumbled on this whilst looking through the cargo template RFCs. From the docs, it's not obvious (at least for me) whether this is supported so I figured I'd just ask as it might be a good feature addition in future:

If I have a variable of "project", can I use the input the user provides in a default for another variable?

Here's an example of why, albeit a bit of a dumb one:

Let's pretend I want to generate a *_manifest.txt file. If you name your project "my", I would generate "my_manifest.txt" unless you chose to override the name to "other_manifest.txt". So I'd be using the project variable provided as the default for the manifest variable (or whatever).

Is this currently possible?

Versions

Find the latest versions by id

v0.3.0 - Jul 10, 2021

Changes:

  • 51195c8a3b6fb1d479ea656cbcfd4afe4a8d8013 Update keywords
  • 51de34745d928475e219ecfb51a9b8edb8803ae2 Next (#53)
  • ea73816c7f7fc631c548ab967f36a7228e548f22 Minor refresh (#46)
  • 38f8ddf09c4cf16eea2cce9af4568784db94c0b0 Merge pull request #44 from jwollen/better-io-errors
  • 89441d7ba876895fd4fb9dea99d712238f772e20 Add path to more IO errors for context
  • 1e51b6568e5133b6248c20cf8aa1f2ef28d591f0 Update README.md

This list of changes was auto generated.

v0.2.1 - Feb 07, 2020

Changes:

  • d329b88c961e78651535b97c1bab9d79ed86ed93 Merge pull request #38 from Keats/next
  • 9f1415e91df0498abca08fe946f112a26cb968b4 v0.2.1
  • 79f3b258acb6ebbd4870399a868613f21abb230a Merge pull request #35 from Arteneko/master
  • cc76bbccc4f59490b8023ba74adeb17433a5a563 Merge pull request #37 from Keats/windows2
  • 33fdfb7fc938c8493e77a3015922ab4eb5083692 More tests for azure ci
  • 96e744a74b2db9146e1c810598aa80c8eae34d03 Merge pull request #36 from Keats/azure_windwos
  • a9d06509fec65b6ad3a3e3a25112e38195e92015 Make Windows build
  • 8ecc8a6d7b0a0c8a23b3fddf83e2399b47555dde Fixed where $$ is available (FS-only), updated README
  • 6a853b1e967bf2aff9f78c8addd5712c283e4a89 Merge pull request #34 from Arteneko/fix/readme
  • 3f32e07709277f16672c97fb8cef8b24046fd946 Removed useless dep, implemented $$ support for filters, updated README
See More
  • 71d72c859aed8db41dab91b8344d025e7de43a29 Fixed dead link in the README
  • 75ada901c0e8f0323823ab359fc6c7a435ab88a4 Merge remote-tracking branch 'origin/master'
  • 23d6d6df085df77ce664e5a4ea7b324c207ab3de Draft: added support for $$ slugify filter
  • 15f371d2450d3912d27e282e01e281fc178cd872 Fixed dead link on Tera reference

This list of changes was auto generated.

v0.2.0 - Jan 09, 2020

Changes:

  • 2498147167fa93d5cfcf1abf54974723850b8a5a Not v1 anymore
  • c135a5e7d934ce34025400ee81ca8ed285e3b161 Merge pull request #30 from Keats/vp_travis_tests
  • bb9674c05b553b3da1c088226bbd5c37b4b6a14c Switch to Azure pipelines
  • e8c5ed0e3487e106619417663645c7e1d529dd42 Do not build in release in travis
  • 6c3924aa9a3c18143f7b0f76eaabed0f21c46837 Add some debug
  • a4bcd647e91760a73866e2844ce38ad98e7cbe6a Update secrets
  • d5f7408b0c1c8dfea8be7c721cae6499a469bc5f Merge pull request #29 from Keats/ci
  • a974f51509095cc8490a10575b6c1b6c006dcab1 Remove GH workflows
  • 358c53ce9dfee9258cd88a1c19c51a4cda603f3c Merge pull request #27 from Keats/v1
  • b676278ac8ffc8a5de48fa6dbe61e05254559b6f rustfmt
See More
  • b9cd32697df1d9b6533c2e9ce65f7ba72b7eab9c Add dev status badge
  • 2a0ed2c34ef8aafa96a2a5d9db9e1143c44b37aa Update readme
  • c278bcf2c90cd9adfa966284c3b05f8fee16ae3b Add directory variable to template
  • 239f937425b8ae471f0bf1c7b84c3408a63df346 Remove old CI
  • fe6f43eab3d70485c13be83e7b5bb74f68d1e03c Edition 2018
  • 8dff5444485a0b6a359d438c664dede1fbdd0b51 Try to update pinned version
  • cfb0b8ca188226eb3c9952782a5a5e15e4c01e25 First try at GH release action
  • 7dea70be335b640cf399fc8f540fd7b37760d98c Remove nightly testing
  • 3ddb8009a10533f493a8701eb17f8274612fca59 GH actions
  • c26585a4552bacea11b7a86ad8da9f0a3be12bdd Update deps & error handling
  • cf269a0114baaa138bf745ab7cd2bbe1cc97f83e Merge pull request #25 from Arteneko/master
  • 8b7ed59a7b3b3e4906df496e27ceea653c3645c2 Fixed trait return type declaration

This list of changes was auto generated.

v0.1.8 - Sep 30, 2018

v0.1.7 - Aug 09, 2018

v0.1.6 - Aug 02, 2018

Information - Updated Apr 01, 2022

Stars: 248
Forks: 15
Issues: 14

Repositories & Extras

Cross-platform Terminal Manipulation Library

a simple terminal editor for both unix and windows clients

Cross-platform Terminal Manipulation Library

Cross-platform library for system information fetching

Examples can be found Async-first

Cross-platform library for system information fetching

Cross-platform filesystem notification library for Rust

Add file-system notifications via this library for Rust

Cross-platform filesystem notification library for Rust

Cross-platform, realtime MIDI processing in Rust

You can find some examples in the examples directory

Cross-platform, realtime MIDI processing in Rust

Cross-platform network scan library

This library requires the ability to create raw sockets

Cross-platform network scan library

Cross-platform music tagger written in Rust, Vue

You might need to install additional dependencies to make One Tagger work:

Cross-platform music tagger written in Rust, Vue

Cross-platform command-line application used to analyze specific metrics from the CKJM Extended Tool

ckjm_analyzer --jar <JAR_PATH> --path <PROJECTS_PATH>

Cross-platform command-line application used to analyze specific metrics from the CKJM Extended Tool

Cross platform FFI bindings for FFmpeg inner libraries

Linking FFmpeg libraries for you

Cross platform FFI bindings for FFmpeg inner libraries
Facebook Instagram Twitter GitHub Dribbble
Privacy