Repository navigation
Releases: nerima-lisp/cl-nix-forge
Release list
v0.6.1
Fixes a Nix evaluation crash on large .asd files.
Fixed
defsystemFormsread.asdfiles one character at a time with plain recursion. Nix has no tail-call elimination, so every character and token cost a stack frame againstmax-call-depth, and a.asdof roughly 10k characters or more overflowed the default limit of 10000. SincemkPackageFlakeevaluatescl.fromAsdSystemfor every attribute, such a flake could not evaluate at all (nix flake check,nix run, andnix buildall failed) unless the caller raisedmax-call-depth. The reader now tokenizes withbuiltins.splitand drives lexing, paren matching, and form scanning withbuiltins.genericClosure, so depth no longer grows with file size. Results are identical to the previous reader on all existing fixtures, plus two new large-file edge cases (a generated 133 KB system and a real 33 KB.asd) that overflowed the old reader and now evaluate normally.
v0.6.0
Ships a real Darwin executable and refines library API behavior and documentation.
Added
program-opis now used unconditionally on every platform, including Darwin. The Darwin build previously dumped a bare.corefile wrapped by ansbcl --corelauncher script becauseprogram-opwas once observed not to produce a binary there; rebuilding under current SBCL produces a real, ad-hoc-signed Mach-O executable, so$out/bin/<pname>is now the executable itself on every platform, unwrapped unless native libraries require wrapper arguments.
Changed
- Various API behavior refinements and documentation updates across the
lib/batteries and example flakes.
v0.5.0
追加
-
asdSystemDependencies—.asdの:depends-onを defsystem ごとに読み出す。これまで各消費リポジトリが Nix 側で手作業に再構築していた依存辺を、.asdから直接読めるようにする。cl.asdSystemDependencies { asd = ./cl-cli.asd; features = [ "sbcl" ]; } # => { cl-cli = [ "uiop" "cl-host-kit" ]; ... }
featuresは必須引数。#+/#-のリーダー条件と(:feature ...)をその特徴集合に対して評価する。リーダー条件の答えは対象処理系の関数であり、.asd単体では決まらないため既定値を置いていない。 -
checks.api-index-contract—lib/default.nixの全エクスポートがdocs/src/reference/api.mdにリンク付きで載っていることを評価時に検証する。api.mdが「これを強制する仕組みは何もない」と書いていた穴を塞ぐもの。
変更
docs/src/reference/versions.mdを Reading a.asdに改題。ファイル名とアンカーは既存の被リンクを壊さないよう据え置き。- 公開関数が 29 から 30 に。
互換性
リリース済み API に変更はない。既存の消費者は無変更で上げられる。
v0.4.2
flake.nix declares aarch64-darwin again, alongside x86_64-linux. Everything
else is a routine dependency bump and the documentation catching up with it.
Changed
systemsis[ "x86_64-linux" "aarch64-darwin" ]again. The
2026-08-01 revision of the org package standard had dropped
aarch64-darwin, on the grounds that a declared platform with no CI gate
behind it is a claim nothing backs. That reasoning was reverted the next
day:mkPackageFlakegeneratespackages,checks,apps, and
devShellsfrom this one list, so droppingaarch64-darwindid not just
remove an unverified package — it tooknix buildandnix developoff
the development machine entirely.aarch64-darwinstill carries no CI
gate, and the standard now accepts that explicitly rather than pretending
the list means "verified".nixpkgsandtreefmt-nixbumped vianix flake update.
Documented
- Platform coverage
and the README's development section described one declared system; both
now state the two-system list, why it changed twice in three days, and why
CI still evaluates and buildsx86_64-linuxalone (--all-systemswould
fail on a platform mismatch onubuntu-latest, not widen coverage). - The flake input pin shown in the README, Getting started, and the release
process page moved fromv0.4.1tov0.4.2.
v0.4.1
Documentation only. lib/ is unchanged from v0.4.0 — no behaviour differs,
and an existing flake input can be moved to this tag without touching
anything else.
Documented
mkPackageFlakehas a reference entry. It was exported in v0.3.0 and
referred to by name on three pages, but was described nowhere: what it
generates, its arguments, the context record itsctx -> …arguments
receive, and whyextraOutputsandoverrideOutputsare two channels
rather than one. The API index had asserted an invariant — "this index and
lib/default.nixname exactly the same 28 attributes" — that the missing
entry made false, sincelib/exports 29. Nothing gates that invariant, so
the index now records the gap it had and the one command that checks it.- A release process page. Where the version lives now that
CHANGELOG.md
is gone org-wide, why it is aVERSIONfile rather thanflake.nixor the
git tag, therelease.ymlstep that refuses a tag disagreeing with it, and
whatchecks.defaultactually builds. examples/org-preset/is in the examples catalogue, with what its
twenty checks discriminate — including the absence assertions, the two
escape hatches proved in both directions, and the devShell check that is
run against a pre-fix shell to prove it would have failed.
Corrected
- Platform coverage. The page still described two declared systems and a
CI step that evaluates all of them with--all-systems; since v0.4.0 the
flake declaresx86_64-linuxalone and the flag is forbidden by the
package standard. Droppingaarch64-darwindid not reduce the Darwin
branch's coverage — it stopped the declaration from implying coverage —
and the page now makes that distinction instead of stating the old shape.
The same--all-systemsrecipe is corrected in the README and the examples
guide. mkDocsSite'sfilesetargument was motivated by a repo-root
CHANGELOG.mdthat a changelog page snippet-includes. The org abolished
CHANGELOG.mdon 2026-08-01 and the repository cited as the example
removed the snippets extension with it. The argument's reason to exist is
unchanged, so the example is replaced with one that still holds.- The flake input pin shown in the README and Getting started was still
v0.1.0.
Note for the org
GitHub Pages was never enabled on this repository, so every docs.yml run
since the workflow was added had failed at actions/configure-pages. Pages
is now enabled with build_type: workflow, matching every sibling repo, and
https://nerima-lisp.github.io/cl-nix-forge/ is live.
v0.4.0
Fixed
mkPackageFlakebuilds its generateddevShells.defaultfrom the
check-enabled derivation, so a package whose sibling dependency is
test-only can actually load it undernix develop. Two of the three first
adopters had written the sameoverrideOutputsworkaround, which is what
identified this as the library's defect rather than one package's quirk;
the third could never have caught it, being its own test framework with no
external test dependency. It costs no extra build —mkShell's
inputsFromtakes inputs rather than outputs and subtracts the named
derivation, so the check-enabled derivation is never realised, while the
check dependencies it names are already built bychecks.default.mkLispSource's doc comment claimed an allowlist stops a local test run
from invalidating the build. It narrows that, it does not close it: an
allowlist by extension excludes an artefact directory of HTML but not one
of generated.lisp. What closes it is the flake source being Git-backed.
The claim is narrowed to what is true.
v0.3.0
Everything here was found by APPLYING the library to a real repository for
the first time, not by reading it. This is the release that justifies the
note at the top of this file about 1.0.0.
Added
mkPackageFlakegainsexecutable, which builds a delivered CLI from the
preset's OWN resolvedlispDerivationarguments.mkExecutable'sargs
was documented as "the exact attrset you'd pass to lispDerivation", but the
preset had already computed that attrset and exposed only the result — so a
delivered binary re-spelledpname,lispSystem,meta,versionand
srcin an escape hatch. Two sources of truth for the package's identity,
inside the one function whose purpose is removing exactly that. The first
package to deliver a CLI and carrylispDependencieswould have shipped a
binary silently missing them. The resolved attrset is also on the context
for anything the argument does not cover; re-spellingargswholesale is
rejected by name.mkExecutablegainsinstallSource, plus a written contract for what
$outcontains and what a delivered image may assume about its
surroundings. A Lisp image that resolves its ASDF source root from
*runtime-pathname*found nothing, because this function published
$out/binand nothing else; the binary died on its first re-load of one of
its own systems. Both sides were individually correct and disagreed
silently, so the missing contract was the actual defect. The dependency
closure is installed alongside the system's own tree — sources that are
findable while their dependencies' are not fail at the same place, one
asdf:load-systemlater.
Changed
- Breaking:
mkPackageFlake'srootis required.root ? selfwas the
obvious default and never worked: a flake'sselfis an attrset carrying
anoutPath, andlib.filesetrejects it, so the failure surfaced from
insidemkLispSourcenaming neitherselfnor the argument responsible.
It survived the suite because examples are handedpkgsandcldirectly
and theirselfwas already a path literal — the test suite could not
reach the bug because it never exercises a real flakeself. - Delivered executables carry their version in the store path again.
v0.2.0
Added
mkPackageFlake— the nerima-lisp flake standard as a function call
instead of a template to copy. One call returns a package's whole output
set (packages,checks,apps,devShells,formatter,overlays)
from its declarations. It is the only module takinglibwithoutpkgs:
every other module is instantiated for onepkgs, and a preset built that
way could only emit the single system it was instantiated for, so this one
takessystemsand obtains apkgs— and a cl-nix-forge — per declared
system itself.extraOutputsadds andoverrideOutputsreplaces, kept
separate so an intended override stays distinguishable from an accidental
name collision; a collision is an evaluation error.- Implementation table rows for
ccl,abcl,clispandclasp, joining
sbclandecl. CCL is why the rows carry their reasoning: it has no
--script, rejects a bare filename outright, and needs--batchto route
an unhandled condition to a non-zero exit — without which a failing suite
exits 0 and every test appears to pass. - This repository's own documentation site, built by its own
mkDocsSite.
Changed
mkCheckMatrixdecides availability fromlib.meta.availableOnrather
than a platform list kept in this library, so one matrix can be written
once and used on every system — nixpkgs is the authority on where CCL
builds, and it changes. A platform skip, a caller'sskipand an
expectedFailureremain three distinct things: conflating them would let
a real regression hide behind an implementation that cannot run on the
host. A package that IS available here but broken, unfree or insecure
still throws, exactly as it would anywhere else in nixpkgs.- README is a 136-line entry point, under the org standard's 150-line cap,
with the reference material moved todocs/src/.
Known gaps
mkExecutable's two delivery paths are never verified by the same
machine. The branch isisDarwin && sbcl, so a Linux runner always takes
asdf:program-opand an aarch64-darwin developer always takes the
save-lisp-and-diefallback. CI isx86_64-linuxonly, which leaves the
Darwin fallback resting on localnix flake checkalone.ccl,clispandclasprows are unverified by execution on
aarch64-darwin, where nixpkgs reports all three unavailable. CI is the
first machine to run them.- No consumer has been migrated yet. See the note at the top about
1.0.0.
v0.1.0
First tagged release. Everything below is new; the sections describe what the
library does rather than what changed, since there is no prior version.
Added
Core (lib/core/)
lispDerivation— build and test one or more ASDF systems from a source
tree.$outis source plus compiled FASLs side by side, directly reusable
as another package'sCL_SOURCE_REGISTRYentry. Lisp dependencies enter the
registry and neverbuildInputs.lispMultiDerivation— several ASDF systems from one source tree, merged
into a single derivation when they depend on each other. Systems that merge
must agree on every non-dependency build argument; disagreement is an
evaluation error naming the arguments and both systems, never a silent pick.lispWithSystems,lispScript— a wrapped implementation, and a script
packaged with the same dependency environment.mkScriptCheck— run a check through an arbitrary Lisp entry point instead
ofasdf:test-system, defaulting to the nerima-lisp standard
run-tests.lisp. Required for a suite that cannot be driven by an enclosing
test-op: a framework that tests its own ASDF integration putstest-opon
the plan twice and ASDF rejects it as a circular dependency.mkLispSource— thesrca Lisp build should see, as an allowlist. A
denylist overlib.cleanSourceFilteris wrong in both directions: it keeps
.fasl/.coreand every artefact directory nothing has been taught about
yet, so a local test run changes the derivation hash; and it cannot
distinguish "the filter droppedt/" from "t/was untracked".mkCheckMatrix— declarative multi-implementation test matrix, replacing
hand-maintainedmeta.brokenpredicate lists.markNativeLibraryand the native-loader helpers — a native library
declared once stays visible to consumers any number of hops away, through
the same dependency walk as everything else.fromDerivation/fromNixpkgsLisp— consume a nixpkgs or foreign-flake
package as a dependency.fromNixpkgsLisprequireslispImplementation,
so a consumer on another implementation fails during evaluation rather than
attempting to compile FASLs into the immutable Nix store.ancestryWalker/unionAttrsBy— the deduplication primitive the
multi-system path is built on.
Batteries (lib/batteries/)
fromAsdSystem— extract a literal:versionfrom a.asdfile.
Recognisesdefsystem,asdf:defsystemandasdf/defsystem:defsystem.
One file normally defines<pkg>and<pkg>/testcarrying the same
version: that unanimity is accepted. Versions that disagree are real drift
and fail loudly, naming each value and its system.asdSystemVersions— the same extraction keyed by system name.mkTestCheck— a named check for a derivation'sasdf:test-systempath.mkCommandCheck— run a command (an argv list), assert it produced named
artifacts, validate them, and publish the artifacts — and only the
artifacts — as the check's$out.mkCoverageReport— an sb-cover HTML report. SBCL only, and it says so
during evaluation rather than producing an empty report at build time.mkExecutable— deliver a standalone binary viaasdf:program-op, with a
fallback on Darwin/SBCL where that path was observed to produce no binary
within five minutes.mkApp,mkTestApp,mkOverlay— flakeappsandoverlaysentries.mkDocsSite,mkDevShell,collect— a mkdocs-material site, a
nix developshell, and sibling-package collection from flake inputs.
Known gaps
mkExecutable's two delivery paths are never verified by the same machine,
and CI covers only one of them. The branch isisDarwin && sbcl, so a
Linux runner always takesasdf:program-opand an aarch64-darwin developer
always takes thesave-lisp-and-diefallback. CI isx86_64-linuxonly,
which leaves the Darwin fallback resting on localnix flake checkalone.- Only
sbclandeclhave rows in the implementation table. - The library has no consumers yet. See the note above about
1.0.0.