From 196c70d8404c6b52e0e514bb1df5db926536fc55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesu=CC=81s=20Pe=CC=81rez?= Date: Mon, 29 Dec 2025 04:19:26 +0000 Subject: [PATCH] chore: add CI/CD files and .typedialog for ci settings --- .cargo/audit.toml | 37 ++ .cargo/config.toml | 77 +++ .github/workflows/nickel-typecheck.yml | 116 ++++ .github/workflows/rust-ci.yml | 47 ++ .pre-commit-config.yaml | 124 ++++ .taplo.toml | 49 ++ .typedialog/ci/README.md | 319 ++++++++++ .typedialog/ci/config.ncl | 138 ++++ .typedialog/ci/configure.sh | 116 ++++ .typedialog/ci/envrc | 27 + .typedialog/ci/form.toml | 217 +++++++ .vale.ini | 41 ++ .vale/Vocab/TypeDialog/accept.txt | 25 + .vale/Vocab/TypeDialog/reject.txt | 2 + .vale/styles/Google/AMPM.yml | 9 + .vale/styles/Google/Acronyms.yml | 64 ++ .vale/styles/Google/Colons.yml | 8 + .vale/styles/Google/Contractions.yml | 30 + .vale/styles/Google/DateFormat.yml | 9 + .vale/styles/Google/Ellipses.yml | 9 + .vale/styles/Google/EmDash.yml | 12 + .vale/styles/Google/Exclamation.yml | 12 + .vale/styles/Google/FirstPerson.yml | 13 + .vale/styles/Google/Gender.yml | 9 + .vale/styles/Google/GenderBias.yml | 43 ++ .vale/styles/Google/HeadingPunctuation.yml | 13 + .vale/styles/Google/Headings.yml | 29 + .vale/styles/Google/Latin.yml | 11 + .vale/styles/Google/LyHyphens.yml | 14 + .vale/styles/Google/OptionalPlurals.yml | 12 + .vale/styles/Google/Ordinal.yml | 7 + .vale/styles/Google/OxfordComma.yml | 7 + .vale/styles/Google/Parens.yml | 7 + .vale/styles/Google/Passive.yml | 184 ++++++ .vale/styles/Google/Periods.yml | 7 + .vale/styles/Google/Quotes.yml | 7 + .vale/styles/Google/Ranges.yml | 7 + .vale/styles/Google/Semicolons.yml | 8 + .vale/styles/Google/Slang.yml | 11 + .vale/styles/Google/Spacing.yml | 10 + .vale/styles/Google/Spelling.yml | 10 + .vale/styles/Google/Units.yml | 8 + .vale/styles/Google/We.yml | 11 + .vale/styles/Google/Will.yml | 7 + .vale/styles/Google/WordList.yml | 80 +++ .vale/styles/Google/meta.json | 4 + .vale/styles/Google/vocab.txt | 0 .vale/styles/write-good/Cliches.yml | 702 +++++++++++++++++++++ .vale/styles/write-good/E-Prime.yml | 32 + .vale/styles/write-good/Illusions.yml | 11 + .vale/styles/write-good/Passive.yml | 183 ++++++ .vale/styles/write-good/README.md | 27 + .vale/styles/write-good/So.yml | 5 + .vale/styles/write-good/ThereIs.yml | 6 + .vale/styles/write-good/TooWordy.yml | 221 +++++++ .vale/styles/write-good/Weasel.yml | 29 + .vale/styles/write-good/meta.json | 4 + .woodpecker/Dockerfile | 45 ++ .woodpecker/Dockerfile.cross | 42 ++ .woodpecker/README.md | 78 +++ .woodpecker/ci-advanced.yml | 168 +++++ .woodpecker/ci.yml | 84 +++ .yamllint-ci.yml | 18 + CODE_OF_CONDUCT.md | 103 +++ CONTRIBUTING.md | 129 ++++ Cargo.toml | 2 +- SECURITY.md | 98 +++ clippy.toml | 46 ++ deny.toml | 74 +++ justfile | 3 +- justfiles/ci.just | 227 +++++++ rustfmt.toml | 57 ++ 72 files changed, 4399 insertions(+), 2 deletions(-) create mode 100644 .cargo/audit.toml create mode 100644 .cargo/config.toml create mode 100644 .github/workflows/nickel-typecheck.yml create mode 100644 .github/workflows/rust-ci.yml create mode 100644 .pre-commit-config.yaml create mode 100644 .taplo.toml create mode 100644 .typedialog/ci/README.md create mode 100644 .typedialog/ci/config.ncl create mode 100755 .typedialog/ci/configure.sh create mode 100644 .typedialog/ci/envrc create mode 100644 .typedialog/ci/form.toml create mode 100644 .vale.ini create mode 100644 .vale/Vocab/TypeDialog/accept.txt create mode 100644 .vale/Vocab/TypeDialog/reject.txt create mode 100644 .vale/styles/Google/AMPM.yml create mode 100644 .vale/styles/Google/Acronyms.yml create mode 100644 .vale/styles/Google/Colons.yml create mode 100644 .vale/styles/Google/Contractions.yml create mode 100644 .vale/styles/Google/DateFormat.yml create mode 100644 .vale/styles/Google/Ellipses.yml create mode 100644 .vale/styles/Google/EmDash.yml create mode 100644 .vale/styles/Google/Exclamation.yml create mode 100644 .vale/styles/Google/FirstPerson.yml create mode 100644 .vale/styles/Google/Gender.yml create mode 100644 .vale/styles/Google/GenderBias.yml create mode 100644 .vale/styles/Google/HeadingPunctuation.yml create mode 100644 .vale/styles/Google/Headings.yml create mode 100644 .vale/styles/Google/Latin.yml create mode 100644 .vale/styles/Google/LyHyphens.yml create mode 100644 .vale/styles/Google/OptionalPlurals.yml create mode 100644 .vale/styles/Google/Ordinal.yml create mode 100644 .vale/styles/Google/OxfordComma.yml create mode 100644 .vale/styles/Google/Parens.yml create mode 100644 .vale/styles/Google/Passive.yml create mode 100644 .vale/styles/Google/Periods.yml create mode 100644 .vale/styles/Google/Quotes.yml create mode 100644 .vale/styles/Google/Ranges.yml create mode 100644 .vale/styles/Google/Semicolons.yml create mode 100644 .vale/styles/Google/Slang.yml create mode 100644 .vale/styles/Google/Spacing.yml create mode 100644 .vale/styles/Google/Spelling.yml create mode 100644 .vale/styles/Google/Units.yml create mode 100644 .vale/styles/Google/We.yml create mode 100644 .vale/styles/Google/Will.yml create mode 100644 .vale/styles/Google/WordList.yml create mode 100644 .vale/styles/Google/meta.json create mode 100644 .vale/styles/Google/vocab.txt create mode 100644 .vale/styles/write-good/Cliches.yml create mode 100644 .vale/styles/write-good/E-Prime.yml create mode 100644 .vale/styles/write-good/Illusions.yml create mode 100644 .vale/styles/write-good/Passive.yml create mode 100644 .vale/styles/write-good/README.md create mode 100644 .vale/styles/write-good/So.yml create mode 100644 .vale/styles/write-good/ThereIs.yml create mode 100644 .vale/styles/write-good/TooWordy.yml create mode 100644 .vale/styles/write-good/Weasel.yml create mode 100644 .vale/styles/write-good/meta.json create mode 100644 .woodpecker/Dockerfile create mode 100644 .woodpecker/Dockerfile.cross create mode 100644 .woodpecker/README.md create mode 100644 .woodpecker/ci-advanced.yml create mode 100644 .woodpecker/ci.yml create mode 100644 .yamllint-ci.yml create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md create mode 100644 SECURITY.md create mode 100644 clippy.toml create mode 100644 deny.toml create mode 100644 justfiles/ci.just create mode 100644 rustfmt.toml diff --git a/.cargo/audit.toml b/.cargo/audit.toml new file mode 100644 index 0000000..b965267 --- /dev/null +++ b/.cargo/audit.toml @@ -0,0 +1,37 @@ +# Generated by dev-system/ci +# cargo-audit configuration for security vulnerability scanning + +# Database configuration +[advisories] +# The database path +db-path = "~/.cargo/advisory-db" + +# Advisory database URLs +db-urls = ["https://github.com/rustsec/advisory-db"] + +# How to handle different kinds of advisories +# "allow" - Pass the check despite the warning +# "warn" - Pass the check but warn about the issue +# "deny" - Fail the check +deny = ["unmaintained", "unsound", "yanked"] + +# Specific vulnerability IDs to ignore (in case of false positives) +# You can use: https://rustsec.org/ +ignore = [ + # Example: { id = "RUSTSEC-2023-XXXX", reason = "Not applicable to our use case" } +] + +# How to handle vulnerabilities based on severity +[output] +# Deny on high severity vulnerabilities +deny = ["high", "critical"] +# Warn on medium severity vulnerabilities +warn = ["medium", "low"] +# Advisory format: "terminal", "json" +format = "terminal" + +# Target configuration +[target] +# Check only specific targets +# Uncomment to restrict to specific target triples +# triple = "x86_64-unknown-linux-gnu" diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..09b8772 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,77 @@ +# Generated by dev-system/ci +# Cargo configuration for build and compilation settings + +[build] +# Number of parallel jobs for compilation +jobs = 4 + +# Code generation backend +# codegen-backend = "llvm" + +[profile.dev] +# Development profile - fast compilation, debug info +opt-level = 0 +debug = true +debug-assertions = true +overflow-checks = true +lto = false +panic = "unwind" +incremental = true + +[profile.release] +# Release profile - slow compilation, optimized binary +opt-level = 3 +debug = false +debug-assertions = false +overflow-checks = false +lto = "thin" +codegen-units = 1 +panic = "abort" +incremental = false +strip = false + +[profile.test] +# Test profile - inherits from dev but can be optimized +opt-level = 1 +debug = true +debug-assertions = true +overflow-checks = true +lto = false +panic = "unwind" +incremental = true + +[profile.bench] +# Benchmark profile - same as release +opt-level = 3 +debug = false +debug-assertions = false +overflow-checks = false +lto = "thin" +codegen-units = 1 +panic = "abort" +incremental = false + +# Resolver version +resolver = "2" + +[term] +# Terminal colors +color = "auto" +verbose = false +progress.when = "auto" +progress.width = 80 + +[net] +# Network settings +git-fetch-with-cli = true +offline = false + +# Strict version requirements for dependencies +# force-non-semver-pre = true + +[alias] +# Custom cargo commands +build-all = "build --all-targets" +check-all = "check --all-targets --all-features" +test-all = "test --all-features --workspace" +doc-all = "doc --all-features --no-deps --open" diff --git a/.github/workflows/nickel-typecheck.yml b/.github/workflows/nickel-typecheck.yml new file mode 100644 index 0000000..325a550 --- /dev/null +++ b/.github/workflows/nickel-typecheck.yml @@ -0,0 +1,116 @@ +# GitHub Actions Nickel Type Checking Workflow +# Generated by dev-system/ci +# Validates all Nickel schemas with nickel typecheck + +name: Nickel Type Check + +on: + push: + branches: [main, develop] + paths: ['**.ncl'] + pull_request: + branches: [main] + paths: ['**.ncl'] + +jobs: + typecheck: + name: Nickel Type Checking + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Nickel + run: | + #!/usr/bin/env bash + set -e + + echo "πŸ“¦ Installing Nickel..." + + if command -v nickel &> /dev/null; then + echo "βœ“ Nickel already installed" + nickel --version + else + echo "Installing via homebrew..." + brew install nickel || { + echo "Homebrew installation failed, trying from source..." + curl --proto '=https' --tlsv1.2 -sSf https://install.nickel-lang.org | bash || exit 1 + } + fi + + nickel --version + + - name: Setup environment + run: | + #!/usr/bin/env bash + # Set NICKEL_IMPORT_PATH for schema imports + export NICKEL_IMPORT_PATH="/Users/Akasha/Tools/dev-system/ci/schemas:/Users/Akasha/Tools/dev-system/ci/validators:/Users/Akasha/Tools/dev-system/ci/defaults" + echo "NICKEL_IMPORT_PATH=$NICKEL_IMPORT_PATH" >> $GITHUB_ENV + + - name: Type check schemas + run: | + #!/usr/bin/env bash + set -e + + echo "πŸ” Type checking Nickel schemas..." + + # Find all .ncl files + SCHEMAS=$(find . -name "*.ncl" -type f \ + ! -path "./target/*" \ + ! -path "./.git/*" \ + ! -path "./node_modules/*" \ + | sort) + + if [ -z "$SCHEMAS" ]; then + echo "⚠️ No Nickel schemas found" + exit 0 + fi + + FAILED=0 + PASSED=0 + + # Set import path + export NICKEL_IMPORT_PATH="/Users/Akasha/Tools/dev-system/ci/schemas:/Users/Akasha/Tools/dev-system/ci/validators:/Users/Akasha/Tools/dev-system/ci/defaults:." + + for schema in $SCHEMAS; do + echo "Checking: $schema" + if nickel typecheck "$schema" > /dev/null 2>&1; then + echo " βœ“ Valid" + ((PASSED++)) + else + echo " ❌ Type error" + nickel typecheck "$schema" || true + ((FAILED++)) + fi + done + + echo "" + echo "Summary: $PASSED passed, $FAILED failed" + + if [ $FAILED -gt 0 ]; then + exit 1 + fi + + - name: Export and validate + run: | + #!/usr/bin/env bash + set -e + + echo "πŸ“Š Exporting Nickel configurations..." + + export NICKEL_IMPORT_PATH="/Users/Akasha/Tools/dev-system/ci/schemas:/Users/Akasha/Tools/dev-system/ci/validators:/Users/Akasha/Tools/dev-system/ci/defaults:." + + # Export main configs if they exist + if [ -f ".typedialog/ci/schemas/ci-local.ncl" ]; then + echo "Exporting CI config..." + nickel export .typedialog/ci/schemas/ci-local.ncl > /tmp/ci-export.json + if [ $? -eq 0 ]; then + echo " βœ“ Successfully exported" + else + echo " ❌ Export failed" + exit 1 + fi + fi + + echo "βœ“ All exports successful" diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml new file mode 100644 index 0000000..73c2af1 --- /dev/null +++ b/.github/workflows/rust-ci.yml @@ -0,0 +1,47 @@ +jobs: + audit: + name: Security Audit + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + - name: Audit + run: cargo audit --deny warnings + - name: Deny Check + run: cargo deny check licenses advisories + check: + name: Check + Test + Lint + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install Rust + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.rust-version }} + - name: Cache + uses: Swatinem/rust-cache@v2 + - name: Check + run: cargo check --all-targets + - name: Format Check + run: cargo fmt --all -- --check + - name: Clippy + run: cargo clippy --all-targets -- -D warnings + - name: Tests + run: cargo test --workspace + strategy: + matrix: + rust-version: + - stable + - nightly +name: Rust CI +on: + pull_request: + branches: + - main + push: + branches: + - main + - develop diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..6ae7559 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,124 @@ +# Pre-commit Framework Configuration +# Generated by dev-system/ci +# Configures git pre-commit hooks for Rust projects + +repos: + # ============================================================================ + # Rust Hooks + # ============================================================================ + - repo: local + hooks: + - id: rust-fmt + name: Rust formatting (cargo fmt) + entry: bash -c 'cargo fmt --all -- --check' + language: system + types: [rust] + pass_filenames: false + stages: [commit] + + - id: rust-clippy + name: Rust linting (cargo clippy) + entry: bash -c 'cargo clippy --all-targets -- -D warnings' + language: system + types: [rust] + pass_filenames: false + stages: [commit] + + - id: rust-test + name: Rust tests + entry: bash -c 'cargo test --workspace' + language: system + types: [rust] + pass_filenames: false + stages: [push] + + - id: cargo-deny + name: Cargo deny (licenses & advisories) + entry: bash -c 'cargo deny check licenses advisories' + language: system + pass_filenames: false + stages: [push] + + # ============================================================================ + # Nushell Hooks (optional - enable if using Nushell) + # ============================================================================ + # - repo: local + # hooks: + # - id: nushell-check + # name: Nushell validation (nu --ide-check) + # entry: bash -c 'for f in $(git diff --cached --name-only --diff-filter=ACM | grep "\.nu$"); do echo "Checking: $f"; nu --ide-check 100 "$f" || exit 1; done' + # language: system + # types: [file] + # files: \.nu$ + # pass_filenames: false + # stages: [commit] + + # ============================================================================ + # Nickel Hooks (optional - enable if using Nickel) + # ============================================================================ + # - repo: local + # hooks: + # - id: nickel-typecheck + # name: Nickel type checking + # entry: bash -c 'export NICKEL_IMPORT_PATH="/Users/Akasha/Tools/dev-system/ci/schemas:/Users/Akasha/Tools/dev-system/ci/validators:/Users/Akasha/Tools/dev-system/ci/defaults:."; for f in $(git diff --cached --name-only --diff-filter=ACM | grep "\.ncl$"); do echo "Checking: $f"; nickel typecheck "$f" || exit 1; done' + # language: system + # types: [file] + # files: \.ncl$ + # pass_filenames: false + # stages: [commit] + + # ============================================================================ + # Bash Hooks (optional - enable if using Bash) + # ============================================================================ + # - repo: local + # hooks: + # - id: shellcheck + # name: Shellcheck (bash linting) + # entry: shellcheck + # language: system + # types: [shell] + # stages: [commit] + # + # - id: shfmt + # name: Shell script formatting + # entry: bash -c 'shfmt -i 2 -d' + # language: system + # types: [shell] + # stages: [commit] + + # ============================================================================ + # Markdown Hooks (optional - enable if using Markdown) + # ============================================================================ + # - repo: local + # hooks: + # - id: markdownlint + # name: Markdown linting (markdownlint-cli2) + # entry: markdownlint-cli2 + # language: system + # types: [markdown] + # stages: [commit] + + # ============================================================================ + # General Pre-commit Hooks + # ============================================================================ + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: check-added-large-files + args: ['--maxkb=1000'] + + - id: check-case-conflict + + - id: check-merge-conflict + + - id: check-toml + + - id: check-yaml + exclude: ^\.woodpecker/ + + - id: end-of-file-fixer + + - id: trailing-whitespace + exclude: \.md$ + + - id: mixed-line-ending diff --git a/.taplo.toml b/.taplo.toml new file mode 100644 index 0000000..5d20bf8 --- /dev/null +++ b/.taplo.toml @@ -0,0 +1,49 @@ +# Taplo configuration for TOML formatting and linting +# https://taplo.tamasfe.dev/configuration/ + +[formatting] +# Indent tables with 2 spaces +indent_string = " " +indent_tables = true + +# Reorder keys alphabetically within tables +reorder_keys = true + +# Reorder arrays to be more readable +reorder_arrays = false + +# Align entries vertically in inline tables +align_entries = false + +# Allow compact inline tables +allowed_blank_lines = 1 + +# Trailing newline +trailing_newline = true + +# Column width for wrapping +column_width = 100 + +# Compact arrays +compact_arrays = true + +# Compact inline tables +compact_inline_tables = false + +# === INCLUDE/EXCLUDE PATTERNS === + +include = ["Cargo.toml", "*/Cargo.toml", "config/**/*.toml", "**/*.toml"] + +exclude = ["target/**", "node_modules/**", ".git/**"] + +# === SCHEMA VALIDATION === + +# Cargo.toml schema validation +[[rule]] +include = ["**/Cargo.toml"] +# Taplo includes built-in Cargo.toml schema + +# TypeDialog form definition TOML files +[[rule]] +include = ["**/.typedialog/**/*.toml", "config/**/forms/*.toml", "tests/fixtures/**/*.toml"] +keys = ["name", "description", "fields", "items", "elements"] diff --git a/.typedialog/ci/README.md b/.typedialog/ci/README.md new file mode 100644 index 0000000..c51e5ad --- /dev/null +++ b/.typedialog/ci/README.md @@ -0,0 +1,319 @@ +# CI System - Configuration Guide + +**Installed**: 2025-12-28 +**Detected Languages**: rust, nickel, bash, markdown + +--- + +## Quick Start + +### Option 1: Using configure.sh (Recommended) + +A convenience script is installed in `.typedialog/ci/`: + +```bash +# Use web backend (default) - Opens in browser +.typedialog/ci/configure.sh + +# Use TUI backend - Terminal interface +.typedialog/ci/configure.sh tui + +# Use CLI backend - Command-line prompts +.typedialog/ci/configure.sh cli +``` + +**This script automatically:** +- Sources `.typedialog/ci/envrc` for environment setup +- Loads defaults from `config.ncl` (Nickel format) +- Uses cascading search for fragments (local β†’ Tools) +- Creates backup before overwriting existing config +- Saves output in Nickel format using nickel-roundtrip with documented template +- Generates `config.ncl` compatible with `nickel doc` command + +### Option 2: Direct TypeDialog Commands + +Use TypeDialog nickel-roundtrip directly with manual paths: + +#### Web Backend (Recommended - Easy Viewing) + +```bash +cd .typedialog/ci # Change to CI directory +source envrc # Load environment +typedialog-web nickel-roundtrip config.ncl form.toml \ + --output config.ncl \ + --ncl-template $TOOLS_PATH/dev-system/ci/templates/config.ncl.j2 +``` + +#### TUI Backend + +```bash +cd .typedialog/ci +source envrc +typedialog-tui nickel-roundtrip config.ncl form.toml \ + --output config.ncl \ + --ncl-template $TOOLS_PATH/dev-system/ci/templates/config.ncl.j2 +``` + +#### CLI Backend + +```bash +cd .typedialog/ci +source envrc +typedialog nickel-roundtrip config.ncl form.toml \ + --output config.ncl \ + --ncl-template $TOOLS_PATH/dev-system/ci/templates/config.ncl.j2 +``` + +**Note:** The `--ncl-template` flag uses a Tera template that adds: +- Descriptive comments for each section +- Documentation compatible with `nickel doc config.ncl` +- Consistent formatting and structure + +**All backends will:** +- Show only options relevant to your detected languages +- Guide you through all configuration choices +- Validate your inputs +- Generate config.ncl in Nickel format + +### Option 3: Manual Configuration + +Edit `config.ncl` directly: + +```bash +vim .typedialog/ci/config.ncl +``` + +--- + +## Configuration Format: Nickel + +**This project uses Nickel format by default** for all configuration files. + +### Why Nickel? + +- βœ… **Typed configuration** - Static type checking with `nickel typecheck` +- βœ… **Documentation** - Generate docs with `nickel doc config.ncl` +- βœ… **Validation** - Built-in schema validation +- βœ… **Comments** - Rich inline documentation support +- βœ… **Modular** - Import/export system for reusable configs + +### Nickel Template + +The output structure is controlled by a **Tera template** at: +- **Tools default**: `$TOOLS_PATH/dev-system/ci/templates/config.ncl.j2` +- **Local override**: `.typedialog/ci/config.ncl.j2` (optional) + +**To customize the template:** + +```bash +# Copy the default template +cp $TOOLS_PATH/dev-system/ci/templates/config.ncl.j2 \ + .typedialog/ci/config.ncl.j2 + +# Edit to add custom comments, documentation, or structure +vim .typedialog/ci/config.ncl.j2 + +# Your template will now be used automatically +``` + +**Template features:** +- Customizable comments per section +- Control field ordering +- Add project-specific documentation +- Configure output for `nickel doc` command + +### TypeDialog Environment Variables + +You can customize TypeDialog behavior with environment variables: + +```bash +# Web server configuration +export TYPEDIALOG_PORT=9000 # Port for web backend (default: 9000) +export TYPEDIALOG_HOST=localhost # Host binding (default: localhost) + +# Localization +export TYPEDIALOG_LANG=en_US.UTF-8 # Form language (default: system locale) + +# Run with custom settings +TYPEDIALOG_PORT=8080 .typedialog/ci/configure.sh web +``` + +**Common use cases:** + +```bash +# Access from other machines in network +TYPEDIALOG_HOST=0.0.0.0 TYPEDIALOG_PORT=8080 .typedialog/ci/configure.sh web + +# Use different port if 9000 is busy +TYPEDIALOG_PORT=3000 .typedialog/ci/configure.sh web + +# Spanish interface +TYPEDIALOG_LANG=es_ES.UTF-8 .typedialog/ci/configure.sh web +``` + +## Configuration Structure + +Your config.ncl is organized in the `ci` namespace (Nickel format): + +```nickel +{ + ci = { + project = { + name = "rust", + detected_languages = ["rust, nickel, bash, markdown"], + primary_language = "rust", + }, + tools = { + # Tools are added based on detected languages + }, + features = { + # CI features (pre-commit, GitHub Actions, etc.) + }, + ci_providers = { + # CI provider configurations + }, + }, +} +``` + +## Available Fragments + +Tool configurations are modular. Check `.typedialog/ci/fragments/` for: + +- rust-tools.toml - Tools for rust +- nickel-tools.toml - Tools for nickel +- bash-tools.toml - Tools for bash +- markdown-tools.toml - Tools for markdown +- general-tools.toml - Cross-language tools +- ci-providers.toml - GitHub Actions, Woodpecker, etc. + +## Cascading Override System + +This project uses a **local β†’ Tools cascading search** for all resources: + +### How It Works + +Resources are searched in priority order: + +1. **Local files** (`.typedialog/ci/`) - **FIRST** (highest priority) +2. **Tools files** (`$TOOLS_PATH/dev-system/ci/`) - **FALLBACK** (default) + +### Affected Resources + +| Resource | Local Path | Tools Path | +|----------|------------|------------| +| Fragments | `.typedialog/ci/fragments/` | `$TOOLS_PATH/dev-system/ci/forms/fragments/` | +| Schemas | `.typedialog/ci/schemas/` | `$TOOLS_PATH/dev-system/ci/schemas/` | +| Validators | `.typedialog/ci/validators/` | `$TOOLS_PATH/dev-system/ci/validators/` | +| Defaults | `.typedialog/ci/defaults/` | `$TOOLS_PATH/dev-system/ci/defaults/` | +| Nickel Template | `.typedialog/ci/config.ncl.j2` | `$TOOLS_PATH/dev-system/ci/templates/config.ncl.j2` | + +### Environment Setup (.envrc) + +The `.typedialog/ci/.envrc` file configures search paths: + +```bash +# Source this file to load environment +source .typedialog/ci/.envrc + +# Or use direnv for automatic loading +echo 'source .typedialog/ci/.envrc' >> .envrc +``` + +**What's in .envrc:** + +```bash +export NICKEL_IMPORT_PATH="schemas:$TOOLS_PATH/dev-system/ci/schemas:validators:..." +export TYPEDIALOG_FRAGMENT_PATH=".:$TOOLS_PATH/dev-system/ci/forms" +export NCL_TEMPLATE="" +export TYPEDIALOG_PORT=9000 # Web server port +export TYPEDIALOG_HOST=localhost # Web server host +export TYPEDIALOG_LANG="${LANG}" # Form localization +``` + +### Creating Overrides + +**By default:** All resources come from Tools (no duplication). + +**To customize:** Create file in local directory with same name: + +```bash +# Override a fragment +cp $TOOLS_PATH/dev-system/ci/fragments/rust-tools.toml \ + .typedialog/ci/fragments/rust-tools.toml + +# Edit your local version +vim .typedialog/ci/fragments/rust-tools.toml + +# Override Nickel template (customize comments, structure, nickel doc output) +cp $TOOLS_PATH/dev-system/ci/templates/config.ncl.j2 \ + .typedialog/ci/config.ncl.j2 + +# Edit to customize documentation and structure +vim .typedialog/ci/config.ncl.j2 + +# Now your version will be used instead of Tools version +``` + +**Benefits:** + +- βœ… Override only what you need +- βœ… Everything else stays synchronized with Tools +- βœ… No duplication by default +- βœ… Automatic updates when Tools is updated + +**See:** `$TOOLS_PATH/dev-system/ci/docs/cascade-override.md` for complete documentation. + +## Testing Your Configuration + +### Validate Configuration + +```bash +nu $env.TOOLS_PATH/dev-system/ci/scripts/validator.nu \ + --config .typedialog/ci/config.ncl \ + --project . \ + --namespace ci +``` + +### Regenerate CI Files + +```bash +nu $env.TOOLS_PATH/dev-system/ci/scripts/generate-configs.nu \ + --config .typedialog/ci/config.ncl \ + --templates $env.TOOLS_PATH/dev-system/ci/templates \ + --output . \ + --namespace ci +``` + +## Common Tasks + +### Add a New Tool + +Edit `config.ncl` and add under `ci.tools`: + +```nickel +{ + ci = { + tools = { + newtool = { + enabled = true, + install_method = "cargo", + version = "latest", + }, + }, + }, +} +``` + +### Disable a Feature + +```toml +[ci.features] +enable_pre_commit = false +``` + +## Need Help? + +For detailed documentation, see: +- $env.TOOLS_PATH/dev-system/ci/docs/configuration-guide.md +- $env.TOOLS_PATH/dev-system/ci/docs/installation-guide.md diff --git a/.typedialog/ci/config.ncl b/.typedialog/ci/config.ncl new file mode 100644 index 0000000..8752436 --- /dev/null +++ b/.typedialog/ci/config.ncl @@ -0,0 +1,138 @@ +# CI Configuration - Nickel Format +# Auto-generated by dev-system CI installer +# +# This file is managed by TypeDialog using nickel-roundtrip. +# Edit via: .typedialog/ci/configure.sh +# Or manually edit and validate with: nickel typecheck config.ncl +# +# Documentation: nickel doc config.ncl + +{ + # CI namespace - all configuration lives under 'ci' + ci = { + # Project Information + # Detected languages and primary language for this project + project = { + # Project name + name = "SecretumVault", + # Project description + description = "Secretum Vault", + # Project website or documentation site URL + site_url = "https://secretumvault.dev", + # Project repository URL (GitHub, GitLab, etc.) + repo_url = "https://repo.jesusperez.pro/jesus/secretumvault.git", + # Languages detected in codebase (auto-detected by installer) + detected_languages = [ + "rust", + "nickel", + "bash", + "markdown" + ], + # Primary language (determines default tooling) + primary_language = "rust", + }, + + # CI Tools Configuration + # Each tool can be enabled/disabled and configured here + tools = { + # Taplo - TOML formatter and linter + taplo = { + enabled = true, + install_method = "cargo", + }, + # YAMLlint - YAML formatter and linter + yamllint = { + enabled = true, + install_method = "brew", + }, + # Clippy - Rust linting tool + clippy = { + enabled = true, + install_method = "builtin", + deny_warnings = true, + }, + # Cargo Audit - Security vulnerability scanner + audit = { + enabled = true, + install_method = "cargo", + }, + # Cargo Deny - Dependency checker + deny = { + enabled = true, + install_method = "cargo", + }, + # Cargo SBOM - Software Bill of Materials + sbom = { + enabled = true, + install_method = "cargo", + }, + # LLVM Coverage - Code coverage tool + llvm_cov = { + enabled = true, + install_method = "cargo", + }, + # Shellcheck - Bash/shell script linter + shellcheck = { + enabled = true, + install_method = "brew", + }, + # Shfmt - Shell script formatter + shfmt = { + enabled = true, + install_method = "brew", + }, + # Markdownlint - Markdown linter + markdownlint = { + enabled = true, + install_method = "npm", + }, + # Vale - Prose linter + vale = { + enabled = true, + install_method = "brew", + }, + # Nickel - Configuration language type checker + nickel = { + enabled = true, + install_method = "brew", + check_all = true, + }, + }, + + # CI Features + # High-level feature flags for CI behavior + features = { + enable_ci_cd = true, + enable_pre_commit = true, + generate_taplo_config = true, + generate_contributing = true, + generate_security = true, + generate_code_of_conduct = true, + generate_dockerfiles = true, + enable_cross_compilation = true, + }, + + # CI Provider Configurations + # Settings for GitHub Actions, Woodpecker, GitLab CI, etc. + ci_providers = { + # GitHub Actions + github_actions = { + enabled = true, + branches_push = "main,develop", + branches_pr = "main", + }, + # Woodpecker CI + woodpecker = { + enabled = true, + }, + }, + + # CI Settings + settings = { + parallel_jobs = 1, + job_timeout_minutes = 1, + require_status_checks = true, + run_on_draft_prs = true, + }, + }, +} diff --git a/.typedialog/ci/configure.sh b/.typedialog/ci/configure.sh new file mode 100755 index 0000000..28cf7c8 --- /dev/null +++ b/.typedialog/ci/configure.sh @@ -0,0 +1,116 @@ +#!/usr/bin/env bash +# CI Configuration Script +# Auto-generated by dev-system/ci installer +# +# Interactive configuration for CI tools using TypeDialog. +# Uses Nickel format for configuration files. + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +TYPEDIALOG_CI="${SCRIPT_DIR}" + +# Source envrc to load fragment paths and other environment variables +if [[ -f "${TYPEDIALOG_CI}/envrc" ]]; then + # shellcheck source=/dev/null + source "${TYPEDIALOG_CI}/envrc" +fi + +# Configuration files +FORM_FILE="${TYPEDIALOG_CI}/form.toml" +CONFIG_FILE="${TYPEDIALOG_CI}/config.ncl" + +# NCL_TEMPLATE is set by envrc (cascading: local β†’ Tools) +# If not set, use default from Tools +NCL_TEMPLATE="${NCL_TEMPLATE:-${TOOLS_PATH}/dev-system/ci/templates/config.ncl.j2}" + +# TypeDialog environment variables (can be overridden) +# Port for web backend (default: 9000) +export TYPEDIALOG_PORT="${TYPEDIALOG_PORT:-9000}" + +# Host for web backend (default: localhost) +export TYPEDIALOG_HOST="${TYPEDIALOG_HOST:-localhost}" + +# Locale for form localization (default: system locale) +export TYPEDIALOG_LANG="${TYPEDIALOG_LANG:-${LANG:-en_US.UTF-8}}" + +# Detect which TypeDialog backend to use (default: web) +BACKEND="${1:-web}" + +# Validate backend +case "$BACKEND" in + cli|tui|web) + ;; + *) + echo "Usage: $0 [cli|tui|web]" + echo "" + echo "Launches TypeDialog for interactive CI configuration." + echo "Backend options:" + echo " cli - Command-line interface (simple prompts)" + echo " tui - Terminal UI (interactive panels)" + echo " web - Web server (browser-based) [default]" + exit 1 + ;; +esac + +# Check if form exists +if [[ ! -f "$FORM_FILE" ]]; then + echo "Error: Form file not found: $FORM_FILE" + exit 1 +fi + +# Create backup if config exists +if [[ -f "$CONFIG_FILE" ]]; then + BACKUP="${CONFIG_FILE}.$(date +%Y%m%d_%H%M%S).bak" + cp "$CONFIG_FILE" "$BACKUP" + echo "ℹ️ Backed up existing config to: $(basename "$BACKUP")" +fi + +# Launch TypeDialog with Nickel roundtrip (preserves Nickel format) +echo "πŸ”§ Launching TypeDialog ($BACKEND backend)..." +echo "" + +# Show web server info if using web backend +if [[ "$BACKEND" == "web" ]]; then + echo "🌐 Web server will start on: http://${TYPEDIALOG_HOST}:${TYPEDIALOG_PORT}" + echo " (Override with: TYPEDIALOG_PORT=8080 TYPEDIALOG_HOST=0.0.0.0 $0)" + echo "" +fi + +# Build nickel-roundtrip command with optional template +NCL_TEMPLATE_ARG="" +if [[ -f "$NCL_TEMPLATE" ]]; then + NCL_TEMPLATE_ARG="--ncl-template $NCL_TEMPLATE" + echo "ℹ️ Using Nickel template: $NCL_TEMPLATE" +fi + +case "$BACKEND" in + cli) + typedialog nickel-roundtrip "$CONFIG_FILE" "$FORM_FILE" --output "$CONFIG_FILE" $NCL_TEMPLATE_ARG + ;; + tui) + typedialog-tui nickel-roundtrip "$CONFIG_FILE" "$FORM_FILE" --output "$CONFIG_FILE" $NCL_TEMPLATE_ARG + ;; + web) + typedialog-web nickel-roundtrip "$CONFIG_FILE" "$FORM_FILE" --output "$CONFIG_FILE" $NCL_TEMPLATE_ARG + ;; +esac + +EXIT_CODE=$? + +if [[ $EXIT_CODE -eq 0 ]]; then + echo "" + echo "βœ… Configuration saved to: $CONFIG_FILE" + echo "" + echo "Next steps:" + echo " - Review the configuration: cat $CONFIG_FILE" + echo " - Apply CI tools: (run your CI setup command)" + echo " - Re-run this script anytime to update: $0" +else + echo "" + echo "❌ Configuration cancelled or failed (exit code: $EXIT_CODE)" + if [[ -f "${CONFIG_FILE}.bak" ]]; then + echo " Previous config restored from backup" + fi + exit $EXIT_CODE +fi diff --git a/.typedialog/ci/envrc b/.typedialog/ci/envrc new file mode 100644 index 0000000..4c00a1b --- /dev/null +++ b/.typedialog/ci/envrc @@ -0,0 +1,27 @@ +# Auto-generated by dev-system/ci +# +# Cascading Path Strategy: +# 1. Local files in .typedialog/ci/ take precedence (overrides) +# 2. Central files in $TOOLS_PATH/dev-system/ci/ as fallback (defaults) +# +# To customize: Create file in .typedialog/ci/{schemas,validators,defaults,fragments}/ +# Your local version will be used instead of the Tools version. + +# Nickel import paths (cascading: local β†’ Tools) +export NICKEL_IMPORT_PATH="schemas:$TOOLS_PATH/dev-system/ci/schemas:validators:$TOOLS_PATH/dev-system/ci/validators:defaults:$TOOLS_PATH/dev-system/ci/defaults" + +# TypeDialog fragment search paths (cascading: local β†’ Tools) +export TYPEDIALOG_FRAGMENT_PATH=".typedialog/ci:$TOOLS_PATH/dev-system/ci/forms" + +# Nickel template for config.ncl generation (with cascading) +# Local template takes precedence if exists +if [[ -f ".typedialog/ci/config.ncl.j2" ]]; then + export NCL_TEMPLATE=".typedialog/ci/config.ncl.j2" +else + export NCL_TEMPLATE="$TOOLS_PATH/dev-system/ci/templates/config.ncl.j2" +fi + +# TypeDialog web backend configuration (override if needed) +export TYPEDIALOG_PORT=${TYPEDIALOG_PORT:-9000} +export TYPEDIALOG_HOST=${TYPEDIALOG_HOST:-localhost} +export TYPEDIALOG_LANG=${TYPEDIALOG_LANG:-${LANG:-en_US.UTF-8}} diff --git a/.typedialog/ci/form.toml b/.typedialog/ci/form.toml new file mode 100644 index 0000000..48fa061 --- /dev/null +++ b/.typedialog/ci/form.toml @@ -0,0 +1,217 @@ +description = "Interactive configuration for continuous integration and code quality tools" +display_mode = "complete" +locales_path = "" +name = "CI Configuration Form" + +[[elements]] +border_bottom = true +border_top = true +name = "project_header" +title = "πŸ“¦ Project Information" +type = "section_header" + +[[elements]] +help = "Name of the project" +name = "project_name" +nickel_path = [ + "ci", + "project", + "name", +] +placeholder = "my-project" +prompt = "Project name" +required = true +type = "text" + +[[elements]] +help = "Optional description" +name = "project_description" +nickel_path = [ + "ci", + "project", + "description", +] +placeholder = "Brief description of what this project does" +prompt = "Project description" +required = false +type = "text" + +[[elements]] +default = "" +help = "Project website or documentation site URL" +name = "project_site_url" +nickel_path = [ + "ci", + "project", + "site_url", +] +placeholder = "https://example.com" +prompt = "Project Site URL" +required = false +type = "text" + +[[elements]] +default = "" +help = "Project repository URL (GitHub, GitLab, etc.)" +name = "project_repo_url" +nickel_path = [ + "ci", + "project", + "repo_url", +] +placeholder = "https://github.com/user/repo" +prompt = "Project Repo URL" +required = false +type = "text" + +[[elements]] +border_bottom = true +border_top = true +name = "languages_header" +title = "πŸ” Detected Languages" +type = "section_header" + +[[elements]] +default = "rust" +display_mode = "grid" +help = "Select all languages detected or used in the project" +min_selected = 1 +name = "detected_languages" +nickel_path = [ + "ci", + "project", + "detected_languages", +] +prompt = "Which languages are used in this project?" +required = true +searchable = true +type = "multiselect" + +[[elements.options]] +value = "rust" +label = "πŸ¦€ Rust" + +[[elements.options]] +value = "nickel" +label = "βš™οΈ Nickel" + +[[elements.options]] +value = "bash" +label = "πŸ”§ Bash/Shell" + +[[elements.options]] +value = "markdown" +label = "πŸ“ Markdown/Documentation" + +[[elements]] +help = "Main language used for defaults (e.g., in GitHub Actions workflows)" +name = "primary_language" +nickel_path = [ + "ci", + "project", + "primary_language", +] +options_from = "detected_languages" +prompt = "Primary language" +required = true +type = "select" +default = "rust" + +[[elements.options]] +value = "rust" +label = "πŸ¦€ Rust" + +[[elements.options]] +value = "nickel" +label = "βš™οΈ Nickel" + +[[elements.options]] +value = "bash" +label = "πŸ”§ Bash" + +[[elements.options]] +value = "markdown" +label = "πŸ“ Markdown" + +[[elements]] +includes = ["fragments/rust-tools.toml"] +name = "rust_tools_group" +type = "group" +when = "rust in detected_languages" + +[[elements]] +includes = ["fragments/nickel-tools.toml"] +name = "nickel_tools_group" +type = "group" +when = "nickel in detected_languages" + +[[elements]] +includes = ["fragments/bash-tools.toml"] +name = "bash_tools_group" +type = "group" +when = "bash in detected_languages" + +[[elements]] +includes = ["fragments/markdown-tools.toml"] +name = "markdown_tools_group" +type = "group" +when = "markdown in detected_languages" + +[[elements]] +includes = ["fragments/general-tools.toml"] +name = "general_tools_group" +type = "group" + +[[elements]] +border_bottom = true +border_top = true +name = "ci_cd_header" +title = "πŸ”„ CI/CD Configuration" +type = "section_header" + +[[elements]] +default = "true" +help = "Set up continuous integration and deployment pipelines" +name = "enable_ci_cd" +nickel_path = [ + "ci", + "features", + "enable_ci_cd", +] +prompt = "Enable CI/CD integration?" +type = "confirm" + +[[elements]] +includes = ["fragments/ci-providers.toml"] +name = "ci_providers_group" +type = "group" +when = "enable_ci_cd == true" + +[[elements]] +includes = ["fragments/ci-settings.toml"] +name = "ci_settings_group" +type = "group" +when = "enable_ci_cd == true" + +[[elements]] +includes = ["fragments/build-deployment.toml"] +name = "build_deployment_group" +type = "group" +when = "enable_ci_cd == true" + +[[elements]] +includes = ["fragments/documentation.toml"] +name = "documentation_group" +type = "group" + +[[elements]] +border_bottom = true +border_top = true +name = "confirmation_header" +title = "βœ… Ready to Install" +type = "section_header" + +[[elements]] +content = "Review your configuration above. After confirming, the CI system will be installed with your chosen settings." +name = "confirmation_footer" +type = "footer" diff --git a/.vale.ini b/.vale.ini new file mode 100644 index 0000000..6289603 --- /dev/null +++ b/.vale.ini @@ -0,0 +1,41 @@ +# Vale configuration for TypeDialog documentation +# https://vale.sh/docs/topics/config/ + +StylesPath = .vale/styles +MinAlertLevel = warning + +# Global settings +[*] +Packages = Google, write-good +Vocab = TypeDialog + +# Markdown files: docs/**/*.md and root *.md (excluding .claude, .coder, CLAUDE.md) +[*.md] +BasedOnStyles = write-good, Google + +# Ignore code blocks and specific patterns +TokenIgnores = (\$\{[^\}]+\}), (`[^`]+`), (\*\*[^\*]+\*\*) + +# Disable noisy rules for technical documentation +Google.Headings = NO +Google.Parens = NO +Google.Acronyms = NO +Google.Passive = NO +Google.We = NO +Google.Will = NO +Google.WordList = NO +Google.Colons = NO + +write-good.E-Prime = NO +write-good.TooWordy = NO +write-good.Passive = NO + +Vale.Spelling = NO + +# Keep enabled (useful for technical docs): +# - write-good.Weasel (vague words like "various") +# - Google.Contractions (maintain formal tone) +# - Google.FirstPerson (avoid "we/our") +# - Google.Exclamation +# - Google.Slang +# - Google.Units diff --git a/.vale/Vocab/TypeDialog/accept.txt b/.vale/Vocab/TypeDialog/accept.txt new file mode 100644 index 0000000..ffc7ad8 --- /dev/null +++ b/.vale/Vocab/TypeDialog/accept.txt @@ -0,0 +1,25 @@ +# TypeDialog accepted terms (case-insensitive) +# Technical acronyms and abbreviations +API +CLI +TUI +JSON +YAML +TOML +REST +HTTP +HTTPS +TLS +SSL +CORS +URL +URI +NPM +SDK +HTML +CSS +JWT +WASM +WebAssembly +README +CHANGELOG diff --git a/.vale/Vocab/TypeDialog/reject.txt b/.vale/Vocab/TypeDialog/reject.txt new file mode 100644 index 0000000..a7f5a8f --- /dev/null +++ b/.vale/Vocab/TypeDialog/reject.txt @@ -0,0 +1,2 @@ +# TypeDialog rejected terms +# Add terms that should never be used diff --git a/.vale/styles/Google/AMPM.yml b/.vale/styles/Google/AMPM.yml new file mode 100644 index 0000000..37b49ed --- /dev/null +++ b/.vale/styles/Google/AMPM.yml @@ -0,0 +1,9 @@ +extends: existence +message: "Use 'AM' or 'PM' (preceded by a space)." +link: "https://developers.google.com/style/word-list" +level: error +nonword: true +tokens: + - '\d{1,2}[AP]M\b' + - '\d{1,2} ?[ap]m\b' + - '\d{1,2} ?[aApP]\.[mM]\.' diff --git a/.vale/styles/Google/Acronyms.yml b/.vale/styles/Google/Acronyms.yml new file mode 100644 index 0000000..f41af01 --- /dev/null +++ b/.vale/styles/Google/Acronyms.yml @@ -0,0 +1,64 @@ +extends: conditional +message: "Spell out '%s', if it's unfamiliar to the audience." +link: 'https://developers.google.com/style/abbreviations' +level: suggestion +ignorecase: false +# Ensures that the existence of 'first' implies the existence of 'second'. +first: '\b([A-Z]{3,5})\b' +second: '(?:\b[A-Z][a-z]+ )+\(([A-Z]{3,5})\)' +# ... with the exception of these: +exceptions: + - API + - ASP + - CLI + - CPU + - CSS + - CSV + - DEBUG + - DOM + - DPI + - FAQ + - GCC + - GDB + - GET + - GPU + - GTK + - GUI + - HTML + - HTTP + - HTTPS + - IDE + - JAR + - JSON + - JSX + - LESS + - LLDB + - NET + - NOTE + - NVDA + - OSS + - PATH + - PDF + - PHP + - POST + - RAM + - REPL + - RSA + - SCM + - SCSS + - SDK + - SQL + - SSH + - SSL + - SVG + - TBD + - TCP + - TODO + - URI + - URL + - USB + - UTF + - XML + - XSS + - YAML + - ZIP diff --git a/.vale/styles/Google/Colons.yml b/.vale/styles/Google/Colons.yml new file mode 100644 index 0000000..4a027c3 --- /dev/null +++ b/.vale/styles/Google/Colons.yml @@ -0,0 +1,8 @@ +extends: existence +message: "'%s' should be in lowercase." +link: 'https://developers.google.com/style/colons' +nonword: true +level: warning +scope: sentence +tokens: + - '(?=1.0.0" +} diff --git a/.vale/styles/Google/vocab.txt b/.vale/styles/Google/vocab.txt new file mode 100644 index 0000000..e69de29 diff --git a/.vale/styles/write-good/Cliches.yml b/.vale/styles/write-good/Cliches.yml new file mode 100644 index 0000000..c953143 --- /dev/null +++ b/.vale/styles/write-good/Cliches.yml @@ -0,0 +1,702 @@ +extends: existence +message: "Try to avoid using clichΓ©s like '%s'." +ignorecase: true +level: warning +tokens: + - a chip off the old block + - a clean slate + - a dark and stormy night + - a far cry + - a fine kettle of fish + - a loose cannon + - a penny saved is a penny earned + - a tough row to hoe + - a word to the wise + - ace in the hole + - acid test + - add insult to injury + - against all odds + - air your dirty laundry + - all fun and games + - all in a day's work + - all talk, no action + - all thumbs + - all your eggs in one basket + - all's fair in love and war + - all's well that ends well + - almighty dollar + - American as apple pie + - an axe to grind + - another day, another dollar + - armed to the teeth + - as luck would have it + - as old as time + - as the crow flies + - at loose ends + - at my wits end + - avoid like the plague + - babe in the woods + - back against the wall + - back in the saddle + - back to square one + - back to the drawing board + - bad to the bone + - badge of honor + - bald faced liar + - ballpark figure + - banging your head against a brick wall + - baptism by fire + - barking up the wrong tree + - bat out of hell + - be all and end all + - beat a dead horse + - beat around the bush + - been there, done that + - beggars can't be choosers + - behind the eight ball + - bend over backwards + - benefit of the doubt + - bent out of shape + - best thing since sliced bread + - bet your bottom dollar + - better half + - better late than never + - better mousetrap + - better safe than sorry + - between a rock and a hard place + - beyond the pale + - bide your time + - big as life + - big cheese + - big fish in a small pond + - big man on campus + - bigger they are the harder they fall + - bird in the hand + - bird's eye view + - birds and the bees + - birds of a feather flock together + - bit the hand that feeds you + - bite the bullet + - bite the dust + - bitten off more than he can chew + - black as coal + - black as pitch + - black as the ace of spades + - blast from the past + - bleeding heart + - blessing in disguise + - blind ambition + - blind as a bat + - blind leading the blind + - blood is thicker than water + - blood sweat and tears + - blow off steam + - blow your own horn + - blushing bride + - boils down to + - bolt from the blue + - bone to pick + - bored stiff + - bored to tears + - bottomless pit + - boys will be boys + - bright and early + - brings home the bacon + - broad across the beam + - broken record + - brought back to reality + - bull by the horns + - bull in a china shop + - burn the midnight oil + - burning question + - burning the candle at both ends + - burst your bubble + - bury the hatchet + - busy as a bee + - by hook or by crook + - call a spade a spade + - called onto the carpet + - calm before the storm + - can of worms + - can't cut the mustard + - can't hold a candle to + - case of mistaken identity + - cat got your tongue + - cat's meow + - caught in the crossfire + - caught red-handed + - checkered past + - chomping at the bit + - cleanliness is next to godliness + - clear as a bell + - clear as mud + - close to the vest + - cock and bull story + - cold shoulder + - come hell or high water + - cool as a cucumber + - cool, calm, and collected + - cost a king's ransom + - count your blessings + - crack of dawn + - crash course + - creature comforts + - cross that bridge when you come to it + - crushing blow + - cry like a baby + - cry me a river + - cry over spilt milk + - crystal clear + - curiosity killed the cat + - cut and dried + - cut through the red tape + - cut to the chase + - cute as a bugs ear + - cute as a button + - cute as a puppy + - cuts to the quick + - dark before the dawn + - day in, day out + - dead as a doornail + - devil is in the details + - dime a dozen + - divide and conquer + - dog and pony show + - dog days + - dog eat dog + - dog tired + - don't burn your bridges + - don't count your chickens + - don't look a gift horse in the mouth + - don't rock the boat + - don't step on anyone's toes + - don't take any wooden nickels + - down and out + - down at the heels + - down in the dumps + - down the hatch + - down to earth + - draw the line + - dressed to kill + - dressed to the nines + - drives me up the wall + - dull as dishwater + - dyed in the wool + - eagle eye + - ear to the ground + - early bird catches the worm + - easier said than done + - easy as pie + - eat your heart out + - eat your words + - eleventh hour + - even the playing field + - every dog has its day + - every fiber of my being + - everything but the kitchen sink + - eye for an eye + - face the music + - facts of life + - fair weather friend + - fall by the wayside + - fan the flames + - feast or famine + - feather your nest + - feathered friends + - few and far between + - fifteen minutes of fame + - filthy vermin + - fine kettle of fish + - fish out of water + - fishing for a compliment + - fit as a fiddle + - fit the bill + - fit to be tied + - flash in the pan + - flat as a pancake + - flip your lid + - flog a dead horse + - fly by night + - fly the coop + - follow your heart + - for all intents and purposes + - for the birds + - for what it's worth + - force of nature + - force to be reckoned with + - forgive and forget + - fox in the henhouse + - free and easy + - free as a bird + - fresh as a daisy + - full steam ahead + - fun in the sun + - garbage in, garbage out + - gentle as a lamb + - get a kick out of + - get a leg up + - get down and dirty + - get the lead out + - get to the bottom of + - get your feet wet + - gets my goat + - gilding the lily + - give and take + - go against the grain + - go at it tooth and nail + - go for broke + - go him one better + - go the extra mile + - go with the flow + - goes without saying + - good as gold + - good deed for the day + - good things come to those who wait + - good time was had by all + - good times were had by all + - greased lightning + - greek to me + - green thumb + - green-eyed monster + - grist for the mill + - growing like a weed + - hair of the dog + - hand to mouth + - happy as a clam + - happy as a lark + - hasn't a clue + - have a nice day + - have high hopes + - have the last laugh + - haven't got a row to hoe + - head honcho + - head over heels + - hear a pin drop + - heard it through the grapevine + - heart's content + - heavy as lead + - hem and haw + - high and dry + - high and mighty + - high as a kite + - hit paydirt + - hold your head up high + - hold your horses + - hold your own + - hold your tongue + - honest as the day is long + - horns of a dilemma + - horse of a different color + - hot under the collar + - hour of need + - I beg to differ + - icing on the cake + - if the shoe fits + - if the shoe were on the other foot + - in a jam + - in a jiffy + - in a nutshell + - in a pig's eye + - in a pinch + - in a word + - in hot water + - in the gutter + - in the nick of time + - in the thick of it + - in your dreams + - it ain't over till the fat lady sings + - it goes without saying + - it takes all kinds + - it takes one to know one + - it's a small world + - it's only a matter of time + - ivory tower + - Jack of all trades + - jockey for position + - jog your memory + - joined at the hip + - judge a book by its cover + - jump down your throat + - jump in with both feet + - jump on the bandwagon + - jump the gun + - jump to conclusions + - just a hop, skip, and a jump + - just the ticket + - justice is blind + - keep a stiff upper lip + - keep an eye on + - keep it simple, stupid + - keep the home fires burning + - keep up with the Joneses + - keep your chin up + - keep your fingers crossed + - kick the bucket + - kick up your heels + - kick your feet up + - kid in a candy store + - kill two birds with one stone + - kiss of death + - knock it out of the park + - knock on wood + - knock your socks off + - know him from Adam + - know the ropes + - know the score + - knuckle down + - knuckle sandwich + - knuckle under + - labor of love + - ladder of success + - land on your feet + - lap of luxury + - last but not least + - last hurrah + - last-ditch effort + - law of the jungle + - law of the land + - lay down the law + - leaps and bounds + - let sleeping dogs lie + - let the cat out of the bag + - let the good times roll + - let your hair down + - let's talk turkey + - letter perfect + - lick your wounds + - lies like a rug + - life's a bitch + - life's a grind + - light at the end of the tunnel + - lighter than a feather + - lighter than air + - like clockwork + - like father like son + - like taking candy from a baby + - like there's no tomorrow + - lion's share + - live and learn + - live and let live + - long and short of it + - long lost love + - look before you leap + - look down your nose + - look what the cat dragged in + - looking a gift horse in the mouth + - looks like death warmed over + - loose cannon + - lose your head + - lose your temper + - loud as a horn + - lounge lizard + - loved and lost + - low man on the totem pole + - luck of the draw + - luck of the Irish + - make hay while the sun shines + - make money hand over fist + - make my day + - make the best of a bad situation + - make the best of it + - make your blood boil + - man of few words + - man's best friend + - mark my words + - meaningful dialogue + - missed the boat on that one + - moment in the sun + - moment of glory + - moment of truth + - money to burn + - more power to you + - more than one way to skin a cat + - movers and shakers + - moving experience + - naked as a jaybird + - naked truth + - neat as a pin + - needle in a haystack + - needless to say + - neither here nor there + - never look back + - never say never + - nip and tuck + - nip it in the bud + - no guts, no glory + - no love lost + - no pain, no gain + - no skin off my back + - no stone unturned + - no time like the present + - no use crying over spilled milk + - nose to the grindstone + - not a hope in hell + - not a minute's peace + - not in my backyard + - not playing with a full deck + - not the end of the world + - not written in stone + - nothing to sneeze at + - nothing ventured nothing gained + - now we're cooking + - off the top of my head + - off the wagon + - off the wall + - old hat + - older and wiser + - older than dirt + - older than Methuselah + - on a roll + - on cloud nine + - on pins and needles + - on the bandwagon + - on the money + - on the nose + - on the rocks + - on the spot + - on the tip of my tongue + - on the wagon + - on thin ice + - once bitten, twice shy + - one bad apple doesn't spoil the bushel + - one born every minute + - one brick short + - one foot in the grave + - one in a million + - one red cent + - only game in town + - open a can of worms + - open and shut case + - open the flood gates + - opportunity doesn't knock twice + - out of pocket + - out of sight, out of mind + - out of the frying pan into the fire + - out of the woods + - out on a limb + - over a barrel + - over the hump + - pain and suffering + - pain in the + - panic button + - par for the course + - part and parcel + - party pooper + - pass the buck + - patience is a virtue + - pay through the nose + - penny pincher + - perfect storm + - pig in a poke + - pile it on + - pillar of the community + - pin your hopes on + - pitter patter of little feet + - plain as day + - plain as the nose on your face + - play by the rules + - play your cards right + - playing the field + - playing with fire + - pleased as punch + - plenty of fish in the sea + - point with pride + - poor as a church mouse + - pot calling the kettle black + - pretty as a picture + - pull a fast one + - pull your punches + - pulling your leg + - pure as the driven snow + - put it in a nutshell + - put one over on you + - put the cart before the horse + - put the pedal to the metal + - put your best foot forward + - put your foot down + - quick as a bunny + - quick as a lick + - quick as a wink + - quick as lightning + - quiet as a dormouse + - rags to riches + - raining buckets + - raining cats and dogs + - rank and file + - rat race + - reap what you sow + - red as a beet + - red herring + - reinvent the wheel + - rich and famous + - rings a bell + - ripe old age + - ripped me off + - rise and shine + - road to hell is paved with good intentions + - rob Peter to pay Paul + - roll over in the grave + - rub the wrong way + - ruled the roost + - running in circles + - sad but true + - sadder but wiser + - salt of the earth + - scared stiff + - scared to death + - sealed with a kiss + - second to none + - see eye to eye + - seen the light + - seize the day + - set the record straight + - set the world on fire + - set your teeth on edge + - sharp as a tack + - shoot for the moon + - shoot the breeze + - shot in the dark + - shoulder to the wheel + - sick as a dog + - sigh of relief + - signed, sealed, and delivered + - sink or swim + - six of one, half a dozen of another + - skating on thin ice + - slept like a log + - slinging mud + - slippery as an eel + - slow as molasses + - smart as a whip + - smooth as a baby's bottom + - sneaking suspicion + - snug as a bug in a rug + - sow wild oats + - spare the rod, spoil the child + - speak of the devil + - spilled the beans + - spinning your wheels + - spitting image of + - spoke with relish + - spread like wildfire + - spring to life + - squeaky wheel gets the grease + - stands out like a sore thumb + - start from scratch + - stick in the mud + - still waters run deep + - stitch in time + - stop and smell the roses + - straight as an arrow + - straw that broke the camel's back + - strong as an ox + - stubborn as a mule + - stuff that dreams are made of + - stuffed shirt + - sweating blood + - sweating bullets + - take a load off + - take one for the team + - take the bait + - take the bull by the horns + - take the plunge + - takes one to know one + - takes two to tango + - the more the merrier + - the real deal + - the real McCoy + - the red carpet treatment + - the same old story + - there is no accounting for taste + - thick as a brick + - thick as thieves + - thin as a rail + - think outside of the box + - third time's the charm + - this day and age + - this hurts me worse than it hurts you + - this point in time + - three sheets to the wind + - through thick and thin + - throw in the towel + - tie one on + - tighter than a drum + - time and time again + - time is of the essence + - tip of the iceberg + - tired but happy + - to coin a phrase + - to each his own + - to make a long story short + - to the best of my knowledge + - toe the line + - tongue in cheek + - too good to be true + - too hot to handle + - too numerous to mention + - touch with a ten foot pole + - tough as nails + - trial and error + - trials and tribulations + - tried and true + - trip down memory lane + - twist of fate + - two cents worth + - two peas in a pod + - ugly as sin + - under the counter + - under the gun + - under the same roof + - under the weather + - until the cows come home + - unvarnished truth + - up the creek + - uphill battle + - upper crust + - upset the applecart + - vain attempt + - vain effort + - vanquish the enemy + - vested interest + - waiting for the other shoe to drop + - wakeup call + - warm welcome + - watch your p's and q's + - watch your tongue + - watching the clock + - water under the bridge + - weather the storm + - weed them out + - week of Sundays + - went belly up + - wet behind the ears + - what goes around comes around + - what you see is what you get + - when it rains, it pours + - when push comes to shove + - when the cat's away + - when the going gets tough, the tough get going + - white as a sheet + - whole ball of wax + - whole hog + - whole nine yards + - wild goose chase + - will wonders never cease? + - wisdom of the ages + - wise as an owl + - wolf at the door + - words fail me + - work like a dog + - world weary + - worst nightmare + - worth its weight in gold + - wrong side of the bed + - yanking your chain + - yappy as a dog + - years young + - you are what you eat + - you can run but you can't hide + - you only live once + - you're the boss + - young and foolish + - young and vibrant diff --git a/.vale/styles/write-good/E-Prime.yml b/.vale/styles/write-good/E-Prime.yml new file mode 100644 index 0000000..074a102 --- /dev/null +++ b/.vale/styles/write-good/E-Prime.yml @@ -0,0 +1,32 @@ +extends: existence +message: "Try to avoid using '%s'." +ignorecase: true +level: suggestion +tokens: + - am + - are + - aren't + - be + - been + - being + - he's + - here's + - here's + - how's + - i'm + - is + - isn't + - it's + - she's + - that's + - there's + - they're + - was + - wasn't + - we're + - were + - weren't + - what's + - where's + - who's + - you're diff --git a/.vale/styles/write-good/Illusions.yml b/.vale/styles/write-good/Illusions.yml new file mode 100644 index 0000000..b4f1321 --- /dev/null +++ b/.vale/styles/write-good/Illusions.yml @@ -0,0 +1,11 @@ +extends: repetition +message: "'%s' is repeated!" +level: warning +alpha: true +action: + name: edit + params: + - truncate + - " " +tokens: + - '[^\s]+' diff --git a/.vale/styles/write-good/Passive.yml b/.vale/styles/write-good/Passive.yml new file mode 100644 index 0000000..f472cb9 --- /dev/null +++ b/.vale/styles/write-good/Passive.yml @@ -0,0 +1,183 @@ +extends: existence +message: "'%s' may be passive voice. Use active voice if you can." +ignorecase: true +level: warning +raw: + - \b(am|are|were|being|is|been|was|be)\b\s* +tokens: + - '[\w]+ed' + - awoken + - beat + - become + - been + - begun + - bent + - beset + - bet + - bid + - bidden + - bitten + - bled + - blown + - born + - bought + - bound + - bred + - broadcast + - broken + - brought + - built + - burnt + - burst + - cast + - caught + - chosen + - clung + - come + - cost + - crept + - cut + - dealt + - dived + - done + - drawn + - dreamt + - driven + - drunk + - dug + - eaten + - fallen + - fed + - felt + - fit + - fled + - flown + - flung + - forbidden + - foregone + - forgiven + - forgotten + - forsaken + - fought + - found + - frozen + - given + - gone + - gotten + - ground + - grown + - heard + - held + - hidden + - hit + - hung + - hurt + - kept + - knelt + - knit + - known + - laid + - lain + - leapt + - learnt + - led + - left + - lent + - let + - lighted + - lost + - made + - meant + - met + - misspelt + - mistaken + - mown + - overcome + - overdone + - overtaken + - overthrown + - paid + - pled + - proven + - put + - quit + - read + - rid + - ridden + - risen + - run + - rung + - said + - sat + - sawn + - seen + - sent + - set + - sewn + - shaken + - shaven + - shed + - shod + - shone + - shorn + - shot + - shown + - shrunk + - shut + - slain + - slept + - slid + - slit + - slung + - smitten + - sold + - sought + - sown + - sped + - spent + - spilt + - spit + - split + - spoken + - spread + - sprung + - spun + - stolen + - stood + - stridden + - striven + - struck + - strung + - stuck + - stung + - stunk + - sung + - sunk + - swept + - swollen + - sworn + - swum + - swung + - taken + - taught + - thought + - thrived + - thrown + - thrust + - told + - torn + - trodden + - understood + - upheld + - upset + - wed + - wept + - withheld + - withstood + - woken + - won + - worn + - wound + - woven + - written + - wrung diff --git a/.vale/styles/write-good/README.md b/.vale/styles/write-good/README.md new file mode 100644 index 0000000..3edcc9b --- /dev/null +++ b/.vale/styles/write-good/README.md @@ -0,0 +1,27 @@ +Based on [write-good](https://github.com/btford/write-good). + +> Naive linter for English prose for developers who can't write good and wanna learn to do other stuff good too. + +``` +The MIT License (MIT) + +Copyright (c) 2014 Brian Ford + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +``` diff --git a/.vale/styles/write-good/So.yml b/.vale/styles/write-good/So.yml new file mode 100644 index 0000000..e57f099 --- /dev/null +++ b/.vale/styles/write-good/So.yml @@ -0,0 +1,5 @@ +extends: existence +message: "Don't start a sentence with '%s'." +level: error +raw: + - '(?:[;-]\s)so[\s,]|\bSo[\s,]' diff --git a/.vale/styles/write-good/ThereIs.yml b/.vale/styles/write-good/ThereIs.yml new file mode 100644 index 0000000..8b82e8f --- /dev/null +++ b/.vale/styles/write-good/ThereIs.yml @@ -0,0 +1,6 @@ +extends: existence +message: "Don't start a sentence with '%s'." +ignorecase: false +level: error +raw: + - '(?:[;-]\s)There\s(is|are)|\bThere\s(is|are)\b' diff --git a/.vale/styles/write-good/TooWordy.yml b/.vale/styles/write-good/TooWordy.yml new file mode 100644 index 0000000..275701b --- /dev/null +++ b/.vale/styles/write-good/TooWordy.yml @@ -0,0 +1,221 @@ +extends: existence +message: "'%s' is too wordy." +ignorecase: true +level: warning +tokens: + - a number of + - abundance + - accede to + - accelerate + - accentuate + - accompany + - accomplish + - accorded + - accrue + - acquiesce + - acquire + - additional + - adjacent to + - adjustment + - admissible + - advantageous + - adversely impact + - advise + - aforementioned + - aggregate + - aircraft + - all of + - all things considered + - alleviate + - allocate + - along the lines of + - already existing + - alternatively + - amazing + - ameliorate + - anticipate + - apparent + - appreciable + - as a matter of fact + - as a means of + - as far as I'm concerned + - as of yet + - as to + - as yet + - ascertain + - assistance + - at the present time + - at this time + - attain + - attributable to + - authorize + - because of the fact that + - belated + - benefit from + - bestow + - by means of + - by virtue of + - by virtue of the fact that + - cease + - close proximity + - commence + - comply with + - concerning + - consequently + - consolidate + - constitutes + - demonstrate + - depart + - designate + - discontinue + - due to the fact that + - each and every + - economical + - eliminate + - elucidate + - employ + - endeavor + - enumerate + - equitable + - equivalent + - evaluate + - evidenced + - exclusively + - expedite + - expend + - expiration + - facilitate + - factual evidence + - feasible + - finalize + - first and foremost + - for all intents and purposes + - for the most part + - for the purpose of + - forfeit + - formulate + - have a tendency to + - honest truth + - however + - if and when + - impacted + - implement + - in a manner of speaking + - in a timely manner + - in a very real sense + - in accordance with + - in addition + - in all likelihood + - in an effort to + - in between + - in excess of + - in lieu of + - in light of the fact that + - in many cases + - in my opinion + - in order to + - in regard to + - in some instances + - in terms of + - in the case of + - in the event that + - in the final analysis + - in the nature of + - in the near future + - in the process of + - inception + - incumbent upon + - indicate + - indication + - initiate + - irregardless + - is applicable to + - is authorized to + - is responsible for + - it is + - it is essential + - it seems that + - it was + - magnitude + - maximum + - methodology + - minimize + - minimum + - modify + - monitor + - multiple + - necessitate + - nevertheless + - not certain + - not many + - not often + - not unless + - not unlike + - notwithstanding + - null and void + - numerous + - objective + - obligate + - obtain + - on the contrary + - on the other hand + - one particular + - optimum + - overall + - owing to the fact that + - participate + - particulars + - pass away + - pertaining to + - point in time + - portion + - possess + - preclude + - previously + - prior to + - prioritize + - procure + - proficiency + - provided that + - purchase + - put simply + - readily apparent + - refer back + - regarding + - relocate + - remainder + - remuneration + - requirement + - reside + - residence + - retain + - satisfy + - shall + - should you wish + - similar to + - solicit + - span across + - strategize + - subsequent + - substantial + - successfully complete + - sufficient + - terminate + - the month of + - the point I am trying to make + - therefore + - time period + - took advantage of + - transmit + - transpire + - type of + - until such time as + - utilization + - utilize + - validate + - various different + - what I mean to say is + - whether or not + - with respect to + - with the exception of + - witnessed diff --git a/.vale/styles/write-good/Weasel.yml b/.vale/styles/write-good/Weasel.yml new file mode 100644 index 0000000..d1d90a7 --- /dev/null +++ b/.vale/styles/write-good/Weasel.yml @@ -0,0 +1,29 @@ +extends: existence +message: "'%s' is a weasel word!" +ignorecase: true +level: warning +tokens: + - clearly + - completely + - exceedingly + - excellent + - extremely + - fairly + - huge + - interestingly + - is a number + - largely + - mostly + - obviously + - quite + - relatively + - remarkably + - several + - significantly + - substantially + - surprisingly + - tiny + - usually + - various + - vast + - very diff --git a/.vale/styles/write-good/meta.json b/.vale/styles/write-good/meta.json new file mode 100644 index 0000000..a115d28 --- /dev/null +++ b/.vale/styles/write-good/meta.json @@ -0,0 +1,4 @@ +{ + "feed": "https://github.com/errata-ai/write-good/releases.atom", + "vale_version": ">=1.0.0" +} diff --git a/.woodpecker/Dockerfile b/.woodpecker/Dockerfile new file mode 100644 index 0000000..892a63a --- /dev/null +++ b/.woodpecker/Dockerfile @@ -0,0 +1,45 @@ +# Custom Docker image for Woodpecker CI +# Pre-installs common tools to speed up CI runs +# +# Build: docker build -t your-registry/ci:latest -f .woodpecker/Dockerfile . +# Push: docker push your-registry/ci:latest +# +# Then update .woodpecker/ci.yml to use: image: your-registry/ci:latest + +FROM rust:latest + +# Install system dependencies +RUN apt-get update && apt-get install -y \ + shellcheck \ + curl \ + git \ + && rm -rf /var/lib/apt/lists/* + +# Install just +RUN curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to /usr/local/bin + +# Install Rust components +RUN rustup component add clippy rustfmt + +# Install Rust tools (pre-compiled to speed up CI) +RUN cargo install \ + cargo-audit \ + cargo-deny \ + cargo-sbom \ + nickel-lang-cli \ + nu \ + --locked + +# Set working directory +WORKDIR /workspace + +# Verify installations +RUN just --version && \ + cargo --version && \ + cargo audit --version && \ + cargo deny --version && \ + cargo sbom --version && \ + nickel --version && \ + nu --version + +CMD ["/bin/bash"] \ No newline at end of file diff --git a/.woodpecker/Dockerfile.cross b/.woodpecker/Dockerfile.cross new file mode 100644 index 0000000..ea1edca --- /dev/null +++ b/.woodpecker/Dockerfile.cross @@ -0,0 +1,42 @@ +# Dockerfile for cross-platform compilation +# Supports building for multiple targets using docker + +FROM ubuntu:22.04 + +# Install build essentials +RUN apt-get update && apt-get install -y \ + build-essential \ + curl \ + git \ + pkg-config \ + && rm -rf /var/lib/apt/lists/* + +# Install Rust +RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable +ENV PATH="/root/.cargo/bin:${PATH}" + +# Install cross tool for cross-compilation +RUN cargo install cross --locked + +# Create workspace directory +WORKDIR /workspace + +# Copy entire project +COPY . . + +# Default build target +ARG TARGET=x86_64-unknown-linux-gnu +ENV BUILD_TARGET="${TARGET}" + +# Build command +RUN cross build --target "${BUILD_TARGET}" --release + +# Extract binaries to output directory +RUN mkdir -p /output/bin && \ + find target/"${BUILD_TARGET}"/release -maxdepth 1 -type f -executable -exec cp {} /output/bin/ \; + +# Create manifest +RUN echo "{ \"target\": \"${BUILD_TARGET}\", \"built\": \"$(date -u +'%Y-%m-%dT%H:%M:%SZ')\" }" > /output/BUILD_INFO.json + +# Default command +CMD ["/bin/bash"] \ No newline at end of file diff --git a/.woodpecker/README.md b/.woodpecker/README.md new file mode 100644 index 0000000..58b4853 --- /dev/null +++ b/.woodpecker/README.md @@ -0,0 +1,78 @@ +# Woodpecker CI Configuration + +Pipelines for Gitea/Forgejo + Woodpecker CI. + +## Files + +- **`ci.yml`** - Main CI pipeline (push, pull requests) +- **`Dockerfile`** - Custom CI image with pre-installed tools +- **`Dockerfile.cross`** - Cross-compilation image for multi-platform builds + +## Setup + +### 1. Activate Woodpecker CI + +Enable Woodpecker CI in your Gitea/Forgejo repository settings. + +### 2. (Optional) Build Custom Image + +Speeds up CI by pre-installing tools (~5 min faster per run). + +```bash +# Build CI image +docker build -t your-registry/ci:latest -f .woodpecker/Dockerfile . + +# Push to your registry +docker push your-registry/ci:latest + +# Update .woodpecker/ci.yml +# Change: image: rust:latest +# To: image: your-registry/ci:latest +``` + +### 3. Cross-Compilation Setup + +For multi-platform builds: + +```bash +# Build cross-compilation image +docker build -t your-registry/ci-cross:latest -f .woodpecker/Dockerfile.cross . + +# Push to registry +docker push your-registry/ci-cross:latest +``` + +## CI Pipeline (`ci.yml`) + +**Triggers**: Push to `main`/`develop`, Pull Requests + +**Jobs**: +1. Lint (Rust, Bash, Nickel, Nushell, Markdown) - Parallel +2. Test (all features) +3. Build (release) +4. Security audit +5. License compliance check + +**Duration**: ~15-20 minutes (without custom image), ~10-15 minutes (with custom image) + +## Triggering Pipelines + +```bash +# CI pipeline (automatic on push/PR) +git push origin main +``` + +## Viewing Results + +- **Gitea/Forgejo**: Repository β†’ Actions β†’ Pipeline runs +- **Woodpecker UI**: https://your-woodpecker.instance/repos/{user}/{repo} + +## Differences from GitHub Actions + +| Feature | GitHub Actions | Woodpecker CI | +|---------|---------------|---------------| +| Matrix builds | βœ… 3 OS | ❌ Linux only* | +| Caching | βœ… Built-in | ⚠️ Server-side** | + +\* Multi-OS builds require multiple Woodpecker agents +\*\* Configure in Woodpecker server settings diff --git a/.woodpecker/ci-advanced.yml b/.woodpecker/ci-advanced.yml new file mode 100644 index 0000000..3bda3c4 --- /dev/null +++ b/.woodpecker/ci-advanced.yml @@ -0,0 +1,168 @@ +# Woodpecker CI - Advanced Pipeline +# Multi-platform builds, coverage, benchmarks, and security scanning + +when: + event: [push, pull_request, manual] + branch: + - main + - develop + +matrix: + PLATFORM: + - linux/amd64 + - linux/arm64 + +steps: + # === LINTING (Parallel) === + + lint-rust: + image: rust:latest + commands: + - curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to /usr/local/bin + - rustup component add clippy rustfmt + - cargo fmt --all -- --check + - cargo clippy --all-targets --all-features -- -D warnings + environment: + CARGO_TERM_COLOR: always + + lint-bash: + image: koalaman/shellcheck-alpine:stable + commands: + - apk add --no-cache curl bash + - find . -name '*.sh' -type f ! -path './target/*' -exec shellcheck {} + + + lint-nickel: + image: rust:latest + commands: + - cargo install nickel-lang-cli --locked + - find . -name '*.ncl' -type f ! -path './target/*' -exec nickel typecheck {} \; + + lint-nushell: + image: rust:latest + commands: + - cargo install nu --locked + - find . -name '*.nu' -type f ! -path './target/*' -exec nu --ide-check 100 {} \; + + lint-markdown: + image: node:alpine + commands: + - npm install -g markdownlint-cli2 + - markdownlint-cli2 '**/*.md' '#node_modules' '#target' + + # === TESTING === + + test: + image: rust:latest + commands: + - cargo test --workspace --all-features --no-fail-fast + depends_on: + - lint-rust + - lint-bash + - lint-nickel + - lint-nushell + - lint-markdown + environment: + RUST_BACKTRACE: 1 + + # === CODE COVERAGE === + + coverage: + image: rust:latest + commands: + - cargo install cargo-tarpaulin --locked + - cargo tarpaulin --workspace --all-features --out Xml --output-dir coverage + - | + if [ -f coverage/cobertura.xml ]; then + echo "Coverage report generated successfully" + fi + depends_on: + - test + when: + event: [push, pull_request] + branch: [main, develop] + + # === BUILD (Multi-platform) === + + build-native: + image: rust:latest + commands: + - cargo build --release --workspace + - ls -lh target/release/ + depends_on: + - test + + build-cross: + image: rust:latest + commands: + - cargo install cross --locked + - cross build --target x86_64-unknown-linux-musl --release + - cross build --target aarch64-unknown-linux-musl --release + depends_on: + - test + when: + matrix: + PLATFORM: linux/amd64 + + # === BENCHMARKS === + + benchmark: + image: rust:latest + commands: + - rustup toolchain install nightly + - cargo +nightly bench --workspace --no-fail-fast + - | + if [ -d target/criterion ]; then + echo "Benchmark results available in target/criterion" + fi + depends_on: + - build-native + when: + event: pull_request + + # === SECURITY AUDITS === + + security-audit: + image: rust:latest + commands: + - cargo install cargo-audit --locked + - cargo audit --deny warnings --deny unmaintained --deny unsound + depends_on: + - lint-rust + + license-check: + image: rust:latest + commands: + - cargo install cargo-deny --locked + - cargo deny check licenses advisories sources bans + depends_on: + - lint-rust + + dependency-check: + image: rust:latest + commands: + - cargo install cargo-outdated --locked + - cargo outdated --exit-code 1 --root-deps-only + depends_on: + - lint-rust + when: + event: manual + + # === SONARQUBE ANALYSIS === + + sonarqube: + image: sonarsource/sonar-scanner-cli:latest + commands: + - | + sonar-scanner \ + -Dsonar.projectKey=${CI_REPO_NAME} \ + -Dsonar.sources=. \ + -Dsonar.host.url=${SONAR_HOST_URL} \ + -Dsonar.token=${SONAR_TOKEN} \ + -Dsonar.rust.clippy.reportPaths=clippy-report.json \ + -Dsonar.coverageReportPaths=coverage/cobertura.xml + depends_on: + - coverage + secrets: [sonar_host_url, sonar_token] + when: + event: [push, pull_request] + branch: [main, develop] diff --git a/.woodpecker/ci.yml b/.woodpecker/ci.yml new file mode 100644 index 0000000..be8aba9 --- /dev/null +++ b/.woodpecker/ci.yml @@ -0,0 +1,84 @@ +# Woodpecker CI Pipeline +# Equivalent to GitHub Actions CI workflow +# Generated by dev-system/ci + +when: + event: [push, pull_request, manual] + branch: + - main + - develop + +steps: + # === LINTING === + + lint-rust: + image: rust:latest + commands: + - curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to /usr/local/bin + - rustup component add clippy + - cargo fmt --all -- --check + - cargo clippy --all-targets -- -D warnings + + lint-bash: + image: koalaman/shellcheck-alpine:stable + commands: + - apk add --no-cache curl bash + - find . -name '*.sh' -type f ! -path './target/*' -exec shellcheck {} + + + lint-nickel: + image: rust:latest + commands: + - cargo install nickel-lang-cli --locked + - find . -name '*.ncl' -type f ! -path './target/*' -exec nickel typecheck {} \; + + lint-nushell: + image: rust:latest + commands: + - cargo install nu --locked + - find . -name '*.nu' -type f ! -path './target/*' -exec nu --ide-check 100 {} \; + + lint-markdown: + image: node:alpine + commands: + - npm install -g markdownlint-cli2 + - markdownlint-cli2 '**/*.md' '#node_modules' '#target' + + # === TESTING === + + test: + image: rust:latest + commands: + - cargo test --workspace --all-features + depends_on: + - lint-rust + - lint-bash + - lint-nickel + - lint-nushell + - lint-markdown + + # === BUILD === + + build: + image: rust:latest + commands: + - cargo build --release + depends_on: + - test + + # === SECURITY === + + security-audit: + image: rust:latest + commands: + - cargo install cargo-audit --locked + - cargo audit --deny warnings + depends_on: + - lint-rust + + license-check: + image: rust:latest + commands: + - cargo install cargo-deny --locked + - cargo deny check licenses advisories + depends_on: + - lint-rust diff --git a/.yamllint-ci.yml b/.yamllint-ci.yml new file mode 100644 index 0000000..3575afe --- /dev/null +++ b/.yamllint-ci.yml @@ -0,0 +1,18 @@ +extends: default + +rules: + line-length: + max: 200 # More reasonable for infrastructure code + comments: + min-spaces-from-content: 1 # Allow single space before comments + document-start: disable # Cloud-init files don't need --- start + truthy: + allowed-values: ["true", "false", "yes", "no", "on", "off"] # Allow cloud-init and GitHub Actions common values + +# Ignore cloud-init files for comment spacing since #cloud-config is a special directive +# Ignore directories with generated/runtime files +ignore: | + **/cloud-init.yml + build/** + data/** + envs/** diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..ef8db03 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,103 @@ +# Code of Conduct + +## Our Pledge + +We, as members, contributors, and leaders, pledge to make participation in our project and community a harassment-free experience for everyone, regardless of: + +- Age +- Body size +- Visible or invisible disability +- Ethnicity +- Sex characteristics +- Gender identity and expression +- Level of experience +- Education +- Socioeconomic status +- Nationality +- Personal appearance +- Race +- Caste +- Color +- Religion +- Sexual identity and orientation + +We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our community include: + +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by mistakes +- Focusing on what is best not just for us as individuals, but for the overall community + +Examples of unacceptable behavior include: + +- The use of sexualized language or imagery +- Trolling, insulting, or derogatory comments +- Personal or political attacks +- Public or private harassment +- Publishing others' private information (doxing) +- Other conduct which could reasonably be considered inappropriate in a professional setting + +## Enforcement Responsibilities + +Project maintainers are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate corrective action in response to unacceptable behavior. + +Maintainers have the right and responsibility to: + +- Remove, edit, or reject comments, commits, code, and other contributions +- Ban contributors for behavior they deem inappropriate, threatening, or harmful + +## Scope + +This Code of Conduct applies to: + +- All community spaces (GitHub, forums, chat, events, etc.) +- Official project channels and representations +- Interactions between community members related to the project + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to project maintainers: + +- Email: [project contact] +- GitHub: Private security advisory +- Issues: Report with `conduct` label (public discussions only) + +All complaints will be reviewed and investigated promptly and fairly. + +### Enforcement Guidelines + +**1. Correction** +- Community impact: Use of inappropriate language or unwelcoming behavior +- Action: Private written warning with explanation and clarity on impact +- Consequence: Warning and no further violations + +**2. Warning** +- Community impact: Violation through single incident or series of actions +- Action: Written warning with severity consequences for continued behavior +- Consequence: Suspension from community interaction + +**3. Temporary Ban** +- Community impact: Serious violation of standards +- Action: Temporary ban from community interaction +- Consequence: Revocation of ban after reflection period + +**4. Permanent Ban** +- Community impact: Pattern of violating community standards +- Action: Permanent ban from community interaction + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 2.1. + +For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. + +--- + +**Thank you for being part of our community!** + +We believe in creating a welcoming and inclusive space where everyone can contribute their best work. Together, we make this project better. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..030c6d6 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,129 @@ +# Contributing to SecretumVault + +Thank you for your interest in contributing! This document provides guidelines and instructions for contributing to this project. + +## Code of Conduct + +This project adheres to a Code of Conduct. By participating, you are expected to uphold this code. Please see [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) for details. + +## Getting Started + +### Prerequisites + +- Rust 1.70+ (if project uses Rust) +- NuShell (if project uses Nushell scripts) +- Git + +### Development Setup + +1. Fork the repository +2. Clone your fork: `git clone https://repo.jesusperez.pro/jesus/secretumvault.git` +3. Add upstream: `git remote add upstream https://repo.jesusperez.pro/jesus/secretumvault.git` +4. Create a branch: `git checkout -b feature/your-feature` + +## Development Workflow + +### Before You Code + +- Check existing issues and pull requests to avoid duplication +- Create an issue to discuss major changes before implementing +- Assign yourself to let others know you're working on it + +### Code Standards + +#### Rust + +- Run `cargo fmt --all` before committing +- All code must pass `cargo clippy -- -D warnings` +- Write tests for new functionality +- Maintain 100% documentation coverage for public APIs + +#### Nushell + +- Validate scripts with `nu --ide-check 100 script.nu` +- Follow consistent naming conventions +- Use type hints where applicable + +#### Nickel + +- Type check schemas with `nickel typecheck` +- Document schema fields with comments +- Test schema validation + +### Commit Guidelines + +- Write clear, descriptive commit messages +- Reference issues with `Fixes #123` or `Related to #123` +- Keep commits focused on a single concern +- Use imperative mood: "Add feature" not "Added feature" + +### Testing + +All changes must include tests: + +```bash +# Run all tests +cargo test --workspace + +# Run with coverage +cargo llvm-cov --all-features --lcov + +# Run locally before pushing +just ci-full +``` + +### Pull Request Process + +1. Update documentation for any changed functionality +2. Add tests for new code +3. Ensure all CI checks pass +4. Request review from maintainers +5. Be responsive to feedback and iterate quickly + +## Review Process + +- Maintainers will review your PR within 3-5 business days +- Feedback is constructive and meant to improve the code +- All discussions should be respectful and professional +- Once approved, maintainers will merge the PR + +## Reporting Bugs + +Found a bug? Please file an issue with: + +- **Title**: Clear, descriptive title +- **Description**: What happened and what you expected +- **Steps to reproduce**: Minimal reproducible example +- **Environment**: OS, Rust version, etc. +- **Screenshots**: If applicable + +## Suggesting Enhancements + +Have an idea? Please file an issue with: + +- **Title**: Clear feature title +- **Description**: What, why, and how +- **Use cases**: Real-world scenarios where this would help +- **Alternative approaches**: If you've considered any + +## Documentation + +- Keep README.md up to date +- Document public APIs with rustdoc comments +- Add examples for non-obvious functionality +- Update CHANGELOG.md with your changes + +## Release Process + +Maintainers handle releases following semantic versioning: +- MAJOR: Breaking changes +- MINOR: New features (backward compatible) +- PATCH: Bug fixes + +## Questions? + +- Check existing documentation and issues +- Ask in discussions or open an issue +- Join our community channels + +Thank you for contributing! diff --git a/Cargo.toml b/Cargo.toml index 045e233..593c59c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -78,7 +78,7 @@ hex = "0.4" regex = "1.12" [dev-dependencies] -tempfile = "3.23" +tempfile = "3.24" wiremock = "0.6" proptest = "1.9" diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..e49aa37 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,98 @@ +# Security Policy + +## Supported Versions + +This project provides security updates for the following versions: + +| Version | Supported | +|---------|-----------| +| 1.x | βœ… Yes | +| 0.x | ❌ No | + +Only the latest major version receives security patches. Users are encouraged to upgrade to the latest version. + +## Reporting a Vulnerability + +**Do not open public GitHub issues for security vulnerabilities.** + +Instead, please report security issues to the maintainers privately: + +### Reporting Process + +1. Email security details to the maintainers (see project README for contact) +2. Include: + - Description of the vulnerability + - Steps to reproduce (if possible) + - Potential impact + - Suggested fix (if you have one) + +3. Expect acknowledgment within 48 hours +4. We will work on a fix and coordinate disclosure timing + +### Responsible Disclosure + +- Allow reasonable time for a fix before public disclosure +- Work with us to understand and validate the issue +- Maintain confidentiality until the fix is released + +## Security Best Practices + +### For Users + +- Keep dependencies up to date +- Use the latest version of this project +- Review security advisories regularly +- Report vulnerabilities responsibly + +### For Contributors + +- Run `cargo audit` before submitting PRs +- Use `cargo deny` to check license compliance +- Follow secure coding practices +- Don't hardcode secrets or credentials +- Validate all external inputs + +## Dependency Security + +We use automated tools to monitor dependencies: + +- **cargo-audit**: Scans for known security vulnerabilities +- **cargo-deny**: Checks licenses and bans unsafe dependencies + +These run in CI on every push and PR. + +## Code Review + +All code changes go through review before merging: +- At least one maintainer review required +- Security implications considered +- Tests required for all changes +- CI checks must pass + +## Known Vulnerabilities + +We maintain transparency about known issues: +- Documented in GitHub security advisories +- Announced in release notes +- Tracked in issues with `security` label + +## Security Contact + +For security inquiries, please contact: +- Email: [project maintainers] +- Issue: Open a private security advisory on GitHub + +## Changelog + +Security fixes are highlighted in CHANGELOG.md with [SECURITY] prefix. + +## Resources + +- [OWASP Top 10](https://owasp.org/www-project-top-ten/) +- [CWE: Common Weakness Enumeration](https://cwe.mitre.org/) +- [Rust Security](https://www.rust-lang.org/governance/security-disclosures) +- [npm Security](https://docs.npmjs.com/about-npm/security) + +## Questions? + +If you have security questions (not vulnerabilities), open a discussion or issue with the `security` label. diff --git a/clippy.toml b/clippy.toml new file mode 100644 index 0000000..e946976 --- /dev/null +++ b/clippy.toml @@ -0,0 +1,46 @@ +# Generated by dev-system/ci +# Clippy configuration for Rust linting + +# Lint level thresholds +cognitive-complexity-threshold = 25 +type-complexity-threshold = 500 +excessive-nesting-threshold = 5 + +# Allowed patterns (prevent lints on specific code) +# allow-expect-in-tests = true +# allow-unwrap-in-tests = true + +# Single-letter lifetime parameters +single-char-lifetime-names-threshold = 4 + +# Lint configuration +[clippy] +# Additional lints to enable by default +enable = [] + +# Specific lint configurations +[lints] +# Warn on panics in tests (but allow expect) +"clippy::panic" = "warn" +# Warn on todo! and unimplemented! macros +"clippy::todo" = "warn" +# Warn on large copies +"clippy::large-include-file" = "warn" + +# These are good practices but not strict requirements +"clippy::missing-docs-in-crate-items" = "allow" +"clippy::missing-errors-doc" = "allow" + +# Performance lints +"clippy::perf" = "warn" +"clippy::single-match" = "warn" +"clippy::match-bool" = "warn" + +# Style lints +"clippy::style" = "warn" +"clippy::all" = "warn" + +# Pedantic is too strict for production code, so warn only on important ones +"clippy::pedantic" = "allow" +"clippy::match-wild-err-arm" = "warn" +"clippy::or-patterns" = "warn" diff --git a/deny.toml b/deny.toml new file mode 100644 index 0000000..a6a8652 --- /dev/null +++ b/deny.toml @@ -0,0 +1,74 @@ +# Generated by dev-system/ci +# Configuration for cargo-deny +# See: https://embarkstudios.github.io/cargo-deny/ + +[advisories] +# The path where the advisory database is cloned/fetched into +db-path = "~/.cargo/advisory-db" +# The url(s) of the advisory databases to use +db-urls = ["https://github.com/rustsec/advisory-db"] +# How to handle crates with security vulnerabilities +vulnerability = "deny" +# How to handle unmaintained crates +unmaintained = "warn" +# How to handle crates that have been yanked from crates.io +yanked = "warn" + +[licenses] +# The lint level for crates which do not have a detectable license +unlicensed = "deny" +# List of explicitly allowed licenses +allow = [ + "MIT", + "MIT-0", + "Apache-2.0", + "Apache-2.0 WITH LLVM-exception", + "BSD-2-Clause", + "BSD-3-Clause", + "ISC", + "Unicode-DFS-2016", +] +# List of explicitly disallowed licenses +deny = [ + "GPL-2.0", + "GPL-3.0", + "AGPL-3.0", +] +# Lint level for licenses considered copyleft +copyleft = "warn" +# Blanket approval or denial for OSI-approved or FSF Free/Libre licenses +allow-osi-fsf-free = "both" +# Lint level used when no other predicates are matched +default = "deny" + +[bans] +# Lint level for when multiple versions of the same crate are detected +multiple-versions = "warn" +# Lint level for when an allow-listed crate is detected without an exact version +allow = [ + # Each entry can be just the name and an optional wildcard version. + # This would ideally be pulled from Cargo.lock deps to keep up to date + # but that is more complex. It depends on the use case. +] +# Each entry must be a single version number +deny = [ + # Each entry is a crate name. Optionally with a version +] +# Certain crates/versions that will be skipped when doing duplicate detection +skip = [ + # { name = "ansi_term", version = "<= 0.11.0" } +] +# Similarly named crates that are allowed to coexist +skip-tree = [ + # { name = "windows", version = "<=0.46.0" } +] + +[sources] +# Lint level for what to happen when a crate from a crate registry that is not in the allow list is detected +unknown-registry = "deny" +# Lint level for what to happen when a crate from a Git repository that is not in the allow list is detected +unknown-git = "deny" +# The allow list of crate registries +allow-registry = ["https://github.com/rust-lang/crates.io-index"] +# The allow list of Git repositories +allow-git = [] diff --git a/justfile b/justfile index 26ebb4d..0784358 100644 --- a/justfile +++ b/justfile @@ -8,6 +8,7 @@ mod build "justfiles/build.just" # Build recipes (release, debug, features) mod test "justfiles/test.just" # Test suite (unit, integration) mod dev "justfiles/dev.just" # Development tools (fmt, lint, check) +mod ci "justfiles/ci.just" # CI/CD pipeline (validate, test, build) mod deploy "justfiles/deploy.just" # Deployment (Docker, K8s, Helm) mod vault "justfiles/vault.just" # Vault operations (init, unseal) @@ -278,4 +279,4 @@ help MODULE="": else \ echo "Unknown module: {{ MODULE }}"; \ echo "Available: build, test, dev, deploy, vault"; \ - fi + fi \ No newline at end of file diff --git a/justfiles/ci.just b/justfiles/ci.just new file mode 100644 index 0000000..b9eb20f --- /dev/null +++ b/justfiles/ci.just @@ -0,0 +1,227 @@ +# CI/CD Just Recipes +# Generated by dev-system/ci +# Provides `just` recipes for running CI checks locally + +# Show CI help +[doc("Show ci help")] +help: + @echo "CI/CD Just Recipes" + @echo "" + @echo "Main Commands:" + @echo " just ci-full - Run all CI checks" + @echo " just ci-fmt - Check Rust formatting" + @echo " just ci-fmt-toml - Check TOML formatting" + @echo " just fmt - Format Rust + TOML" + @echo " just fmt-toml - Format TOML files only" + @echo " just ci-lint - Run all linting checks" + @echo " just ci-test - Run all tests" + @echo " just ci-audit - Run security audits" + @echo "" + @echo "Language-Specific:" + @echo " just ci-lint-rust - Lint Rust (clippy)" + @echo " just ci-lint-toml - Lint TOML files (taplo)" + @echo " just ci-lint-nushell - Validate Nushell" + @echo " just ci-lint-nickel - Type check Nickel" + @echo " just ci-lint-bash - Lint Bash scripts" + @echo "" + @echo "Other:" + @echo " just ci-sbom - Generate SBOM" + @echo " just setup-hooks - Install pre-commit hooks" + @echo " just hooks-run-all - Run pre-commit on all files" + @echo " just clean - Clean build artifacts" +# Run all CI checks +ci-full: ci-fmt ci-fmt-toml ci-lint ci-test ci-audit + @echo "βœ… All CI checks passed!" + +# ============================================================================== +# Formatting Checks +# ============================================================================== + +# Check Rust code formatting +ci-fmt: + @echo "πŸ“ Checking Rust code formatting..." + cargo fmt --all -- --check + +# Check TOML file formatting +ci-fmt-toml: + @echo "πŸ“ Checking TOML formatting..." + @command -v taplo >/dev/null || (echo "❌ taplo not installed: cargo install taplo-cli"; exit 1) + taplo format --check + +# Format all code (Rust + TOML) +fmt: + @echo "🎨 Formatting code..." + cargo fmt --all + just fmt-toml + +# Format TOML files +fmt-toml: + @echo "🎨 Formatting TOML files..." + @command -v taplo >/dev/null || (echo "❌ taplo not installed: cargo install taplo-cli"; exit 1) + taplo format + +# ============================================================================== +# Linting +# ============================================================================== + +# Run all linting checks +ci-lint: ci-lint-rust ci-lint-toml ci-lint-nushell ci-lint-nickel ci-lint-bash + @echo "βœ… All lint checks passed!" + +# Lint Rust code +ci-lint-rust: + @echo "πŸ” Linting Rust (clippy)..." + cargo clippy --all-targets --all-features -- -D warnings + +# Lint TOML files +ci-lint-toml: + @echo "πŸ” Linting TOML files..." + @command -v taplo >/dev/null || (echo "❌ taplo not installed: cargo install taplo-cli"; exit 1) + taplo lint + +# Lint Nushell scripts +ci-lint-nushell: + #!/usr/bin/env bash + echo "πŸ” Validating Nushell scripts..." + SCRIPTS=$(find . -name "*.nu" -type f \ + ! -path "./target/*" \ + ! -path "./.git/*" \ + ! -path "./node_modules/*" \ + | head -20) + + if [ -z "$SCRIPTS" ]; then + echo " ℹ️ No Nushell scripts found" + exit 0 + fi + + for script in $SCRIPTS; do + echo " Checking: $script" + nu --ide-check 100 "$script" || exit 1 + done + echo " βœ“ All Nushell scripts valid" + +# Lint Nickel schemas +ci-lint-nickel: + #!/usr/bin/env bash + echo "πŸ” Type checking Nickel..." + SCHEMAS=$(find . -name "*.ncl" -type f \ + ! -path "./target/*" \ + ! -path "./.git/*" \ + ! -path "./node_modules/*" \ + | head -20) + + if [ -z "$SCHEMAS" ]; then + echo " ℹ️ No Nickel schemas found" + exit 0 + fi + + export NICKEL_IMPORT_PATH="/Users/Akasha/Tools/dev-system/ci/schemas:/Users/Akasha/Tools/dev-system/ci/validators:/Users/Akasha/Tools/dev-system/ci/defaults:." + + for schema in $SCHEMAS; do + echo " Checking: $schema" + nickel typecheck "$schema" || exit 1 + done + echo " βœ“ All Nickel schemas valid" + +# Lint Bash scripts +ci-lint-bash: + #!/usr/bin/env bash + echo "πŸ” Linting Bash scripts..." + SCRIPTS=$(find . -name "*.sh" -o -name "*.bash" \ + ! -path "./target/*" \ + ! -path "./.git/*" \ + ! -path "./node_modules/*" \ + | head -20) + + if [ -z "$SCRIPTS" ]; then + echo " ℹ️ No Bash scripts found" + exit 0 + fi + + for script in $SCRIPTS; do + echo " Checking: $script" + shellcheck "$script" || exit 1 + done + echo " βœ“ All Bash scripts valid" + +# ============================================================================== +# Testing +# ============================================================================== + +# Run all tests +ci-test: + @echo "πŸ§ͺ Running tests..." + cargo test --workspace --all-features + +# Run tests with coverage (requires cargo-llvm-cov) +ci-test-coverage: + @echo "πŸ“Š Running tests with coverage..." + cargo llvm-cov --all-features --lcov --output-path lcov.info + +# ============================================================================== +# Security Auditing +# ============================================================================== + +# Run all security audits +ci-audit: ci-audit-rust + @echo "βœ… All security audits passed!" + +# Audit Rust dependencies +ci-audit-rust: + @echo "πŸ”’ Auditing Rust dependencies..." + cargo audit + cargo deny check licenses + cargo deny check advisories + +# Generate SBOM +ci-sbom: + @echo "πŸ“¦ Generating Software Bill of Materials..." + cargo sbom > sbom.json + @echo "βœ“ SBOM generated: sbom.json" + +# ============================================================================== +# Documentation +# ============================================================================== + +# Generate documentation +docs: + @echo "πŸ“š Generating documentation..." + cargo doc --no-deps --open + +# Check documentation +ci-docs: + @echo "πŸ“š Checking documentation..." + cargo doc --no-deps --document-private-items 2>&1 | grep -i "warning:" && exit 1 || true + @echo "βœ“ Documentation check passed" + +# ============================================================================== +# Pre-commit Setup +# ============================================================================== + +# Install pre-commit hooks +setup-hooks: + @echo "πŸͺ Installing pre-commit hooks..." + @if command -v pre-commit &> /dev/null; then \ + pre-commit install && pre-commit install --hook-type pre-push; \ + echo "βœ“ Pre-commit hooks installed"; \ + else \ + echo "❌ pre-commit not found. Install with: pip install pre-commit"; \ + exit 1; \ + fi + +# Run pre-commit on all files +hooks-run-all: + @echo "πŸͺ Running pre-commit on all files..." + pre-commit run --all-files + +# ============================================================================== +# Utility Commands +# ============================================================================== + +# Clean build artifacts +clean: + @echo "🧹 Cleaning..." + cargo clean + rm -rf target/ + rm -f sbom.json lcov.info + diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..13e16e1 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,57 @@ +# Generated by dev-system/ci +# Rustfmt configuration for consistent Rust code formatting + +# Basic formatting options +edition = "2021" +max_width = 100 +hard_tabs = false +tab_spaces = 4 +newline_style = "Unix" + +# Comment formatting +comment_width = 80 +wrap_comments = true + +# Code structure +use_small_heuristics = "Default" + +# Spaces and indentation +fn_single_line = false +fn_args_layout = "Tall" +where_single_line = false + +# Match expressions +match_block_trailing_comma = false + +# Imports +reorder_imports = true +reorder_modules = true +remove_nested_parens = true +group_imports = "StdExternalCrate" + +# Chains +chain_width = 60 +chain_indent = "Block" + +# Formatting +format_strings = true +format_code_in_doc_comments = false +normalize_comments = true +normalize_doc_attributes = true + +# Line breaks +match_arm_blocks = true +overflow_delimited_expressions = false +blank_lines_lower_bound = 0 +blank_lines_upper_bound = 1 + +# Performance +condense_wildcard_imports = false + +# Spaces +space_before_colon = false +space_after_colon = true +spaces_around_ranges = false + +# Stability +unstable_features = false