Skip to content

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

utility-core

The shared foundation of the *Utility line — Windows terminal tools with a common look and the same plumbing underneath:

Product Status
DiskUtility shipping (the crate was extracted from it)
AccountUtility next
MouseUtility planned
KeyboardUtility later

What's in the crate

Module Purpose
AppInfo / init Product identity (name, display name, GitHub repo, tagline, version, build time), registered once at startup
ui Theme (one accent per product over shared neutrals), header with update/elevation badges, footer key hints, centred modal frame, spinner
shell The app loop: Shell state + Product trait; owns the Shift+U update dialog, ? help, c copy-log, quit/restart, status expiry; launch, snapshot/render for --snapshot and layout tests; shared confirm/input/busy drawers
cli --version, --update, --no-update-check / <NAME>_NO_UPDATE_CHECK, auto-update on launch
update Self-update from GitHub releases: repo URL allowlist, SHA-256 against checksums.txt, PE header + --version probe, rename-swap, relaunch
config %APPDATA%\<name>\config.json load/save for any serde struct, plus CoreSettings (auto_update, notify)
logger <name>.log next to the exe, 5 MiB rotation, copy-to-clipboard
ps Hidden-window Windows PowerShell with a hardened prelude, CLIXML error decoding, elevation check
notify Windows toast notifications without extra dependencies
text human_bytes, fit, fmt_elapsed

The Windows-only modules (ps, update, notify) are gated on cfg(windows); the rest builds anywhere.

Starting a new product

./scaffold.ps1 -Name accountutility -DisplayName 'Account Utility' `
    -Tagline 'switch Steam · Epic · Discord accounts' `
    -Description 'A terminal account switcher for Windows.' `
    -Theme ACCOUNT -Dest G:\AccountUtility

This copies templates/ with the placeholders filled in, runs git init, builds it and prints accountutility v0.1.0 (built …). The result already has:

  • a working TUI skeleton on utility_core::shell (src/main.rs, src/app.rs, src/ui.rs): list panel, a product modal, background scan, --snapshot, and two tests — header, footer, help, Shift+U update dialog and c copy log come from the shell;
  • build.rs baking the compile time in;
  • CI (clippy -D warnings, tests, --version smoke test);
  • a CHANGELOG-driven release workflow (tag vX.Y.Z → build → GitHub release with <name>.exe + checksums.txt → winget submission when WINGET_TOKEN is set);
  • install.ps1 one-liner with checksum verification;
  • winget manifest generation and submission scripts driven by packaging/product.ps1;
  • packaging/release.ps1 that checks CHANGELOG/Cargo.toml/lockfile/tree, then tags and pushes.

Pass -LocalCore to depend on this checkout by path while utility-core itself is changing; otherwise the product pins the git tag in its Cargo.toml.

Using it from a product

[dependencies]
utility-core = { git = "https://github.com/viorizz/utility-core", tag = "v0.2.1" }
static APP: utility_core::AppInfo = utility_core::AppInfo {
    name: "accountutility",
    display_name: "Account Utility",
    repo: "viorizz/accountutility",
    tagline: "switch Steam · Epic · Discord accounts",
    version: env!("CARGO_PKG_VERSION"),
    build_epoch: env!("BUILD_EPOCH"),
};

fn main() {
    if let Some(code) = utility_core::cli::handle_common_args(&APP) {
        std::process::exit(code);
    }
    utility_core::init(&APP);
    let cfg: Config = utility_core::config::load();
    let mut app = App::new(cfg);            // App embeds a `shell::Shell` and implements `shell::Product`
    std::process::exit(utility_core::shell::launch(&mut app).unwrap());
}

The Product impl is the whole surface a product writes: draw (header/panels/ footer/own modals), on_key (return true when consumed — always while one of your modals is open), on_tick (drain your channel), hints, and config access for the update dialog's auto-update toggle. See templates/src/app.rs for a complete example, including the --snapshot flag and a frame test via shell::snapshot.

Release contract for the self-updater: every GitHub release ships <name>.exe and a checksums.txt line "<sha256> <name>.exe", and the binary answers --version with <name> v<version> …. The templates do all of this.

Releasing utility-core

Add a ## vX.Y.Z section to CHANGELOG.md, bump Cargo.toml, commit, then git tag vX.Y.Z && git push origin vX.Y.Z. Products update the tag in their Cargo.toml.

License

MIT

About

Shared foundation for the *Utility line of Windows terminal tools (Rust/ratatui): theme, self-update, config, logging, release tooling

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages