Name: werker Version: 0.1.0 # werker/ has no version of its own, so a source change needs a manual Release # bump here or master's NVR-skip publishes nothing. Release: 1%{?dist} Summary: Job executor sharing one build budget across concurrent builds License: AGPL-3.0-or-later URL: https://github.com/kalkin/monorepo # In-repo source (werker/): pkgs/rpm/source-archive snapshots the tracked tree # into this tarball at srpm time — see the `source-dir` marker. Source0: %{name}-%{version}.tar.gz Source1: werker-executord.service Source2: 90-werker.preset Source3: executord.sh Source4: executor-submit.sh BuildArch: noarch # Completions are rendered at build time by janet-wrk's generator. A PR that # changes janet-wrk too submits that build and this one concurrently, so this # package resolves the build dep against the project as it was before the PR # and reds once. Re-run the gate after janet-wrk's build settles. BuildRequires: janet BuildRequires: janet-wrk # The generator loads each entry point to render its completion, which pulls # in shared/modpath.janet and, through it, spork/path (see the Requires below). BuildRequires: janet-spork BuildRequires: systemd-rpm-macros Requires: janet Requires: janet-wrk # shared/modpath.janet imports spork/path, so this is direct, not transitive. Requires: janet-spork Requires: systemd %description The executor runs jobs submitted over a unix socket under one budget shared by everyone connected to that socket, including the make and cargo processes those jobs spawn. It exists so that concurrent builds stop each owning a private -jN pool, and it speaks the GNU make jobserver protocol so those child builds join the same pool rather than opening their own. executord is the daemon and ships as a systemd user unit, enabled for real users at install and started at their next login. executor-submit runs one command on a daemon that is already up, forwarding its output and exiting with its status. %prep %autosetup -n %{name}-%{version} %build # Pure janet, nothing to compile beyond rendering the completions below. # No ../janet tree ships in this tarball, so the generator's own `cli` # import falls through to janet-wrk's syspath copy, which is also where this # syspath lookup finds the generator itself. syspath=$(janet -e '(prin (dyn :syspath))') for cmd in executord executor-submit; do janet "$syspath/cli/completion" ./$cmd > _$cmd done %install install -d %{buildroot}%{_libexecdir}/werker # Only the commands named here ship. The other scripts in the tarball are # repo-only and have no installed counterpart. install -pm0755 executord executor-submit %{buildroot}%{_libexecdir}/werker/ cp -a executor shared %{buildroot}%{_libexecdir}/werker/ # Neither the tests nor the developer README is a runtime artifact. No -f: # a renamed or missing path here must red the build, not silently ship it. rm -r %{buildroot}%{_libexecdir}/werker/executor/test rm %{buildroot}%{_libexecdir}/werker/executor/README.md # Only the pruned test scripts import this, so it would ship as a module # nothing in the package can reach. rm %{buildroot}%{_libexecdir}/werker/executor/testlib.janet find %{buildroot}%{_libexecdir}/werker -name '*.janet' -exec chmod 0644 {} + install -Dpm0644 %{SOURCE1} \ %{buildroot}%{_userunitdir}/werker-executord.service install -Dpm0644 %{SOURCE2} \ %{buildroot}%{_userpresetdir}/90-werker.preset install -Dpm0755 %{SOURCE3} %{buildroot}%{_bindir}/executord install -Dpm0755 %{SOURCE4} %{buildroot}%{_bindir}/executor-submit install -d %{buildroot}%{zsh_completions_dir} install -pm0644 _executord _executor-submit %{buildroot}%{zsh_completions_dir}/ %check # %%files already reds the build for a listed file that was not installed. What # it cannot see is a wrapper or a unit naming a path this package does not # ship: both carry absolute paths as plain text, so a typo in either passes # packaging and fails on the target. These read the shipped text and resolve it # against the staged tree rather than against a literal repeated here, which # would only check this file against itself. for w in executord executor-submit; do target=$(sed -n 's|^exec \(/[^ ]*\).*|\1|p' %{buildroot}%{_bindir}/$w) test -n "$target" test -x "%{buildroot}$target" done unit_target=$(sed -n 's|^ExecStart=\([^ ]*\).*|\1|p' %{buildroot}%{_userunitdir}/werker-executord.service) test -n "$unit_target" test -x "%{buildroot}$unit_target" # The unit name is repeated as plain text in the preset and in each scriptlet, # and %%files pins only the unit's own filename, so a typo in either of the # others builds clean, installs, and then enables nothing: Fedora's catch-all # `disable *` wins and the scriptlet macro's `|| :` swallows the failure. # # This covers the preset half, by deriving the name from the unit actually # staged rather than repeating a literal. The scriptlet arguments are spec # text, not buildroot content, so nothing here can read them. unit=$(cd %{buildroot}%{_userunitdir} && echo *.service) grep -qxF "enable $unit" \ %{buildroot}%{_userpresetdir}/90-werker.preset # Pruned in %%install, so a regression there would ship the test harness and a # developer-facing README to every user. test ! -e %{buildroot}%{_libexecdir}/werker/executor/test test ! -e %{buildroot}%{_libexecdir}/werker/executor/README.md test ! -e %{buildroot}%{_libexecdir}/werker/executor/testlib.janet # A completion's #compdef line names the command its own callbacks invoke # through PATH, so a name this package does not ship as a %%{_bindir} command # would be dead on every install that gets it. for comp in %{buildroot}%{zsh_completions_dir}/_*; do name=$(basename "$comp" | cut -c2-) test "$(head -n1 "$comp")" = "#compdef $name" test -x "%{buildroot}%{_bindir}/$name" done # Runs the staged --jobs completion callback against the staged executord, # proving the installed janet-wrk and this package complete end to end # rather than only that the rendered script text looks plausible. out=$(CLI_COMPLETE=zsh CLI_COMPLETE_TARGET=--jobs CLI_CURRENT=2 \ janet %{buildroot}%{_libexecdir}/werker/executord executord "") last=$(printf '%s\n' "$out" | tail -n 1) printf '%s\n' "$last" | grep -qE '^_message |_describe ' # A %%{version} bump with no matching :vers bump in the scripts would ship a # binary that lies about its own version. for cmd in executord executor-submit; do test "$(janet %{buildroot}%{_libexecdir}/werker/$cmd --version)" = "$cmd %{version}" done %files %license COPYING %doc README.md %dir %{_libexecdir}/werker %{_libexecdir}/werker/executord %{_libexecdir}/werker/executor-submit %{_libexecdir}/werker/executor/ %{_libexecdir}/werker/shared/ %{_bindir}/executord %{_bindir}/executor-submit %{_userunitdir}/werker-executord.service %{_userpresetdir}/90-werker.preset %{zsh_completions_dir}/_executord %{zsh_completions_dir}/_executor-submit %post %systemd_user_post werker-executord.service %preun %systemd_user_preun werker-executord.service %postun %systemd_user_postun_with_restart werker-executord.service %changelog * Wed Sep 30 2026 Bahtiar `kalkin-` Gadimov - 0.1.0-1 - Initial package of the in-repo job executor - Ship executord as a systemd user unit, enabled by a shipped preset for non-system users, replacing the removed --detach flag - Ship zsh completions for both commands, rendered at build time