meat/lib/meat.ml
2024-11-23 16:49:05 +11:00

125 lines
3.6 KiB
OCaml

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)