diff options
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | AGENTS.md | 72 | ||||
| -rw-r--r-- | README.asciidoc | 39 | ||||
| -rw-r--r-- | README.rst | 269 | ||||
| -rw-r--r-- | bin/cmd.ml | 84 | ||||
| -rw-r--r-- | bin/dune | 1 | ||||
| -rw-r--r-- | bin/main.ml | 1 | ||||
| -rw-r--r-- | flake.lock | 8 | ||||
| -rw-r--r-- | flake.nix | 15 | ||||
| -rw-r--r-- | lib/dune | 2 | ||||
| -rw-r--r-- | lib/error.ml | 10 | ||||
| -rw-r--r-- | lib/input.ml | 97 | ||||
| -rw-r--r-- | lib/input_foreman.ml | 44 | ||||
| -rw-r--r-- | lib/lock_loader.ml | 6 | ||||
| -rw-r--r-- | lib/lockfile.ml | 83 | ||||
| -rw-r--r-- | lib/manifest.ml | 173 | ||||
| -rw-r--r-- | lib/nixtamal.ml | 161 | ||||
| -rw-r--r-- | lib/prefetch.ml | 119 | ||||
| -rw-r--r-- | lib/schema.ml | 31 | ||||
| -rw-r--r-- | llm/2026-01-07-Session-Changes-Summary.md | 33 | ||||
| -rw-r--r-- | llm/2026-02-07-attribution-audit.md | 25 | ||||
| -rw-r--r-- | llm/2026-02-07-phase1-flake-integration.md | 133 | ||||
| -rw-r--r-- | llm/README.md | 41 | ||||
| -rw-r--r-- | nixtamal.opam | 2 | ||||
| -rw-r--r-- | test/dune | 1 |
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/ @@ -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 @@ -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 @@ -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 @@ -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" } }, @@ -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 }; @@ -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]; + ( + match f.reference with + | `Branch b -> ["branch", b] + | `Tag t -> ["tag", t] + | `Checkin c -> ["checkin", c] + ); + Option.fold ~none: [] ~some: (fun d -> ["date", d]) f.date; + Option.fold ~none: [] ~some: (fun c -> ["latest-checkin", c]) f.latest_checkin; + ] in let data_tuples : (string * string) list = List.concat [ @@ -346,6 +373,21 @@ let prefetch ~env ~proc_mgr ~name () : (unit, error) result = }, p_data.path ) + | `Nilla n, `Nilla n_data -> + Ok ( + {input with + kind = + `Nilla {n with + latest_revision = Some n_data.rev; + datetime = n_data.datetime; + }; + hash = {input.hash with + algorithm = n_data.hash.algorithm; + value = Some n_data.hash.value; + }; + }, + n_data.path + ) | _, _ -> failwith "Prefetch kind mismatch" |
