summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/error.ml6
-rw-r--r--lib/input_foreman.ml177
2 files changed, 70 insertions, 113 deletions
diff --git a/lib/error.ml b/lib/error.ml
index a658f50..83cca60 100644
--- a/lib/error.ml
+++ b/lib/error.ml
@@ -4,6 +4,9 @@
└─────────────────────────────────────────────────────────────────────────────*)
open Name
+let pp_exn ppf exn =
+ Fmt.pf ppf "%s" (Printexc.to_string exn)
+
type manifest_error = [
| `Parsing of KDL.Valid.err list
| `Not_set_up
@@ -27,10 +30,9 @@ type prefetch_method = [
type prefetch_error = [
| `Empty_output of prefetch_method
- | `Stderr of prefetch_method * string
| `JSON_parsing of prefetch_method * string
| `Darcs_context of string
- | `Exception of prefetch_method * string
+ | `RunException of prefetch_method * exn * string
]
[@@deriving show]
diff --git a/lib/input_foreman.ml b/lib/input_foreman.ml
index db39a92..8963ee0 100644
--- a/lib/input_foreman.ml
+++ b/lib/input_foreman.ml
@@ -205,13 +205,24 @@ let prefetch ~env ~proc_mgr ~name () : (unit, error) result =
let unix_env = Unix.environment () in
Array.append unix_env [|"NIX_HASH_ALGO=" ^ hash_algo_type_val|]
in
- let stdout_buf = Buffer.create 1024
- and stderr_buf = Buffer.create 1024
- in
- let stdout_sink = Eio.Flow.buffer_sink stdout_buf
- and stderr_sink = Eio.Flow.buffer_sink stderr_buf
- and models = Input.jg_models2 input
+ let run_and_gather ?(buffer_size = 1024) method' cmd =
+ let stdout_buf = Buffer.create buffer_size
+ and stderr_buf = Buffer.create buffer_size
+ in
+ let stdout_sink = Eio.Flow.buffer_sink stdout_buf
+ and stderr_sink = Eio.Flow.buffer_sink stderr_buf
+ in
+ let* () =
+ try
+ Eio.Process.run proc_mgr ~env: proc_env ~stdout: stdout_sink ~stderr: stderr_sink cmd;
+ Ok ()
+ with
+ | exn ->
+ Error (`RunException (method', exn, String.trim (Buffer.contents stdout_buf)))
+ in
+ Ok (String.trim (Buffer.contents stdout_buf))
in
+ let models = Input.jg_models2 input in
let prefetch_file (f : File.t) : (Input.t, Error.prefetch_error) result =
let method' = `URL
and url = Uri.of_string (Input.Template.fill f.url ~models)
@@ -224,32 +235,22 @@ let prefetch ~env ~proc_mgr ~name () : (unit, error) result =
]
in
Logs.debug (fun m -> m "Running file cmd: %a" (Fmt.list ~sep: Fmt.sp Fmt.string) cmd);
- try
- let () =
- Eio.Process.run
- proc_mgr
- ~env: proc_env
- ~stdout: stdout_sink
- ~stderr: stderr_sink
- cmd
- in
- let stderr_str = String.trim @@ Buffer.contents stderr_buf in
- (* Fkin’ A… why use stderr for *not* errors, Nix‽ *)
- if stderr_str <> "" && not (String.starts_with ~prefix: "path is" stderr_str) then
- Error (`Stderr (method', stderr_str))
- else
- let stdin_str = String.trim @@ Buffer.contents stdout_buf in
- Logs.debug (fun m -> m "Command output: %s" stdin_str);
+ match run_and_gather method' cmd with
+ | Ok "" ->
+ Error (`Empty_output method')
+ | Ok stdout ->
+ begin
+ Logs.debug (fun m -> m "Command output: %s" stdout);
let last_nonempty_line =
- String.split_on_char '\n' stdin_str
+ String.split_on_char '\n' stdout
|> List.rev
|> List.find_opt (fun line -> line <> "")
in
match last_nonempty_line with
| None -> Error (`Empty_output method')
| value -> Ok {input with hash = {input.hash with value}}
- with
- | exn -> Error (`Exception (method', Printexc.to_string exn))
+ end
+ | Error err -> Error err
and prefetch_archive (a : Archive.t) : (Input.t, Error.prefetch_error) result =
let method' = `URL
@@ -264,32 +265,22 @@ let prefetch ~env ~proc_mgr ~name () : (unit, error) result =
]
in
Logs.debug (fun m -> m "Running archive cmd: %a" (Fmt.list ~sep: Fmt.sp Fmt.string) cmd);
- try
- let () =
- Eio.Process.run
- proc_mgr
- ~env: proc_env
- ~stdout: stdout_sink
- ~stderr: stderr_sink
- cmd
- in
- let stderr_str = String.trim @@ Buffer.contents stderr_buf in
- (* Fkin’ A… why use stderr for *not* errors, Nix‽ *)
- if stderr_str <> "" && not (String.starts_with ~prefix: "path is" stderr_str) then
- Error (`Stderr (method', stderr_str))
- else
- let stdin_str = String.trim @@ Buffer.contents stdout_buf in
- Logs.debug (fun m -> m "Command output: %s" stdin_str);
+ match run_and_gather method' cmd with
+ | Ok "" ->
+ Error (`Empty_output method')
+ | Ok stdout ->
+ begin
+ Logs.debug (fun m -> m "Command output: %s" stdout);
let last_nonempty_line =
- String.split_on_char '\n' stdin_str
+ String.split_on_char '\n' stdout
|> List.rev
|> List.find_opt (fun line -> line <> "")
in
match last_nonempty_line with
| None -> Error (`Empty_output method')
| value -> Ok {input with hash = {input.hash with value}}
- with
- | exn -> Error (`Exception (method', Printexc.to_string exn))
+ end
+ | Error err -> Error err
and prefetch_git (g : Git.t) : (Input.t, Error.prefetch_error) result =
let method' = `Git
@@ -303,7 +294,6 @@ let prefetch ~env ~proc_mgr ~name () : (unit, error) result =
Uri.to_string repository;
]
in
- Logs.debug (fun m -> m "Running Git cmd: %a" (Fmt.list ~sep: Fmt.sp Fmt.string) cmd);
let cmd =
List.concat [
cmd;
@@ -316,27 +306,16 @@ let prefetch ~env ~proc_mgr ~name () : (unit, error) result =
if g.lfs then ["--fetch-lfs"] else [];
];
in
- try
- let () =
- Eio.Process.run
- proc_mgr
- ~env: proc_env
- ~stdout: stdout_sink
- ~stderr: stderr_sink
- cmd
- in
- let stderr_str = String.trim @@ Buffer.contents stderr_buf in
- if stderr_str <> "" then
- Error (`Stderr (method', stderr_str))
- else
- let stdin_str = Buffer.contents stdout_buf in
- Logs.debug (fun m -> m "Command output: %s" stdin_str);
+ Logs.debug (fun m -> m "Running Git cmd: %a" (Fmt.list ~sep: Fmt.sp Fmt.string) cmd);
+ match run_and_gather method' cmd with
+ | Ok "" ->
+ Error (`Empty_output method')
+ | Ok stdout ->
+ begin
+ Logs.debug (fun m -> m "Command output: %s" stdout);
let* data =
- if stdin_str = "" then
- Error (`Empty_output method')
- else
- Jsont_bytesrw.decode_string Prefetch.Git.jsont stdin_str
- |> Result.map_error (fun err -> `JSON_parsing (method', err))
+ Jsont_bytesrw.decode_string Prefetch.Git.jsont stdout
+ |> Result.map_error (fun err -> `JSON_parsing (method', err))
in
Ok {input with
kind =
@@ -349,8 +328,8 @@ let prefetch ~env ~proc_mgr ~name () : (unit, error) result =
value = Some data.hash.value;
};
}
- with
- | exn -> Error (`Exception (method', Printexc.to_string exn))
+ end
+ | Error err -> Error err
and prefetch_darcs (d : Darcs.t) : (Input.t, Error.prefetch_error) result =
let method' = `Darcs
@@ -366,27 +345,15 @@ let prefetch ~env ~proc_mgr ~name () : (unit, error) result =
in
let cmd = cmd @ [repository] in
Logs.debug (fun m -> m "Running Darcs cmd: %a" (Fmt.list ~sep: Fmt.sp Fmt.string) cmd);
- try
- let () =
- Eio.Process.run
- proc_mgr
- ~env: proc_env
- ~stdout: stdout_sink
- ~stderr: stderr_sink
- cmd
- in
- let stderr_str = String.trim @@ Buffer.contents stderr_buf in
- if stderr_str <> "" then
- Error (`Stderr (method', stderr_str))
- else
- let stdin_str = Buffer.contents stdout_buf in
- Logs.debug (fun m -> m "Command output: %s" stdin_str);
+ match run_and_gather method' cmd with
+ | Ok "" ->
+ Error (`Empty_output method')
+ | Ok stdout ->
+ begin
+ Logs.debug (fun m -> m "Command output: %s" stdout);
let* data =
- if stdin_str = "" then
- Error (`Empty_output method')
- else
- Jsont_bytesrw.decode_string Prefetch.Darcs.jsont stdin_str
- |> Result.map_error (fun err -> `JSON_parsing (method', err))
+ Jsont_bytesrw.decode_string Prefetch.Darcs.jsont stdout
+ |> Result.map_error (fun err -> `JSON_parsing (method', err))
in
let* reference =
match d.reference with
@@ -412,8 +379,8 @@ let prefetch ~env ~proc_mgr ~name () : (unit, error) result =
value = Some data.hash.value;
};
}
- with
- | exn -> Error (`Exception (method', Printexc.to_string exn))
+ end
+ | Error err -> Error err
and prefetch_pijul (p : Pijul.t) : (Input.t, Error.prefetch_error) result =
let method' = `Pijul
@@ -431,27 +398,15 @@ let prefetch ~env ~proc_mgr ~name () : (unit, error) result =
| `State s -> ["--state"; s]
in
Logs.debug (fun m -> m "Running Pijul cmd: %a" (Fmt.list ~sep: Fmt.sp Fmt.string) cmd);
- try
- let () =
- Eio.Process.run
- proc_mgr
- ~env: proc_env
- ~stdout: stdout_sink
- ~stderr: stderr_sink
- cmd
- in
- let stderr_str = String.trim @@ Buffer.contents stderr_buf in
- if stderr_str <> "" then
- Error (`Stderr (method', stderr_str))
- else
- let stdin_str = Buffer.contents stdout_buf in
- Logs.debug (fun m -> m "Command output: %s" stdin_str);
+ match run_and_gather method' cmd with
+ | Ok "" ->
+ Error (`Empty_output method')
+ | Ok stdout ->
+ begin
+ Logs.debug (fun m -> m "Command output: %s" stdout);
let* data =
- if stdin_str = "" then
- Error (`Empty_output method')
- else
- Jsont_bytesrw.decode_string Prefetch.Pijul.jsont stdin_str
- |> Result.map_error (fun err -> `JSON_parsing (method', err))
+ Jsont_bytesrw.decode_string Prefetch.Pijul.jsont stdout
+ |> Result.map_error (fun err -> `JSON_parsing (method', err))
in
Ok {input with
kind =
@@ -464,8 +419,8 @@ let prefetch ~env ~proc_mgr ~name () : (unit, error) result =
value = Some data.hash.value;
};
}
- with
- | exn -> Error (`Exception (method', Printexc.to_string exn))
+ end
+ | Error err -> Error err
in
let* new_input : Input.t =
Result.map_error (fun err -> `Prefetch (input.name, err)) @@ begin