diff --git a/lib/meat.ml b/lib/meat.ml index 8336f1b..62daf79 100644 --- a/lib/meat.ml +++ b/lib/meat.ml @@ -9,8 +9,9 @@ let help = \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" + \t..N - ..MEATS OF N\n\ + \t..-S N - ..SUBMEAT N\n\ + \t..-A - ..ALL MEATS\n" open Sys @@ -62,20 +63,23 @@ let look () = print_string footer let all_flag () = Array.mem "-a" argv || Array.mem "--all" argv +let sub_flag () = Array.mem "-s" argv || Array.mem "--subflake" 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 readdir d = try Sys.readdir d with Sys_error _ -> [||] + +let walk entry = let rec loop dir : string list = - let contents = Sys.readdir dir |> Array.to_list in + let contents = readdir dir |> Array.to_list in let is_flake = List.mem "flake.nix" contents in - if dir = entry && not include_base then + if dir = entry then let subdirs = contents |> filter_dirs dir in List.flatten (List.map loop subdirs) - else if is_flake || (dir = entry && include_base) then + else if is_flake then let subdirs = contents |> filter_dirs dir in let children = List.flatten (List.map loop subdirs) in [ dir ] @ children @@ -91,37 +95,55 @@ let compdepth a b = 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 all_caps s = s |> String.map (fun c -> Char.uppercase_ascii c) +let all_low s = s |> String.map (fun c -> Char.lowercase_ascii c) +let fmt_dir d = String.split_on_char '/' d |> List.rev |> List.hd |> all_caps + +let submeats s = + s + |> List.iter (fun d -> + meat_print ("PROCESSING SUBMEAT " ^ fmt_dir d ^ ".."); + do_cmd ~args:false ("nix flake update --flake " ^ d)) 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 + (match (sub_flag (), all_flag ()) with + | false, false -> + (* no flags, plain flake inputs *) + let flakes = Array.sub argv 2 (argv_len - 2) in + flakes + |> Array.iter (fun f -> + meat_print ("PROCESSING FRESH MEAT " ^ all_caps f ^ ".."); + do_cmd ~args:false + ("nix flake update " ^ all_low f ^ " --flake $NH_FLAKE")) + | _, true -> + (* all flag, update all subflakes and main flake inputs *) + walk base_dir |> List.sort compdepth |> List.rev |> submeats; + print_string footer; + meat_print "PROCESSING FRESH MEATS.."; + do_cmd ~args:false ("nix flake update --flake " ^ root) + | true, _ when argv_len >= 4 -> + (* sub flag, update inputs as subflakes *) let subflakes = - match argv_len with - | 3 -> [ argv.(2) ] - | _ -> Array.sub argv 2 (argv_len - 2) |> Array.to_list + (match argv_len with + | 4 -> [ argv.(3) ] + | _ -> Array.sub argv 4 (argv_len - 4) |> 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;); + let sf_full = subflakes |> derelativise base_dir in + sf_full |> List.map walk |> List.flatten |> List.sort compdepth + |> List.rev |> List.append sf_full |> submeats; + print_string footer; + meat_print "PROCESSING FRESH MEATS.."; + subflakes + |> List.iter (fun f -> + do_cmd ~args:false + ("nix flake update " ^ all_low f ^ " --flake $NH_FLAKE")) + | _ -> print_string help); + print_string footer; print_newline () - + let help () = print_string (header ^ help ^ footer)