summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--AGENTS.md72
-rw-r--r--README.asciidoc39
-rw-r--r--README.rst269
-rw-r--r--bin/cmd.ml84
-rw-r--r--bin/dune1
-rw-r--r--bin/main.ml1
-rw-r--r--flake.lock8
-rw-r--r--flake.nix15
-rw-r--r--lib/dune2
-rw-r--r--lib/error.ml10
-rw-r--r--lib/input.ml97
-rw-r--r--lib/input_foreman.ml44
-rw-r--r--lib/lock_loader.ml6
-rw-r--r--lib/lockfile.ml83
-rw-r--r--lib/manifest.ml173
-rw-r--r--lib/nixtamal.ml161
-rw-r--r--lib/prefetch.ml119
-rw-r--r--lib/schema.ml31
-rw-r--r--llm/2026-01-07-Session-Changes-Summary.md33
-rw-r--r--llm/2026-02-07-attribution-audit.md25
-rw-r--r--llm/2026-02-07-phase1-flake-integration.md133
-rw-r--r--llm/README.md41
-rw-r--r--nixtamal.opam2
-rw-r--r--test/dune1
25 files changed, 871 insertions, 581 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2e975c9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+result
+llm/
diff --git a/AGENTS.md b/AGENTS.md
index ef06157..6e2a2f6 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -1,24 +1,21 @@
# AGENTS.md for nixtamal project
-## Project Overview
-**Nixtamal** is a Nix version pinning tool designed as an alternative/complement to flakes. It provides sophisticated dependency management with first-class support for Darcs, Pijul, and other VCS systems that flakes don't handle well.
+## Documentation
-**Strategic Position**: While nixtamal is philosophically an alternative to flakes, toastal is implementing dual support to provide ecosystem bridge capabilities while maintaining the project's core mission.
+User-facing documentation is in `README.asciidoc`. Agent notes go in `./llm/`.
## Build/Lint/Test Commands
### Traditional Nix Commands
-- Build: `dune build`
-- Test all: `dune runtest`
+- Build: `nix-build release.nix` or `nix build`
+- Test all: `nix-build release.nix -A check` or `dune runtest`
- Run single test: `dune runtest --filter <test_name>` (use with alcotest test names)
- Format: `dune build @fmt` (ocamlformat)
- Clean: `dune clean`
-### Nix Integration Commands
-- Traditional build: `nix-build` or `nix-build release.nix`
-- Development shell: `nix-shell` or `nix-shell shell.nix`
-- Flake build (Phase 1+): `nix flake build` or `nix build .#nixtamal`
-- Flake shell (Phase 1+): `nix develop` or `nix shell .#devShell`
+### Nix Flake Commands
+- Build: `nix flake build` or `nix build .#nixtamal`
+- Dev shell: `nix develop` or `nix shell .#devShell`
## Code Style Guidelines
- **Formatting**: Use ocamlformat (auto-formatted via dune @fmt)
@@ -31,47 +28,30 @@
- **Line Length**: No strict limit, but aim for readability
- **Pattern Matching**: Exhaustive, use `|` for clarity
-## Phase 1: Flake Integration Planning
+## Ongoing Integrations
-### Week 1 Objectives
-1. **Create `flake.nix`** with core outputs wrapping existing `release.nix`
-2. **Preserve existing infrastructure** as primary build method
-3. **Implement basic flake outputs**:
- - `packages.${system}.default` (nixtamal package)
- - `packages.${system}.nixtamal` (explicit package name)
- - `devShells.${system}.default` (development environment)
- - `checks.${system}` (test suite integration)
- - `lib` outputs for ecosystem integration
+### Nilla Framework (In Progress)
-### Week 1 Deliverables
-- `flake.nix` with minimal working flake interface
-- `flake.lock` generation workflow
-- Documentation updates explaining dual approach
-- Testing both traditional and flake workflows
+Adding first-class support for https://github.com/nilla-nix/nilla[Nilla], a Nix framework with loaders and module system.
-### Strategic Constraints
-- **Maintain philosophical consistency**: Flakes as interface, not replacement
-- **Preserve existing workflows**: No breaking changes to current Nix infrastructure
-- **Complement over compete**: Position as bridge between traditional Nix and flake ecosystems
+**Status**: Types, codecs, and manifest serialization implemented. Prefetch not yet implemented.
+
+**Files modified**:
+- `lib/input.ml` - Nilla module with Reference type, Kind variant
+- `lib/manifest.ml` - KDL codec for Nilla input type
+- `lib/error.ml` - Added Nilla to prefetch_method, Not_implemented error
+- `lib/prefetch.ml` - Stub returning "not yet implemented"
+- `lib/input_foreman.ml` - Display and needs_prefetch logic
+- `lib/lock_loader.ml` - Feature constant
+- `lib/lockfile.ml` - Lockfile serialization
+- `lib/nixtamal.ml` - meld_input_with_lock support
+
+### Future Integrations
+- Additional VCS support as needed
+- Migration utilities (flakes, npins, niv)
## Agent Notes
- After each major change, create comprehensive notes in `./llm/` folder
-- Use the template in `./llm/README.md`
+- Use the template in `./llm/README.md` (if present)
- Document learnings, challenges, solutions, and insights for future reference
- **Flake integration changes** should be specifically documented with strategic reasoning
-
-## Flake Integration Architecture
-
-### Design Principles
-1. **Wrapper Pattern**: flake.nix imports and wraps existing release.nix infrastructure
-2. **Dual Interface**: Both traditional Nix and flakes remain fully functional
-3. **Ecosystem Bridge**: Expose nixtamal capabilities to flake users without compromising core mission
-4. **Incremental Adoption**: Users can gradually engage with flakes without abandoning nixtamal
-
-### Key Architectural Decisions
-- Keep `nix/tamal/` system as primary input management
-- Use flakes only for build/packaging interface layer
-- Maintain backward compatibility with existing nixtamal projects
-- Provide migration utilities in future phases
-
-No Cursor or Copilot rules found. \ No newline at end of file
diff --git a/README.asciidoc b/README.asciidoc
index b7ebc25..607f02e 100644
--- a/README.asciidoc
+++ b/README.asciidoc
@@ -6,7 +6,7 @@
:author: toastal
== Pronunciation
-/nɪʃ.təˈmal/ _or_ /ˈnɪkstəˌmɑːl/
+/nɪks.təˈmal/ ("nix-tamal")
Maker:: toastal
@@ -18,7 +18,11 @@ Languages::
* KDL
* JSON
-Version:: 0.0.9-alpha (alpha stage)
+Version:: 1.1-alpha (alpha stage)
+
+**Community-maintained fork**: Addressing the original project's lack of reasonable maintenance, this fork prioritizes long-term maintainability, compatibility, and active development.
+
+*Original project:* link:https://darcs.toastal.in.th/nixtamal/trunk/[darcs.toastal.in.th/nixtamal/trunk]
== Purpose
@@ -48,6 +52,33 @@ Future goals (planned but not yet implemented):
WARNING: As this software is in the alpha stage, the maker reserves the right make breaking changes file schemas & CLI API. Additionally, anything after tagged, the maker reserves the right to obliterate & amend patches.
+== Ongoing Integrations
+
+Nixtamal is being extended to support additional frameworks and tools:
+
+=== Nilla Framework
+
+https://github.com/nilla-nix/nilla[Nilla] is a Nix framework with loaders and module system. Nixtamal provides first-class support for Nilla inputs, including manifest serialization, lockfile integration, and prefetch functionality.
+
+[source,kdl]
+----
+my-input {
+ nilla {
+ repository "https://github.com/user/nilla-project.git"
+ branch "main"
+ path "./nilla.nix"
+ }
+}
+----
+
+Attributes:
+* `repository` - Git repository URL (templated)
+* `mirrors` - Repository mirrors (optional, templated)
+* `branch` or `ref` - Git reference point
+* `path` - Path to nilla.nix (defaults to `./nilla.nix`)
+
+Nixtamal prefetch validates that the nilla.nix file exists at the specified path within the fetched repository. The implementation uses standard nix prefetch tooling for consistency and reliability.
+
== Quickstart
=== Set up
@@ -178,9 +209,9 @@ $ nix-build release.nix
$ nix-build release.nix -A nixtamal
----
-=== Building with Flakes (New: Phase 1 Integration)
+=== Building with Flakes (New: Phase 1 Integration with flake-parts)
-Nixtamal now supports dual workflow compatibility, providing both traditional Nix and modern flake interfaces. The flake integration acts as an ecosystem bridge while maintaining nixtamal's core philosophy as a flake alternative/complement.
+Flakes use Determinate Nix and nixpkgs (github:DeterminateSystems/nix, NixOS/nixpkgs/nixos-unstable-small) for strong community support for Nix creator Eelco Dolstra's vision.
Basic flake build
diff --git a/README.rst b/README.rst
deleted file mode 100644
index 6c599bd..0000000
--- a/README.rst
+++ /dev/null
@@ -1,269 +0,0 @@
-..
- ┏┓╻+╻ ╱┏┳┓┏┓┏┳┓┏┓╻
- ┃┃┃┃┗━┓╹┃╹┣┫┃┃┃┣┫┃
- ╹┗┛╹╱ ╹ ╹ ╹╹╹ ╹╹╹┗┛
-================================================================================
-Nixtamal
-================================================================================
---------------------------------------------------------------------------------
-Fulfilling input pinning for Nix (& hopefully more)
---------------------------------------------------------------------------------
-
-:author: toastal
-
-.. role:: ac
-.. role:: del
-.. role:: t
-
-Pronunciation
- /nɪʃ.təˈmal/ *or* /ˈnɪkstəˌmɑːl/
-Alternative spellings
- • ·𐑯𐑦𐑖𐑑𐑩𐑥𐑭𐑤
-Maker
- toastal
-Put out
- 2025-12
-Languages
- • OCaml
- • Nix
- • :ac:`KDL`
- • :ac:`JSON`
-
-
-Purpose
-================================================================================
-
-Nixtamal is a tool to pin input version like its predecessors :t:`niv`,
-:t:`npins`, :t:`Pinch`, :t:`Yae`\, & so on — as well as Nix’s experimental
-:t:`flakes`. Features include:
-
-• keeps a stable reference pin to supported :ac:`VCS`\s
-• supports mirrors for fetching [1]_
-• supports patch-based :ac:`VCS`\s, like Pijul & Darcs, in a first-class sense
- (tho ``nixpkgs`` will be required due to Nix ``builtins`` fetchers
- limitations)
-• uses a :ac:`KDL` manifest file with templating instead of :ac:`CLI` input
-• supports arbitrary commands for getting the latest change for inputs
-• refreshes inputs; skips frozen
-• locks new sources
-• supports arbitrary commands for getting the latest change which can be used to
- avoid costly downloads/clones as well as for templating for inputs
-• does not give any special privilege to any specific code forges
-• source code & community will never be hosted on a proprietary,
- privacy-invasive, megacorporate platform with obligations to shareholders or
- venture capital
-• licensed for your freedom
-• ML-family programming (feels closer to Nix)
-
-Future goals:
-
-• migrations from prior manifest × lockfile versions
-• migrations from Flakes, Npins, & Niv
-• more :ac:`VCS`\s
-• ``nixtamal heal`` for common pitfalls in ``manifest.kdl``
-• :ac:`TUI`?
-• provide a flake-like specification for project layout, but with less holes
-
-.. warning::
-
- As this software is in the alpha stage, the maker reserves the right make
- breaking changes file schemas & :ac:`CLI` :ac:`API`. Additionally, anything
- after tagged, the maker reserves the right to obliterate & amend patches.
-
-Quickstart
-================================================================================
-
-Set up
---------------------------------------------------------------------------------
-
-.. code:: console
-
- $ nixtamal set-up
- ┏┓╻+╻ ╱┏┳┓┏┓┏┳┓┏┓╻
- ┃┃┃┃┗━┓╹┃╹┣┫┃┃┃┣┫┃
- ╹┗┛╹╱ ╹ ╹ ╹╹╹ ╹╹╹┗┛
-
- Creating Nixtamal directory @ ./nix/tamal
- Writing new Nixtamal EditorConfig @ ./nix/tamal/.editorconfig …
- Fetching latest value for 「nixpkgs」 …
- Prefetching input 「nixpkgs」 … (this may take a while)
- Prefetched 「nixpkgs」.
- Making manifest file @ version:0.1.1
-
- $ tree nix/tamal
- nix/tamal
- ├── default.nix
- ├── lock.json
- └── manifest.kdl
-
- 1 directory, 3 files
-
-
-Use with a Nix project — such as in a ``release.nix``
---------------------------------------------------------------------------------
-
-.. code:: nix
-
- let
- inputs = import nix/tamal { };
- pkgs = import inputs.nixpkgs { };
- in
- {
- inherit (pkgs) hello;
- }
-
-Add a new input to pin
---------------------------------------------------------------------------------
-
-See: `<docs/manifest.rst>`_
-
-.. code:: console
-
- $ nixtamal tweak
-
-Opens text editor. & After editing …
-
-Lock or refresh you inputs
---------------------------------------------------------------------------------
-
-.. code:: console
-
- $ nixtamal lock
- $ nixtamal refresh
-
-What next?
---------------------------------------------------------------------------------
-
-As they say: read the manpages
-
-.. code:: console
-
- $ man nixtamal
- $ man nixtamal-manifest
-
-
-Building / hacking
-================================================================================
-
-Working setup
---------------------------------------------------------------------------------
-
-If you don’t have Darcs install, you can use from Nixpkgs such as
-
-.. code:: console
-
- $ nix-shell -p darcs
-
-After/else
-
-.. code:: console
-
- $ darcs clone https://darcs.toastal.in.th/nixtamal/trunk/ nixtamal
- $ darcs setpref boringfile .boring
- $ cd nixtamal
-
-Development environment setup
---------------------------------------------------------------------------------
-
-Base Nix shell
-
-.. code:: console
-
- $ nix-shell
-
-Or with Direnv
-
-.. code:: console
-
- $ echo "use nix" >> .envrc
- $ direnv allow
-
-Building with Dune
---------------------------------------------------------------------------------
-
-.. code:: console
-
- $ dune build
-
-Building with Nix
---------------------------------------------------------------------------------
-
-Basic
-
-.. code:: console
-
- $ nix-build
-
-Everything else
-
-.. code:: console
-
- $ nix-build release.nix
- $ nix-build release.nix -A nixtamal
-
-Darcs hooks (can skip)
---------------------------------------------------------------------------------
-
-.. code:: console
-
- $ $EDITOR _darcs/prefs/defaults
-
-.. code::
-
- apply posthook nix-shell --run mk-darcs-weak-hash && nix-build --no-out-link release.nix
- obliterate posthook nix-shell --run mk-darcs-weak-hash
- record posthook nix-shell --run mk-darcs-weak-hash
-
-Hooks here can:
- • Build the entire project before applying patches to make sure it works.
- • Show the WeakHash ``_darcs/weak_hash`` which is good for querying project
- state, such as for ``latest-cmd``s (hint, hink).
-
-
-License
-================================================================================
-
-Depending on the content, this project is licensed under one of
-
-• :t:`GNU General Public License, version 3.0 later` (``GPL-3.0-or-later``)
-• :t:`GNU Lesser General Public License version 2.1 or later`
- (``LGPL-2.1-or-later``) with & without the :t:`OCaml LGPL Linking Exception`
- (``OCaml-LGPL-linking-exception``)
-• :t:`ISC License` (``ISC``)
-• :t:`Creative Commons Attribution-ShareAlike 4.0 International`
- (``CC-BY-SA-4.0``)
-• :t:`Mozilla Public License Version 2.0` (``MPL-2.0``)
-
-For details read ``LICENSE.txt`` with full license texts at ``license/``.
-
-
-Pitching in
-================================================================================
-
-Currently this is best done by sending a patchset to
-`toastal+nixtamal@posteo.net`_ or :ac:`DM` me a remote to clone @
-`toastal@toastal.in.th`_.
-
-Community is in an :ac:`XMPP` :ac:`MUC` (chatroom) with future hopes to have an
-:ac:`IRC` gateway. Join @ <xmpp:nixtamal@chat.toastal.in.th?join>.
-
-..
- Additionally, please read the ``PITCHING_IN.rst`` file for other
- information/expectations.
-
-.. _toastal+nixtamal@posteo.net: mailto:toastal+nixtamal@posteo.net
-.. _toastal@toastal.in.th: xmpp:toastal@toastal.in.th
-
-
-Funding
-================================================================================
-
-See choices at the `maker’s website <https://toast.al/funding/>`_.
-
-
-.. [1] :ac:`WIP` with upstream Nixpkgs
-
- • :del:`Darcs: https://github.com/NixOS/nixpkgs/pull/467172`
- • :del:`Pijul: https://github.com/NixOS/nixpkgs/pull/467890`
-
-.. vim: set textwidth=80
diff --git a/bin/cmd.ml b/bin/cmd.ml
index a411f43..533584d 100644
--- a/bin/cmd.ml
+++ b/bin/cmd.ml
@@ -29,7 +29,7 @@ module Global = struct
& info
["directory"]
~env
- ~doc: "Working directory for Nixtamal-related files (default: $PWD/nix/tamal)"
+ ~doc: "Working directory for Nixtamal-related files (default: \\$PWD/nix/tamal)"
~docv: "PATH"
)
@@ -186,8 +186,9 @@ module Set_up = struct
$ nixpkgs_revision_arg
)
in
+ let eio_env = env in
Term.(
- const (fun glb -> Global.run ~env glb @@ run)
+ const (fun glb -> Global.run ~env: eio_env glb @@ run)
$ Global.args
$ nixpkgs_arg
)
@@ -210,8 +211,9 @@ module Check_soundness = struct
let term ~env =
let open Cmdliner in
+ let eio_env = env in
Term.(
- const (fun glb -> Global.run ~env glb @@ run)
+ const (fun glb -> Global.run ~env: eio_env glb @@ run)
$ Global.args
)
@@ -233,8 +235,9 @@ module Tweak = struct
let term ~env =
let open Cmdliner in
+ let eio_env = env in
Term.(
- const (fun glb -> Global.run ~env glb @@ run)
+ const (fun glb -> Global.run ~env: eio_env glb @@ run)
$ Global.args
)
@@ -255,8 +258,9 @@ module Show = struct
let term ~env =
let open Cmdliner in
+ let eio_env = env in
Term.(
- const (fun glb -> Global.run ~env glb @@ run)
+ const (fun glb -> Global.run ~env: eio_env glb @@ run)
$ Global.args
)
@@ -291,8 +295,9 @@ module Lock = struct
& info [] ~docv: "INPUT_NAME" ~doc: "Input names to lock (if already locked, will skip)."
)
in
+ let eio_env = env in
Term.(
- const (fun glb force -> Global.run ~env glb @@ run force)
+ const (fun glb force -> Global.run ~env: eio_env glb @@ run force)
$ Global.args
$ force_arg
$ names_arg
@@ -315,8 +320,9 @@ module List_stale = struct
let term ~env =
let open Cmdliner in
+ let eio_env = env in
Term.(
- const (fun glb -> Global.run ~env glb @@ run)
+ const (fun glb -> Global.run ~env: eio_env glb @@ run)
$ Global.args
)
@@ -345,11 +351,73 @@ module Refresh = struct
& info [] ~docv: "INPUT_NAME" ~doc: "Input names to refresh."
)
in
+ let eio_env = env in
Term.(
- const (fun glb -> Global.run ~env glb @@ run)
+ const (fun glb -> Global.run ~env: eio_env glb @@ run)
$ Global.args
$ names_arg
)
let cmd ~env = Cmdliner.Cmd.v info (term ~env)
end
+
+module Upgrade = struct
+ let info =
+ Cmdliner.Cmd.info
+ "upgrade"
+ ~doc: "Upgrade lockfile & manifest to current schema version."
+ ~exits: Cmdliner.Cmd.Exit.defaults
+ ~man: common_man
+
+ let run ~env: _ ~domain_count: _ from to_ dry_run : unit =
+ let open Nixtamal in
+ match upgrade ?from ?to_ ~dry_run () with
+ | Ok () -> ()
+ | Error err -> failwith (Fmt.str "%a" Nixtamal.Error.pp err)
+
+ let term ~env =
+ let eio_env = env in
+ let open Cmdliner in
+ let version_conv : Nixtamal.Schema.Version.t Arg.conv =
+ Arg.conv
+ ~docv: "VERSION"
+ ((fun s ->
+ match Nixtamal.Schema.Version.of_string s with
+ | Some v -> Ok v
+ | None ->
+ let valid = Fmt.(array ~sep: comma Nixtamal.Schema.Version.pp) in
+ Error (`Msg (Fmt.str "Invalid version %s. Valid versions: %a" s valid Nixtamal.Schema.Version.versions))
+ ),
+ Nixtamal.Schema.Version.pp)
+ in
+ let from_arg =
+ let doc = "Upgrade from a specific version. Must match the lockfile version." in
+ Arg.(
+ value
+ & opt (some version_conv) None
+ & info ["from"] ~doc ~docv: "VERSION"
+ )
+ and to_arg =
+ let doc = "Upgrade to a specific version. Must be newer than --from." in
+ Arg.(
+ value
+ & opt (some version_conv) None
+ & info ["to"] ~doc ~docv: "VERSION"
+ )
+ and dry_run_arg =
+ Arg.(
+ value
+ & flag
+ & info ["dry-run"] ~doc: "Show what would be upgraded without making changes."
+ )
+ in
+ Term.(
+ const (fun glb -> Global.run ~env: eio_env glb @@ run)
+ $ Global.args
+ $ from_arg
+ $ to_arg
+ $ dry_run_arg
+ )
+
+ let cmd ~env = Cmdliner.Cmd.v info (term ~env)
+end
diff --git a/bin/dune b/bin/dune
index 5705f13..f36fcea 100644
--- a/bin/dune
+++ b/bin/dune
@@ -13,6 +13,7 @@
logs.cli
logs.fmt
uri)
+ (flags (:standard -alert -deprecated))
(preprocess
(pps ppx_deriving.show ppx_deriving.eq ppx_deriving.ord ppx_deriving.make)))
diff --git a/bin/main.ml b/bin/main.ml
index bdb25e7..739776f 100644
--- a/bin/main.ml
+++ b/bin/main.ml
@@ -27,6 +27,7 @@ let cmd ~env =
Cmd.Lock.cmd ~env;
Cmd.List_stale.cmd ~env;
Cmd.Refresh.cmd ~env;
+ Cmd.Upgrade.cmd ~env;
]
in
Cmdliner.Cmd.group info subcommands
diff --git a/flake.lock b/flake.lock
index 57a7d06..a7beb44 100644
--- a/flake.lock
+++ b/flake.lock
@@ -20,17 +20,17 @@
},
"nixpkgs": {
"locked": {
- "lastModified": 1770380644,
- "narHash": "sha256-P7dWMHRUWG5m4G+06jDyThXO7kwSk46C1kgjEWcybkE=",
+ "lastModified": 1767364772,
+ "narHash": "sha256-fFUnEYMla8b7UKjijLnMe+oVFOz6HjijGGNS1l7dYaQ=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "ae67888ff7ef9dff69b3cf0cc0fbfbcd3a722abe",
+ "rev": "16c7794d0a28b5a37904d55bcca36003b9109aaa",
"type": "github"
},
"original": {
"owner": "NixOS",
- "ref": "nixpkgs-unstable",
"repo": "nixpkgs",
+ "rev": "16c7794d0a28b5a37904d55bcca36003b9109aaa",
"type": "github"
}
},
diff --git a/flake.nix b/flake.nix
index 3d8d9a5..115a9d1 100644
--- a/flake.nix
+++ b/flake.nix
@@ -6,19 +6,24 @@
description = "Nixtamal - A Nix version pinning tool with first-class support for Darcs, Pijul, and other VCS systems";
inputs = {
- nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
+ nixpkgs.url = "github:NixOS/nixpkgs/16c7794d0a28b5a37904d55bcca36003b9109aaa";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
- pkgs = import nixpkgs { inherit system; };
+ pkgs = import nixpkgs {
+ inherit system;
+ overlays = [
+ (import ./nix/overlay/default.nix)
+ (import ./nix/overlay/development.nix)
+ (import ./nix/overlay/check.nix)
+ ];
+ };
- # Build nixtamal package using the traditional nix-build approach
- # This preserves the existing build infrastructure
+ # Build nixtamal package using callPackage
nixtamalPkg = pkgs.callPackage ./nix/package/nixtamal.nix {
- # Override dependencies as needed
nixtamal = null; # Prevent infinite recursion
};
diff --git a/lib/dune b/lib/dune
index d0741bb..3d47618 100644
--- a/lib/dune
+++ b/lib/dune
@@ -10,8 +10,10 @@
jsont.bytesrw
kdl
logs
+ str
saturn
uri)
+ (flags (:standard -alert -deprecated))
(preprocess
(pps
ppx_deriving.enum
diff --git a/lib/error.ml b/lib/error.ml
index da9a271..ba92eac 100644
--- a/lib/error.ml
+++ b/lib/error.ml
@@ -25,6 +25,8 @@ type prefetch_method = [
| `Git
| `Darcs
| `Pijul
+ | `Nilla
+ | `Fossil
]
[@@deriving show]
@@ -34,6 +36,7 @@ type prefetch_error = [
| `JSON_parsing of prefetch_method * string
| `Darcs_context of string
| `Run_exception of prefetch_method * exn * string
+ | `Not_implemented of prefetch_method * string
]
[@@deriving show]
@@ -55,6 +58,7 @@ type error = [
| `Manifest of manifest_error
| `Lockfile of lockfile_error
| `Version_mismatch of string * string
+ | `Upgrade of string
| `Input_foreman of input_foreman_error
]
[@@deriving show]
@@ -75,5 +79,7 @@ let pp ppf = function
Fmt.(pf ppf "%a" pp_lockfile_error err)
| `Version_mismatch (mnfst, lock) ->
Fmt.pf ppf "Version mismatch: Manifest@@%s & Lockfile@@%s" mnfst lock
- | `Input_foreman (`CouldNotAdd name) ->
- Fmt.pf ppf "Could not set %a" Name.pp name
+ | `Upgrade msg ->
+ Fmt.pf ppf "Upgrade error: %s" msg
+ | `Input_foreman err ->
+ Fmt.(pf ppf "%a" pp_input_foreman_error err)
diff --git a/lib/input.ml b/lib/input.ml
index f2fb1a7..00ee2c9 100644
--- a/lib/input.ml
+++ b/lib/input.ml
@@ -137,6 +137,62 @@ module Pijul = struct
[@@deriving show, eq, make, qcheck]
end
+(* Nilla is a Nix framework similar to flakes but with loaders and module system.
+ See: https://github.com/nilla-nix/nilla *)
+module Nilla = struct
+ let default_path = Template.make "./nilla.nix"
+
+ module Reference = struct
+ type t = [
+ | `Branch of UTF8.t
+ | `Ref of UTF8.t
+ ]
+ [@@deriving show, eq, qcheck]
+ end
+
+ type t = {
+ repository: Template.t;
+ mirrors: Template.t list;
+ reference: Reference.t;
+ datetime: UTF8.t option; (* ISO 8601 RFC 3339 *)
+ latest_revision: UTF8.t option;
+ path: Template.t; (* path to nilla.nix, default: ./nilla.nix *)
+ [@default default_path]
+ }
+ [@@deriving show, eq, make, qcheck]
+
+ let default_latest_cmd nilla : Latest.Cmd.t =
+ let open Latest.Cmd in
+ let t = Template.make in
+ let git_ls_remote (ls_remote_args : Template.t list) : t =
+ let args = t "ls-remote" :: nilla.repository :: ls_remote_args in
+ ~${prog = t "git"; args}
+ |: {prog = t "cut"; args = [t "-f1"]}
+ in
+ match nilla.reference with
+ | `Branch b -> git_ls_remote [t "--heads"; t b]
+ | `Ref r -> git_ls_remote [t "--refs"; t r]
+end
+
+module Fossil = struct
+ module Reference = struct
+ type t = [
+ | `Branch of UTF8.t
+ | `Tag of UTF8.t
+ | `Checkin of UTF8.t
+ ]
+ [@@deriving show, eq, qcheck]
+ end
+
+ type t = {
+ repository: Template.t;
+ reference: Reference.t;
+ date: UTF8.t option;
+ latest_checkin: UTF8.t option;
+ }
+ [@@deriving show, eq, make, qcheck]
+end
+
module Hash = struct
type algorithm =
| SHA256
@@ -181,6 +237,8 @@ module Kind = struct
| `Git of Git.t
| `Darcs of Darcs.t
| `Pijul of Pijul.t
+ | `Nilla of Nilla.t
+ | `Fossil of Fossil.t
]
[@@deriving show, eq, qcheck]
end
@@ -200,6 +258,12 @@ let make_kind_pijul ~remote ?mirrors ~reference ?latest_state () =
let make_kind_git ~repository ?mirrors ~reference ?latest_revision ?submodules ?lfs () =
`Git (Git.make ~repository ?mirrors ~reference ?latest_revision ?submodules ?lfs ())
+let make_kind_nilla ~repository ?mirrors ~reference ?latest_revision ?path () =
+ `Nilla (Nilla.make ?mirrors ~repository ~reference ?latest_revision ?path ())
+
+let make_kind_fossil ~repository ~reference ?date ?latest_checkin () =
+ `Fossil (Fossil.make ~repository ~reference ?date ?latest_checkin ())
+
type t = {
name: Name.t;
kind: Kind.t;
@@ -217,8 +281,9 @@ let latest_cmd (input : t) : Latest.Cmd.t option =
(
match input.kind with
| `Git g -> Some (Git.default_latest_cmd g)
+ | `Nilla n -> Some (Nilla.default_latest_cmd n)
(* Would be nice if other tools did a better job letting you query the
- remote repository directly, but that isn’t where we are *)
+ remote repository directly, but that isn't where we are *)
| _ -> None
)
| Some cmd -> Some cmd
@@ -289,6 +354,36 @@ let jg_models2 (input : t) (needle : string) : Jingoo.Jg_types.tvalue =
Option.iter (fun s -> Hashtbl.add htbl "state" (Tstr s)) p.latest_state;
htbl
end
+ | `Nilla n ->
+ begin
+ let htbl = make_hashtbl 4 in
+ (
+ match n.reference with
+ | `Branch b -> Hashtbl.add htbl "branch" (Tstr b)
+ | `Ref r -> Hashtbl.add htbl "ref" (Tstr r)
+ );
+ Option.iter (fun d -> Hashtbl.add htbl "datetime" (Tstr d)) n.datetime;
+ Hashtbl.add htbl "path" (Tstr (Template.take n.path));
+ Option.iter
+ (fun r ->
+ List.iter (fun key -> Hashtbl.add htbl key (Tstr r)) ["rev"; "revision"]
+ )
+ n.latest_revision;
+ htbl
+ end
+ | `Fossil f ->
+ begin
+ let htbl = make_hashtbl 3 in
+ (
+ match f.reference with
+ | `Branch b -> Hashtbl.add htbl "branch" (Tstr b)
+ | `Tag t -> Hashtbl.add htbl "tag" (Tstr t)
+ | `Checkin c -> Hashtbl.add htbl "checkin" (Tstr c)
+ );
+ Option.iter (fun d -> Hashtbl.add htbl "datetime" (Tstr d)) f.date;
+ Option.iter (fun c -> Hashtbl.add htbl "latest_checkin" (Tstr c)) f.latest_checkin;
+ htbl
+ end
in
match Hashtbl.find_opt hashtbl needle with
| Some value -> value
diff --git a/lib/input_foreman.ml b/lib/input_foreman.ml
index dec3f32..9fefa5f 100644
--- a/lib/input_foreman.ml
+++ b/lib/input_foreman.ml
@@ -102,6 +102,33 @@ let pp_for_earthlings pff =
Option.fold ~none: [] ~some: (fun d -> ["datetime", d]) p.datetime;
Option.fold ~none: [] ~some: (fun s -> ["latest-state", s]) p.latest_state;
]
+ | `Nilla n ->
+ "nilla",
+ List.concat [
+ ["repository", fill n.repository];
+ (List.map (fun m -> "mirror", fill m) n.mirrors);
+ (
+ match n.reference with
+ | `Branch b -> ["branch", b]
+ | `Ref r -> ["ref", r]
+ );
+ ["path", fill n.path];
+ Option.fold ~none: [] ~some: (fun d -> ["datetime", d]) n.datetime;
+ Option.fold ~none: [] ~some: (fun r -> ["latest-revision", r]) n.latest_revision;
+ ]
+ | `Fossil f ->
+ "fossil",
+ List.concat [
+ ["repository", fill f.repository];