this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 153 lines 5.7 kB view raw
1(** Shared CLI terms and helpers *) 2 3open Cmdliner 4 5let os_dir_term = 6 let doc = "OS-specific cache directory (e.g. /cache/linux-x86_64)" in 7 Arg.(required & opt (some string) None & info [ "os-dir" ] ~docv:"DIR" ~doc) 8 9let cache_dir_term = 10 let doc = "Top-level cache directory" in 11 Arg.(required & opt (some string) None & info [ "cache-dir" ] ~docv:"DIR" ~doc) 12 13let opam_repo_term = 14 let doc = "Path to opam-repository (repeatable, layered in order — \ 15 later repos override earlier ones)" in 16 Arg.(non_empty & opt_all string [] & info [ "opam-repository" ] ~docv:"DIR" ~doc) 17 18let np_term = 19 let doc = "Number of parallel workers (default 4)" in 20 Arg.(value & opt int 4 & info [ "np"; "j" ] ~docv:"N" ~doc) 21 22let arch_term = 23 let doc = "Architecture (default x86_64)" in 24 Arg.(value & opt string "x86_64" & info [ "arch" ] ~docv:"ARCH" ~doc) 25 26let os_distribution_term = 27 let doc = "OS distribution (default debian)" in 28 Arg.(value & opt string "debian" & info [ "os-distribution" ] ~docv:"DIST" ~doc) 29 30let os_version_term = 31 let doc = "OS version (default bookworm)" in 32 Arg.(value & opt string "bookworm" & info [ "os-version" ] ~docv:"VER" ~doc) 33 34let ocaml_version_term = 35 let doc = "OCaml compiler version (e.g. ocaml-base-compiler.5.2.1 \ 36 or ocaml-variants.5.2.0+ox)" in 37 Arg.(value & opt (some string) None & info [ "ocaml-version" ] ~docv:"PKG" ~doc) 38 39let patches_dir_term = 40 let doc = "Directory of patches to apply before building. \ 41 Structure: DIR/PKG.VERSION/*.patch" in 42 Arg.(value & opt (some string) None & info [ "patches-dir" ] ~docv:"DIR" ~doc) 43 44let opam_build_repo_term = 45 let doc = "Path to local opam-build source checkout \ 46 (builds opam-build from source for the base image)" in 47 Arg.(value & opt (some string) None & info [ "opam-build-repo" ] ~docv:"DIR" ~doc) 48 49let with_eio f = 50 Eio_main.run @@ fun env -> f (env :> Eio_unix.Stdenv.base) 51 52let fpath s = Fpath.v s 53 54let setup_solver ?(arch = "x86_64") ?(os = "linux") 55 ?(os_distribution = "debian") ?(os_family = "debian") 56 ?(os_version = "12") opam_repositories = 57 let repos_with_heads = List.map (fun repo -> 58 (repo, None) 59 ) opam_repositories in 60 let git_packages, repos_with_shas = 61 Day11_opam.Git_packages.of_repositories repos_with_heads in 62 (* ocaml-git corrupts Bos's temp dir setting — reset it *) 63 Bos.OS.Dir.set_default_tmp (Fpath.v (Filename.get_temp_dir_name ())); 64 let opam_env = Day11_opam.Opam_env.std_env 65 ~arch ~os ~os_distribution ~os_family ~os_version () in 66 (git_packages, repos_with_shas, opam_env) 67 68let parse_ocaml_version = function 69 | None -> None 70 | Some s -> Some (OpamPackage.of_string s) 71 72(* ── Profile support ───────────────────────────────────────────── *) 73 74let profile_term = 75 let doc = "Profile name (from ~/.day11/profiles/)" in 76 Arg.(required & opt (some string) None & info [ "profile" ] ~docv:"NAME" ~doc) 77 78let profile_dir_term = 79 let doc = "Profile directory (default ~/.day11)" in 80 Arg.(value & opt string "" & info [ "profile-dir" ] ~docv:"DIR" ~doc) 81 82type paths = { 83 profile_dir : Fpath.t; 84 cache_dir : Fpath.t; 85 os_dir : Fpath.t; 86 snapshots_base : Fpath.t; 87} 88 89let resolve_profile_dir s = 90 if s = "" then Day11_batch.Profile.default_dir () 91 else Fpath.v s 92 93let load_profile ~profile_dir ~name = 94 let pdir = resolve_profile_dir profile_dir in 95 let profiles_dir = Fpath.(pdir / "profiles") in 96 match Day11_batch.Profile.load ~dir:profiles_dir ~name with 97 | Error e -> Error e 98 | Ok profile -> 99 let cache_dir = Fpath.(pdir / "cache") in 100 let os_dir = Fpath.(cache_dir / Day11_batch.Profile.os_dir_name profile) in 101 let snapshots_base = Fpath.(pdir / "snapshots" / name) in 102 Ok (profile, { profile_dir = pdir; cache_dir; os_dir; snapshots_base }) 103 104let ensure_paths (paths : paths) = 105 ignore (Bos.OS.Dir.create ~path:true paths.cache_dir); 106 ignore (Bos.OS.Dir.create ~path:true paths.os_dir); 107 ignore (Bos.OS.Dir.create ~path:true paths.snapshots_base) 108 109let latest_snapshot_dir (paths : paths) = 110 match Bos.OS.Dir.contents paths.snapshots_base with 111 | Error _ -> None 112 | Ok entries -> 113 let dirs = entries 114 |> List.filter (fun p -> Bos.OS.Dir.exists p |> Result.get_ok) 115 |> List.filter_map (fun p -> 116 try 117 let stat = Unix.stat (Fpath.to_string p) in 118 Some (p, stat.Unix.st_mtime) 119 with Unix.Unix_error _ -> None) 120 |> List.sort (fun (_, t1) (_, t2) -> compare t2 t1) 121 in 122 match dirs with 123 | (p, _) :: _ -> Some p 124 | [] -> None 125 126let snapshot_dirs_by_recency (paths : paths) = 127 match Bos.OS.Dir.contents paths.snapshots_base with 128 | Error _ -> [] 129 | Ok entries -> 130 entries 131 |> List.filter (fun p -> Bos.OS.Dir.exists p |> Result.get_ok) 132 |> List.filter_map (fun p -> 133 try 134 let stat = Unix.stat (Fpath.to_string p) in 135 Some (p, stat.Unix.st_mtime) 136 with Unix.Unix_error _ -> None) 137 |> List.sort (fun (_, t1) (_, t2) -> compare t2 t1) 138 |> List.map fst 139 140let read_pins_from_dir dir = 141 let opam_files = Sys.readdir dir |> Array.to_list 142 |> List.filter (fun f -> Filename.check_suffix f ".opam") in 143 List.fold_left (fun acc filename -> 144 let name = Filename.chop_suffix filename ".opam" in 145 let path = Filename.concat dir filename in 146 try 147 let opam = OpamFile.OPAM.read 148 (OpamFile.make (OpamFilename.raw path)) in 149 OpamPackage.Name.Map.add 150 (OpamPackage.Name.of_string name) 151 (OpamPackage.Version.of_string "dev", opam) acc 152 with _ -> acc 153 ) OpamPackage.Name.Map.empty opam_files