ci: Preparing the repo to go public

This commit is contained in:
2025-09-11 17:19:52 -06:00
parent 1849e11063
commit ca990f460e
31 changed files with 1229 additions and 46 deletions
+4
View File
@@ -0,0 +1,4 @@
--artifact-server-path=./.act/artifacts
--cache-server-path=./.act/cache
--container-options --privileged
--env ACT=true
+13
View File
@@ -0,0 +1,13 @@
#!/bin/sh
set -e
echo "Running pre-push hook:"
echo "Executing: cargo fmt"
cargo fmt
echo "Executing: make lint"
make lint
echo "Executing: cargo test"
cargo test -- --skip prop_
+13
View File
@@ -0,0 +1,13 @@
#!/bin/sh
set -e
echo "Running pre-push hook:"
echo "Executing: cargo fmt --check"
cargo fmt --check
echo "Executing: make lint"
make lint
echo "Executing: cargo test"
cargo test -- --skip prop_
+10
View File
@@ -0,0 +1,10 @@
[tool.commitizen]
name = "cz_conventional_commits"
tag_format = "v$version"
version_scheme = "semver"
version_provider = "cargo"
update_changelog_on_bump = true
major_version_zero = true
[tool.commitizen.hooks]
pre-commit = "git add Cargo.toml Cargo.lock"
+1
View File
@@ -0,0 +1 @@
github: Dark-Alex-17
+4
View File
@@ -0,0 +1,4 @@
---
name: Blank Issue
about: Create a blank issue.
---
+69
View File
@@ -0,0 +1,69 @@
name: Bug Report
description: Create a report to help us improve
labels: bug
body:
- type: markdown
attributes:
value: Thank you for filing a bug report!
- type: textarea
id: problem
attributes:
label: Summary
description: >
Please provide a short summary of the bug, along with any information
you feel relevant to replicate the bug.
validations:
required: true
- type: textarea
id: reproduction-steps
attributes:
label: Reproduction Steps
value: |
I tried this:
1. `gman`
I expected this to happen:
Instead, this happened:
- type: textarea
id: gman-log
attributes:
label: G-Man log
description: Include the G-Man log file to help diagnose the issue.
value: |
| OS | Log file location |
| ------- | ----------------------------------------------------- |
| Linux | `~/.cache/gman/gman.log` |
| Mac | `~/Library/Logs/gman/gman.log` |
| Windows | `C:\Users\<User>\AppData\Local\gman\gman.log` |
```
please provide a copy of your gman log file here if possible, you may need to redact some of the lines
```
- type: input
id: platform
attributes:
label: Platform
placeholder: Linux / macOS / Windows
validations:
required: true
- type: input
id: terminal-emulator
attributes:
label: Terminal Emulator
placeholder: wezterm 20220101-133340-7edc5b5a
validations:
required: true
- type: input
id: gman-version
attributes:
label: G-Man Version
description: >
G-Man version (`gman --version` if using a release, `git describe` if building
from main).
**Make sure that you are using the [latest gman release](https://github.com/Dark-Alex-17/gman/releases) or a newer main build**
placeholder: "gman 0.1.0"
validations:
required: true
+13
View File
@@ -0,0 +1,13 @@
---
name: Enhancement
about: Suggest an improvement
title: ''
labels: enhancement
assignees: ''
---
<!--
Your enhancement may already be reported!
Please search on the issue tracker before creating a new issue.
If this is an idea for a feature, please open an "Idea" Discussion instead.
-->
+84
View File
@@ -0,0 +1,84 @@
on:
push:
branches:
- main
pull_request:
name: Check
env:
CARGO_TERM_COLOR: always
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
fmt:
name: stable / fmt
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- name: Run cargo fmt
run: cargo fmt -- --check
- name: Cache Cargo dependencies
uses: Swatinem/rust-cache@v2
clippy:
name: ${{ matrix.toolchain }} / clippy
runs-on: ubuntu-latest
permissions:
checks: write
strategy:
fail-fast: false
matrix:
toolchain: [stable, beta]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- name: Run clippy action
uses: clechasseur/rs-clippy-check@v3
- name: Cache Cargo dependencies
uses: Swatinem/rust-cache@v2
doc:
name: nightly / doc
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust nightly
uses: dtolnay/rust-toolchain@nightly
- name: Run cargo doc
run: cargo doc --no-deps --all-features
env:
RUSTDOCFLAGS: --cfg docsrs
msrv:
name: 1.89.0 / check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install 1.89.0
uses: dtolnay/rust-toolchain@master
with:
toolchain: 1.89.0
- name: cargo +1.89.0 check
run: cargo check
+548
View File
@@ -0,0 +1,548 @@
name: Create release
permissions:
pull-requests: write
contents: write
on:
workflow_dispatch:
inputs:
bump_type:
description: 'Specify the type of version bump'
required: true
default: 'patch'
type: choice
options:
- patch
- minor
- major
jobs:
bump-version:
name: bump-version
runs-on: ubuntu-latest
steps:
- name: Configure SSH for Git
if: env.ACT != 'true'
run: |
mkdir -p ~/.ssh
echo "${{ secrets.RELEASE_BOT_SSH_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
ssh-keyscan -H github.com >> ~/.ssh/known_hosts
- name: Checkout repository
if: env.ACT != 'true'
uses: actions/checkout@v3
with:
ssh-key: ${{ secrets.RELEASE_BOT_SSH_KEY }}
fetch-depth: 0
- name: Checkout repository
if: env.ACT == 'true'
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install Commitizen
run: |
python -m pip install --upgrade pip
pip install commitizen
npm install -g conventional-changelog-cli
- name: Configure Git user
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Bump version with Commitizen
run: |
cz bump --yes --increment ${{ github.event.inputs.bump_type }}
- name: Amend commit message to include '[skip ci]'
run: |
git commit --amend --no-edit -m "$(git log -1 --pretty=%B) [skip ci]"
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
- name: Get the new version tag
id: version
run: |
mkdir -p artifacts
NEW_TAG=$(cz version --project)
echo "New version: $NEW_TAG"
echo "version=$NEW_TAG" >> $GITHUB_ENV
echo "$NEW_TAG" > artifacts/release-version
- name: Get the previous version tag
id: prev_version
run: |
PREV_TAG=$(git describe --tags --abbrev=0 ${GITHUB_SHA}^)
echo "Previous tag: $PREV_TAG"
echo "prev_version=$PREV_TAG" >> $GITHUB_ENV
- name: Bump Cargo.toml version
shell: bash
working-directory: ${{ github.workspace }}
env:
VERSION: ${{ env.version }}
run: |
set -euo pipefail
: "${VERSION:?env.version is empty}"
# Ignore Act's local artifact dir noise
echo artifacts/ >> .git/info/exclude || true
# Edit the version line right after name="gman"
sed -E -i '
/^[[:space:]]*name[[:space:]]*=[[:space:]]*"gman"[[:space:]]*$/ {
n
s|^[[:space:]]*version[[:space:]]*=[[:space:]]*"[^"]*"|version = "'"$VERSION"'"|
}
' Cargo.toml
cargo update || true
# Git config that helps in Act
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git config --global --add safe.directory "$GITHUB_WORKSPACE"
git status --porcelain
git diff --name-only -- Cargo.toml Cargo.lock || true
if ! git diff --quiet -- Cargo.toml Cargo.lock; then
git add -u -- Cargo.toml Cargo.lock
git commit -m "chore: bump Cargo.toml to $VERSION"
else
echo "No changes to commit (already at $VERSION)"
fi
- name: Generate changelog for the version bump
id: changelog
run: |
changelog=$(conventional-changelog -p angular -i CHANGELOG.md -s --from ${{ env.prev_version }} --to ${{ env.version }})
echo "$changelog" > artifacts/changelog.md
echo "changelog_body=$(cat artifacts/changelog.md)" >> $GITHUB_ENV
- name: Push changes
if: env.ACT != 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git push origin --follow-tags
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
path: artifacts
- name: Upload the changed Cargo files (Act)
if: env.ACT == 'true'
uses: actions/upload-artifact@v4
with:
name: bumped-cargo-files
path: |
Cargo.toml
Cargo.lock
build-release-artifacts:
name: build-release
needs: [bump-version]
runs-on: ${{ matrix.job.os }}
env:
RUST_BACKTRACE: 1
strategy:
fail-fast: true
matrix:
# prettier-ignore
job:
- { name: "macOS-arm64", os: "macOS-latest", target: "aarch64-apple-darwin", artifact_suffix: "macos-arm64", use-cross: true }
- { name: "macOS-amd64", os: "macOS-latest", target: "x86_64-apple-darwin", artifact_suffix: "macos" }
- { name: "windows-amd64", os: "windows-latest", target: "x86_64-pc-windows-msvc", artifact_suffix: "windows" }
- { name: "windows-aarch64", os: "windows-latest", target: "aarch64-pc-windows-msvc", artifact_suffix: "windows-aarch64", use-cross: true }
- { name: "linux-gnu", os: "ubuntu-latest", target: "x86_64-unknown-linux-gnu", artifact_suffix: "linux" }
- { name: "linux-musl", os: "ubuntu-latest", target: "x86_64-unknown-linux-musl", artifact_suffix: "linux-musl", use-cross: true, }
- { name: "linux-aarch64-gnu", os: "ubuntu-latest", target: "aarch64-unknown-linux-gnu", artifact_suffix: "aarch64-gnu", use-cross: true, test-bin: "--bin gman" }
- { name: "linux-aarch64-musl", os: "ubuntu-latest", target: "aarch64-unknown-linux-musl", artifact_suffix: "aarch64-musl", use-cross: true, test-bin: "--bin gman" }
- { name: "linux-arm-gnu", os: "ubuntu-latest", target: "arm-unknown-linux-gnueabi", artifact_suffix: "armv6-gnu", use-cross: true, test-bin: "--bin gman" }
- { name: "linux-arm-musl", os: "ubuntu-latest", target: "arm-unknown-linux-musleabihf", artifact_suffix: "armv6-musl", use-cross: true, test-bin: "--bin gman" }
- { name: "linux-armv7-gnu", os: "ubuntu-latest", target: "armv7-unknown-linux-gnueabihf", artifact_suffix: "armv7-gnu", use-cross: true, test-bin: "--bin gman" }
- { name: "linux-armv7-musl", os: "ubuntu-latest", target: "armv7-unknown-linux-musleabihf", artifact_suffix: "armv7-musl", use-cross: true, test-bin: "--bin gman" }
rust: [stable]
steps:
- name: Check if actor is repository owner
if: ${{ github.actor != github.repository_owner && env.ACT != 'true' }}
run: |
echo "You are not authorized to run this workflow."
exit 1
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Ensure repository is up-to-date
if: env.ACT != 'true'
run: |
git fetch --all
git pull
- name: Get bumped Cargo files (Act)
if: env.ACT == 'true'
uses: actions/download-artifact@v4
with:
name: bumped-cargo-files
path: ${{ github.workspace }}
- uses: actions/cache@v3
name: Cache Cargo registry
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('Cargo.lock') }}
- uses: actions/cache@v3
if: startsWith(matrix.job.name, 'linux-')
with:
path: ~/.cargo/bin
key: ${{ runner.os }}-cargo-bin-${{ hashFiles('.github/workflows/release.yml') }}
- uses: dtolnay/rust-toolchain@stable
name: Set Rust toolchain
with:
targets: ${{ matrix.job.target }}
- uses: taiki-e/setup-cross-toolchain-action@v1
with:
# NB: sets CARGO_BUILD_TARGET evar - do not need --target flag in build
target: ${{ matrix.job.target }}
- uses: taiki-e/install-action@cross
if: ${{ matrix.job.use-cross }}
- name: Installing needed Ubuntu dependencies
if: matrix.job.os == 'ubuntu-latest'
shell: bash
run: |
sudo apt-get -y update
case ${{ matrix.job.target }} in
arm*-linux-*) sudo apt-get -y install gcc-arm-linux-gnueabihf ;;
aarch64-*-linux-*) sudo apt-get -y install gcc-aarch64-linux-gnu ;;
esac
- name: Build
run: cargo build --release --verbose --target=${{ matrix.job.target }} --locked
- name: Verify file
shell: bash
run: |
file target/${{ matrix.job.target }}/release/gman
- name: Test
if: matrix.job.target != 'aarch64-apple-darwin' && matrix.job.target != 'aarch64-pc-windows-msvc'
run: cargo test --release --verbose --target=${{ matrix.job.target }} ${{ matrix.job.test-bin }}
- name: Packaging final binary (Windows)
if: matrix.job.os == 'windows-latest'
shell: bash
run: |
cd target/${{ matrix.job.target }}/release
BINARY_NAME=gman.exe
if [ "${{ matrix.job.target }}" != "aarch64-pc-windows-msvc" ]; then
# strip the binary
strip $BINARY_NAME
fi
RELEASE_NAME=gman-${{ matrix.job.artifact_suffix }}
mkdir -p artifacts
tar czvf $RELEASE_NAME.tar.gz $BINARY_NAME
# create sha checksum files
certutil -hashfile $RELEASE_NAME.tar.gz sha256 | grep -E [A-Fa-f0-9]{64} > $RELEASE_NAME.sha256
echo "RELEASE_NAME=$RELEASE_NAME" >> $GITHUB_ENV
- name: Packaging final binary (macOS and Linux)
if: matrix.job.os != 'windows-latest'
shell: bash
run: |
# set the right strip executable
STRIP="strip";
case ${{ matrix.job.target }} in
arm*-linux-*) STRIP="arm-linux-gnueabihf-strip" ;;
aarch64-*-linux-*) STRIP="aarch64-linux-gnu-strip" ;;
esac;
cd target/${{ matrix.job.target }}/release
BINARY_NAME=gman
# strip the binary
"$STRIP" "$BINARY_NAME"
RELEASE_NAME=gman-${{ matrix.job.artifact_suffix }}
tar czvf $RELEASE_NAME.tar.gz $BINARY_NAME
# create sha checksum files
shasum -a 256 $RELEASE_NAME.tar.gz > $RELEASE_NAME.sha256
echo "RELEASE_NAME=$RELEASE_NAME" >> $GITHUB_ENV
- name: Add artifacts
run: |
mkdir -p artifacts
cp target/${{ matrix.job.target }}/release/${{ env.RELEASE_NAME }}.tar.gz artifacts/
cp target/${{ matrix.job.target }}/release/${{ env.RELEASE_NAME }}.sha256 artifacts/
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: artifacts-${{ env.RELEASE_NAME }}
path: artifacts
overwrite: true
publish-github-release:
name: publish-github-release
needs: [build-release-artifacts]
runs-on: ubuntu-latest
steps:
- name: Check if actor is repository owner
if: ${{ github.actor != github.repository_owner && env.ACT != 'true' }}
run: |
echo "You are not authorized to run this workflow."
exit 1
- name: Checkout repository
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
merge-multiple: true
- name: Ensure repository is up-to-date
if: env.ACT != 'true'
run: |
git fetch --all
git pull
- name: Set environment variables
run: |
release_version="$(cat ./artifacts/release-version)"
echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV
changelog_body="$(cat ./artifacts/changelog.md)"
echo "changelog_body=$(cat artifacts/changelog.md)" >> $GITHUB_ENV
- name: Validate release environment variables
run: |
echo "Release version: ${{ env.RELEASE_VERSION }}"
echo "Changelog body: ${{ env.changelog_body }}"
- name: Create a GitHub Release
if: env.ACT != 'true'
uses: softprops/action-gh-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
files: |
artifacts/gman-macos-arm64.tar.gz
artifacts/gman-macos-arm64.sha256
artifacts/gman-macos.tar.gz
artifacts/gman-macos.sha256
artifacts/gman-windows.tar.gz
artifacts/gman-windows.sha256
artifacts/gman-windows-aarch64.tar.gz
artifacts/gman-windows-aarch64.sha256
artifacts/gman-linux.tar.gz
artifacts/gman-linux.sha256
artifacts/gman-linux-musl.tar.gz
artifacts/gman-linux-musl.sha256
artifacts/gman-aarch64-gnu.tar.gz
artifacts/gman-aarch64-gnu.sha256
artifacts/gman-aarch64-musl.tar.gz
artifacts/gman-aarch64-musl.sha256
artifacts/gman-armv6-gnu.tar.gz
artifacts/gman-armv6-gnu.sha256
artifacts/gman-armv6-musl.tar.gz
artifacts/gman-armv6-musl.sha256
artifacts/gman-armv7-gnu.tar.gz
artifacts/gman-armv7-gnu.sha256
artifacts/gman-armv7-musl.tar.gz
artifacts/gman-armv7-musl.sha256
tag_name: v${{ env.RELEASE_VERSION }}
name: 'v${{ env.RELEASE_VERSION }}'
body: ${{ env.changelog_body }}
draft: false
prerelease: false
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
path: artifacts
overwrite: true
publish-chocolatey-package:
needs: [publish-github-release]
name: Publish Chocolatey Package
runs-on: windows-latest
steps:
- name: Check if actor is repository owner
if: ${{ github.actor != github.repository_owner && env.ACT != 'true' }}
run: |
echo "You are not authorized to run this workflow."
exit 1
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Get release artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
merge-multiple: true
- name: Set release assets and version
shell: pwsh
run: |
# Read the first column from the SHA256 file
$windows_sha = Get-Content ./artifacts/gman-windows.sha256 | ForEach-Object { $_.Split(' ')[0] }
Add-Content -Path $env:GITHUB_ENV -Value "WINDOWS_SHA=$windows_sha"
# Read the release version from the release-version file
$release_version = Get-Content ./artifacts/release-version
Add-Content -Path $env:GITHUB_ENV -Value "RELEASE_VERSION=$release_version"
- name: Validate release environment variables
run: |
echo "Release SHA windows: ${{ env.WINDOWS_SHA }}"
echo "Release version: ${{ env.RELEASE_VERSION }}"
- name: Package and Publish package to Chocolatey
if: env.ACT != 'true'
run: |
mkdir ./deployment/chocolatey/tools
# Run packaging script
python "./deployment/chocolatey/packager.py" ${{ env.RELEASE_VERSION }} "./deployment/chocolatey/gman.nuspec.template" "./deployment/chocolatey/gman.nuspec" ${{ env.WINDOWS_SHA }}
python "./deployment/chocolatey/packager.py" ${{ env.RELEASE_VERSION }} "./deployment/chocolatey/chocolateyinstall.ps1.template" "./deployment/chocolatey/tools/chocolateyinstall.ps1" ${{ env.WINDOWS_SHA }}
# Publish to Chocolatey
cd ./deployment/chocolatey
choco pack
echo y | choco install gman -dv -s .
$version = gman --version
$version = $version -replace " ", "."
choco push $version.nupkg -s https://push.chocolatey.org/ --api-key ${{ secrets.CHOCOLATEY_API_KEY }};
publish-homebrew-formula:
needs: [publish-github-release]
name: Update Homebrew formulas
runs-on: ubuntu-latest
steps:
- name: Check if actor is repository owner
if: ${{ github.actor != github.repository_owner && env.ACT != 'true' }}
run: |
echo "You are not authorized to run this workflow."
exit 1
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Get release artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
merge-multiple: true
- name: Set release assets and version
shell: bash
run: |
# Set environment variables
macos_sha="$(cat ./artifacts/gman-macos.sha256 | awk '{print $1}')"
echo "MACOS_SHA=$macos_sha" >> $GITHUB_ENV
macos_sha_arm="$(cat ./artifacts/gman-macos-arm64.sha256 | awk '{print $1}')"
echo "MACOS_SHA_ARM=$macos_sha_arm" >> $GITHUB_ENV
linux_sha="$(cat ./artifacts/gman-linux-musl.sha256 | awk '{print $1}')"
echo "LINUX_SHA=$linux_sha" >> $GITHUB_ENV
release_version="$(cat ./artifacts/release-version)"
echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV
- name: Validate release environment variables
run: |
echo "Release SHA macos: ${{ env.MACOS_SHA }}"
echo "Release SHA macos-arm: ${{ env.MACOS_SHA_ARM }}"
echo "Release SHA linux musl: ${{ env.LINUX_SHA }}"
echo "Release version: ${{ env.RELEASE_VERSION }}"
- name: Execute Homebrew packaging script
if: env.ACT != 'true'
run: |
# run packaging script
python "./deployment/homebrew/packager.py" ${{ env.RELEASE_VERSION }} "./deployment/homebrew/gman.rb.template" "./gman.rb" ${{ env.MACOS_SHA }} ${{ env.MACOS_SHA_ARM }} ${{ env.LINUX_SHA }}
- name: Push changes to Homebrew tap
if: env.ACT != 'true'
env:
TOKEN: ${{ secrets.GMAN_GITHUB_TOKEN }}
run: |
# push to Git
git config --global user.name "Dark-Alex-17"
git config --global user.email "alex.j.tusa@gmail.com"
git clone https://Dark-Alex-17:${{ secrets.GMAN_GITHUB_TOKEN }}@github.com/Dark-Alex-17/homebrew-gman.git
rm homebrew-gman/Formula/gman.rb
cp gman.rb homebrew-gman/Formula
cd homebrew-gman
git add .
git diff-index --quiet HEAD || git commit -am "Update formula for G-Man release ${{ env.RELEASE_VERSION }}"
git push https://$TOKEN@github.com/Dark-Alex-17/homebrew-gman.git
publish-crate:
needs: publish-github-release
name: Publish Crate
runs-on: ubuntu-latest
steps:
- name: Check if actor is repository owner
if: ${{ github.actor != github.repository_owner && env.ACT != 'true' }}
run: |
echo "You are not authorized to run this workflow."
exit 1
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get bumped Cargo files (Act)
if: env.ACT == 'true'
uses: actions/download-artifact@v4
with:
name: bumped-cargo-files
path: ${{ github.workspace }}
- name: Ensure repository is up-to-date
if: env.ACT != 'true'
run: |
git fetch --all
git pull
- uses: actions/cache@v3
name: Cache Cargo registry
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('Cargo.lock') }}
- uses: actions/cache@v3
with:
path: ~/.cargo/bin
key: ${{ runner.os }}-cargo-bin-${{ hashFiles('.github/workflows/release.yml') }}
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
- uses: katyo/publish-crates@v2
if: env.ACT != 'true'
with:
registry-token: ${{ secrets.CARGO_REGISTRY_TOKEN }}
+100
View File
@@ -0,0 +1,100 @@
on:
push:
branches:
- main
pull_request:
name: Test Suite
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
required:
runs-on: ubuntu-latest
name: ubuntu / ${{ matrix.toolchain }}
strategy:
fail-fast: false
matrix:
toolchain: [stable, beta]
steps:
- uses: actions/checkout@v4
- name: Install ${{ matrix.toolchain }}
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ matrix.toolchain }}
- name: cargo generate-lockfile
if: hashFiles('Cargo.lock') == ''
run: cargo generate-lockfile
- name: cargo test --locked
run: cargo test --locked --all-features --all-targets
os-check:
runs-on: ${{ matrix.os }}
name: ${{ matrix.os }} / stable
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest]
steps:
# if your project needs OpenSSL, uncomment this to fix Windows builds.
# it's commented out by default as the install command takes 5-10m.
# - run: echo "VCPKG_ROOT=$env:VCPKG_INSTALLATION_ROOT" | Out-File -FilePath $env:GITHUB_ENV -Append
# if: runner.os == 'Windows'
# - run: vcpkg install openssl:x64-windows-static-md
# if: runner.os == 'Windows'
- name: Checkout
uses: actions/checkout@v4
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
- name: cargo generate-lockfile
if: hashFiles('Cargo.lock') == ''
run: cargo generate-lockfile
- name: cargo test
run: cargo test --locked --all-features --all-targets
- name: Cache Cargo dependencies
uses: Swatinem/rust-cache@v2
coverage:
runs-on: ubuntu-latest
name: ubuntu / stable / coverage
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
with:
components: llvm-tools-preview
- name: cargo install cargo-llvm-cov
uses: taiki-e/install-action@cargo-llvm-cov
- name: cargo generate-lockfile
if: hashFiles('Cargo.lock') == ''
run: cargo generate-lockfile
- name: cargo llvm-cov
run: cargo llvm-cov --locked --all-features --lcov --output-path lcov.info
- name: Record Rust version
run: echo "RUST=$(rustc --version)" >> "$GITHUB_ENV"
- name: Cache Cargo dependencies
uses: Swatinem/rust-cache@v2
- name: Upload to codecov.io
if: env.ACT != 'true'
uses: codecov/codecov-action@v4
with:
fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }}
env_vars: OS,RUST
+8
View File
@@ -0,0 +1,8 @@
repos:
- hooks:
- id: commitizen
- id: commitizen-branch
stages:
- pre-push
repo: https://github.com/commitizen-tools/commitizen
rev: v3.30.0
+128
View File
@@ -0,0 +1,128 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
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, socio-economic status,
nationality, personal appearance, race, religion, or 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 our mistakes,
and learning from the experience
* 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, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
d4udts@gmail.com.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.
+80
View File
@@ -0,0 +1,80 @@
# Contributing
Contributors are very welcome! **No contribution is too small and all contributions are valued.**
## Rust
You'll need to have the stable Rust toolchain installed in order to develop GMan.
The Rust toolchain (stable) can be installed via rustup using the following command:
```shell
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```
This will install `rustup`, `rustc` and `cargo`. For more information, refer to the [official Rust installation documentation](https://www.rust-lang.org/tools/install).
## Commitizen
[Commitizen](https://github.com/commitizen-tools/commitizen?tab=readme-ov-file) is a nifty tool that helps us write better commit messages. It ensures that our
commits have a consistent style and makes it easier to generate CHANGELOGS. Additionally,
Commitizen is used to run pre-commit checks to enforce style constraints.
To install `commitizen` and the `pre-commit` prerequisite, run the following command:
```shell
python3 -m pip install commitizen pre-commit
```
### Commitizen Quick Guide
To see an example commit to get an idea for the Commitizen style, run:
```shell
cz example
```
To see the allowed types of commits and their descriptions, run:
```shell
cz info
```
If you'd like to create a commit using Commitizen with an interactive prompt to help you get
comfortable with the style, use:
```shell
cz commit
```
## Setup workspace
1. Clone this repo
2. Run `cargo test` to set up hooks
3. Make changes
4. Run the application using `make run` or `cargo run`
5. Commit changes. This will trigger pre-commit hooks that will run format, test and lint. If there are errors or
warnings from Clippy, please fix them.
6. Push your code to a new branch named after the feature/bug/etc. you're adding. This will trigger pre-push hooks that
will run lint and test.
7. Create a PR
### CI/CD Testing with Act
If you also are planning on testing out your changes before pushing them with [Act](https://github.com/nektos/act), you will need to set up `act`,
`docker`, and configure your local system to run different architectures:
1. Install `docker` by following the instructions on the [official Docker installation page](https://docs.docker.com/get-docker/).
2. Install `act` by following the instructions on the [official Act installation page](https://nektosact.com/installation/index.html).
3. Install `binfmt` on your system once so that `act` can run the correct architecture for the CI/CD workflows.
You can do this by running:
```shell
sudo docker run --rm --privileged tonistiigi/binfmt --install all
```
Then, you can run workflows locally without having to commit and see if the GitHub action passes or fails.
**For example**: To test the [release.yml](.github/workflows/release.yml) workflow locally, you can run:
```shell
act -W .github/workflows/release.yml --input_type bump=minor
```
## Questions? Reach out to me!
If you encounter any questions while developing G-Man, please don't hesitate to reach out to me at
alex.j.tusa@gmail.com. I'm happy to help contributors in any way I can, regardless of if they're new or experienced!
Generated
+7
View File
@@ -224,6 +224,12 @@ version = "3.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
[[package]]
name = "cargo-husky"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b02b629252fe8ef6460461409564e2c21d0c8e77e0944f3d189ff06c4e932ad"
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.2.36" version = "1.2.36"
@@ -708,6 +714,7 @@ dependencies = [
"assert_cmd", "assert_cmd",
"backtrace", "backtrace",
"base64", "base64",
"cargo-husky",
"chacha20poly1305", "chacha20poly1305",
"chrono", "chrono",
"clap", "clap",
+2
View File
@@ -48,6 +48,8 @@ tempfile = "3.10.1"
proptest = "1.5.0" proptest = "1.5.0"
assert_cmd = "2.0.16" assert_cmd = "2.0.16"
predicates = "3.1.2" predicates = "3.1.2"
cargo-husky = { version = "1.5.0", default-features = false, features = ["user-hooks"] }
[[bin]] [[bin]]
bench = false bench = false
+40
View File
@@ -0,0 +1,40 @@
#!make
default: run
.PHONY: test test-cov build run lint lint-fix fmt minimal-versions analyze release delete-tag
test:
@cargo test --all
## Run all tests with coverage - `cargo install cargo-tarpaulin`
test-cov:
@cargo tarpaulin
build: test
@cargo build --release
run:
@CARGO_INCREMENTAL=1 cargo fmt && make lint && cargo run
lint:
@find . | grep '\.\/src\/.*\.rs$$' | xargs touch && CARGO_INCREMENTAL=0 cargo clippy --all-targets --workspace
lint-fix:
@cargo fix
fmt:
@cargo fmt
minimal-versions:
@cargo +nightly update -Zdirect-minimal-versions
## Analyze for unsafe usage - `cargo install cargo-geiger`
analyze:
@cargo geiger
release:
@git tag -a ${V} -m "Release ${V}" && git push origin ${V}
delete-tag:
@git tag -d ${V} && git push --delete origin ${V}
+9 -1
View File
@@ -1,4 +1,12 @@
# gman - Universal Credential Manager # G-Man - Universal Credential Manager
![Check](https://github.com/Dark-Alex-17/gman/actions/workflows/check.yml/badge.svg)
![Test](https://github.com/Dark-Alex-17/gman/actions/workflows/test.yml/badge.svg)
![LOC](https://tokei.rs/b1/github/Dark-Alex-17/gman?category=code)
[![crates.io link](https://img.shields.io/crates/v/gman.svg)](https://crates.io/crates/gman)
![Release](https://img.shields.io/github/v/release/Dark-Alex-17/gman?color=%23c694ff)
![Crate.io downloads](https://img.shields.io/crates/d/gman?label=Crate%20downloads)
[![GitHub Downloads](https://img.shields.io/github/downloads/Dark-Alex-17/gman/total.svg?label=GitHub%20downloads)](https://github.com/Dark-Alex-17/gman/releases)
`gman` is a command-line tool for managing and injecting secrets for your scripts, automations, and applications. `gman` is a command-line tool for managing and injecting secrets for your scripts, automations, and applications.
It provides a single, secure interface to store, retrieve, and inject secrets so you can stop hand-rolling config It provides a single, secure interface to store, retrieve, and inject secrets so you can stop hand-rolling config
+15
View File
@@ -0,0 +1,15 @@
# Security Policy
## Supported Versions
Only latest version of the software will be supported with security patches.
| Version | Supported |
| -------- | ------------------ |
| latest | :white_check_mark: |
## Reporting a Vulnerability
If you find a vulnerability, please reach out to me via email (alex.j.tusa@gmail.com).
If you yourself decide you'd like to tackle a fix, please submit a PR with the fix and I'll review it as soon as
possible.
+14
View File
@@ -0,0 +1,14 @@
coverage:
status:
project:
default:
target: auto
threshold: 0.5%
base: auto
patch:
default:
target: 80%
threshold: 0%
ignore:
- "target/**"
- "tests/**"
+6
View File
@@ -0,0 +1,6 @@
{
"name": "gman",
"lockfileVersion": 3,
"requires": true,
"packages": {}
}
+1
View File
@@ -0,0 +1 @@
{}
+1 -1
View File
@@ -1,5 +1,5 @@
use crate::command::preview_command; use crate::command::preview_command;
use anyhow::{anyhow, Context, Result}; use anyhow::{Context, Result, anyhow};
use gman::config::{Config, ProviderConfig, RunConfig}; use gman::config::{Config, ProviderConfig, RunConfig};
use gman::providers::SecretProvider; use gman::providers::SecretProvider;
use heck::ToSnakeCase; use heck::ToSnakeCase;
+2 -2
View File
@@ -1,12 +1,12 @@
use clap::{ use clap::{
crate_authors, crate_description, crate_name, crate_version, CommandFactory, Parser, ValueEnum, CommandFactory, Parser, ValueEnum, crate_authors, crate_description, crate_name, crate_version,
}; };
use std::ffi::OsString; use std::ffi::OsString;
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use clap::Subcommand; use clap::Subcommand;
use crossterm::execute; use crossterm::execute;
use crossterm::terminal::{disable_raw_mode, LeaveAlternateScreen}; use crossterm::terminal::{LeaveAlternateScreen, disable_raw_mode};
use gman::config::load_config; use gman::config::load_config;
use heck::ToSnakeCase; use heck::ToSnakeCase;
use std::io::{self, IsTerminal, Read, Write}; use std::io::{self, IsTerminal, Read, Write};
+18 -14
View File
@@ -25,7 +25,7 @@ use anyhow::Result;
use log::debug; use log::debug;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_with::serde_as; use serde_with::serde_as;
use serde_with::{skip_serializing_none, DisplayFromStr}; use serde_with::{DisplayFromStr, skip_serializing_none};
use std::borrow::Cow; use std::borrow::Cow;
use std::path::PathBuf; use std::path::PathBuf;
use validator::{Validate, ValidationError}; use validator::{Validate, ValidationError};
@@ -188,19 +188,23 @@ pub struct Config {
} }
fn default_provider_exists(config: &Config) -> Result<(), ValidationError> { fn default_provider_exists(config: &Config) -> Result<(), ValidationError> {
if let Some(default) = &config.default_provider { if let Some(default) = &config.default_provider {
if config.providers.iter().any(|p| p.name.as_deref() == Some(default)) { if config
Ok(()) .providers
} else { .iter()
let mut err = ValidationError::new("default_provider_missing"); .any(|p| p.name.as_deref() == Some(default))
err.message = Some(Cow::Borrowed( {
"The default_provider does not match any configured provider names", Ok(())
)); } else {
Err(err) let mut err = ValidationError::new("default_provider_missing");
} err.message = Some(Cow::Borrowed(
} else { "The default_provider does not match any configured provider names",
Ok(()) ));
} Err(err)
}
} else {
Ok(())
}
} }
impl Default for Config { impl Default for Config {
+4 -4
View File
@@ -20,15 +20,15 @@
//! The `config` and `providers` modules power the CLI. They can be embedded //! The `config` and `providers` modules power the CLI. They can be embedded
//! in other programs, but many functions interact with the user or the //! in other programs, but many functions interact with the user or the
//! filesystem. Prefer `no_run` doctests for those. //! filesystem. Prefer `no_run` doctests for those.
use anyhow::{anyhow, bail, Context, Result}; use anyhow::{Context, Result, anyhow, bail};
use argon2::{ use argon2::{
password_hash::{rand_core::RngCore, SaltString},
Algorithm, Argon2, Params, Version, Algorithm, Argon2, Params, Version,
password_hash::{SaltString, rand_core::RngCore},
}; };
use base64::{engine::general_purpose::STANDARD as B64, Engine as _}; use base64::{Engine as _, engine::general_purpose::STANDARD as B64};
use chacha20poly1305::{ use chacha20poly1305::{
aead::{Aead, KeyInit, OsRng},
Key, XChaCha20Poly1305, XNonce, Key, XChaCha20Poly1305, XNonce,
aead::{Aead, KeyInit, OsRng},
}; };
use secrecy::{ExposeSecret, SecretString}; use secrecy::{ExposeSecret, SecretString};
use zeroize::Zeroize; use zeroize::Zeroize;
+24 -13
View File
@@ -4,9 +4,9 @@ use dialoguer::Confirm;
use dialoguer::theme::ColorfulTheme; use dialoguer::theme::ColorfulTheme;
use indoc::formatdoc; use indoc::formatdoc;
use log::debug; use log::debug;
use std::{env, fs};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::process::{Command, Stdio}; use std::process::{Command, Stdio};
use std::{env, fs};
use validator::Validate; use validator::Validate;
#[derive(Debug, Validate, Clone)] #[derive(Debug, Validate, Clone)]
@@ -41,11 +41,17 @@ pub fn sync_and_push(opts: &SyncOpts<'_>) -> Result<()> {
.with_context(|| "get default vault path")?; .with_context(|| "get default vault path")?;
let repo_vault = repo_dir.join("vault.yml"); let repo_vault = repo_dir.join("vault.yml");
if default_vault.exists() && !repo_vault.exists() { if default_vault.exists() && !repo_vault.exists() {
fs::rename(&default_vault, &repo_vault) fs::rename(&default_vault, &repo_vault).with_context(|| {
.with_context(|| format!("move {} -> {}", default_vault.display(), repo_vault.display()))?; format!(
"move {} -> {}",
default_vault.display(),
repo_vault.display()
)
})?;
} else if !repo_vault.exists() { } else if !repo_vault.exists() {
// Ensure an empty vault exists to allow initial commits // Ensure an empty vault exists to allow initial commits
fs::write(&repo_vault, "{}\n").with_context(|| format!("create {}", repo_vault.display()))?; fs::write(&repo_vault, "{}\n")
.with_context(|| format!("create {}", repo_vault.display()))?;
} }
let git = resolve_git(opts.git_executable.as_ref())?; let git = resolve_git(opts.git_executable.as_ref())?;
@@ -265,19 +271,16 @@ fn fetch_and_pull(git: &Path, repo: &Path, branch: &str) -> Result<()> {
.with_context(|| "Failed to checkout remote branch over local state")?; .with_context(|| "Failed to checkout remote branch over local state")?;
run_git(git, repo, &["reset", "--hard", &origin_ref]) run_git(git, repo, &["reset", "--hard", &origin_ref])
.with_context(|| "Failed to hard reset to remote branch")?; .with_context(|| "Failed to hard reset to remote branch")?;
run_git(git, repo, &["clean", "-fd"]).with_context(|| "Failed to clean untracked files")?; run_git(git, repo, &["clean", "-fd"])
.with_context(|| "Failed to clean untracked files")?;
} }
return Ok(()); return Ok(());
} }
// If we have local history and the remote branch exists, fast-forward. // If we have local history and the remote branch exists, fast-forward.
if remote_has_branch { if remote_has_branch {
run_git( run_git(git, repo, &["merge", "--ff-only", &origin_ref])
git, .with_context(|| "Failed to merge remote changes")?;
repo,
&["merge", "--ff-only", &origin_ref],
)
.with_context(|| "Failed to merge remote changes")?;
} }
Ok(()) Ok(())
} }
@@ -286,7 +289,12 @@ fn has_remote_branch(git: &Path, repo: &Path, branch: &str) -> bool {
Command::new(git) Command::new(git)
.arg("-C") .arg("-C")
.arg(repo) .arg(repo)
.args(["show-ref", "--verify", "--quiet", &format!("refs/remotes/origin/{}", branch)]) .args([
"show-ref",
"--verify",
"--quiet",
&format!("refs/remotes/origin/{}", branch),
])
.stdout(Stdio::null()) .stdout(Stdio::null())
.stderr(Stdio::null()) .stderr(Stdio::null())
.status() .status()
@@ -399,7 +407,10 @@ mod tests {
#[test] #[test]
fn test_repo_name_from_url() { fn test_repo_name_from_url() {
assert_eq!(repo_name_from_url("git@github.com:user/vault.git"), "vault"); assert_eq!(repo_name_from_url("git@github.com:user/vault.git"), "vault");
assert_eq!(repo_name_from_url("https://github.com/user/test-vault.git"), "test-vault"); assert_eq!(
repo_name_from_url("https://github.com/user/test-vault.git"),
"test-vault"
);
assert_eq!(repo_name_from_url("ssh://git@example.com/x/y/z.git"), "z"); assert_eq!(repo_name_from_url("ssh://git@example.com/x/y/z.git"), "z");
assert_eq!(repo_name_from_url("git@example.com:ns/repo"), "repo"); assert_eq!(repo_name_from_url("git@example.com:ns/repo"), "repo");
} }
+5 -5
View File
@@ -1,4 +1,4 @@
use anyhow::{anyhow, bail, Context}; use anyhow::{Context, anyhow, bail};
use secrecy::{ExposeSecret, SecretString}; use secrecy::{ExposeSecret, SecretString};
use std::collections::HashMap; use std::collections::HashMap;
use std::fs; use std::fs;
@@ -6,20 +6,20 @@ use std::path::{Path, PathBuf};
use zeroize::Zeroize; use zeroize::Zeroize;
use crate::config::ProviderConfig; use crate::config::ProviderConfig;
use crate::providers::git_sync::{repo_name_from_url, sync_and_push, SyncOpts};
use crate::providers::SecretProvider; use crate::providers::SecretProvider;
use crate::providers::git_sync::{SyncOpts, repo_name_from_url, sync_and_push};
use crate::{ use crate::{
ARGON_M_COST_KIB, ARGON_P, ARGON_T_COST, HEADER, KDF, KEY_LEN, NONCE_LEN, SALT_LEN, VERSION, ARGON_M_COST_KIB, ARGON_P, ARGON_T_COST, HEADER, KDF, KEY_LEN, NONCE_LEN, SALT_LEN, VERSION,
}; };
use anyhow::Result; use anyhow::Result;
use argon2::{Algorithm, Argon2, Params, Version}; use argon2::{Algorithm, Argon2, Params, Version};
use base64::{engine::general_purpose::STANDARD as B64, Engine as _}; use base64::{Engine as _, engine::general_purpose::STANDARD as B64};
use chacha20poly1305::aead::rand_core::RngCore; use chacha20poly1305::aead::rand_core::RngCore;
use chacha20poly1305::{ use chacha20poly1305::{
aead::{Aead, KeyInit, OsRng},
Key, XChaCha20Poly1305, XNonce, Key, XChaCha20Poly1305, XNonce,
aead::{Aead, KeyInit, OsRng},
}; };
use dialoguer::{theme, Input}; use dialoguer::{Input, theme};
use log::{debug, error}; use log::{debug, error};
use serde::Deserialize; use serde::Deserialize;
use theme::ColorfulTheme; use theme::ColorfulTheme;
+1 -1
View File
@@ -16,7 +16,7 @@ pub mod local;
use crate::config::ProviderConfig; use crate::config::ProviderConfig;
use crate::providers::local::LocalProvider; use crate::providers::local::LocalProvider;
use anyhow::{anyhow, Result}; use anyhow::{Result, anyhow};
use serde::Deserialize; use serde::Deserialize;
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
use std::str::FromStr; use std::str::FromStr;
+2 -2
View File
@@ -1,4 +1,4 @@
mod config_tests;
mod providers;
mod bin; mod bin;
mod config_tests;
mod prop_crypto; mod prop_crypto;
mod providers;