first release

This commit is contained in:
atagen 2024-11-23 16:49:05 +11:00
commit 3393f1ecfe
16 changed files with 615 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
_build
.direnv/
.envrc

0
bin/.ocamlformat Normal file
View File

4
bin/dune Normal file
View File

@ -0,0 +1,4 @@
(executable
(public_name meat)
(name main)
(libraries meat))

16
bin/main.ml Normal file
View File

@ -0,0 +1,16 @@
open Meat
let () =
print_int (Array.length Sys.argv);
if Array.length Sys.argv >= 2 then (
print_endline " args. contents:";
Array.iter print_endline Sys.argv;
match String.lowercase_ascii (Array.get Sys.argv 1) with
| "yum" -> yum ()
| "cook" -> cook ()
| "poke" -> poke ()
| "gut" -> gut ()
| "look" -> look ()
| "fresh" -> fresh ()
| _ -> help ()
) else help ();

26
dune-project Normal file
View File

@ -0,0 +1,26 @@
(lang dune 3.17)
(name meat)
(generate_opam_files true)
(source
(github username/reponame))
(authors "Author Name <author@example.com>")
(maintainers "Maintainer Name <maintainer@example.com>")
(license LICENSE)
(documentation https://url/to/documentation)
(package
(name meat)
(synopsis "A short synopsis")
(description "A longer description")
(depends ocaml dune)
(tags
("add topics" "to describe" your project)))
; See the complete stanza docs at https://dune.readthedocs.io/en/stable/reference/dune-project/index.html

239
flake.lock generated Normal file
View File

@ -0,0 +1,239 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1726560853,
"narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_2": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_3": {
"inputs": {
"systems": "systems_3"
},
"locked": {
"lastModified": 1726560853,
"narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flakey-profile": {
"locked": {
"lastModified": 1712898590,
"narHash": "sha256-FhGIEU93VHAChKEXx905TSiPZKga69bWl1VB37FK//I=",
"owner": "lf-",
"repo": "flakey-profile",
"rev": "243c903fd8eadc0f63d205665a92d4df91d42d9d",
"type": "github"
},
"original": {
"owner": "lf-",
"repo": "flakey-profile",
"type": "github"
}
},
"lix": {
"flake": false,
"locked": {
"lastModified": 1732112222,
"narHash": "sha256-H7GN4++a4vE49SUNojZx+FSk4mmpb2ifJUtJMJHProI=",
"rev": "66f6dbda32959dd5cf3a9aaba15af72d037ab7ff",
"type": "tarball",
"url": "https://git.lix.systems/api/v1/repos/lix-project/lix/archive/66f6dbda32959dd5cf3a9aaba15af72d037ab7ff.tar.gz?rev=66f6dbda32959dd5cf3a9aaba15af72d037ab7ff"
},
"original": {
"type": "tarball",
"url": "https://git.lix.systems/lix-project/lix/archive/main.tar.gz"
}
},
"lix-module": {
"inputs": {
"flake-utils": "flake-utils_2",
"flakey-profile": "flakey-profile",
"lix": [
"lix"
],
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1731967274,
"narHash": "sha256-n6dPGRlMGdL8X5gviA6ZuRfUdbdD5KiNN/BpABA5YT0=",
"rev": "aa2846680fa9a2032939d720487942567fd9eb63",
"type": "tarball",
"url": "https://git.lix.systems/api/v1/repos/lix-project/nixos-module/archive/aa2846680fa9a2032939d720487942567fd9eb63.tar.gz?rev=aa2846680fa9a2032939d720487942567fd9eb63"
},
"original": {
"type": "tarball",
"url": "https://git.lix.systems/lix-project/nixos-module/archive/main.tar.gz"
}
},
"nh": {
"inputs": {
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1732089528,
"narHash": "sha256-+yXeJiSFn96pW6H/50DfCfZiOLSfZNGhK7R4f0aUvGY=",
"owner": "viperML",
"repo": "nh",
"rev": "cff51af0ebb09227070b0332c598c7a4b7f8175a",
"type": "github"
},
"original": {
"owner": "viperML",
"repo": "nh",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1731386116,
"narHash": "sha256-lKA770aUmjPHdTaJWnP3yQ9OI1TigenUqVC3wweqZuI=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "689fed12a013f56d4c4d3f612489634267d86529",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-24.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1730359060,
"narHash": "sha256-Hkk0mf4pgvX9Ut0YA397nsFqMLhzFVBdFHc4PhBrxYE=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e19cfce6f3f08d07653157d8826f5c920c770d7b",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e19cfce6f3f08d07653157d8826f5c920c770d7b",
"type": "github"
}
},
"ocaml-overlay": {
"inputs": {
"flake-utils": "flake-utils_3",
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1730414122,
"narHash": "sha256-eAfo1XsQMdKuiOOhqCuai7vpIBH8S4ll7Sm4BP/M58c=",
"owner": "nix-ocaml",
"repo": "nix-overlays",
"rev": "1de1cabdb68cbc667dd48da2f128c2df6d5fe604",
"type": "github"
},
"original": {
"owner": "nix-ocaml",
"repo": "nix-overlays",
"type": "github"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"lix": "lix",
"lix-module": "lix-module",
"nh": "nh",
"nixpkgs": [
"ocaml-overlay",
"nixpkgs"
],
"ocaml-overlay": "ocaml-overlay"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_3": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

112
flake.nix Normal file
View File

@ -0,0 +1,112 @@
{
inputs = {
nixpkgs.follows = "ocaml-overlay/nixpkgs";
ocaml-overlay = {
url = "github:nix-ocaml/nix-overlays";
};
flake-utils.url = "github:numtide/flake-utils";
nh.url = "github:viperML/nh";
lix = {
url = "https://git.lix.systems/lix-project/lix/archive/main.tar.gz";
flake = false;
};
lix-module = {
url = "https://git.lix.systems/lix-project/nixos-module/archive/main.tar.gz";
inputs.nixpkgs.follows = "nixpkgs";
inputs.lix.follows = "lix";
};
};
outputs = inputs @ {
self,
nixpkgs,
flake-utils,
ocaml-overlay,
...
}: let
inherit (inputs) nixpkgs;
lix-overlay = inputs.lix-module.overlays.default;
lix-module = inputs.lix-module.nixosModules.default;
nh-overlay = inputs.nh.overlays.default;
in
flake-utils.lib.eachDefaultSystem (
system: let
pkgs = import nixpkgs {
inherit system;
overlays = [
ocaml-overlay.overlays.default
lix-overlay
nh-overlay
];
modules = [lix-module];
extra-substituters = "https://anmonteiro.nix-cache.workers.dev";
extra-trusted-public-keys = "ocaml.nix-cache.com-1:/xI2h2+56rwFfKyyFVbkJSeGqSIYMC/Je+7XXqGKDIY=";
};
minimal = let
inherit (pkgs) ocaml-ng;
inherit
(ocaml-ng.ocamlPackages_5_2)
dune_3
ocaml
;
in [
dune_3
ocaml
];
dev = let
inherit (pkgs) ocaml-ng;
inherit
(ocaml-ng.ocamlPackages_5_2)
utop
ocaml-lsp
ocamlformat
ocamlformat-rpc-lib
;
in [
utop
ocaml-lsp
ocamlformat
ocamlformat-rpc-lib
];
inherit (pkgs) lix nh;
in {
devShells.default = let
inherit (pkgs) mkShell;
in
mkShell {
buildInputs = minimal ++ dev ++ [lix nh];
};
packages.default = pkgs.callPackage ./nix/default.nix {ocaml-deps = minimal;};
defaultPackage = self.packages.${system}.default;
}
)
// {
nixosModules.meat = import ./nix/module.nix {
meatOverlays = [self.overlays.meat nh-overlay];
lixModule = lix-module;
};
overlays.meat = final: _prev: let
ocaml-deps = let
inherit (final) ocaml-ng;
inherit
(ocaml-ng.ocamlPackages_5_2)
dune_3
ocaml
;
in [
dune_3
ocaml
];
in {
meat = final.callPackage ./nix/default.nix {inherit ocaml-deps;};
};
};
}

0
lib/.ocamlformat Normal file
View File

3
lib/dune Normal file
View File

@ -0,0 +1,3 @@
(library
(name meat)
(libraries unix))

124
lib/meat.ml Normal file
View File

@ -0,0 +1,124 @@
let header = "\n ----- MEAT ----------------------------------------\n"
let footer = "\n ---------------------------------------------------\n"
let help =
"\n\
\tYUM - CONSUME DELICIOUS MEATS\n\
\tCOOK - ONLY PREPARE MEATS\n\
\tPOKE - TASTE SUSPICIOUS MEATS\n\
\tGUT - CLEAN MEAT STORES\n\
\tLOOK - INSPECT MEAT\n\
\tFRESH - HUNT LATEST MEATS\n\
\t ..N - ..LATEST SUBMEATS OF N\n\
\t ..-A - ..HUNT ALL SUBMEATS\n"
open Sys
let pass_args () =
let len = Array.length argv and sconcat acc el = acc ^ " " ^ el in
match len with
| 3 -> argv.(2)
| n when n > 3 ->
print_int (n - 1);
Array.fold_left sconcat "" (Array.sub argv 2 (n - 2))
| _ -> ""
let do_cmd ?(args = true) cmd =
match command (if args then cmd ^ pass_args () else cmd) with _ -> ()
let meat_print text = print_endline ("\n \t" ^ text ^ "\n")
let yum () =
print_string header;
meat_print "CONSUMING DELICIOUS MEATS..";
do_cmd "nh os switch";
print_string footer
let cook () =
print_string header;
meat_print "PREPARING DELICIOUS MEATS..";
do_cmd "nh os build";
print_string footer
let poke () =
print_string header;
meat_print "PREPARING SUSPICIOUS MEATS..";
do_cmd "nh os build --show-trace";
print_string footer
let gut () =
print_string header;
meat_print "CLEANING MEAT STORES..";
do_cmd "nh clean all";
print_string footer
let look () =
print_string header;
meat_print "INSPECTING MEAT..";
do_cmd "nix flake info --flake $NH_FLAKE";
print_string footer
let all_flag () = Array.mem "-a" argv || Array.mem "--all" argv
let derelativise base = List.map (fun a -> base ^ "/" ^ a)
let filter_dirs fullpath dirs =
dirs |> derelativise fullpath
|> List.filter (fun d -> (Unix.stat d).st_kind = S_DIR)
let walk ?(include_base = false) entry =
let rec loop dir : string list =
let contents = Sys.readdir dir |> Array.to_list in
let is_flake = List.mem "flake.nix" contents in
if dir = entry && not include_base then
let subdirs = contents |> filter_dirs dir in
List.flatten (List.map loop subdirs)
else if is_flake || (dir = entry && include_base) then
let subdirs = contents |> filter_dirs dir in
let children = List.flatten (List.map loop subdirs) in
[ dir ] @ children
else []
in
loop entry
let countdepth s =
s |> String.fold_left (fun acc el -> acc + if el = '/' then 1 else 0) 0
let compdepth a b =
let ad = countdepth a and bd = countdepth b in
let dif = ad - bd in
match dif with 0 -> 0 | _ -> dif / abs dif
let allcaps s =
String.map (fun c -> Char.uppercase_ascii c) s
let fresh () =
print_string header;
meat_print "HUNTING FRESH MEATS..";
print_string footer;
let argv_len = Array.length argv in
let root = Sys.getenv "NH_FLAKE" in
let base_dir = root ^ "/flakes" in
let update =
if all_flag () then walk base_dir |> List.sort compdepth |> List.rev
else if argv_len >= 3 then
let subflakes =
match argv_len with
| 3 -> [ argv.(2) ]
| _ -> Array.sub argv 2 (argv_len - 2) |> Array.to_list
in
subflakes |> derelativise base_dir
|> List.map (walk ~include_base:true)
|> List.flatten |> List.sort compdepth |> List.rev
else []
in
update @ [ root ]
|> List.iter (fun d ->
if d != root then
(meat_print ("PROCESSING SUBMEAT " ^ (String.split_on_char '/' d |> List.rev |> List.hd |> allcaps) ^ "..");)
else
meat_print ("PROCESSING FRESH MEATS..");
do_cmd ~args:false ("nix flake update --flake " ^ d);
print_string footer;);
print_newline ()
let help () = print_string (header ^ help ^ footer)

31
meat.opam Normal file
View File

@ -0,0 +1,31 @@
# This file is generated by dune, edit dune-project instead
opam-version: "2.0"
synopsis: "A short synopsis"
description: "A longer description"
maintainer: ["Maintainer Name <maintainer@example.com>"]
authors: ["Author Name <author@example.com>"]
license: "LICENSE"
tags: ["add topics" "to describe" "your" "project"]
homepage: "https://github.com/username/reponame"
doc: "https://url/to/documentation"
bug-reports: "https://github.com/username/reponame/issues"
depends: [
"ocaml"
"dune" {>= "3.17"}
"odoc" {with-doc}
]
build: [
["dune" "subst"] {dev}
[
"dune"
"build"
"-p"
name
"-j"
jobs
"@install"
"@runtest" {with-test}
"@doc" {with-doc}
]
]
dev-repo: "git+https://github.com/username/reponame.git"

18
nix/default.nix Normal file
View File

@ -0,0 +1,18 @@
{
pkgs,
lib,
ocamlPackages,
ocaml-deps,
nh,
nix,
...
}:
ocamlPackages.buildDunePackage {
pname = "meat";
version = "delicious-0.1";
minimalOCamlVersion = "5.2";
src = ./..;
buildInputs = ocaml-deps;
}

30
nix/meat-module.nix Normal file
View File

@ -0,0 +1,30 @@
{
pkgs,
lib,
config,
...
}: let
inherit (lib) mkEnableOption mkOption types;
cfg = config.programs.meat;
in {
options.programs.meat = {
enable = mkEnableOption "meat";
flake = mkOption {
type = with types; nullOr (either path str);
default = null;
description = "path to your system flake";
};
};
config = let
inherit (pkgs) meat nh lix;
in
lib.mkIf
cfg.enable
{
environment.systemPackages = [meat nh lix];
environment.sessionVariables.NH_FLAKE =
if (cfg.flake == null)
then abort "Please set the programs.meat.flake option to your system flake."
else config.programs.meat.flake;
};
}

7
nix/module.nix Normal file
View File

@ -0,0 +1,7 @@
{
meatOverlays,
lixModule,
}: {
imports = [./meat-module.nix lixModule];
nixpkgs.overlays = meatOverlays;
}

2
test/dune Normal file
View File

@ -0,0 +1,2 @@
(test
(name test_meat))

0
test/test_meat.ml Normal file
View File