From 6c49c253baae45f9c3f19fb8dfeb518e0e34fdda Mon Sep 17 00:00:00 2001 From: Tyler Cook <10459406+cilki@users.noreply.github.com> Date: Sat, 4 May 2024 09:19:38 -0500 Subject: [PATCH] chore: rename crate --- .github/workflows/check.yml | 119 +++++++++++++++++++++++++ .github/workflows/release.yml | 46 ++++++++++ .github/workflows/test.yml | 163 ++++++++++++++++++++++++++++++++++ Cargo.lock | 45 ++-------- Cargo.toml | 9 +- src/lib.rs | 11 +++ src/main.rs | 36 +++++--- 7 files changed, 372 insertions(+), 57 deletions(-) create mode 100644 .github/workflows/check.yml create mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 0000000..10c7c05 --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,119 @@ +# This workflow runs whenever a PR is opened or updated, or a commit is pushed to main. It runs +# several checks: +# - fmt: checks that the code is formatted according to rustfmt +# - clippy: checks that the code does not contain any clippy warnings +# - doc: checks that the code can be documented without errors +# - hack: check combinations of feature flags +# - msrv: check that the msrv specified in the crate is correct +name: check +permissions: + contents: read +# This configuration allows maintainers of this repo to create a branch and pull request based on +# the new branch. Restricting the push trigger to the main branch ensures that the PR only gets +# built once. +on: + push: + branches: [master] + pull_request: +# If new code is pushed to a PR branch, then cancel in progress workflows for that PR. Ensures that +# we don't waste CI time, and returns results quicker https://github.com/jonhoo/rust-ci-conf/pull/5 +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true +jobs: + fmt: + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, 'chore: release')" + name: stable / fmt + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Install stable + uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt + - name: cargo fmt --check + run: cargo fmt --check + clippy: + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, 'chore: release')" + name: ${{ matrix.toolchain }} / clippy + permissions: + contents: read + checks: write + strategy: + fail-fast: false + matrix: + # Get early warning of new lints which are regularly introduced in beta channels. + toolchain: [stable, beta] + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Install ${{ matrix.toolchain }} + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.toolchain }} + components: clippy + - name: cargo clippy + uses: giraffate/clippy-action@v1 + with: + reporter: 'github-pr-check' + github_token: ${{ secrets.GITHUB_TOKEN }} + doc: + # run docs generation on nightly rather than stable. This enables features like + # https://doc.rust-lang.org/beta/unstable-book/language-features/doc-cfg.html which allows an + # API be documented as only available in some specific platforms. + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, 'chore: release')" + name: nightly / doc + steps: + - run: sudo apt-get install -y libpango-1.0-0 + - uses: actions/checkout@v4 + with: + submodules: true + - name: Install nightly + uses: dtolnay/rust-toolchain@nightly + - name: cargo doc + run: cargo doc --no-deps --all-features + env: + RUSTDOCFLAGS: --cfg docsrs + hack: + # cargo-hack checks combinations of feature flags to ensure that features are all additive + # which is required for feature unification + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, 'chore: release')" + name: ubuntu / stable / features + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Install stable + uses: dtolnay/rust-toolchain@stable + - name: cargo install cargo-hack + uses: taiki-e/install-action@cargo-hack + # intentionally no target specifier; see https://github.com/jonhoo/rust-ci-conf/pull/4 + # --feature-powerset runs for every combination of features + - name: cargo hack + run: cargo hack --feature-powerset check + msrv: + # check that we can build using the minimal rust version that is specified by this crate + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, 'chore: release')" + # we use a matrix here just because env can't be used in job names + # https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability + strategy: + matrix: + msrv: ["1.74.0"] + name: ubuntu / ${{ matrix.msrv }} + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Install ${{ matrix.msrv }} + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.msrv }} + - name: cargo +${{ matrix.msrv }} check + run: cargo check diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..e210a4c --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,46 @@ +name: release +permissions: + pull-requests: write + contents: write +on: + push: + branches: + - master + +jobs: + release-pr: + name: Release PR + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, 'chore: release')" + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + - name: Run release-plz + uses: MarcoIeni/release-plz-action@v0.5 + with: + command: release-pr + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + release: + name: Release + runs-on: ubuntu-latest + if: "contains(github.event.head_commit.message, 'chore: release')" + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + - name: Run release-plz + uses: MarcoIeni/release-plz-action@v0.5 + with: + command: release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..9e91187 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,163 @@ +# This is the main CI workflow that runs the test suite on all pushes to main and all pull requests. +# It runs the following jobs: +# - required: runs the test suite on ubuntu with stable and beta rust toolchains +# - minimal: runs the test suite with the minimal versions of the dependencies that satisfy the +# requirements of this crate, and its dependencies +# - os-check: runs the test suite on mac and windows +# - coverage: runs the test suite and collects coverage information +# See check.yml for information about how the concurrency cancellation and workflow triggering works +name: test +permissions: + contents: read +on: + push: + branches: [master] + pull_request: +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true +jobs: + required: + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, 'chore: release')" + name: ubuntu / ${{ matrix.toolchain }} + strategy: + matrix: + # run on stable and beta to ensure that tests won't break on the next version of the rust + # toolchain + toolchain: [stable, beta] + steps: + - run: sudo apt-get install -y libpango-1.0-0 + - uses: actions/checkout@v4 + with: + submodules: true + - name: Install ${{ matrix.toolchain }} + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.toolchain }} + - name: cargo generate-lockfile + # enable this ci template to run regardless of whether the lockfile is checked in or not + if: hashFiles('Cargo.lock') == '' + run: cargo generate-lockfile + # https://twitter.com/jonhoo/status/1571290371124260865 + - name: cargo test --locked + run: cargo test --locked --all-features --all-targets + # https://github.com/rust-lang/cargo/issues/6669 + - name: cargo test --doc + run: cargo test --locked --all-features --doc + minimal: + # This action chooses the oldest version of the dependencies permitted by Cargo.toml to ensure + # that this crate is compatible with the minimal version that this crate and its dependencies + # require. This will pickup issues where this create relies on functionality that was introduced + # later than the actual version specified (e.g., when we choose just a major version, but a + # method was added after this version). + # + # This particular check can be difficult to get to succeed as often transitive dependencies may + # be incorrectly specified (e.g., a dependency specifies 1.0 but really requires 1.1.5). There + # is an alternative flag available -Zdirect-minimal-versions that uses the minimal versions for + # direct dependencies of this crate, while selecting the maximal versions for the transitive + # dependencies. Alternatively, you can add a line in your Cargo.toml to artificially increase + # the minimal dependency, which you do with e.g.: + # ```toml + # # for minimal-versions + # [target.'cfg(any())'.dependencies] + # openssl = { version = "0.10.55", optional = true } # needed to allow foo to build with -Zminimal-versions + # ``` + # The optional = true is necessary in case that dependency isn't otherwise transitively required + # by your library, and the target bit is so that this dependency edge never actually affects + # Cargo build order. See also + # https://github.com/jonhoo/fantoccini/blob/fde336472b712bc7ebf5b4e772023a7ba71b2262/Cargo.toml#L47-L49. + # This action is run on ubuntu with the stable toolchain, as it is not expected to fail + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, 'chore: release')" + name: ubuntu / stable / minimal-versions + steps: + - run: sudo apt-get install -y libpango-1.0-0 + - uses: actions/checkout@v4 + with: + submodules: true + - name: Install stable + uses: dtolnay/rust-toolchain@stable + - name: Install nightly for -Zminimal-versions + uses: dtolnay/rust-toolchain@nightly + - name: rustup default stable + run: rustup default stable + - name: cargo update -Zminimal-versions + run: cargo +nightly update -Zminimal-versions + - name: cargo test + run: cargo test --locked --all-features --all-targets + os-check: + # run cargo test on mac and windows + runs-on: ${{ matrix.os }} + if: "!contains(github.event.head_commit.message, 'chore: release')" + 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' + - uses: actions/checkout@v4 + with: + submodules: true + - name: Install 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 + coverage: + # use llvm-cov to build and collect coverage and outputs in a format that + # is compatible with codecov.io + # + # note that codecov as of v4 requires that CODECOV_TOKEN from + # + # https://app.codecov.io/gh///settings + # + # is set in two places on your repo: + # + # - https://github.com/jonhoo/guardian/settings/secrets/actions + # - https://github.com/jonhoo/guardian/settings/secrets/dependabot + # + # (the former is needed for codecov uploads to work with Dependabot PRs) + # + # PRs coming from forks of your repo will not have access to the token, but + # for those, codecov allows uploading coverage reports without a token. + # it's all a little weird and inconvenient. see + # + # https://github.com/codecov/feedback/issues/112 + # + # for lots of more discussion + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, 'chore: release')" + name: ubuntu / stable / coverage + steps: + - run: sudo apt-get install -y libpango-1.0-0 + - uses: actions/checkout@v4 + with: + submodules: true + - name: Install 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: Upload to codecov.io + uses: codecov/codecov-action@v4 + with: + fail_ci_if_error: true + token: ${{ secrets.CODECOV_TOKEN }} + env_vars: OS,RUST diff --git a/Cargo.lock b/Cargo.lock index 1acf0e6..8a2b193 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -152,7 +152,7 @@ dependencies = [ "petgraph", "semver", "serde", - "toml 0.7.8", + "toml", "url", ] @@ -1862,19 +1862,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.19.15", -] - -[[package]] -name = "toml" -version = "0.8.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit 0.22.12", + "toml_edit", ] [[package]] @@ -1896,20 +1884,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "winnow 0.5.40", -] - -[[package]] -name = "toml_edit" -version = "0.22.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef" -dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", - "winnow 0.6.7", + "winnow", ] [[package]] @@ -2294,28 +2269,20 @@ dependencies = [ ] [[package]] -name = "winnow" -version = "0.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14b9415ee827af173ebb3f15f9083df5a122eb93572ec28741fb153356ea2578" -dependencies = [ - "memchr", -] - -[[package]] -name = "wsm" +name = "wsx" version = "0.1.0" dependencies = [ "anyhow", "built", "cmd_lib", "git-repository", + "home", "log", "pico-args", "regex", "serde", "sha2", - "toml 0.8.12", + "toml", "tracing", "tracing-subscriber", "walkdir", diff --git a/Cargo.toml b/Cargo.toml index e0cf520..5075973 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,14 +1,15 @@ [package] -name = "wsm" -description = "Cilki's WorkSpace Manager" +name = "wsx" +description = "Cilki's WorkSpace eXplorer" version = "0.1.0" edition = "2021" -repository = "https://github.com/cilki/wsm/" +repository = "https://github.com/cilki/wsx/" [dependencies] anyhow = "1.0.82" cmd_lib = "1.3.0" git-repository = { version = "0", optional = true } +home = "0.5.9" log = "0.4.17" pico-args = "0.5.0" regex = "1" @@ -23,4 +24,4 @@ walkdir = "2" built = { version = "0.7", features = ["cargo-lock", "dependency-tree", "git2", "chrono", "semver"] } [features] -git_oxide = ["dep:git-repository"] \ No newline at end of file +git_oxide = ["dep:git-repository"] diff --git a/src/lib.rs b/src/lib.rs index 7c1756a..2e4a7f9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,6 +20,17 @@ pub struct Config { pub cache: Option, } +impl Default for Config { + // Place the cache according to platform + + fn default() -> Self { + Self { + workspace: vec![], + cache: None, + } + } +} + impl Config { /// Resolve a repository pattern against local repositories. pub fn resolve_local(&self, pattern: &RepoPattern) -> Vec { diff --git a/src/main.rs b/src/main.rs index 3953662..01b7294 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ use anyhow::Result; use tracing::debug; -use wsm::Config; +use wsx::Config; /// Build info provided by built crate. pub mod build_info { @@ -14,19 +14,24 @@ fn main() -> Result<()> { .init(); // Locate configuration file - let config_path = match std::env::home_dir() { - Some(home) => format!("{}/.wsm/config.toml", home.display()), + let config_path = match home::home_dir() { + Some(home) => format!("{}/.config/wsx.toml", home.display()), None => todo!(), }; - debug!(config_path = %config_path, "Loading configuration file"); - // Read configuration file - let config: Config = match std::fs::read_to_string(config_path) { - Ok(content) => toml::from_str(&content)?, - Err(_) => todo!(), + // Load configuration file + let config: Config = match std::fs::metadata(&config_path) { + Ok(_) => { + debug!(config_path = %config_path, "Loading configuration file"); + toml::from_str(&std::fs::read_to_string(config_path)?)? + } + Err(_) => { + debug!("Using default config"); + Config::default() + } }; - debug!("Read user configuration: {:?}", &config); + debug!(config = ?config, "Using configuration"); match std::env::var("_ARGCOMPLETE_") { Ok(shell_type) => { @@ -40,12 +45,15 @@ fn main() -> Result<()> { } let mut args = pico_args::Arguments::from_env(); + if args.contains("--help") { + return print_help(); + } match args.subcommand()? { Some(command) => match command.as_str() { - "drop" => wsm::cmd::drop::run_drop(&config, args.opt_free_from_str()?), + "drop" => wsx::cmd::drop::run_drop(&config, args.opt_free_from_str()?), "help" => print_help(), - _ => wsm::cmd::open::run_open(&config, Some(command)), + _ => wsx::cmd::open::run_open(&config, Some(command)), }, None => todo!(), // TODO open UI } @@ -54,13 +62,13 @@ fn main() -> Result<()> { /// Output help text. fn print_help() -> Result<()> { println!( - "wsm {} ({})", + "wsx {} ({})", build_info::PKG_VERSION, build_info::BUILT_TIME_UTC ); println!(""); - println!("wsm - Clone one or more repositories"); - println!("wsm drop [repo pattern] - Drop one or more repositories"); + println!("wsx - Clone one or more repositories"); + println!("wsx drop [repo pattern] - Drop one or more repositories"); Ok(()) }