diff options
| -rw-r--r-- | Justfile | 9 | ||||
| -rw-r--r-- | cargo-generate.toml | 1 | ||||
| -rw-r--r-- | cli/README.md | 2 | ||||
| -rw-r--r-- | cli/template/.editorconfig | 11 | ||||
| -rw-r--r-- | cli/template/.gitignore | 2 | ||||
| -rw-r--r-- | cli/template/.rustfmt.toml | 19 | ||||
| -rw-r--r-- | cli/template/Cargo.toml | 61 | ||||
| -rw-r--r-- | cli/template/Justfile | 38 | ||||
| -rw-r--r-- | cli/template/LICENSE | 13 | ||||
| -rw-r--r-- | cli/template/README.md | 11 | ||||
| -rw-r--r-- | cli/template/build.rs | 21 | ||||
| -rw-r--r-- | cli/template/cargo-generate.toml | 5 | ||||
| -rw-r--r-- | cli/template/dprint.json | 24 | ||||
| -rw-r--r-- | cli/template/rust-toolchain.toml | 3 | ||||
| -rw-r--r-- | cli/template/src/main.rs | 72 |
15 files changed, 292 insertions, 0 deletions
@@ -4,6 +4,15 @@ default: generate-all: just web just lib + just cli + + +cli $CARGO_NAME="your name" $CARGO_EMAIL="author@example.com": + rm -rv cli-generated + cargo generate --path ./cli \ + --name cli-generated \ + --define project-description="An example generated using the cli template" \ + --define use-gitserver=false web $CARGO_NAME="your name" $CARGO_EMAIL="author@example.com": rm -rv web-generated diff --git a/cargo-generate.toml b/cargo-generate.toml index d613432..af89a1e 100644 --- a/cargo-generate.toml +++ b/cargo-generate.toml @@ -5,4 +5,5 @@ cargo_generate_version = ">=0.23.0" sub_templates = [ "web", "lib", + "cli", ] diff --git a/cli/README.md b/cli/README.md new file mode 100644 index 0000000..e1ed241 --- /dev/null +++ b/cli/README.md @@ -0,0 +1,2 @@ +# cli template + diff --git a/cli/template/.editorconfig b/cli/template/.editorconfig new file mode 100644 index 0000000..d6c3cc6 --- /dev/null +++ b/cli/template/.editorconfig @@ -0,0 +1,11 @@ +# https://EditorConfig.org +root = true + +[*] +charset = utf-8 +trim_trailing_whitespace = true +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 4 + diff --git a/cli/template/.gitignore b/cli/template/.gitignore new file mode 100644 index 0000000..9fbc864 --- /dev/null +++ b/cli/template/.gitignore @@ -0,0 +1,2 @@ +target/ +tmp/ diff --git a/cli/template/.rustfmt.toml b/cli/template/.rustfmt.toml new file mode 100644 index 0000000..3aff51c --- /dev/null +++ b/cli/template/.rustfmt.toml @@ -0,0 +1,19 @@ +style_edition = "2024" +max_width = 79 +# Make Rust more readable given most people have wide screens nowadays. +# This is also the setting used by [rustc](https://github.com/rust-lang/rust/blob/master/rustfmt.toml) +use_small_heuristics = "Max" + +# Use field initialize shorthand if possible +use_field_init_shorthand = true + +reorder_modules = true + +# All unstable features that we wish for +# unstable_features = true +# Provide a cleaner impl order +# reorder_impl_items = true +# Provide a cleaner import sort order +# group_imports = "StdExternalCrate" +# Group "use" statements by crate +# imports_granularity = "Crate" diff --git a/cli/template/Cargo.toml b/cli/template/Cargo.toml new file mode 100644 index 0000000..41f977e --- /dev/null +++ b/cli/template/Cargo.toml @@ -0,0 +1,61 @@ +[package] +name = "{{project-name}}" +version = "0.1.0" + +authors = ["{{authors}}"] +description = "{{project-description}}" +edition = "2024" +license = "ISC" + +# +# lints +# + +[lints.rust] +absolute_paths_not_starting_with_crate = "warn" +non_ascii_idents = "warn" +tail_expr_drop_order = "warn" +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(coverage)', 'cfg(coverage_nightly)'] } +unit-bindings = "warn" +unsafe_op_in_unsafe_fn = "warn" +unused_unsafe = "warn" + +[lints.clippy] +all = { level = "warn", priority = -1 } + +# +# dep +# + +[dependencies] +anyhow = "=1.0.100" +clap = { version = "=4.5.53", features = ["derive"] } +env_logger = "=0.11.8" +log = "=0.4.28" + +# +# profiles +# + +[profile.dev] +debug = false + +[profile.test] +debug = false + +[profile.release-with-debug] +inherits = "release" +strip = false +debug = true + +[profile.coverage] +inherits = "release" +opt-level = 2 +codegen-units = 256 +lto = "thin" +debug-assertions = true +overflow-checks = true + +[profile.dev-no-debug-assertions] +inherits = "dev" +debug-assertions = false diff --git a/cli/template/Justfile b/cli/template/Justfile new file mode 100644 index 0000000..d751545 --- /dev/null +++ b/cli/template/Justfile @@ -0,0 +1,38 @@ +#!/usr/bin/env -S just --justfile + +_default: + @just --list -u + +# ==================== ALIASES ==================== +alias r := ci + +# ==================== SETUP & INITIALIZATION ==================== + +# Install git pre-commit hook to format files +install-hook: + echo -e "#!/bin/sh\njust fmt" > .git/hooks/pre-commit + chmod +x .git/hooks/pre-commit + +# ==================== CORE DEVELOPMENT ==================== + +watch +args='test --all': + cargo watch --clear --exec '{{args}}' + +ci: + cargo test --all + cargo clippy --all + cargo fmt --all -- --check + +# publish current master branch +publish: + #!/usr/bin/env bash + set -euxo pipefail + rm -rf tmp/release + git clone git@github.com + VERSION=`sed -En 's/version[[:space:]]*=[[:space:]]*"([^"]+)"/\1/p' Cargo.toml | head -1` + cd tmp/release + git tag -a $VERSION -m "Release $VERSION" + git push origin $VERSION + cargo publish + cd ../.. + rm -rf tmp/release diff --git a/cli/template/LICENSE b/cli/template/LICENSE new file mode 100644 index 0000000..1d0d924 --- /dev/null +++ b/cli/template/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2025 murilo ijanc' <murilo@ijanc.org> + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/cli/template/README.md b/cli/template/README.md new file mode 100644 index 0000000..3dcf61b --- /dev/null +++ b/cli/template/README.md @@ -0,0 +1,11 @@ +# {{project-name}} + +## Run + +``` +RUST_LOG=debug cargo run +``` + +## License + +This project is licensed under the ISC license ([LICENSE](LICENSE) or http://opensource.org/licenses/ISC) diff --git a/cli/template/build.rs b/cli/template/build.rs new file mode 100644 index 0000000..52cbd9f --- /dev/null +++ b/cli/template/build.rs @@ -0,0 +1,21 @@ +use std::process::Command; + +fn main() { + let git_hash = Command::new("git") + .args(["rev-parse", "HEAD"]) + .output() + .map(|out| String::from_utf8_lossy(&out.stdout).trim().to_string()) + .unwrap_or_else(|_| "unknown".into()); + + let git_date = Command::new("git") + .args(["show", "-s", "--format=%cI", "HEAD"]) + .output() + .map(|out| String::from_utf8_lossy(&out.stdout).trim().to_string()) + .unwrap_or_else(|_| "unknown".into()); + + println!("cargo:rustc-env=GIT_HASH={}", git_hash); + println!("cargo:rustc-env=BUILD_DATE={}", git_date); + + println!("cargo:rerun-if-changed=.git/HEAD"); + println!("cargo:rerun-if-changed=.git/refs/heads"); +} diff --git a/cli/template/cargo-generate.toml b/cli/template/cargo-generate.toml new file mode 100644 index 0000000..ec598e7 --- /dev/null +++ b/cli/template/cargo-generate.toml @@ -0,0 +1,5 @@ +[template] +cargo_generate_version = ">=0.23.0" + +[placeholders] +project-description = { type = "string", prompt = "Short description of the project", default = "An example generated using the simple template" } diff --git a/cli/template/dprint.json b/cli/template/dprint.json new file mode 100644 index 0000000..74406fe --- /dev/null +++ b/cli/template/dprint.json @@ -0,0 +1,24 @@ +{ + "markdown": { + }, + "toml": { + }, + "excludes": [ + ], + "exec": { + "cwd": "${configDir}", + "commands": [{ + "command": "rustfmt", + "exts": ["rs"], + "cacheKeyFiles": [ + ".rustfmt.toml", + "rust-toolchain.toml" + ] + }] + }, + "plugins": [ + "https://plugins.dprint.dev/markdown-0.20.0.wasm", + "https://plugins.dprint.dev/toml-0.7.0.wasm", + "https://plugins.dprint.dev/exec-0.6.0.json@a054130d458f124f9b5c91484833828950723a5af3f8ff2bd1523bd47b83b364" + ] +} diff --git a/cli/template/rust-toolchain.toml b/cli/template/rust-toolchain.toml new file mode 100644 index 0000000..02cb8fc --- /dev/null +++ b/cli/template/rust-toolchain.toml @@ -0,0 +1,3 @@ +[toolchain] +channel = "stable" +profile = "default" diff --git a/cli/template/src/main.rs b/cli/template/src/main.rs new file mode 100644 index 0000000..575cc3d --- /dev/null +++ b/cli/template/src/main.rs @@ -0,0 +1,72 @@ +// +// Copyright (c) 2025 murilo ijanc' <murilo@ijanc.org> +// +// Permission to use, copy, modify, and distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +use anyhow::Result; +use clap::{ArgAction, Parser}; +use log::{LevelFilter, info, debug}; + +const LONG_VERSION: &str = concat!( + env!("CARGO_PKG_NAME"), + " ", + env!("CARGO_PKG_VERSION"), + " (", + env!("GIT_HASH", "unknown"), + " ", + env!("BUILD_DATE", "unknown"), + ")", +); + +#[derive(Debug, Parser)] +#[command( + name = "{{project-name}}", + about = "{{project-description}}", + version = env!("CARGO_PKG_VERSION"), + long_version = LONG_VERSION, + author, + propagate_version = true +)] +struct Args { + /// Increase verbosity (use -v, -vv, ...). + /// + /// When no RUST_LOG is set, a single -v switches the log level to DEBUG. + #[arg(short, long, global = true, action = ArgAction::Count)] + verbose: u8, +} + +fn main() -> Result<()> { + let args = Args::parse(); + + init_logger(args.verbose); + + info!("hello world cli"); + debug!("hello world cli"); + + Ok(()) +} + +fn init_logger(verbose: u8) { + use std::io::Write; + + let level = + if verbose > 0 { LevelFilter::Debug } else { LevelFilter::Info }; + + env_logger::builder() + .filter(None, level) + .format(|buf, record| { + writeln!(buf, "[{}]: {}", record.level(), record.args()) + }) + .init(); +} |