1 Contributing
Anagnostakis Ioannis edited this page 2026-06-25 03:12:30 +03:00

Contributing

slacker is a small, synchronous Rust program with no async runtime and no error crates — errors are plain Result<_, String> for simple, greppable messages. This page is the map for forking, fixing, or extending it.


Architecture at a glance

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#161b22','primaryBorderColor':'#1f6feb','primaryTextColor':'#e6edf3','lineColor':'#6e7781','fontFamily':'monospace'}}}%%
flowchart LR
  C["config.rs<br/>reads /etc/slacker"]:::grey --> R["repo.rs<br/>fetch + parse metadata"]:::grey
  R --> DB["pkgdb.rs<br/>unified priority DB"]:::blue
  DB --> M["main.rs<br/>CLI → plan"]:::blue
  M --> S["system.rs<br/>calls pkgtools"]:::green
  classDef grey fill:#0d1117,stroke:#6e7781,color:#8b949e;
  classDef blue fill:#0d1117,stroke:#1f6feb,color:#e6edf3;
  classDef green fill:#0d1117,stroke:#2ea043,color:#e6edf3;

The mental model: config.rs reads your config → repo.rs fetches and parses each repo's metadata into AvailPkg records → pkgdb.rs unifies them into one priority-ordered database and answers "what wins / what upgrades / what matches" → main.rs turns a CLI command into a plan and calls system.rs to run the real pkgtools.


The modules (14)

Module Owns
main.rs CLI (clap), command dispatch, the install/upgrade plan builder, one cmd_* per action, the pager
config.rs parsing /etc/slacker into typed structs: repos, tag-priorities, blacklist, verify policy, ADM_DIR/PKG_DB_DIR, mirror/<subpath>
pkg.rs Slackware package-name parsing (name-version-arch-build) and build_tag()
repo.rs fetch + parse PACKAGES.TXT/CHECKSUMS, lazy MANIFEST, .dep, quarantine/trust markers
pkgdb.rs the unified priority DB, matching, upgrade resolution, baseline names
download.rs http/https (ureq+native-tls) + file:// + md5/sha
system.rs the installed DB and the installpkg/upgradepkg/removepkg wrappers
history.rs the package-change timeline from the admin dirs
manifest.rs file-search over the decompressed MANIFEST
changelog.rs check-updates / show-changelog
gpg.rs key import + TOFU pinning + verify (fail-closed)
template.rs template generate/load/delete
newconfig.rs .new config handling
ui.rs minimal ANSI colouring (TTY + NO_COLOR aware), plan tables

A deeper, item-by-item source map ships in the repository as CODE_MAP.txt, and the high-level structure in structure.md.


Build and test

cargo build --release
cargo test            # ~70 unit tests, no root and no network needed

The build is warning-clean — keep it that way. Tests use in-memory/temp fixtures; add a unit test next to any matching/priority change (that family of tests is the project's safety net). Live bare-metal testing on a real -current box still catches things sandboxes miss (encoding, paging, arch edge cases).


Principles to preserve

  • Priority above all. A distinct, high priority locks a repo's tagged packages against any lower repo, even a newer version. Changes near installed_priority/upgrades_for must be checked against the upgrade tests.
  • Tags carry meaning. build_tag() is load-bearing for upgrade protection, @_tag, IGNORE_TAGS, and clean-system. Treat it as a stable contract.
  • Stay a thin layer. Don't reimplement pkgtools, gpg, or bzip2 — Slackware ships them.
  • Fail-closed on GPG and checksums. Security checks stop the run, never warn-and-continue.
  • Model data correctly, never mask it. Prefer a correct model over a heuristic that papers over a structural data issue.
  • Errors are strings — short, specific, actionable.

Adding a command

Add a Cmd variant + a match arm in run() + a cmd_* function. If it takes patterns, reuse collect() so it gets @-selector validation and the multi-match chooser for free. Then update the docs that don't auto-generate: README.md, slacker.8, structure.md, CODE_MAP.txt (the clap --help updates itself).


Toolchain and dependencies

Edition 2021, but the effective MSRV is 1.85.1 (a transitive dep, clap_lex, is edition 2024). Direct crates: clap, ureq, native-tls, md-5, regex — think hard before adding a sixth. When you cut a distributable package, freeze the dependency set first: see Building and Releasing.