├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── template.toml
└── {{project_name}}
├── .editorconfig
├── .gitignore
├── .travis.yml
├── CHANGELOG
├── Cargo.toml
├── LICENSE
├── README.md
├── appveyor.yml
├── build.rs
├── ci
├── before_deploy.ps1
├── before_deploy.sh
├── install.sh
└── script.sh
└── src
├── cli.rs
├── errors.rs
├── main.rs
└── terminal.rs
/.gitignore:
--------------------------------------------------------------------------------
1 | target
2 | .idea/
3 | my-cli
4 | My-CLI
5 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: rust
2 | rust:
3 | - beta
4 |
5 | sudo: false
6 |
7 | notifications:
8 | email: false
9 |
10 | before_script:
11 | - cargo install kickstart
12 |
13 | script:
14 | - kickstart validate template.toml
15 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Vincent Prouillet
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # rust-cli-template
2 |
3 | A template to get started with writing cross-platforms CLI applications
4 | hosted on GitHub.
5 |
6 | ## Features
7 |
8 | - CLI app setup with clap
9 | - Optional terminal colours & styling
10 | - CI setup
11 | - Cross-platform binary release via [trust](https://github.com/japaric/trust)
12 | - Shell completion scripts setup
13 | - Various repo housekeeping: changelog, editorconfig etc
14 |
15 | All of the above is optional: you can pick only the features you want.
16 |
17 | ## Pre-requisites
18 | If you want to enable the publication of binaries, you will need to do the following steps first.
19 |
20 | ### Create the GitHub repo
21 | You might also need to enable it in Travis/AppVeyor.
22 |
23 | ### Encrypt a GH token for Travis
24 | Go to https://github.com/settings/tokens/new and create 1 `public_repo` tokens, the
25 | name is up to you but should be something like `{{project}} Travis` so it is easy to find.
26 |
27 | Encrypt the token by using the `travis` gem:
28 |
29 | ```bash
30 | $ travis encrypt $TOKEN -r $GH_USER/$GH_REPO
31 | ```
32 |
33 | If your repo is using travis.com (likely now), you will also need to pass the `--com` flag.
34 |
35 | Copy the output somewhere, we will need it later!
36 |
37 | ### Encrypt it for AppVeyor
38 | Go to https://github.com/settings/tokens/new and create 1 `public_repo` tokens, the
39 | name is up to you but should be something like `{{project}} AppVeyor` so it is easy to find.
40 |
41 | Go to https://ci.appveyor.com/tools/encrypt and encrypt the second GitHub token.
42 | As before, you will also need the output later.
43 |
44 | ## Get started
45 | This is a [kickstart template](https://github.com/Keats/kickstart) so you
46 | will need to have `kickstart` installed:
47 |
48 | ```bash
49 | $ cargo install kickstart
50 | ```
51 |
52 | Once you have it installed and have the encrypted tokens generated above if needed, run:
53 |
54 | ```bash
55 | $ kickstart https://github.com/Keats/rust-cli-template
56 | ```
57 |
58 | ## Steps left for you
59 |
60 | - Check that the name repo name in the badges in the README match the actual one: it uses the project
61 | name by default
62 |
63 |
64 | ## Template TODOs
65 |
66 | - Is there an equivalent to Trust for GitLab?
67 |
--------------------------------------------------------------------------------
/template.toml:
--------------------------------------------------------------------------------
1 | name = "Rust CLI template"
2 | description = "A template to get started with a Rust CLI application on the right foot"
3 | kickstart_version = 1
4 | ignore = [
5 | ".gitignore",
6 | "README.md",
7 | "LICENSE",
8 | ".travis.yml",
9 | ]
10 |
11 | cleanup = [
12 | {name = "license", value = "None", paths = ["{{project_name}}/LICENSE"]},
13 | {name = "changelog", value = false, paths = ["{{project_name}}/CHANGELOG"]},
14 | {name = "on_github", value = false, paths = ["{{project_name}}/.travis.yml", "{{project_name}}/appveyor.yml", "{{project_name}}/ci"]},
15 | {name = "shell_completions", value = false, paths = ["{{project_name}}/build.rs", "{{project_name}}/completions"]},
16 | {name = "editorconfig", value = false, paths = ["{{project_name}}/.editorconfig"]},
17 | {name = "fancy_term", value = false, paths = ["{{project_name}}/src/terminal.rs"]},
18 | ]
19 |
20 | [[variables]]
21 | name = "project_name"
22 | default = "My-CLI"
23 | prompt = "What's the name of the project?"
24 | validation = "^([a-zA-Z][a-zA-Z0-9_-]+)$"
25 |
26 | [[variables]]
27 | name = "bin"
28 | default = "my-cli"
29 | prompt = "What's the name of the executable?"
30 | validation = "^([a-zA-Z][a-zA-Z-_]+)$"
31 |
32 | [[variables]]
33 | name = "description"
34 | default = "A CLI application"
35 | prompt = "A short description of the app?"
36 |
37 | [[variables]]
38 | name = "author"
39 | default = "No One"
40 | prompt = "What is your name?"
41 |
42 | [[variables]]
43 | name = "email"
44 | default = "no@one.com"
45 | prompt = "What is your email?"
46 |
47 | [[variables]]
48 | name = "license"
49 | default = "MIT"
50 | prompt = "Which open-source license do you want to use?"
51 | choices = [
52 | "MIT",
53 | "BSD",
54 | "GPLv3",
55 | "None",
56 | ]
57 |
58 | [[variables]]
59 | name = "on_github"
60 | default = true
61 | prompt = "Will the project be hosted on GitHub?"
62 |
63 | [[variables]]
64 | name = "gh_username"
65 | default = ""
66 | prompt = "What is your GitHub username?"
67 | only_if = { name = "on_github", value = true }
68 |
69 | [[variables]]
70 | name = "publish_binaries"
71 | default = true
72 | prompt = "Do you want to publish binary releases for Linux, MacOs and Windows?"
73 | only_if = { name = "on_github", value = true }
74 |
75 | [[variables]]
76 | name = "gh_token"
77 | default = "REPLACE_ME"
78 | prompt = "What is the Travis encrypted Travis token?"
79 | only_if = { name = "publish_binaries", value = true }
80 |
81 | [[variables]]
82 | name = "appveyor_token"
83 | default = "REPLACE_ME"
84 | prompt = "What is the AppVeyor encrypted Travis token?"
85 | only_if = { name = "publish_binaries", value = true }
86 |
87 | [[variables]]
88 | name = "ci_notifications"
89 | default = false
90 | prompt = "Do you want to be notified by email for every CI build?"
91 | only_if = { name = "publish_binaries", value = true }
92 |
93 | [[variables]]
94 | name = "shell_completions"
95 | default = true
96 | prompt = "Do you want to generate shell completions?"
97 |
98 | [[variables]]
99 | name = "fancy_term"
100 | default = false
101 | prompt = "Do you want to add colours/style to the terminal output?"
102 |
103 | [[variables]]
104 | name = "changelog"
105 | default = true
106 | prompt = "Do you want to keep a changelog?"
107 |
108 | [[variables]]
109 | name = "editorconfig"
110 | default = true
111 | prompt = "Do you want to use editorconfig (https://editorconfig.org)?"
112 |
--------------------------------------------------------------------------------
/{{project_name}}/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 | charset = utf-8
6 | trim_trailing_whitespace = true
7 | insert_final_newline = true
8 | indent_style = space
9 | indent_size = 4
10 |
11 | [*.rs]
12 | indent_style = space
13 | indent_size = 4
14 |
15 | [*.toml]
16 | indent_style = space
17 | indent_size = 4
18 |
19 | [*.md]
20 | trim_trailing_whitespace = false
21 |
--------------------------------------------------------------------------------
/{{project_name}}/.gitignore:
--------------------------------------------------------------------------------
1 | target
2 | **/*.rs.bk
3 |
4 | .idea/
5 |
6 | .vscode/*
7 | !.vscode/settings.json
8 | !.vscode/tasks.json
9 | !.vscode/launch.json
10 | !.vscode/extensions.json
11 |
--------------------------------------------------------------------------------
/{{project_name}}/.travis.yml:
--------------------------------------------------------------------------------
1 | dist: trusty
2 | language: rust
3 | services: docker
4 |
5 | env:
6 | global:
7 | - CRATE_NAME={{bin}}
8 |
9 | matrix:
10 | include:
11 | # Linux
12 | - env: TARGET=x86_64-unknown-linux-gnu
13 | # OSX
14 | - env: TARGET=x86_64-apple-darwin
15 | os: osx
16 |
17 | # Testing other channels
18 | - env: TARGET=x86_64-unknown-linux-gnu
19 | rust: beta
20 | - env: TARGET=x86_64-unknown-linux-gnu
21 | rust: nightly
22 |
23 |
24 | before_install: set -e
25 |
26 | install:
27 | - sh ci/install.sh
28 | - source ~/.cargo/env || true
29 |
30 | script:
31 | - bash ci/script.sh
32 |
33 | after_script: set +e
34 |
35 | before_deploy:
36 | - sh ci/before_deploy.sh
37 |
38 | deploy:
39 | api_key:
40 | # if you see REPLACE_ME here, fix it by following the README of the template
41 | secure: {{gh_token | default(value="")}}
42 | file_glob: true
43 | file: $CRATE_NAME-$TRAVIS_TAG-$TARGET.*
44 | on:
45 | condition: $TRAVIS_RUST_VERSION = stable
46 | tags: true
47 | provider: releases
48 | skip_cleanup: true
49 |
50 | cache: cargo
51 | before_cache:
52 | # Travis can't cache files that are not readable by "others"
53 | - chmod -R a+r $HOME/.cargo
54 |
55 | branches:
56 | only:
57 | # release tags
58 | - /^v\d+\.\d+\.\d+.*$/
59 | - master
60 |
61 | notifications:
62 | email: {{ci_notifications | default(value=false)}}
63 |
--------------------------------------------------------------------------------
/{{project_name}}/CHANGELOG:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## 0.1.0 (unreleased)
4 | - Initial release
5 |
--------------------------------------------------------------------------------
/{{project_name}}/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "{{project_name}}"
3 | description = "{{description}}"
4 | version = "0.1.0"
5 | authors = ["{{author}} <{{email}}>"]
6 | autobins = false
7 | {% if license != "None" -%}
8 | license = "{{license}}"
9 | {%- endif %}
10 |
11 | [[bin]]
12 | name = "{{bin}}"
13 | path = "src/main.rs"
14 |
15 | [dependencies]
16 | clap = "2"
17 | {% if fancy_term -%}
18 | term = "0.5"
19 | {%- endif -%}
20 |
21 | {%- if shell_completions %}
22 |
23 | [build-dependencies]
24 | clap = "2"
25 | {%- endif %}
26 |
--------------------------------------------------------------------------------
/{{project_name}}/LICENSE:
--------------------------------------------------------------------------------
1 | {%- set year = now() | date(format="%Y") -%}
2 | {%- if license == "MIT" -%}
3 | MIT License
4 |
5 | Copyright (c) {{year}} {{author}}
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy
8 | of this software and associated documentation files (the "Software"), to deal
9 | in the Software without restriction, including without limitation the rights
10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | copies of the Software, and to permit persons to whom the Software is
12 | furnished to do so, subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in all
15 | copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | SOFTWARE.
24 | {%- elif license == "BSD" -%}
25 | Copyright (c) {{year}}, {{author}}
26 | All rights reserved.
27 |
28 | Redistribution and use in source and binary forms, with or without modification,
29 | are permitted provided that the following conditions are met:
30 |
31 | * Redistributions of source code must retain the above copyright notice, this
32 | list of conditions and the following disclaimer.
33 |
34 | * Redistributions in binary form must reproduce the above copyright notice, this
35 | list of conditions and the following disclaimer in the documentation and/or
36 | other materials provided with the distribution.
37 |
38 | * Neither the name of {{ project_name }} nor the names of its
39 | contributors may be used to endorse or promote products derived from this
40 | software without specific prior written permission.
41 |
42 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
43 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
44 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
45 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
46 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
47 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
48 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
49 | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
50 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 | OF THE POSSIBILITY OF SUCH DAMAGE.
52 | {%- elif license == "GPLv3" -%}
53 | Copyright (c) {{year}}, {{author}}
54 |
55 | This program is free software: you can redistribute it and/or modify
56 | it under the terms of the GNU General Public License as published by
57 | the Free Software Foundation, either version 3 of the License, or
58 | (at your option) any later version.
59 |
60 | This program is distributed in the hope that it will be useful,
61 | but WITHOUT ANY WARRANTY; without even the implied warranty of
62 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
63 | GNU General Public License for more details.
64 |
65 | You should have received a copy of the GNU General Public License
66 | along with this program. If not, see .
67 | {%- endif -%}
68 |
--------------------------------------------------------------------------------
/{{project_name}}/README.md:
--------------------------------------------------------------------------------
1 | # {{project_name}}
2 |
3 | {{description}}
4 |
5 | {%- if on_github -%}
6 |
7 | [](https://travis-ci.org/{{gh_username}}/{{project_name}})
8 | [](https://ci.appveyor.com/project/{{gh_username}}/{{project_name}})
9 | {%- endif %}
10 |
11 | {%- if license %}
12 |
13 | Licensed under {{license}}.
14 | {%- endif %}
15 |
16 | {%- if changelog %}
17 |
18 | ## Changelog
19 |
20 | Please see the [CHANGELOG](CHANGELOG.md) for a release history.
21 | {%- endif -%}
22 |
23 | {%- if publish_binaries %}
24 |
25 | ## Installation
26 | Binaries are automatically uploaded to GitHub for each version.
27 | {%- endif -%}
28 |
--------------------------------------------------------------------------------
/{{project_name}}/appveyor.yml:
--------------------------------------------------------------------------------
1 | # Based on the "trust" template v0.1.2
2 | # https://github.com/japaric/trust/tree/v0.1.2
3 |
4 | environment:
5 | global:
6 | # TODO This is the Rust channel that build jobs will use by default but can be
7 | # overridden on a case by case basis down below
8 | RUST_VERSION: stable
9 |
10 | # TODO Update this to match the name of your project.
11 | CRATE_NAME: {{bin}}
12 |
13 | # TODO These are all the build jobs. Adjust as necessary. Comment out what you
14 | # don't need
15 | matrix:
16 | # MinGW
17 | - TARGET: i686-pc-windows-gnu
18 | - TARGET: x86_64-pc-windows-gnu
19 |
20 | # MSVC
21 | - TARGET: i686-pc-windows-msvc
22 | - TARGET: x86_64-pc-windows-msvc
23 |
24 | # Testing other channels
25 | - TARGET: x86_64-pc-windows-gnu
26 | RUST_VERSION: nightly
27 | - TARGET: x86_64-pc-windows-msvc
28 | RUST_VERSION: nightly
29 |
30 | install:
31 | - ps: >-
32 | If ($Env:TARGET -eq 'x86_64-pc-windows-gnu') {
33 | $Env:PATH += ';C:\msys64\mingw64\bin'
34 | } ElseIf ($Env:TARGET -eq 'i686-pc-windows-gnu') {
35 | $Env:PATH += ';C:\msys64\mingw32\bin'
36 | }
37 | - curl -sSf -o rustup-init.exe https://win.rustup.rs/
38 | - rustup-init.exe -y --default-host %TARGET% --default-toolchain %RUST_VERSION%
39 | - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
40 | - rustc -Vv
41 | - cargo -V
42 |
43 | # TODO This is the "test phase", tweak it as you see fit
44 | test_script:
45 | # we don't run the "test phase" when doing deploys
46 | - if [%APPVEYOR_REPO_TAG%]==[false] (
47 | cargo build --target %TARGET% &&
48 | cargo build --target %TARGET% --release &&
49 | cargo test --target %TARGET% &&
50 | cargo test --target %TARGET% --release &&
51 | cargo run --target %TARGET% &&
52 | cargo run --target %TARGET% --release
53 | )
54 |
55 | before_deploy:
56 | # TODO Update this to build the artifacts that matter to you
57 | - cargo rustc --target %TARGET% --release --bin {{bin}} -- -C lto
58 | - ps: ci\before_deploy.ps1
59 |
60 | deploy:
61 | artifact: /.*\.zip/
62 | # TODO update `auth_token.secure`
63 | # - Create a `public_repo` GitHub token. Go to: https://github.com/settings/tokens/new
64 | # - Encrypt it. Go to https://ci.appveyor.com/tools/encrypt
65 | # - Paste the output down here
66 | auth_token:
67 | secure: {{appveyor_token | default(value="")}}
68 | description: ''
69 | on:
70 | # TODO Here you can pick which targets will generate binary releases
71 | # In this example, there are some targets that are tested using the stable
72 | # and nightly channels. This condition makes sure there is only one release
73 | # for such targets and that's generated using the stable channel
74 | RUST_VERSION: stable
75 | appveyor_repo_tag: true
76 | provider: GitHub
77 |
78 | cache:
79 | - C:\Users\appveyor\.cargo\registry
80 | - target
81 |
82 | branches:
83 | only:
84 | # Release tags
85 | - /^v\d+\.\d+\.\d+.*$/
86 | - master
87 |
88 | notifications:
89 | - provider: Email
90 | to:
91 | - {{email}}
92 | on_build_success: {{ci_notifications | default(value=false)}}
93 |
94 | # Building is done in the test phase, so we disable Appveyor's build phase.
95 | build: false
96 |
--------------------------------------------------------------------------------
/{{project_name}}/build.rs:
--------------------------------------------------------------------------------
1 | #[macro_use]
2 | extern crate clap;
3 |
4 | use clap::Shell;
5 |
6 | include!("src/cli.rs");
7 |
8 | fn main() {
9 | // this might fail in CI
10 | let mut app = build_cli();
11 | app.gen_completions("{{bin}}", Shell::Bash, "completions/");
12 | app.gen_completions("{{bin}}", Shell::Fish, "completions/");
13 | app.gen_completions("{{bin}}", Shell::Zsh, "completions/");
14 | app.gen_completions("{{bin}}", Shell::PowerShell, "completions/");
15 | }
16 |
--------------------------------------------------------------------------------
/{{project_name}}/ci/before_deploy.ps1:
--------------------------------------------------------------------------------
1 | # This script takes care of packaging the build artifacts that will go in the
2 | # release zipfile
3 |
4 | $SRC_DIR = $PWD.Path
5 | $STAGE = [System.Guid]::NewGuid().ToString()
6 |
7 | Set-Location $ENV:Temp
8 | New-Item -Type Directory -Name $STAGE
9 | Set-Location $STAGE
10 |
11 | $ZIP = "$SRC_DIR\$($Env:CRATE_NAME)-$($Env:APPVEYOR_REPO_TAG_NAME)-$($Env:TARGET).zip"
12 |
13 | # TODO Update this to package the right artifacts
14 | Copy-Item "$SRC_DIR\target\$($Env:TARGET)\release\{{bin}}.exe" '.\'
15 |
16 | 7z a "$ZIP" *
17 |
18 | Push-AppveyorArtifact "$ZIP"
19 |
20 | Remove-Item *.* -Force
21 | Set-Location ..
22 | Remove-Item $STAGE
23 | Set-Location $SRC_DIR
24 |
--------------------------------------------------------------------------------
/{{project_name}}/ci/before_deploy.sh:
--------------------------------------------------------------------------------
1 | # This script takes care of building your crate and packaging it for release
2 |
3 | set -ex
4 |
5 | main() {
6 | local src=$(pwd) \
7 | stage=
8 |
9 | case $TRAVIS_OS_NAME in
10 | linux)
11 | stage=$(mktemp -d)
12 | ;;
13 | osx)
14 | stage=$(mktemp -d -t tmp)
15 | ;;
16 | esac
17 |
18 | test -f Cargo.lock || cargo generate-lockfile
19 |
20 | # TODO Update this to build the artifacts that matter to you
21 | cross rustc --bin {{bin}} --target $TARGET --release -- -C lto
22 |
23 | # TODO Update this to package the right artifacts
24 | cp target/$TARGET/release/{{bin}} $stage/
25 |
26 | cd $stage
27 | tar czf $src/$CRATE_NAME-$TRAVIS_TAG-$TARGET.tar.gz *
28 | cd $src
29 |
30 | rm -rf $stage
31 | }
32 |
33 | main
34 |
--------------------------------------------------------------------------------
/{{project_name}}/ci/install.sh:
--------------------------------------------------------------------------------
1 | set -ex
2 |
3 | main() {
4 | local target=
5 | if [ $TRAVIS_OS_NAME = linux ]; then
6 | target=x86_64-unknown-linux-musl
7 | sort=sort
8 | else
9 | target=x86_64-apple-darwin
10 | sort=gsort # for `sort --sort-version`, from brew's coreutils.
11 | fi
12 |
13 | # Builds for iOS are done on OSX, but require the specific target to be
14 | # installed.
15 | case $TARGET in
16 | aarch64-apple-ios)
17 | rustup target install aarch64-apple-ios
18 | ;;
19 | armv7-apple-ios)
20 | rustup target install armv7-apple-ios
21 | ;;
22 | armv7s-apple-ios)
23 | rustup target install armv7s-apple-ios
24 | ;;
25 | i386-apple-ios)
26 | rustup target install i386-apple-ios
27 | ;;
28 | x86_64-apple-ios)
29 | rustup target install x86_64-apple-ios
30 | ;;
31 | esac
32 |
33 | # This fetches latest stable release
34 | local tag=$(git ls-remote --tags --refs --exit-code https://github.com/japaric/cross \
35 | | cut -d/ -f3 \
36 | | grep -E '^v[0.1.0-9.]+$' \
37 | | $sort --version-sort \
38 | | tail -n1)
39 | curl -LSfs https://japaric.github.io/trust/install.sh | \
40 | sh -s -- \
41 | --force \
42 | --git japaric/cross \
43 | --tag $tag \
44 | --target $target
45 | }
46 |
47 | main
48 |
--------------------------------------------------------------------------------
/{{project_name}}/ci/script.sh:
--------------------------------------------------------------------------------
1 | # This script takes care of testing your crate
2 |
3 | set -ex
4 |
5 | # TODO This is the "test phase", tweak it as you see fit
6 | main() {
7 | cross build --target $TARGET
8 | cross build --target $TARGET --release
9 |
10 | if [ ! -z $DISABLE_TESTS ]; then
11 | return
12 | fi
13 |
14 | cross test --all --target $TARGET
15 | cross test --all --target $TARGET --release
16 | }
17 |
18 | # we don't run the "test phase" when doing deploys
19 | if [ -z $TRAVIS_TAG ]; then
20 | main
21 | fi
22 |
--------------------------------------------------------------------------------
/{{project_name}}/src/cli.rs:
--------------------------------------------------------------------------------
1 | use clap::{App, Arg, SubCommand};
2 |
3 |
4 | pub fn build_cli() -> App<'static, 'static> {
5 | App::new("{{bin}}")
6 | .version(crate_version!())
7 | .author(crate_authors!())
8 | .about(crate_description!())
9 | .subcommands(vec![])
10 | }
11 |
--------------------------------------------------------------------------------
/{{project_name}}/src/errors.rs:
--------------------------------------------------------------------------------
1 | use std::error::Error as StdError;
2 | use std::result;
3 |
4 | /// A crate private constructor for `Error`.
5 | pub(crate) fn new_error(kind: ErrorKind) -> Error {
6 | Error(Box::new(kind))
7 | }
8 |
9 | /// A type alias for `Result`.
10 | pub type Result = result::Result;
11 |
12 | /// An error that can occur when encoding/decoding JWTs
13 | #[derive(Debug)]
14 | pub struct Error(Box);
15 |
16 | impl Error {
17 | /// Return the specific type of this error.
18 | pub fn kind(&self) -> &ErrorKind {
19 | &self.0
20 | }
21 | /// Unwrap this error into its underlying type.
22 | pub fn into_kind(self) -> ErrorKind {
23 | *self.0
24 | }
25 | }
26 |
27 | /// The specific type of an error.
28 | #[derive(Debug)]
29 | pub enum ErrorKind {
30 | // Add your errors there
31 | }
32 |
--------------------------------------------------------------------------------
/{{project_name}}/src/main.rs:
--------------------------------------------------------------------------------
1 | #[macro_use]
2 | extern crate clap;
3 | {%- if fancy_term %}
4 |
5 | extern crate term;
6 | {%- endif %}
7 |
8 | mod cli;
9 | mod errors;
10 | {%- if fancy_term %}
11 | mod terminal;
12 | {%- endif %}
13 |
14 | fn main() {
15 | let matches = cli::build_cli().get_matches();
16 | // Do your thing here
17 | }
18 |
--------------------------------------------------------------------------------
/{{project_name}}/src/terminal.rs:
--------------------------------------------------------------------------------
1 | use std::io::prelude::*;
2 |
3 | use term;
4 |
5 | // Some examples on how to use the term crate
6 |
7 | pub fn error(message: &str) {
8 | if let Some(mut t) = term::stderr() {
9 | match t.fg(term::color::BRIGHT_RED) {
10 | Ok(_) => {
11 | write!(t, "{}", message).unwrap();
12 | t.reset().unwrap();
13 | },
14 | Err(_) => writeln!(t, "{}", message).unwrap()
15 | };
16 | } else {
17 | eprint!("{}", message);
18 | }
19 | }
20 |
21 |
22 | pub fn success(message: &str) {
23 | if let Some(mut t) = term::stdout() {
24 | match t.fg(term::color::GREEN) {
25 | Ok(_) => {
26 | write!(t, "{}", message).unwrap();
27 | t.reset().unwrap();
28 | },
29 | Err(_) => writeln!(t, "{}", message).unwrap()
30 | };
31 | } else {
32 | eprint!("{}", message);
33 | }
34 | }
35 |
36 |
--------------------------------------------------------------------------------