aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-09-25 10:37:05 +0200
committerDanilo M. <danix@danix.xyz>2026-09-25 10:37:05 +0200
commit8d919d4cc4d277d06d24a9c8dd6157fe9bcf1aa1 (patch)
tree974a8af5277a824c20955b8af91ec4214a2a5815
parent89dcf4cc463eec41ed85dffc6d30040d9b27f3a2 (diff)
downloadsbo-slackbuilds-8d919d4cc4d277d06d24a9c8dd6157fe9bcf1aa1.tar.gz
sbo-slackbuilds-8d919d4cc4d277d06d24a9c8dd6157fe9bcf1aa1.zip
Move maintainer tooling out of the repo
Git hooks, the upstream sweep and the SBo delivery workflow are the maintainer's operational tools, not package knowledge. They now live in a private workspace that wraps all three SlackBuild repos, with one shared copy of each hook instead of three drifting ones. Also in this pass: - AGENTS.md: checksum loop documented as sbodl (sbofixinfo does not fix checksums), nvchecker must not run without a token config, prefer use_latest_release over use_max_tag - README: Git Hooks section replaced by a short Contributing note - sweep report renamed to LAST_SWEEP.md across all three repos Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
-rwxr-xr-x.extras/hooks/post-commit70
-rwxr-xr-x.extras/hooks/pre-commit99
-rw-r--r--.gitignore2
-rw-r--r--AGENTS.md231
-rw-r--r--README.md18
5 files changed, 48 insertions, 372 deletions
diff --git a/.extras/hooks/post-commit b/.extras/hooks/post-commit
deleted file mode 100755
index 6f55d61..0000000
--- a/.extras/hooks/post-commit
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/bin/bash
-# post-commit hook: create SBo submission archive for added/updated packages
-set -u
-
-REPO_ROOT=$(git rev-parse --show-toplevel)
-SBO_DIR="$REPO_ROOT/SBo"
-
-# Find packages whose .SlackBuild was added (A) or modified (M) in this commit.
-# git diff-tree output format: <status>\t<file>
-# Paths are <category>/<package>/<package>.SlackBuild, matching SBo's own
-# layout. Depth isn't asserted: any dir holding a .SlackBuild is a build.
-PACKAGES=()
-while IFS=$'\t' read -r status file; do
- [[ "$status" != "A" && "$status" != "M" ]] && continue
- dir=$(dirname "$file")
- base=$(basename "$file")
- [[ "$dir" == "." ]] && continue # skip root-level files
- [[ "$base" == *.SlackBuild ]] || continue
- PACKAGES+=("$dir")
-done < <(git diff-tree --no-commit-id -r --name-status HEAD)
-
-[[ ${#PACKAGES[@]} -eq 0 ]] && exit 0
-
-for pkg in "${PACKAGES[@]}"; do
- echo ""
- echo "==> Package: $pkg"
- echo ""
- echo "Files to be archived:"
- echo "---------------------"
- while IFS= read -r f; do
- printf '%s\n' "${f#"$REPO_ROOT/"}"
- done < <(find "$REPO_ROOT/$pkg" -type f | sort)
- echo ""
- # Non-interactive override: set SBO_ARCHIVE=yes|no to skip the prompt.
- # Lets agents and scripts answer without a terminal.
- case "${SBO_ARCHIVE:-}" in
- [yY]|[yY][eE][sS]) answer=yes ;;
- [nN]|[nN][oO]) echo " -> Skipped (SBO_ARCHIVE=no)."; continue ;;
- "")
- # No override: need an interactive terminal to prompt.
- if [ ! -r /dev/tty ]; then
- echo " -> No terminal, skipped (set SBO_ARCHIVE=yes to archive)."
- continue
- fi
- printf "Create SBo archive for '%s'? [y/N] " "$pkg"
- answer=""
- read -r answer </dev/tty || answer=""
- ;;
- *) echo " -> Skipped (SBO_ARCHIVE='$SBO_ARCHIVE' unrecognized)."; continue ;;
- esac
- case "$answer" in
- [yY]|[yY][eE][sS])
- mkdir -p "$SBO_DIR"
- # $pkg is <category>/<package>. SBo expects a tarball named after
- # the package, with the package dir (not the category) at its
- # root, so name it by basename and tar from inside the category.
- name=$(basename "$pkg")
- if tar -czf "$SBO_DIR/$name.tar.gz" -C "$REPO_ROOT/$(dirname "$pkg")" "$name"; then
- echo " -> Archive created: SBo/$name.tar.gz"
- else
- echo " -> Archive FAILED." >&2
- fi
- ;;
- *)
- echo " -> Skipped."
- ;;
- esac
-done
-
-exit 0
diff --git a/.extras/hooks/pre-commit b/.extras/hooks/pre-commit
deleted file mode 100755
index d7bbbc8..0000000
--- a/.extras/hooks/pre-commit
+++ /dev/null
@@ -1,99 +0,0 @@
-#!/bin/bash
-
-# 20220315 bkw: SBo pre-commit hook, wrapper for sbolint.
-
-# Installation:
-
-# Copy this to <gitdir>/.git/hooks, mode 0755 (or anyway, make it
-# executable). Also get sbolint and install it somewhere on $PATH,
-# like /usr/local/bin. sbolint comes from:
-
-# https://slackware.uk/~urchlay/repos/sbostuff/plain/sbolint
-
-# That's a wgettable URL. You can also clone the sbostuff
-# repo from https://slackware.uk/~urchlay/repos/sbostuff if you want.
-
-# Usage:
-
-# Just do your usual "git commit". When you do, sbolint will run on
-# the build you're updating. If it finds any issues, it will cause the
-# commit to abort, so you can fix whatever's wrong and try the commit
-# again.
-
-# Since sbolint isn't perfect, you can skip the check for any commit
-# by running e.g:
-
-# SBOLINT=no git commit <arguments>
-
-# You can also run sbolint by itself, and read its documentation with
-# "sbolint --docs".
-
-set -e
-exec 1>&2
-
-# Check for staged source archives (.tar.gz, .tar.xz, .tar.bz2, .zip, etc.)
-# Symlinks: auto-removed. Regular files: blocked (must not be committed).
-source_pattern='\.\(tar\.gz\|tar\.xz\|tar\.bz2\|tar\.zst\|tgz\|zip\|7z\|rpm\|deb\)$'
-source_blocked=""
-while IFS= read -r f; do
- mode=$(git ls-files --stage -- "$f" | awk '{print $1}')
- if [ "$mode" = "120000" ]; then
- echo "Removing staged symlink to source archive: $f"
- git rm --cached -q -- "$f"
- rm -f "$f"
- else
- source_blocked="$source_blocked $f"
- fi
-done < <(git diff --cached --name-only | grep -i "$source_pattern")
-if [ -n "$source_blocked" ]; then
- echo "*** ERROR: source archives staged for commit:"
- for f in $source_blocked; do echo "*** $f"; done
- echo "*** Remove them with: git rm --cached -- $source_blocked"
- exit 1
-fi
-
-# There should normally only be one changed build per commit, but this
-# rule may get broken when the repo's frozen pending a new Slackware
-# release. So use a loop.
-
-# The weird-looking "< <(command)" syntax is why this script must
-# have a #!/bin/bash at the top: it won't work with #!/bin/sh, even if
-# /bin/sh is a symlink to bash.
-
-if [ "${SBOLINT:-yes}" = "yes" ]; then
- sbolintfailed=""
- if ! which sbolint &>/dev/null; then
- echo "WARNING: can't find sbolint in PATH, no linting will be done"
- else
- while read build; do
- # if there's no slack-desc or README, assume the build has been removed.
- # the directory still might exist after a "git rm -rf" because it
- # might contain untracked files (e.g. the source tarball).
- if [ -e "$build/slack-desc" -o -e "$build/README" ]; then
- sbolint "$build" || sbolintfailed=1
- fi
- done < <(git diff --cached --name-only | while IFS= read -r f; do
- # Walk up from the changed file to the directory that holds
- # the .SlackBuild: that's the build dir sbolint wants. Depth
- # isn't assumed, so this works for both a flat layout
- # (<pkg>/) and SBo's own (<category>/<pkg>/). Root-level
- # files (AGENTS.md, .extras/...) walk up to "." and are
- # dropped, they aren't builds.
- d=$(dirname "$f")
- while [ "$d" != "." ] && [ "$d" != "/" ]; do
- if compgen -G "$d/*.SlackBuild" >/dev/null; then
- printf '%s\n' "$d"
- break
- fi
- d=$(dirname "$d")
- done
- done | sort -u)
- fi
- if [ -n "$sbolintfailed" ]; then
- echo "*** sbolint failed, fix the errors or set SBOLINT=no"
- echo "*** in the environment to commit anyway."
- exit 1
- fi
-fi
-
-exit 0
diff --git a/.gitignore b/.gitignore
index fda1e69..78da7a9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,4 +2,4 @@
.agents
SBo/
*.bak
-LAST_SWEEP
+LAST_SWEEP.md
diff --git a/AGENTS.md b/AGENTS.md
index e746418..9a8d86e 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -11,14 +11,16 @@ on SBo:
1. Track upstream version changes (via nvchecker).
2. Reflect a new upstream version in the package's `.SlackBuild` / `.info`.
-3. Test-build with the `test-build` tool (see below).
-4. Generate the SBo submission tarball to upload.
+3. Test-build the bump on both Slackware 15.0 and -current.
+4. Deliver the update to SBo (GitHub PR or submission tarball).
New-package development happens in **other** repos, not here:
-- `../GITHUB/my-slackbuilds/` — regular packages, plus SBo packages whose
- upstream moves faster than SBo review (worked ahead of the SBo copy).
-- `../GITHUB/Slackware-Pentesting-Suite/` — cybersecurity packages.
+- [my-slackbuilds](https://github.com/danixland/my-slackbuilds): regular
+ packages, plus SBo packages whose upstream moves faster than SBo review
+ (worked ahead of the SBo copy).
+- [Slackware-Pentesting-Suite](https://github.com/danixland/Slackware-Pentesting-Suite):
+ cybersecurity packages.
When a new package is uploaded to SBo and approved, it **moves here** and this
repo takes over its maintenance.
@@ -53,9 +55,9 @@ Current categories: `misc` (SecLists, exploitdb, nuclei), `games`
metasploit-framework-bin, r8125).
Matching SBo's layout means a package directory exports to the SBo repo at
-the identical relative path, with no mapping step. Both git hooks locate a
-build by walking up to the directory holding the `.SlackBuild`, so neither
-asserts a fixed depth.
+the identical relative path, with no mapping step. Tooling that locates a
+build must walk up to the directory holding the `.SlackBuild` rather than
+assume a fixed depth.
Version tracking is handled by a single file:
@@ -66,8 +68,10 @@ Version tracking is handled by a single file:
### `.extras/` holds all non-package repo files
Anything that is not a SlackBuild package must live under `.extras/`, never at
-the repo root. Currently: `nvchecker.toml` (version tracking), `hooks/` (git
-hooks), `assets/`.
+the repo root. Currently: `nvchecker.toml` (version tracking), `assets/`.
+
+Maintainer tooling (git hooks, the upstream sweep, test builds, the SBo PR
+export) is kept outside this repo, in the maintainer's private workspace.
---
@@ -226,38 +230,6 @@ tarball, so a changed blurb is not a new release: compare `Version`,
---
-## Test-building
-
-Because these packages are already published on SBo, the build here is a
-**verification step** on a version bump, not development. It runs in a throwaway
-Slackware container via the **`test-build`** tool, which lives in its own repo,
-`../sbo-dockerbuild` (installed to `~/bin/test-build`). Being hermetic and
-disposable, **the agent may run it directly** (unlike a real `slackrepo build` on
-the buildsystem VM).
-
-Workflow for a bump: edit the `.SlackBuild`/`.info`, then verify on **both**
-trees (these are all SBo-published packages, so both are mandatory):
-
-```bash
-test-build <pkg> # -current
-test-build --stable <pkg> # 15.0
-```
-
-`test-build` resolves the target from the local dir (CWD or a path) and its deps
-from the configured SBo tree, builds in a `--rm` container, and lints with
-`sbopkglint`. Use `--keep` to copy the built `.txz` out (e.g. a binary repack
-like `metasploit-framework-bin` whose post-install artifacts are regenerated by
-extracting the kept `.txz` and running the generator against it, no host
-install, but see the gem-path gotcha in the msfvenom bash-completion section
-above). See `../sbo-dockerbuild` for the full tool and its image-builder
-chain.
-
-The one artifact worth keeping from a clean bump is the **SBo submission
-tarball** (`SBo/<pkg>.tar.gz`), produced by the `post-commit` hook — that is
-what gets uploaded to SlackBuilds.org.
-
----
-
## SlackBuild Scripting Guidelines
### Templates (local clone)
@@ -313,31 +285,20 @@ PRGNAM, VERSION, HOMEPAGE, DOWNLOAD, MD5SUM (or SHA256SUM), REQUIRES, MAINTAINER
## Version Tracking: nvchecker
A single `.extras/nvchecker.toml` tracks upstream versions for all packages.
+**Every package in this repo must have a stanza there.**
-To check for new upstream versions:
+The file has no `[__config__]`. Do not run it as-is against GitHub: the
+anonymous API budget (60 req/h) runs out and later stanzas 403. Run it from a
+throwaway copy with a `[__config__]` that adds a GitHub token keyfile, and
+probe single stanzas with `nvchecker -c <cfg> -e <name>`.
-```bash
-nvchecker -c .extras/nvchecker.toml
-```
+For github stanzas prefer `use_latest_release` (hits `releases/latest`,
+lenient) over `use_max_tag` (hits `git/refs/tags`, tightly rate-limited); use
+`use_max_tag` only for repos that tag but don't cut Releases (a
+`use_latest_release` probe 404s on those).
When a new version is detected, update `VERSION` in both `.SlackBuild` and
-`.info`, then run `sbofixinfo` to refresh checksums.
-
-**When the sweep reports every package current, record that and stop in one
-pass:** write the `LAST_SWEEP` report (date plus the shipped-vs-upstream
-table), and update `HANDOFF.md` with the sweep result and date. Both are
-local-only, gitignored artifacts. The point is that a clean sweep is a
-complete unit of work, no follow-up step is left pending, so the next session
-reads `HANDOFF.md` and moves on.
-
-**Every package added to this repo must have a corresponding entry in
-`.extras/nvchecker.toml`.**
-
-For **nvchecker** github stanzas prefer `use_latest_release` (hits
-`releases/latest`, lenient) over `use_max_tag` (hits `git/refs/tags`, tightly
-rate-limited and 403s under the shared anon budget); use `use_max_tag` only for
-repos that tag but don't cut Releases (a `use_latest_release` probe 404s on
-those). Probe ONE stanza with `nvchecker -c <cfg> -e <name>`.
+`.info`, then fix the checksum with `sbodl` (see below).
---
@@ -352,46 +313,39 @@ Source: https://slackware.uk/~urchlay/repos/sbo-maintainer-tools
| `sbofixinfo` | Auto-fix common `.info` file issues |
| `sbodl` | Download sources and verify `MD5SUM`/`SHA256SUM` from `.info` |
-### Git hook setup
-
-Both hooks are tracked in `.extras/hooks/`. Install them after cloning:
+Run `sbolint` on every changed package before committing. A `pre-commit`
+wrapper that does it automatically is available from
+https://slackware.uk/~urchlay/repos/sbostuff.
-```bash
-cp .extras/hooks/pre-commit .git/hooks/pre-commit
-cp .extras/hooks/post-commit .git/hooks/post-commit
-chmod +x .git/hooks/pre-commit .git/hooks/post-commit
-```
+### Checksums and source symlinks
-To bypass the pre-commit lint check in exceptional cases:
-```bash
-SBOLINT=no git commit -m'Message here'
-```
+`sbodl` verifies checksums, `sbofixinfo` only normalizes `.info` formatting
+and does not touch checksums. After a version bump: run `sbodl`, it
+downloads and prints `WARN: md5sum doesn't match ... got: <new>`; put the
+`got:` value in `MD5SUM`; run `sbodl` again until `md5sum matches OK`.
-Note: `sbodl` creates symlinks in the package directory pointing to downloaded
-sources. Remove them before staging; they must never be committed. Run it from
-the repo root so no package is missed:
+`sbodl` creates symlinks in the package directory pointing to downloaded
+sources. Remove them before staging; they must never be committed. Run it
+from the repo root so no package is missed:
```bash
find . -type l -print -delete
```
-The `pre-commit` hook also strips staged symlinks to source archives and blocks
-staged *real* archives, but do not rely on that as the only guard.
-
### File modes: 0644
SBo requires 0644 for files and 0755 for directories, and the upload form
rejects otherwise. Git tracks the exec bit, so a `.SlackBuild` that was ever
`chmod +x` carries 0755 into the repo. `sbolint` catches it
-(`must have mode 0644, not 0755`), which is one reason the pre-commit hook has
-to actually run. To fix, both on disk and in the index:
+(`must have mode 0644, not 0755`), which is one reason to run it before every
+commit. To fix, both on disk and in the index:
```bash
chmod 644 <category>/<pkg>/<file>
git add --chmod=-x <category>/<pkg>/<file>
```
-Audit the whole repo (`.extras/hooks/` at 0755 is correct, those are hooks):
+Audit the whole repo:
```bash
git ls-files --stage | awk '$1!="100644" && $4 !~ /^\.extras/ {print $1, $4}'
@@ -399,107 +353,6 @@ git ls-files --stage | awk '$1!="100644" && $4 !~ /^\.extras/ {print $1, $4}'
---
-## Who builds SlackBuilds
-
-The agent authors/edits the sources (`.SlackBuild`, `.info`, `README`,
-`slack-desc`, `doinst.sh`, nvchecker stanzas) and runs the non-building checks
-(`sbolint`, `sbodl`, `sbofixinfo`).
-
-**The one exception in this repo** is the throwaway-docker test-build via the
-`test-build` tool (see [Test-building](#test-building)): it is hermetic and
-disposable, so the agent may run it to verify a bump, including `sbopkglint` on
-the throwaway package it produces.
-
-Everything else stays with the user: never run or offer a **real**, persistent
-build — `slackrepo build`, or `bash <pkg>.SlackBuild` / `sudo bash ...` on the
-host (as opposed to inside the throwaway container). Those install to the
-user's system or the buildsystem VM; the user runs them and reports back.
-
----
-
-## Delivery: getting a bump to SBo
-
-Two channels reach SlackBuilds.org. Everything up to the local commit is
-identical for both; only the final step differs.
-
-### Channel 1: GitHub pull request (preferred for updates)
-
-Per SBo's own workflow doc (`https://slackbuilds.org/SBo-Github-Workflows.txt`).
-Applies to **updates of already-published packages**, which is all this repo
-holds. New submissions still go through the upload form, not a PR.
-
-The fork is a **separate clone**, not a remote of this repo, the two trees
-have unrelated histories:
-
-```
-~/Programming/GIT/GITHUB/slackbuilds # fork of SlackBuildsOrg/slackbuilds
- origin -> github:danixland/slackbuilds.git
- upstream -> https://github.com/SlackBuildsOrg/slackbuilds.git
- user.name = danix (local override, matches .info MAINTAINER)
-```
-
-To recreate it (the clone is ~265MB, and `.git/config` is not tracked, so a
-fresh clone silently loses the name override and commits revert to the global
-`Danilo M.`):
-
-```bash
-gh repo fork SlackBuildsOrg/slackbuilds --clone=false
-git clone github:danixland/slackbuilds.git ~/Programming/GIT/GITHUB/slackbuilds
-cd ~/Programming/GIT/GITHUB/slackbuilds
-git remote add upstream https://github.com/SlackBuildsOrg/slackbuilds.git
-git config --local user.name danix # email + GPG signing come from global
-```
-
-Identity must satisfy three things, all verifiable on a pushed commit with
-`gh api repos/SlackBuildsOrg/slackbuilds/pulls/<n>/commits`: the author email
-matches `.info` EMAIL, the email is verified on the `danixland` account (so
-`.author.login` is set, not null), and the GPG key is uploaded there (so
-`.commit.verification.verified` is true). All three held as of 2026-08-08.
-
-Because this repo mirrors SBo's `<category>/<package>/` layout, a package
-directory copies across at the identical relative path, no mapping needed:
-
-```bash
-cd ~/Programming/GIT/GITHUB/slackbuilds
-git fetch upstream
-git checkout -B <package> upstream/master
-rsync -a --delete ~/Programming/GIT/sbo-slackbuilds/<category>/<package>/ <category>/<package>/
-git add <category>/<package>
-git commit -m "<category>/<package>: Updated for version <VERSION>."
-git push -f origin <package>
-gh pr create --repo SlackBuildsOrg/slackbuilds --base master
-```
-
-Notes:
-
-- **One PR per package**, one commit per PR. Local history here can be as
- fine-grained as you like; the PR commit is synthesized at export time, so
- the two histories deliberately diverge.
-- **Commit subject uses SBo's wording**, not this repo's:
- `<category>/<package>: Updated for version X.Y.Z.` (past tense, trailing
- period). Repo-level commits here (AGENTS.md, hooks) keep no prefix and are
- never exported.
-- **Base the PR on `master`.** Merged PRs display a base of `github`, a
- transient integration branch SBo admins retarget onto and then delete. Open
- PRs target `master`; that is what you branch from and PR against.
-- **PR body stays -stable-only.** SBo targets -stable, so do not mention that
- the package was tested on -current in a PR body. If a test note is wanted,
- reference 15.0 only, or omit it.
-- Reviewer feedback is addressed by amending and force-pushing the single
- commit, per the doc. Local history here needn't mirror that amendment.
-
-### Channel 2: submission tarball (fallback)
-
-The `post-commit` hook builds `SBo/<package>.tar.gz` when a `.SlackBuild`
-changes and `SBO_ARCHIVE=yes` is set. The archive is named after the package
-with the **package** directory at its root (not the category), as the upload
-form expects. `SBo/` is gitignored, the tarball is a local artifact.
-
-Use this when a PR would be slower than the form, or as a fallback if a PR
-stalls.
-
----
-
## SBo Submission Guidelines
Before submitting or updating a package on SlackBuilds.org:
@@ -510,7 +363,8 @@ Before submitting or updating a package on SlackBuilds.org:
4. **Check `README`** includes all non-SBo dependencies and any special build notes
5. **Follow the SBo submission guidelines**: https://slackbuilds.org/guidelines/
6. **Bump `VERSION`** in both `.SlackBuild` and `.info` when updating
-7. **Run `sbofixinfo`** after every version bump to catch stale checksums/URLs
+7. **Run `sbodl`** after every version bump to verify the checksum, and
+ `sbofixinfo` to normalize the `.info`
---
@@ -521,13 +375,12 @@ Local commits in this repo:
- One commit per package add/update
- Commit message format: `<package-name>: add version X.Y.Z` or `<package-name>: update to X.Y.Z`
- For fixes: `<package-name>: fix <short description>`
-- Repo-level changes (AGENTS.md, hooks, nvchecker config) take no package
+- Repo-level changes (AGENTS.md, nvchecker config) take no package
prefix and are never exported
The **exported PR commit uses SBo's wording instead**, generated from the path
and `.info` VERSION at export time: `<category>/<package>: Updated for version
-X.Y.Z.` See [Delivery](#delivery-getting-a-bump-to-sbo). The two histories are
-independent by design, so local commits need not adopt SBo's format.
+X.Y.Z.` The two histories are independent by design, so local commits need not adopt SBo's format.
---
diff --git a/README.md b/README.md
index 71470d1..15b29b7 100644
--- a/README.md
+++ b/README.md
@@ -81,20 +81,12 @@ Check each package's `README` for dependencies and any special build instruction
---
-## Git Hooks
+## Contributing
-Two hooks are included in `.extras/hooks/`. Install them after cloning:
-
-```bash
-cp .extras/hooks/pre-commit .git/hooks/pre-commit
-cp .extras/hooks/post-commit .git/hooks/post-commit
-chmod +x .git/hooks/pre-commit .git/hooks/post-commit
-```
-
-| Hook | Purpose |
-|------|---------|
-| `pre-commit` | Runs [`sbolint`](https://slackware.uk/~urchlay/repos/sbo-maintainer-tools) on staged packages before each commit. Also guards against staged source archives: symlinks are auto-removed silently, real archive files block the commit and list the offenders. |
-| `post-commit` | After each commit, offers to create a `SBo/<pkg>.tar.gz` archive ready for submission to SlackBuilds.org |
+Run [`sbolint`](https://slackware.uk/~urchlay/repos/sbo-maintainer-tools) on
+every changed package before sending a patch or pull request, and never commit
+downloaded source archives or the symlinks `sbodl` leaves in package
+directories.
---