Skip to content

Commit

Permalink
pkg: simplify the display logs
Browse files Browse the repository at this point in the history
Only logs the standard output when the command fails or the user
explicitly requests it.

Add new flag `--debug-package-logs`, which force dune to display the
stdout logs when dealing with package management.

Signed-off-by: Etienne Marais <[email protected]>
Signed-off-by: Christine Rose <[email protected]>
Signed-off-by: Etienne Millon <[email protected]>
  • Loading branch information
maiste authored and emillon committed Jul 2, 2024
1 parent 10897a3 commit 29ae7b9
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 23 deletions.
13 changes: 13 additions & 0 deletions bin/common.ml
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,7 @@ module Builder = struct
; debug_artifact_substitution : bool
; debug_load_dir : bool
; debug_digests : bool
; debug_package_logs : bool
; wait_for_filesystem_clock : bool
; only_packages : Only_packages.Clflags.t
; capture_outputs : bool
Expand Down Expand Up @@ -666,6 +667,16 @@ module Builder = struct
[ "debug-digests" ]
~docs
~doc:"Explain why Dune decides to re-digest some files")
and+ debug_package_logs =
let doc = "Always print the standard logs when building packages" in
Arg.(
value
& flag
& info
[ "debug-package-logs" ]
~docs
~doc
~env:(Cmd.Env.info ~doc "DUNE_DEBUG_PACKAGE_LOGS"))
and+ no_buffer =
let doc =
"Do not buffer the output of commands executed by dune. By default dune buffers \
Expand Down Expand Up @@ -970,6 +981,7 @@ module Builder = struct
; debug_artifact_substitution
; debug_load_dir
; debug_digests
; debug_package_logs
; wait_for_filesystem_clock
; only_packages
; capture_outputs = not no_buffer
Expand Down Expand Up @@ -1236,6 +1248,7 @@ let init (builder : Builder.t) =
Dune_engine.Clflags.debug_load_dir := c.builder.debug_load_dir;
Dune_engine.Clflags.debug_fs_cache := c.builder.cache_debug_flags.fs_cache;
Dune_digest.Clflags.debug_digests := c.builder.debug_digests;
Dune_rules.Clflags.debug_package_logs := c.builder.debug_package_logs;
Dune_digest.Clflags.wait_for_filesystem_clock := c.builder.wait_for_filesystem_clock;
Dune_engine.Clflags.capture_outputs := c.builder.capture_outputs;
Dune_engine.Clflags.diff_command := c.builder.diff_command;
Expand Down
3 changes: 3 additions & 0 deletions doc/changes/10662.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- pkg: only logs the standard output when the command fails or the user explicitly requests it.
Add new flag `--debug-package-logs`, which force dune to display the stdout logs when dealing
with package management (#10662, @maiste)
1 change: 1 addition & 0 deletions src/dune_rules/clflags.ml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ let promote_install_files = ref false
let display = Dune_engine.Clflags.display
let capture_outputs = Dune_engine.Clflags.capture_outputs
let debug_artifact_substitution = ref false
let debug_package_logs = ref false
let ignore_lock_dir = ref false

type on_missing_dune_project_file =
Expand Down
3 changes: 3 additions & 0 deletions src/dune_rules/clflags.mli
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ val capture_outputs : bool ref
(** Print debug info about artifact substitution *)
val debug_artifact_substitution : bool ref

(** Print package output when building with package management *)
val debug_package_logs : bool ref

(** Whether we are ignoring "dune.lock/". *)
val ignore_lock_dir : bool ref

Expand Down
110 changes: 89 additions & 21 deletions src/dune_rules/pkg_rules.ml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ include struct
module Checksum = Checksum
module Source = Source
module Build_command = Lock_dir.Build_command
module Display = Dune_engine.Display
end

module Variable = struct
Expand Down Expand Up @@ -405,7 +406,8 @@ module Expander0 = struct
include Expander0

type t =
{ paths : Paths.t
{ name : Dune_pkg.Package_name.t
; paths : Paths.t
; artifacts : Path.t Filename.Map.t
; depends : (Variable.value Package_variable_name.Map.t * Paths.t) Package.Name.Map.t
; context : Context_name.t
Expand Down Expand Up @@ -514,6 +516,63 @@ module Substitute = struct
end

module Run_with_path = struct
module Output : sig
type error

val io : error -> Process.Io.output Process.Io.t

val with_error
: accepted_exit_codes:int Predicate.t
-> pkg:Dune_pkg.Package_name.t * Loc.t
-> display:Display.t
-> (error -> 'a)
-> 'a

val prerr : rc:int -> error -> unit
end = struct
type error =
{ pkg : Dune_pkg.Package_name.t * Loc.t
; filename : Dpath.t
; io : Process.Io.output Process.Io.t
; accepted_exit_codes : int Predicate.t
; display : Display.t
}

let io t = t.io

let with_error ~accepted_exit_codes ~pkg ~display f =
let filename = Temp.create File ~prefix:"dune-pkg" ~suffix:"stderr" in
let io = Process.Io.(file filename Out) in
let t = { filename; io; accepted_exit_codes; display; pkg } in
let result = f t in
Temp.destroy File filename;
result
;;

let to_paragraphs t error =
let pp_pkg =
let pkg_name = Dune_pkg.Package_name.to_string (fst t.pkg) in
Pp.textf "Logs for package %s" pkg_name
in
let loc = snd t.pkg in
[ pp_pkg; Pp.verbatim error ], loc
;;

let prerr ~rc error =
match Predicate.test error.accepted_exit_codes rc, error.display with
| false, _ ->
let paragraphs, loc = Stdune.Io.read_file error.filename |> to_paragraphs error in
User_warning.emit ~loc ~is_error:true paragraphs
| true, Display.Verbose ->
let content = Stdune.Io.read_file error.filename in
if not (String.is_empty content)
then (
let paragraphs, loc = to_paragraphs error content in
User_warning.emit ~loc paragraphs)
| true, _ -> ()
;;
end

module Spec = struct
type 'path chunk =
| String of string
Expand All @@ -525,6 +584,7 @@ module Run_with_path = struct
{ prog : Action.Prog.t
; args : 'path arg Array.Immutable.t
; ocamlfind_destdir : 'path
; pkg : Dune_pkg.Package_name.t * Loc.t
}

let name = "run-with-path"
Expand All @@ -545,7 +605,7 @@ module Run_with_path = struct

let is_useful_to ~memoize:_ = true

let encode { prog; args; ocamlfind_destdir } path _ : Dune_lang.t =
let encode { prog; args; ocamlfind_destdir; pkg = _ } path _ : Dune_lang.t =
let prog =
Dune_lang.atom_or_quoted_string
@@
Expand All @@ -567,11 +627,12 @@ module Run_with_path = struct
;;

let action
{ prog; args; ocamlfind_destdir }
{ prog; args; ocamlfind_destdir; pkg }
~(ectx : Action.Ext.context)
~(eenv : Action.Ext.env)
=
let open Fiber.O in
let display = !Clflags.display in
match prog with
| Error e -> Action.Prog.Not_found.raise e
| Ok prog ->
Expand All @@ -589,31 +650,37 @@ module Run_with_path = struct
~var:"OCAMLFIND_DESTDIR"
~value:(Path.to_absolute_filename ocamlfind_destdir)
in
Process.run
(Accept eenv.exit_codes)
prog
args
~display:!Clflags.display
~metadata
~stdout_to:eenv.stdout_to
~stderr_to:eenv.stderr_to
~stdin_from:eenv.stdin_from
~dir:eenv.working_dir
~env
>>= (function
| Error _ -> Fiber.return ()
| Ok () -> Fiber.return ())
Output.with_error ~accepted_exit_codes:eenv.exit_codes ~pkg ~display (fun error ->
let stdout_to =
match !Clflags.debug_package_logs, display with
| true, _ | false, Display.Verbose -> eenv.stdout_to
| _ -> Process.Io.(null Out)
in
Process.run
Return
prog
args
~display
~metadata
~stdout_to
~stderr_to:(Output.io error)
~stdin_from:eenv.stdin_from
~dir:eenv.working_dir
~env
>>= fun (_, rc) ->
Output.prerr ~rc error;
Fiber.return ())
;;
end

let action prog args ~ocamlfind_destdir =
let action ~pkg prog args ~ocamlfind_destdir =
let module M = struct
type path = Path.t
type target = Path.Build.t

module Spec = Spec

let v = { Spec.prog; args; ocamlfind_destdir }
let v = { Spec.prog; args; ocamlfind_destdir; pkg }
end
in
Action.Extension (module M)
Expand Down Expand Up @@ -742,7 +809,7 @@ module Action_expander = struct
;;

let expand_pform
{ env = _; paths; artifacts = _; context; depends; version = _ }
{ name = _; env = _; paths; artifacts = _; context; depends; version = _ }
~source
(pform : Pform.t)
: (Value.t list, [ `Undefined_pkg_var of Package_variable_name.t ]) result Memo.t
Expand Down Expand Up @@ -877,7 +944,7 @@ module Action_expander = struct
let ocamlfind_destdir =
(Lazy.force expander.paths.install_roots).lib_root |> Path.build
in
Run_with_path.action exe args ~ocamlfind_destdir)
Run_with_path.action ~pkg:(expander.name, prog_loc) exe args ~ocamlfind_destdir)
| Progn t ->
let+ args = Memo.parallel_map t ~f:(expand ~expander) in
Action.Progn args
Expand Down Expand Up @@ -1007,6 +1074,7 @@ module Action_expander = struct
(Pkg_info.variables pkg.info, pkg.paths)
in
{ Expander.paths = pkg.paths
; name = pkg.info.name
; artifacts = binaries
; context
; depends
Expand Down
48 changes: 48 additions & 0 deletions test/blackbox-tests/test-cases/pkg/build-package-logs.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
Test the error message when installing package that fails.

$ . ./helpers.sh
$ make_lockdir
$ export DUNE_DEBUG_PACKAGE_LOGS=0

Make a project with two packages, one successful and one that fails:

$ cat > dune-project << EOF
> (lang dune 3.12)
> EOF

Create a package with a failing command that throws an error:

$ make_lockpkg x << EOF
> (version 0.0.1)
> (build
> (progn
> (run cat i_dont_exist)))
> EOF

Building the package should fail and print an error:

$ build_pkg x 2>&1 | sed -E 's#/.*/cat#cat#g'
File "dune.lock/x.pkg", line 4, characters 11-14:
4 | (run cat i_dont_exist)))
^^^
Error: Logs for package x
cat: i_dont_exist: No such file or directory


Create a package with a succeeding command that displays some text:

$ make_lockpkg y << EOF
> (version 0.0.1)
> (build
> (progn
> (run echo "Success!")))
> EOF

Building the package should succeed and print no output:

$ build_pkg y

Checks the package is installed:

$ show_pkg_cookie y
{ files = map {}; variables = [] }
5 changes: 5 additions & 0 deletions test/blackbox-tests/test-cases/pkg/dune
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
(alias pkg)
(applies_to :whole_subtree))

(env
(_
(env-vars
(DUNE_DEBUG_PACKAGE_LOGS 1))))

(cram
(deps helpers.sh)
(applies_to :whole_subtree))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ Attempt to build the package the first time:
echo aaa
aaa
false
-> required by _build/_private/default/.pkg/foo/target/cookie
File "dune.lock/foo.pkg", line 4, characters 6-13:
^^^^^^^
Error: Logs for package foo


Update the message that gets printed while building foo:
$ cat >foo/Makefile <<EOF
Expand All @@ -55,4 +58,7 @@ The change to the package is picked up:
echo bbb
bbb
false
-> required by _build/_private/default/.pkg/foo/target/cookie
File "dune.lock/foo.pkg", line 4, characters 6-13:
^^^^^^^
Error: Logs for package foo

0 comments on commit 29ae7b9

Please sign in to comment.