2022-02-25 20:00:10 +03:00
|
|
|
(* This file is part of the Catala build system, a specification language for
|
|
|
|
tax and social benefits computation rules. Copyright (C) 2020 Inria,
|
|
|
|
contributors: Denis Merigoux <denis.merigoux@inria.fr>, Emile Rolley
|
2024-06-25 19:29:42 +03:00
|
|
|
<emile.rolley@tuta.io>, Louis Gesbert <louis.gesbert@inria.fr>
|
2022-02-25 20:00:10 +03:00
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
|
|
|
use this file except in compliance with the License. You may obtain a copy of
|
|
|
|
the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
|
|
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
|
|
License for the specific language governing permissions and limitations under
|
|
|
|
the License. *)
|
|
|
|
|
2022-11-21 12:46:17 +03:00
|
|
|
open Catala_utils
|
2022-02-25 20:00:10 +03:00
|
|
|
open Ninja_utils
|
|
|
|
module Nj = Ninja_utils
|
2023-09-26 12:42:46 +03:00
|
|
|
module Scan = Clerk_scan
|
2022-02-25 20:00:10 +03:00
|
|
|
|
2023-09-13 19:03:43 +03:00
|
|
|
(* Version is synchronised with the catala version *)
|
2023-09-12 11:32:35 +03:00
|
|
|
let version = Catala_utils.Cli.version
|
|
|
|
|
2022-02-25 20:00:10 +03:00
|
|
|
(** {1 Command line interface} *)
|
|
|
|
|
2023-09-19 17:26:05 +03:00
|
|
|
module Cli = struct
|
|
|
|
open Cmdliner
|
2022-02-25 20:00:10 +03:00
|
|
|
|
2023-09-19 17:26:05 +03:00
|
|
|
let catala_exe =
|
|
|
|
Arg.(
|
|
|
|
value
|
|
|
|
& opt (some string) None
|
2023-09-13 19:03:43 +03:00
|
|
|
& info ["e"; "exe"] ~docv:"EXE" ~doc:"Catala compiler executable.")
|
2022-02-25 20:00:10 +03:00
|
|
|
|
2023-09-19 17:26:05 +03:00
|
|
|
let catala_opts =
|
|
|
|
Arg.(
|
|
|
|
value
|
|
|
|
& opt_all string []
|
|
|
|
& info ["c"; "catala-opts"] ~docv:"FLAG"
|
|
|
|
~doc:"Option to pass to the Catala compiler. Can be repeated.")
|
2023-09-19 19:21:14 +03:00
|
|
|
|
2023-09-24 12:25:34 +03:00
|
|
|
let build_dir =
|
|
|
|
Arg.(
|
|
|
|
value
|
2023-11-14 18:05:54 +03:00
|
|
|
& opt (some string) None
|
2023-09-24 12:25:34 +03:00
|
|
|
& info ["build-dir"] ~docv:"DIR"
|
2023-11-14 18:05:54 +03:00
|
|
|
~doc:
|
|
|
|
"Directory where compilation artifacts should be written. Defaults \
|
|
|
|
to '_build'.")
|
|
|
|
|
|
|
|
let include_dirs =
|
2024-02-27 17:26:05 +03:00
|
|
|
let arg =
|
|
|
|
Arg.(
|
|
|
|
value
|
|
|
|
& opt_all (list ~sep:':' string) []
|
|
|
|
& info ["I"; "include"] ~docv:"DIR"
|
|
|
|
~env:(Cmd.Env.info "CATALA_INCLUDE")
|
|
|
|
~doc:
|
|
|
|
"Make modules from the given directory available from \
|
|
|
|
everywhere. Several dirs can be specified by repeating the flag \
|
|
|
|
or separating them with '$(b,:)'.")
|
|
|
|
in
|
|
|
|
Term.(const List.flatten $ arg)
|
2023-09-24 12:25:34 +03:00
|
|
|
|
2024-02-26 12:18:08 +03:00
|
|
|
let test_flags =
|
|
|
|
Arg.(
|
|
|
|
value
|
|
|
|
& opt (list string) []
|
|
|
|
& info ["test-flags"] ~docv:"FLAGS"
|
|
|
|
~env:(Cmd.Env.info "CATALA_TEST_FLAGS")
|
|
|
|
~doc:
|
|
|
|
"Flags to pass to the catala interpreter on $(b,catala test-scope) \
|
|
|
|
tests. Comma-separated list. A subset may also be applied to the \
|
2024-02-26 16:47:45 +03:00
|
|
|
compilation of modules, as needed.\n\
|
|
|
|
WARNING: flag shortcuts are not allowed here (i.e. don't use \
|
|
|
|
non-ambiguous prefixes such as $(b,--avoid-ex) for \
|
|
|
|
$(b,--avoid-exceptions))\n\
|
|
|
|
NOTE: if this is set, all inline tests that are $(i,not) \
|
|
|
|
$(b,catala test-scope) are skipped to avoid redundant testing.")
|
2024-02-26 12:18:08 +03:00
|
|
|
|
Generate tests reports from 'clerk test'
This is a proper replacement for the previous shell-based placeholder hack.
Here is a summary:
- `clerk runtest` (normally run by ninja) is much extended:
* besides generating the test@out file, it checks individual tests for success
and can write a report file containing their status, and the positions for
their (expected/current) outputs (this uses `Marshal`)
* it now handles out-tests directly in addition to inline-tests, for which
it generates the separate output file ; they are included in the report
- ninja is now tasked with building all the test reports (which shouldn't fail);
for directories, individual reports are concatenated (as before).
Removing intermediate report rules, and out-test rules means that the ninja
file is much simplified.
- then, clerk takes back control, reads the final reports and formats them in a
user-friendly way. Printing the reports may imply running `diff` internally.
In particular, the commands to easily reproduce each test are provided.
Resetting the test results if required is also done directly by clerk, at this
stage.
A few switches are available to customise the output, but I am waiting for some
feedback before deciding what to make available from the CLI.
The `clerk report` command is available to manually explore test reports, but
normally the processing is done directly at the end of `clerk test` (i.e. ninja
will no longer call that command)
2024-06-14 22:05:19 +03:00
|
|
|
let runtest_report =
|
|
|
|
Arg.(
|
|
|
|
value
|
|
|
|
& opt (some string) None
|
|
|
|
& info ["report"] ~docv:"FILE"
|
|
|
|
~doc:
|
|
|
|
"If set, $(i,clerk runtest) will output a tests result summary in \
|
|
|
|
binary format to the given $(b,FILE)")
|
|
|
|
|
|
|
|
let runtest_out =
|
|
|
|
Arg.(
|
|
|
|
value
|
|
|
|
& pos 1 (some string) None
|
|
|
|
& info [] ~docv:"OUTFILE"
|
|
|
|
~doc:"Write the test outcome to file $(b,OUTFILE) instead of stdout.")
|
|
|
|
|
2023-09-19 17:26:05 +03:00
|
|
|
module Global : sig
|
Generate tests reports from 'clerk test'
This is a proper replacement for the previous shell-based placeholder hack.
Here is a summary:
- `clerk runtest` (normally run by ninja) is much extended:
* besides generating the test@out file, it checks individual tests for success
and can write a report file containing their status, and the positions for
their (expected/current) outputs (this uses `Marshal`)
* it now handles out-tests directly in addition to inline-tests, for which
it generates the separate output file ; they are included in the report
- ninja is now tasked with building all the test reports (which shouldn't fail);
for directories, individual reports are concatenated (as before).
Removing intermediate report rules, and out-test rules means that the ninja
file is much simplified.
- then, clerk takes back control, reads the final reports and formats them in a
user-friendly way. Printing the reports may imply running `diff` internally.
In particular, the commands to easily reproduce each test are provided.
Resetting the test results if required is also done directly by clerk, at this
stage.
A few switches are available to customise the output, but I am waiting for some
feedback before deciding what to make available from the CLI.
The `clerk report` command is available to manually explore test reports, but
normally the processing is done directly at the end of `clerk test` (i.e. ninja
will no longer call that command)
2024-06-14 22:05:19 +03:00
|
|
|
val color : Catala_utils.Global.when_enum Term.t
|
|
|
|
val debug : bool Term.t
|
|
|
|
|
2023-09-19 17:26:05 +03:00
|
|
|
val term :
|
2024-06-25 19:29:42 +03:00
|
|
|
(config_file:File.t option ->
|
2023-09-19 17:26:05 +03:00
|
|
|
catala_exe:File.t option ->
|
|
|
|
catala_opts:string list ->
|
2023-11-14 18:05:54 +03:00
|
|
|
build_dir:File.t option ->
|
|
|
|
include_dirs:string list ->
|
2024-03-15 16:23:30 +03:00
|
|
|
color:Global.when_enum ->
|
2023-09-19 17:26:05 +03:00
|
|
|
debug:bool ->
|
|
|
|
ninja_output:File.t option ->
|
|
|
|
'a) ->
|
|
|
|
'a Term.t
|
|
|
|
end = struct
|
2024-06-25 19:29:42 +03:00
|
|
|
let config_file =
|
2023-09-19 17:26:05 +03:00
|
|
|
Arg.(
|
|
|
|
value
|
2024-06-25 19:29:42 +03:00
|
|
|
& opt (some file) None
|
|
|
|
& info ["config"] ~docv:"FILE"
|
|
|
|
~doc:
|
|
|
|
"Clerk configuration file to use, instead of looking up \
|
|
|
|
\"clerk.toml\" in parent directories.")
|
2023-09-19 17:26:05 +03:00
|
|
|
|
|
|
|
let color =
|
|
|
|
Arg.(
|
|
|
|
value
|
2024-03-15 16:23:30 +03:00
|
|
|
& opt ~vopt:Global.Always Cli.when_opt Auto
|
2023-09-19 17:26:05 +03:00
|
|
|
& info ["color"]
|
|
|
|
~env:(Cmd.Env.info "CATALA_COLOR")
|
|
|
|
~doc:
|
|
|
|
"Allow output of colored and styled text. Use $(i,auto), to \
|
|
|
|
enable when the standard output is to a terminal, $(i,never) to \
|
|
|
|
disable.")
|
|
|
|
|
|
|
|
let debug =
|
|
|
|
Arg.(value & flag & info ["debug"; "d"] ~doc:"Prints debug information")
|
|
|
|
|
|
|
|
let ninja_output =
|
|
|
|
Arg.(
|
|
|
|
value
|
|
|
|
& opt (some string) None
|
|
|
|
& info ["o"; "output"] ~docv:"FILE"
|
|
|
|
~doc:
|
|
|
|
"$(i,FILE) is the file that will contain the build.ninja file \
|
2023-09-26 12:42:46 +03:00
|
|
|
output. If not specified, the build.ninja file is set to \
|
|
|
|
$(i,<builddir>/clerk.ninja) in debug mode, and a temporary file \
|
|
|
|
otherwise")
|
2023-09-19 17:26:05 +03:00
|
|
|
|
|
|
|
let term f =
|
|
|
|
Term.(
|
2023-11-14 18:05:54 +03:00
|
|
|
const
|
|
|
|
(fun
|
2024-06-25 19:29:42 +03:00
|
|
|
config_file
|
2023-11-14 18:05:54 +03:00
|
|
|
catala_exe
|
|
|
|
catala_opts
|
|
|
|
build_dir
|
|
|
|
include_dirs
|
|
|
|
color
|
|
|
|
debug
|
|
|
|
ninja_output
|
|
|
|
->
|
2024-06-25 19:29:42 +03:00
|
|
|
f ~config_file ~catala_exe ~catala_opts ~build_dir ~include_dirs
|
|
|
|
~color ~debug ~ninja_output)
|
|
|
|
$ config_file
|
2023-09-19 17:26:05 +03:00
|
|
|
$ catala_exe
|
|
|
|
$ catala_opts
|
2023-11-14 18:05:54 +03:00
|
|
|
$ build_dir
|
|
|
|
$ include_dirs
|
2023-09-19 17:26:05 +03:00
|
|
|
$ color
|
|
|
|
$ debug
|
|
|
|
$ ninja_output)
|
|
|
|
end
|
|
|
|
|
|
|
|
let files_or_folders =
|
|
|
|
Arg.(
|
|
|
|
value
|
2023-11-14 18:05:54 +03:00
|
|
|
& pos_all string []
|
2023-09-19 17:26:05 +03:00
|
|
|
& info [] ~docv:"FILE(S)" ~doc:"File(s) or folder(s) to process")
|
|
|
|
|
2024-07-04 15:25:46 +03:00
|
|
|
let files =
|
|
|
|
Arg.(
|
|
|
|
value
|
|
|
|
& pos_all file []
|
|
|
|
& info [] ~docv:"FILE(S)" ~doc:"File(s) to process")
|
|
|
|
|
2023-09-19 17:26:05 +03:00
|
|
|
let single_file =
|
|
|
|
Arg.(
|
|
|
|
required
|
|
|
|
& pos 0 (some file) None
|
|
|
|
& info [] ~docv:"FILE" ~doc:"File to process")
|
|
|
|
|
|
|
|
let reset_test_outputs =
|
|
|
|
Arg.(
|
|
|
|
value
|
|
|
|
& flag
|
|
|
|
& info ["r"; "reset"]
|
2022-02-25 20:00:10 +03:00
|
|
|
~doc:
|
2023-09-19 17:26:05 +03:00
|
|
|
"Used with the `test` command, resets the test output to whatever \
|
|
|
|
is output by the Catala compiler.")
|
|
|
|
|
|
|
|
let scope =
|
|
|
|
Arg.(
|
|
|
|
required
|
|
|
|
& opt (some string) None
|
|
|
|
& info ["s"; "scope"] ~docv:"SCOPE"
|
2022-02-25 20:00:10 +03:00
|
|
|
~doc:
|
|
|
|
"Used with the `run` command, selects which scope of a given \
|
|
|
|
Catala file to run.")
|
|
|
|
|
2023-09-19 18:56:18 +03:00
|
|
|
let targets =
|
|
|
|
Arg.(
|
|
|
|
value
|
|
|
|
& pos_all string []
|
|
|
|
& info [] ~docv:"TARGETS"
|
|
|
|
~doc:
|
|
|
|
"Flags or targets to forward to Ninja directly (use $(b,-- \
|
|
|
|
ninja_flags) to separate Ninja flags from Clerk flags)")
|
|
|
|
|
2024-06-19 13:14:26 +03:00
|
|
|
let report_verbosity =
|
|
|
|
Arg.(
|
|
|
|
value
|
|
|
|
& vflag `Failures
|
|
|
|
[
|
|
|
|
( `Summary,
|
|
|
|
info ["summary"] ~doc:"Only display a summary of the test results"
|
|
|
|
);
|
|
|
|
( `Short,
|
|
|
|
info ["short"] ~doc:"Don't display detailed test failures diff" );
|
|
|
|
( `Failures,
|
|
|
|
info ["failures"]
|
|
|
|
~doc:"Show details of files with failed tests only" );
|
|
|
|
( `Verbose,
|
|
|
|
info ["verbose"; "v"]
|
|
|
|
~doc:"Display the full list of tests that have been run" );
|
|
|
|
])
|
|
|
|
|
2024-07-04 15:25:46 +03:00
|
|
|
let report_xml =
|
|
|
|
Arg.(
|
|
|
|
value
|
|
|
|
& flag
|
|
|
|
& info ["xml"]
|
|
|
|
~env:(Cmd.Env.info "CATALA_XML_REPORT")
|
|
|
|
~doc:"Output the test report in JUnit-compatible XML format")
|
|
|
|
|
2024-06-27 12:58:53 +03:00
|
|
|
let diff_command =
|
2024-06-19 13:14:26 +03:00
|
|
|
Arg.(
|
|
|
|
value
|
2024-06-27 12:58:53 +03:00
|
|
|
& opt ~vopt:(Some None) (some (some string)) None
|
|
|
|
& info ["diff"]
|
|
|
|
~env:(Cmd.Env.info "CATALA_DIFF_COMMAND")
|
2024-06-19 13:14:26 +03:00
|
|
|
~doc:
|
2024-06-27 12:58:53 +03:00
|
|
|
"Use a standard $(i,diff) command instead of the default \
|
|
|
|
side-by-side view. If no argument is supplied, the command will \
|
|
|
|
be $(b,patdiff) if available or $(b,diff) otherwise. A supplied \
|
|
|
|
argument will be used as diff command with arguments pointing to \
|
|
|
|
the reference file and the output file")
|
2024-06-19 13:14:26 +03:00
|
|
|
|
2023-09-19 17:26:05 +03:00
|
|
|
let ninja_flags =
|
|
|
|
let env =
|
|
|
|
Cmd.Env.info
|
|
|
|
~doc:
|
|
|
|
"make-compatible flags handling. Currently recognizes the -i and -j \
|
|
|
|
options and forwards them through to Ninja."
|
|
|
|
"MAKEFLAGS"
|
|
|
|
in
|
|
|
|
let makeflags =
|
|
|
|
Arg.(
|
|
|
|
value
|
|
|
|
& opt (some string) None
|
|
|
|
& info ["makeflags"] ~env ~docv:"FLAG"
|
|
|
|
~doc:
|
|
|
|
"Provides the contents of a $(i, MAKEFLAGS) variable to pass on \
|
|
|
|
to Ninja. Currently recognizes the -i and -j options.")
|
|
|
|
in
|
|
|
|
let makeflags_to_ninja_flags (makeflags : string option) =
|
|
|
|
match makeflags with
|
2024-04-19 17:34:53 +03:00
|
|
|
| None -> ["-k0"]
|
2023-09-19 17:26:05 +03:00
|
|
|
| Some makeflags ->
|
|
|
|
let ignore_rex = Re.(compile @@ word (char 'i')) in
|
|
|
|
let has_ignore = Re.execp ignore_rex makeflags in
|
|
|
|
let jobs_rex = Re.(compile @@ seq [str "-j"; group (rep digit)]) in
|
|
|
|
let number_of_jobs =
|
|
|
|
try ["-j" ^ Re.Group.get (Re.exec jobs_rex makeflags) 1]
|
|
|
|
with _ -> []
|
|
|
|
in
|
2024-04-19 17:34:53 +03:00
|
|
|
(if has_ignore then ["-k0"] else []) @ number_of_jobs
|
2023-09-19 17:26:05 +03:00
|
|
|
in
|
|
|
|
Term.(const makeflags_to_ninja_flags $ makeflags)
|
2023-09-13 19:03:43 +03:00
|
|
|
|
2023-09-19 17:26:05 +03:00
|
|
|
let info =
|
|
|
|
let doc =
|
|
|
|
"Build system for Catala, a specification language for tax and social \
|
|
|
|
benefits computation rules."
|
|
|
|
in
|
|
|
|
let man =
|
|
|
|
[
|
|
|
|
`S Manpage.s_description;
|
|
|
|
`P
|
|
|
|
"$(b,clerk) is a build system for Catala, a specification language \
|
|
|
|
for tax and social benefits computation rules";
|
|
|
|
`S Manpage.s_authors;
|
|
|
|
`P "Denis Merigoux <denis.merigoux@inria.fr>";
|
|
|
|
`P "Emile Rolley <emile.rolley@tuta.io>";
|
|
|
|
`P "Louis Gesbert <louis.gesbert@inria.fr>";
|
|
|
|
`S Manpage.s_examples;
|
|
|
|
`P "Typical usage:";
|
|
|
|
`Pre "clerk test file.catala_en";
|
|
|
|
`S Manpage.s_bugs;
|
|
|
|
`P
|
|
|
|
"Please file bug reports at \
|
|
|
|
https://github.com/CatalaLang/catala/issues";
|
|
|
|
]
|
|
|
|
in
|
|
|
|
let exits = Cmd.Exit.defaults @ [Cmd.Exit.info ~doc:"on error." 1] in
|
|
|
|
Cmd.info "clerk" ~version ~doc ~exits ~man
|
|
|
|
end
|
2022-02-25 20:00:10 +03:00
|
|
|
|
2023-09-13 19:03:43 +03:00
|
|
|
(** {1 System analysis} *)
|
2022-02-25 20:00:10 +03:00
|
|
|
|
2023-09-13 19:03:43 +03:00
|
|
|
(** Some functions that poll the surrounding systems (think [./configure]) *)
|
|
|
|
module Poll = struct
|
2024-06-25 19:29:42 +03:00
|
|
|
(** This module is sensitive to the CWD at first use. Therefore it's expected
|
|
|
|
that [chdir] has been run beforehand to the project root. *)
|
|
|
|
let root = lazy (Sys.getcwd ())
|
2023-11-14 18:05:54 +03:00
|
|
|
|
2023-09-13 19:03:43 +03:00
|
|
|
(** Scans for a parent directory being the root of the Catala source repo *)
|
|
|
|
let catala_project_root : File.t option Lazy.t =
|
2024-06-25 19:29:42 +03:00
|
|
|
root
|
|
|
|
|> Lazy.map
|
|
|
|
@@ fun root ->
|
|
|
|
if File.(exists (root / "catala.opam") && exists (root / "dune-project"))
|
|
|
|
then Some root
|
|
|
|
else None
|
2023-09-13 19:03:43 +03:00
|
|
|
|
2024-02-27 13:24:33 +03:00
|
|
|
let exec_dir : File.t = Catala_utils.Cli.exec_dir
|
2023-09-26 12:42:46 +03:00
|
|
|
let clerk_exe : File.t Lazy.t = lazy (Unix.realpath Sys.executable_name)
|
2023-09-13 19:03:43 +03:00
|
|
|
|
|
|
|
let catala_exe : File.t Lazy.t =
|
2023-09-19 19:21:14 +03:00
|
|
|
lazy
|
2023-09-13 19:03:43 +03:00
|
|
|
(let f = File.(exec_dir / "catala") in
|
2023-09-26 12:42:46 +03:00
|
|
|
if Sys.file_exists f then Unix.realpath f
|
2023-09-19 19:21:14 +03:00
|
|
|
else
|
2024-06-25 19:29:42 +03:00
|
|
|
match catala_project_root with
|
|
|
|
| (lazy (Some root)) ->
|
2023-09-26 12:42:46 +03:00
|
|
|
Unix.realpath
|
|
|
|
File.(root / "_build" / "default" / "compiler" / "catala.exe")
|
2023-11-14 18:05:54 +03:00
|
|
|
| _ -> File.check_exec "catala")
|
|
|
|
|
2024-06-25 19:29:42 +03:00
|
|
|
let build_dir : dir:File.t -> unit -> File.t =
|
|
|
|
fun ~dir () ->
|
2024-03-19 17:16:08 +03:00
|
|
|
let d = File.clean_path dir in
|
|
|
|
File.ensure_dir d;
|
|
|
|
d
|
2023-11-14 18:05:54 +03:00
|
|
|
(* Note: it could be safer here to use File.(Sys.getcwd () / "_build") by
|
|
|
|
default, but Ninja treats relative and absolute paths separately so that
|
|
|
|
you wouldn't then be able to build target _build/foo.ml but would have to
|
|
|
|
write the full path every time *)
|
2023-09-13 19:03:43 +03:00
|
|
|
|
|
|
|
(** Locates the main [lib] directory containing the OCaml libs *)
|
|
|
|
let ocaml_libdir : File.t Lazy.t =
|
|
|
|
lazy
|
|
|
|
(try String.trim (File.process_out "opam" ["var"; "lib"])
|
|
|
|
with Failure _ -> (
|
|
|
|
try String.trim (File.process_out "ocamlc" ["-where"])
|
|
|
|
with Failure _ -> (
|
|
|
|
match File.(check_directory (exec_dir /../ "lib")) with
|
|
|
|
| Some d -> d
|
|
|
|
| None ->
|
2024-04-10 19:39:30 +03:00
|
|
|
Message.error
|
2023-09-13 19:03:43 +03:00
|
|
|
"Could not locate the OCaml library directory, make sure OCaml \
|
|
|
|
or opam is installed")))
|
|
|
|
|
|
|
|
(** Locates the directory containing the OCaml runtime to link to *)
|
|
|
|
let ocaml_runtime_dir : File.t Lazy.t =
|
|
|
|
lazy
|
|
|
|
(let d =
|
|
|
|
match Lazy.force catala_project_root with
|
|
|
|
| Some root ->
|
|
|
|
(* Relative dir when running from catala source *)
|
|
|
|
File.(
|
|
|
|
root
|
|
|
|
/ "_build"
|
|
|
|
/ "install"
|
|
|
|
/ "default"
|
|
|
|
/ "lib"
|
|
|
|
/ "catala"
|
|
|
|
/ "runtime_ocaml")
|
|
|
|
| None -> (
|
|
|
|
match
|
|
|
|
File.check_directory
|
|
|
|
File.(exec_dir /../ "lib" / "catala" / "runtime_ocaml")
|
|
|
|
with
|
|
|
|
| Some d -> d
|
2023-10-10 15:11:53 +03:00
|
|
|
| None -> File.(Lazy.force ocaml_libdir / "catala" / "runtime_ocaml")
|
|
|
|
)
|
2023-09-13 19:03:43 +03:00
|
|
|
in
|
|
|
|
match File.check_directory d with
|
|
|
|
| Some dir ->
|
2024-04-10 19:39:30 +03:00
|
|
|
Message.debug "Catala runtime libraries found at @{<bold>%s@}." dir;
|
2023-09-13 19:03:43 +03:00
|
|
|
dir
|
|
|
|
| None ->
|
2024-04-10 19:39:30 +03:00
|
|
|
Message.error
|
2024-01-17 14:51:09 +03:00
|
|
|
"@[<hov>Could not locate the Catala runtime library at %s.@ Make \
|
|
|
|
sure that either catala is correctly installed,@ or you are \
|
|
|
|
running from the root of a compiled source tree.@]"
|
|
|
|
d)
|
2023-09-13 19:03:43 +03:00
|
|
|
|
2024-04-23 13:23:31 +03:00
|
|
|
let ocaml_include_and_lib_flags : (string list * string list) Lazy.t =
|
2023-09-13 19:03:43 +03:00
|
|
|
lazy
|
2024-02-15 18:19:25 +03:00
|
|
|
(let link_libs = ["zarith"; "dates_calc"] in
|
2024-04-23 13:23:31 +03:00
|
|
|
let includes_libs =
|
|
|
|
List.map
|
2023-09-13 19:03:43 +03:00
|
|
|
(fun lib ->
|
|
|
|
match File.(check_directory (Lazy.force ocaml_libdir / lib)) with
|
|
|
|
| None ->
|
2024-04-10 19:39:30 +03:00
|
|
|
Message.error
|
2023-09-13 19:03:43 +03:00
|
|
|
"Required OCaml library not found at %a.@ Try `opam install \
|
|
|
|
%s'"
|
|
|
|
File.format
|
|
|
|
File.(Lazy.force ocaml_libdir / lib)
|
|
|
|
lib
|
|
|
|
| Some d ->
|
2024-04-23 13:23:31 +03:00
|
|
|
( ["-I"; d],
|
|
|
|
String.map (function '-' -> '_' | c -> c) lib ^ ".cmxa" ))
|
2023-09-13 19:03:43 +03:00
|
|
|
link_libs
|
|
|
|
in
|
2024-04-23 13:23:31 +03:00
|
|
|
let includes, libs = List.split includes_libs in
|
|
|
|
( List.concat includes @ ["-I"; Lazy.force ocaml_runtime_dir],
|
|
|
|
libs @ [File.(Lazy.force ocaml_runtime_dir / "runtime_ocaml.cmxa")] ))
|
|
|
|
|
|
|
|
let ocaml_include_flags : string list Lazy.t =
|
|
|
|
lazy (fst (Lazy.force ocaml_include_and_lib_flags))
|
|
|
|
|
|
|
|
let ocaml_link_flags : string list Lazy.t =
|
|
|
|
lazy (snd (Lazy.force ocaml_include_and_lib_flags))
|
2023-09-13 19:03:43 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
(**{1 Building rules}*)
|
|
|
|
|
|
|
|
(** Ninja variable names *)
|
|
|
|
module Var = struct
|
|
|
|
include Nj.Var
|
|
|
|
|
|
|
|
(** Global vars: always defined, at toplevel *)
|
|
|
|
|
|
|
|
let ninja_required_version = make "ninja_required_version"
|
|
|
|
let builddir = make "builddir"
|
|
|
|
let clerk_exe = make "CLERK_EXE"
|
|
|
|
let catala_exe = make "CATALA_EXE"
|
|
|
|
let catala_flags = make "CATALA_FLAGS"
|
2024-02-26 12:18:08 +03:00
|
|
|
let catala_flags_ocaml = make "CATALA_FLAGS_OCAML"
|
|
|
|
let catala_flags_python = make "CATALA_FLAGS_PYTHON"
|
2023-09-13 19:03:43 +03:00
|
|
|
let clerk_flags = make "CLERK_FLAGS"
|
2024-03-05 19:54:53 +03:00
|
|
|
let ocamlc_exe = make "OCAMLC_EXE"
|
2023-09-13 19:03:43 +03:00
|
|
|
let ocamlopt_exe = make "OCAMLOPT_EXE"
|
2024-03-05 19:54:53 +03:00
|
|
|
let ocaml_flags = make "OCAML_FLAGS"
|
2023-09-13 19:03:43 +03:00
|
|
|
let runtime_ocaml_libs = make "RUNTIME_OCAML_LIBS"
|
|
|
|
|
|
|
|
(** Rule vars, Used in specific rules *)
|
|
|
|
|
|
|
|
let input = make "in"
|
|
|
|
let output = make "out"
|
2023-09-15 18:40:15 +03:00
|
|
|
let pool = make "pool"
|
2023-09-26 12:42:46 +03:00
|
|
|
let src = make "src"
|
2024-03-05 19:54:53 +03:00
|
|
|
let orig_src = make "orig-src"
|
2023-09-15 18:40:15 +03:00
|
|
|
let scope = make "scope"
|
2023-09-13 19:03:43 +03:00
|
|
|
let test_id = make "test-id"
|
|
|
|
let ( ! ) = Var.v
|
|
|
|
end
|
|
|
|
|
2024-02-26 12:18:08 +03:00
|
|
|
let base_bindings catala_exe catala_flags build_dir include_dirs test_flags =
|
2023-11-14 18:05:54 +03:00
|
|
|
let includes =
|
|
|
|
List.fold_right
|
|
|
|
(fun dir flags ->
|
|
|
|
if Filename.is_relative dir then
|
|
|
|
"-I" :: File.(Var.(!builddir) / dir) :: flags
|
|
|
|
else "-I" :: dir :: flags)
|
|
|
|
include_dirs []
|
|
|
|
in
|
2023-09-27 12:58:36 +03:00
|
|
|
let catala_flags = ("--directory=" ^ Var.(!builddir)) :: catala_flags in
|
2024-02-26 12:18:08 +03:00
|
|
|
let catala_flags_ocaml =
|
|
|
|
List.filter
|
|
|
|
(function
|
2024-06-21 12:29:02 +03:00
|
|
|
| "--avoid-exceptions" | "-O" | "--optimize" | "--closure-conversion" ->
|
2024-06-21 13:17:31 +03:00
|
|
|
true
|
|
|
|
| _ -> false)
|
2024-02-26 12:18:08 +03:00
|
|
|
test_flags
|
|
|
|
in
|
|
|
|
let catala_flags_python =
|
|
|
|
List.filter
|
|
|
|
(function
|
|
|
|
| "--avoid-exceptions" | "-O" | "--optimize" | "--closure-conversion" ->
|
|
|
|
true
|
|
|
|
| _ -> false)
|
|
|
|
test_flags
|
|
|
|
in
|
2024-04-23 13:23:31 +03:00
|
|
|
let ocaml_flags = Lazy.force Poll.ocaml_include_flags in
|
2023-09-27 12:01:43 +03:00
|
|
|
[
|
2023-09-13 19:03:43 +03:00
|
|
|
Nj.binding Var.ninja_required_version ["1.7"];
|
|
|
|
(* use of implicit outputs *)
|
2023-11-14 18:05:54 +03:00
|
|
|
Nj.binding Var.builddir [build_dir];
|
2023-09-13 19:03:43 +03:00
|
|
|
Nj.binding Var.clerk_exe [Lazy.force Poll.clerk_exe];
|
|
|
|
Nj.binding Var.catala_exe
|
|
|
|
[
|
|
|
|
(match catala_exe with
|
2023-10-16 12:32:39 +03:00
|
|
|
| Some e -> File.check_exec e
|
2023-09-13 19:03:43 +03:00
|
|
|
| None -> Lazy.force Poll.catala_exe);
|
|
|
|
];
|
2023-11-14 18:05:54 +03:00
|
|
|
Nj.binding Var.catala_flags (catala_flags @ includes);
|
2024-02-26 12:18:08 +03:00
|
|
|
Nj.binding Var.catala_flags_ocaml catala_flags_ocaml;
|
|
|
|
Nj.binding Var.catala_flags_python catala_flags_python;
|
2023-09-13 19:03:43 +03:00
|
|
|
Nj.binding Var.clerk_flags
|
2024-02-26 12:18:08 +03:00
|
|
|
("-e"
|
|
|
|
:: Var.(!catala_exe)
|
|
|
|
:: ("--test-flags=" ^ String.concat "," test_flags)
|
|
|
|
:: includes
|
2023-11-14 18:05:54 +03:00
|
|
|
@ List.map (fun f -> "--catala-opts=" ^ f) catala_flags);
|
2024-03-05 19:54:53 +03:00
|
|
|
Nj.binding Var.ocamlc_exe ["ocamlc"];
|
2023-09-13 19:03:43 +03:00
|
|
|
Nj.binding Var.ocamlopt_exe ["ocamlopt"];
|
2024-03-05 19:54:53 +03:00
|
|
|
Nj.binding Var.ocaml_flags (ocaml_flags @ includes);
|
2023-09-13 19:03:43 +03:00
|
|
|
Nj.binding Var.runtime_ocaml_libs (Lazy.force Poll.ocaml_link_flags);
|
|
|
|
]
|
|
|
|
|
2023-11-14 18:05:54 +03:00
|
|
|
let[@ocamlformat "disable"] static_base_rules =
|
2023-09-13 19:03:43 +03:00
|
|
|
let open Var in
|
2024-03-05 19:54:53 +03:00
|
|
|
let shellout l = Format.sprintf "$$(%s)" (String.concat " " l) in
|
2023-09-13 19:03:43 +03:00
|
|
|
[
|
2023-09-27 12:01:43 +03:00
|
|
|
Nj.rule "copy"
|
|
|
|
~command:["cp"; "-f"; !input; !output]
|
|
|
|
~description:["<copy>"; !input];
|
2023-11-14 18:05:54 +03:00
|
|
|
|
2023-09-27 12:01:43 +03:00
|
|
|
Nj.rule "catala-ocaml"
|
2024-03-05 19:54:53 +03:00
|
|
|
~command:[!catala_exe; "ocaml"; !catala_flags; !catala_flags_ocaml;
|
|
|
|
!input; "-o"; !output]
|
2023-09-13 19:03:43 +03:00
|
|
|
~description:["<catala>"; "ocaml"; "⇒"; !output];
|
2023-11-14 18:05:54 +03:00
|
|
|
|
2024-03-14 16:03:28 +03:00
|
|
|
Nj.rule "ocaml-object"
|
2024-03-18 19:51:02 +03:00
|
|
|
~command:[!ocamlc_exe; "-i"; !ocaml_flags; !input; ">"; !input^"i"; "&&";
|
|
|
|
!ocamlc_exe; "-opaque"; !ocaml_flags; !input^"i"; "&&";
|
|
|
|
!ocamlc_exe; "-c"; !ocaml_flags; !input; "&&";
|
2024-03-20 16:38:58 +03:00
|
|
|
!ocamlopt_exe; "-c"; "-intf-suffix"; ".ml"; !ocaml_flags; !input]
|
2024-03-14 16:03:28 +03:00
|
|
|
~description:["<ocaml>"; "⇒"; !output];
|
|
|
|
|
2023-09-13 19:03:43 +03:00
|
|
|
Nj.rule "ocaml-module"
|
|
|
|
~command:
|
2024-03-14 16:03:28 +03:00
|
|
|
[!ocamlopt_exe; "-shared"; !ocaml_flags; !input; "-o"; !output]
|
2023-09-13 19:03:43 +03:00
|
|
|
~description:["<ocaml>"; "⇒"; !output];
|
2023-11-14 18:05:54 +03:00
|
|
|
|
2023-09-13 19:03:43 +03:00
|
|
|
Nj.rule "ocaml-exec"
|
2023-11-14 18:05:54 +03:00
|
|
|
~command: [
|
2024-04-23 13:23:31 +03:00
|
|
|
!ocamlopt_exe; !ocaml_flags; !runtime_ocaml_libs;
|
2024-03-05 19:54:53 +03:00
|
|
|
shellout [!catala_exe; "depends";
|
|
|
|
"--prefix="^ !builddir; "--extension=cmx";
|
|
|
|
!catala_flags; !orig_src];
|
2023-11-14 18:05:54 +03:00
|
|
|
"-o"; !output;
|
|
|
|
]
|
2023-09-13 19:03:43 +03:00
|
|
|
~description:["<ocaml>"; "⇒"; !output];
|
2023-11-14 18:05:54 +03:00
|
|
|
|
2024-02-13 15:53:00 +03:00
|
|
|
Nj.rule "python"
|
2024-03-05 19:54:53 +03:00
|
|
|
~command:[!catala_exe; "python"; !catala_flags; !catala_flags_python;
|
|
|
|
!input; "-o"; !output]
|
2024-02-13 15:53:00 +03:00
|
|
|
~description:["<catala>"; "python"; "⇒"; !output];
|
|
|
|
|
Generate tests reports from 'clerk test'
This is a proper replacement for the previous shell-based placeholder hack.
Here is a summary:
- `clerk runtest` (normally run by ninja) is much extended:
* besides generating the test@out file, it checks individual tests for success
and can write a report file containing their status, and the positions for
their (expected/current) outputs (this uses `Marshal`)
* it now handles out-tests directly in addition to inline-tests, for which
it generates the separate output file ; they are included in the report
- ninja is now tasked with building all the test reports (which shouldn't fail);
for directories, individual reports are concatenated (as before).
Removing intermediate report rules, and out-test rules means that the ninja
file is much simplified.
- then, clerk takes back control, reads the final reports and formats them in a
user-friendly way. Printing the reports may imply running `diff` internally.
In particular, the commands to easily reproduce each test are provided.
Resetting the test results if required is also done directly by clerk, at this
stage.
A few switches are available to customise the output, but I am waiting for some
feedback before deciding what to make available from the CLI.
The `clerk report` command is available to manually explore test reports, but
normally the processing is done directly at the end of `clerk test` (i.e. ninja
will no longer call that command)
2024-06-14 22:05:19 +03:00
|
|
|
Nj.rule "tests"
|
2023-09-15 12:43:40 +03:00
|
|
|
~command:
|
Generate tests reports from 'clerk test'
This is a proper replacement for the previous shell-based placeholder hack.
Here is a summary:
- `clerk runtest` (normally run by ninja) is much extended:
* besides generating the test@out file, it checks individual tests for success
and can write a report file containing their status, and the positions for
their (expected/current) outputs (this uses `Marshal`)
* it now handles out-tests directly in addition to inline-tests, for which
it generates the separate output file ; they are included in the report
- ninja is now tasked with building all the test reports (which shouldn't fail);
for directories, individual reports are concatenated (as before).
Removing intermediate report rules, and out-test rules means that the ninja
file is much simplified.
- then, clerk takes back control, reads the final reports and formats them in a
user-friendly way. Printing the reports may imply running `diff` internally.
In particular, the commands to easily reproduce each test are provided.
Resetting the test results if required is also done directly by clerk, at this
stage.
A few switches are available to customise the output, but I am waiting for some
feedback before deciding what to make available from the CLI.
The `clerk report` command is available to manually explore test reports, but
normally the processing is done directly at the end of `clerk test` (i.e. ninja
will no longer call that command)
2024-06-14 22:05:19 +03:00
|
|
|
[!clerk_exe; "runtest"; !clerk_flags; !input;
|
|
|
|
"--report"; !output;]
|
|
|
|
~description:["<catala>"; "tests"; "⇐"; !input];
|
2023-11-14 18:05:54 +03:00
|
|
|
|
2023-09-15 18:40:15 +03:00
|
|
|
Nj.rule "interpret"
|
|
|
|
~command:
|
|
|
|
[!catala_exe; "interpret"; !catala_flags; !input; "--scope=" ^ !scope]
|
|
|
|
~description:["<catala>"; "interpret"; !scope; "⇐"; !input]
|
|
|
|
~vars:[pool, ["console"]];
|
2023-11-14 18:05:54 +03:00
|
|
|
|
|
|
|
Nj.rule "dir-tests"
|
|
|
|
~command:["cat"; !input; ">"; !output; ";"]
|
2024-02-12 20:00:27 +03:00
|
|
|
~description:["<test>"; !test_id];
|
2023-09-13 19:03:43 +03:00
|
|
|
]
|
|
|
|
|
2023-11-14 18:05:54 +03:00
|
|
|
let gen_build_statements
|
|
|
|
(include_dirs : string list)
|
2024-04-16 00:00:56 +03:00
|
|
|
(same_dir_modules : (string * File.t) list)
|
2023-11-14 18:05:54 +03:00
|
|
|
(item : Scan.item) : Nj.ninja =
|
2023-09-13 19:03:43 +03:00
|
|
|
let open File in
|
|
|
|
let ( ! ) = Var.( ! ) in
|
|
|
|
let src = item.file_name in
|
|
|
|
let modules = List.rev item.used_modules in
|
2023-11-14 18:05:54 +03:00
|
|
|
let modfile ext modname =
|
2024-04-16 00:00:56 +03:00
|
|
|
match List.assoc_opt modname same_dir_modules with
|
|
|
|
| Some f -> (!Var.builddir / Filename.remove_extension f) ^ ext
|
|
|
|
| None -> modname ^ ext
|
2023-11-14 18:05:54 +03:00
|
|
|
in
|
|
|
|
let inc x = !Var.builddir / x in
|
|
|
|
let modd x = modfile "@module" x in
|
2023-09-26 12:42:46 +03:00
|
|
|
let def_src = Nj.binding Var.src [Filename.remove_extension src] in
|
|
|
|
let srcv = !Var.src ^ Filename.extension src in
|
2023-09-24 12:25:34 +03:00
|
|
|
let include_deps =
|
2023-09-27 12:01:43 +03:00
|
|
|
Nj.build "copy" ~inputs:[srcv]
|
|
|
|
~implicit_in:(List.map inc item.included_files @ List.map modd modules)
|
2023-09-26 12:42:46 +03:00
|
|
|
~outputs:[inc srcv]
|
2023-09-24 12:25:34 +03:00
|
|
|
in
|
2024-04-16 00:00:56 +03:00
|
|
|
let target_file ext = (!Var.builddir / !Var.src) ^ "." ^ ext in
|
2023-09-24 12:25:34 +03:00
|
|
|
let module_deps =
|
2023-12-04 18:41:03 +03:00
|
|
|
Option.map
|
|
|
|
(fun m ->
|
2023-12-01 20:07:16 +03:00
|
|
|
Nj.build "phony"
|
2024-04-16 00:00:56 +03:00
|
|
|
~inputs:[inc srcv; target_file "cmi"; target_file "cmxs"]
|
2023-12-01 20:07:16 +03:00
|
|
|
~outputs:[modd m])
|
2023-09-24 12:25:34 +03:00
|
|
|
item.module_def
|
|
|
|
in
|
2024-02-13 15:53:00 +03:00
|
|
|
let ml_file = target_file "ml" in
|
|
|
|
let py_file = target_file "py" in
|
|
|
|
let ocaml, python =
|
2023-12-01 17:24:54 +03:00
|
|
|
if item.extrnal then
|
2024-02-13 15:53:00 +03:00
|
|
|
( Nj.build "copy"
|
|
|
|
~implicit_in:[inc srcv]
|
|
|
|
~inputs:[src -.- "ml"]
|
|
|
|
~outputs:[ml_file],
|
|
|
|
Nj.build "copy"
|
|
|
|
~implicit_in:[inc srcv]
|
|
|
|
~inputs:[src -.- "py"]
|
|
|
|
~outputs:[py_file] )
|
2023-12-01 17:24:54 +03:00
|
|
|
else
|
2024-02-13 15:53:00 +03:00
|
|
|
( Nj.build "catala-ocaml"
|
|
|
|
~inputs:[inc srcv]
|
|
|
|
~implicit_in:[!Var.catala_exe] ~outputs:[ml_file],
|
|
|
|
Nj.build "python"
|
|
|
|
~inputs:[inc srcv]
|
|
|
|
~implicit_in:[!Var.catala_exe] ~outputs:[py_file] )
|
2022-02-25 20:00:10 +03:00
|
|
|
in
|
2023-09-13 19:03:43 +03:00
|
|
|
let ocamlopt =
|
2024-03-14 16:03:28 +03:00
|
|
|
let obj =
|
|
|
|
Nj.build "ocaml-object" ~inputs:[ml_file]
|
2024-02-05 16:01:11 +03:00
|
|
|
~implicit_in:(!Var.catala_exe :: List.map modd modules)
|
2024-06-20 15:41:57 +03:00
|
|
|
~outputs:(List.map target_file ["mli"; "cmi"; "cmo"; "cmx"; "o"])
|
2023-09-24 12:25:34 +03:00
|
|
|
~vars:
|
2023-09-27 14:06:30 +03:00
|
|
|
[
|
2024-03-05 19:54:53 +03:00
|
|
|
( Var.ocaml_flags,
|
|
|
|
!Var.ocaml_flags
|
2023-11-14 18:05:54 +03:00
|
|
|
:: "-I"
|
|
|
|
:: (!Var.builddir / src /../ "")
|
|
|
|
:: List.concat_map
|
|
|
|
(fun d ->
|
|
|
|
[
|
|
|
|
"-I";
|
|
|
|
(if Filename.is_relative d then !Var.builddir / d else d);
|
|
|
|
])
|
|
|
|
include_dirs );
|
2023-09-24 12:25:34 +03:00
|
|
|
]
|
2024-03-14 16:03:28 +03:00
|
|
|
in
|
|
|
|
let modexec =
|
|
|
|
match item.module_def with
|
|
|
|
| Some _ ->
|
|
|
|
Nj.build "ocaml-module"
|
|
|
|
~inputs:[target_file "cmx"]
|
|
|
|
~outputs:[target_file "cmxs"]
|
|
|
|
| None ->
|
|
|
|
Nj.build "ocaml-exec"
|
|
|
|
~inputs:[target_file "cmx"]
|
|
|
|
~outputs:[target_file "exe"]
|
|
|
|
~vars:[Var.orig_src, [inc srcv]]
|
|
|
|
in
|
|
|
|
[obj; modexec]
|
2023-11-14 18:05:54 +03:00
|
|
|
in
|
|
|
|
let expose_module =
|
|
|
|
match item.module_def with
|
|
|
|
| Some m when List.mem (dirname src) include_dirs ->
|
2023-12-04 18:41:03 +03:00
|
|
|
Some (Nj.build "phony" ~outputs:[m ^ "@module"] ~inputs:[modd m])
|
2023-11-14 18:05:54 +03:00
|
|
|
| _ -> None
|
2023-09-13 19:03:43 +03:00
|
|
|
in
|
2023-09-24 12:25:34 +03:00
|
|
|
let interp_deps =
|
2023-09-27 12:01:43 +03:00
|
|
|
!Var.catala_exe
|
2023-11-14 18:05:54 +03:00
|
|
|
:: List.map
|
|
|
|
(fun m ->
|
2024-04-16 00:00:56 +03:00
|
|
|
match List.assoc_opt m same_dir_modules with
|
|
|
|
| Some f -> (!Var.builddir / Filename.remove_extension f) ^ ".cmxs"
|
|
|
|
| None -> m ^ "@module")
|
2023-11-14 18:05:54 +03:00
|
|
|
modules
|
2023-09-15 18:40:15 +03:00
|
|
|
in
|
|
|
|
let interpret =
|
|
|
|
Nj.build "interpret"
|
2023-10-02 19:24:24 +03:00
|
|
|
~outputs:[srcv ^ "@interpret"]
|
2023-09-27 12:01:43 +03:00
|
|
|
~inputs:[inc srcv]
|
2023-09-24 12:25:34 +03:00
|
|
|
~implicit_in:interp_deps
|
2023-09-15 18:40:15 +03:00
|
|
|
in
|
2023-09-27 12:58:36 +03:00
|
|
|
let legacy_test_reference test =
|
|
|
|
(src /../ "output" / Filename.basename src) -.- test.Scan.id
|
|
|
|
in
|
2023-09-13 19:03:43 +03:00
|
|
|
let tests =
|
Generate tests reports from 'clerk test'
This is a proper replacement for the previous shell-based placeholder hack.
Here is a summary:
- `clerk runtest` (normally run by ninja) is much extended:
* besides generating the test@out file, it checks individual tests for success
and can write a report file containing their status, and the positions for
their (expected/current) outputs (this uses `Marshal`)
* it now handles out-tests directly in addition to inline-tests, for which
it generates the separate output file ; they are included in the report
- ninja is now tasked with building all the test reports (which shouldn't fail);
for directories, individual reports are concatenated (as before).
Removing intermediate report rules, and out-test rules means that the ninja
file is much simplified.
- then, clerk takes back control, reads the final reports and formats them in a
user-friendly way. Printing the reports may imply running `diff` internally.
In particular, the commands to easily reproduce each test are provided.
Resetting the test results if required is also done directly by clerk, at this
stage.
A few switches are available to customise the output, but I am waiting for some
feedback before deciding what to make available from the CLI.
The `clerk report` command is available to manually explore test reports, but
normally the processing is done directly at the end of `clerk test` (i.e. ninja
will no longer call that command)
2024-06-14 22:05:19 +03:00
|
|
|
let out_tests_references =
|
|
|
|
List.map (fun test -> legacy_test_reference test) item.legacy_tests
|
|
|
|
in
|
|
|
|
let out_tests_prepare =
|
|
|
|
List.map
|
|
|
|
(fun f -> Nj.build "copy" ~inputs:[f] ~outputs:[inc f])
|
|
|
|
out_tests_references
|
2022-09-23 12:41:45 +03:00
|
|
|
in
|
Generate tests reports from 'clerk test'
This is a proper replacement for the previous shell-based placeholder hack.
Here is a summary:
- `clerk runtest` (normally run by ninja) is much extended:
* besides generating the test@out file, it checks individual tests for success
and can write a report file containing their status, and the positions for
their (expected/current) outputs (this uses `Marshal`)
* it now handles out-tests directly in addition to inline-tests, for which
it generates the separate output file ; they are included in the report
- ninja is now tasked with building all the test reports (which shouldn't fail);
for directories, individual reports are concatenated (as before).
Removing intermediate report rules, and out-test rules means that the ninja
file is much simplified.
- then, clerk takes back control, reads the final reports and formats them in a
user-friendly way. Printing the reports may imply running `diff` internally.
In particular, the commands to easily reproduce each test are provided.
Resetting the test results if required is also done directly by clerk, at this
stage.
A few switches are available to customise the output, but I am waiting for some
feedback before deciding what to make available from the CLI.
The `clerk report` command is available to manually explore test reports, but
normally the processing is done directly at the end of `clerk test` (i.e. ninja
will no longer call that command)
2024-06-14 22:05:19 +03:00
|
|
|
let tests =
|
|
|
|
if (not item.has_inline_tests) && item.legacy_tests = [] then []
|
2023-09-13 19:03:43 +03:00
|
|
|
else
|
|
|
|
[
|
Generate tests reports from 'clerk test'
This is a proper replacement for the previous shell-based placeholder hack.
Here is a summary:
- `clerk runtest` (normally run by ninja) is much extended:
* besides generating the test@out file, it checks individual tests for success
and can write a report file containing their status, and the positions for
their (expected/current) outputs (this uses `Marshal`)
* it now handles out-tests directly in addition to inline-tests, for which
it generates the separate output file ; they are included in the report
- ninja is now tasked with building all the test reports (which shouldn't fail);
for directories, individual reports are concatenated (as before).
Removing intermediate report rules, and out-test rules means that the ninja
file is much simplified.
- then, clerk takes back control, reads the final reports and formats them in a
user-friendly way. Printing the reports may imply running `diff` internally.
In particular, the commands to easily reproduce each test are provided.
Resetting the test results if required is also done directly by clerk, at this
stage.
A few switches are available to customise the output, but I am waiting for some
feedback before deciding what to make available from the CLI.
The `clerk report` command is available to manually explore test reports, but
normally the processing is done directly at the end of `clerk test` (i.e. ninja
will no longer call that command)
2024-06-14 22:05:19 +03:00
|
|
|
Nj.build "tests"
|
2023-09-27 12:01:43 +03:00
|
|
|
~inputs:[inc srcv]
|
Generate tests reports from 'clerk test'
This is a proper replacement for the previous shell-based placeholder hack.
Here is a summary:
- `clerk runtest` (normally run by ninja) is much extended:
* besides generating the test@out file, it checks individual tests for success
and can write a report file containing their status, and the positions for
their (expected/current) outputs (this uses `Marshal`)
* it now handles out-tests directly in addition to inline-tests, for which
it generates the separate output file ; they are included in the report
- ninja is now tasked with building all the test reports (which shouldn't fail);
for directories, individual reports are concatenated (as before).
Removing intermediate report rules, and out-test rules means that the ninja
file is much simplified.
- then, clerk takes back control, reads the final reports and formats them in a
user-friendly way. Printing the reports may imply running `diff` internally.
In particular, the commands to easily reproduce each test are provided.
Resetting the test results if required is also done directly by clerk, at this
stage.
A few switches are available to customise the output, but I am waiting for some
feedback before deciding what to make available from the CLI.
The `clerk report` command is available to manually explore test reports, but
normally the processing is done directly at the end of `clerk test` (i.e. ninja
will no longer call that command)
2024-06-14 22:05:19 +03:00
|
|
|
~implicit_in:
|
|
|
|
((!Var.clerk_exe :: interp_deps)
|
|
|
|
@ List.map inc out_tests_references)
|
|
|
|
~outputs:[inc srcv ^ "@test"; inc srcv ^ "@out"]
|
|
|
|
~implicit_out:
|
|
|
|
(List.map (fun o -> inc o ^ "@out") out_tests_references);
|
2023-09-13 19:03:43 +03:00
|
|
|
]
|
2022-02-25 20:00:10 +03:00
|
|
|
in
|
Generate tests reports from 'clerk test'
This is a proper replacement for the previous shell-based placeholder hack.
Here is a summary:
- `clerk runtest` (normally run by ninja) is much extended:
* besides generating the test@out file, it checks individual tests for success
and can write a report file containing their status, and the positions for
their (expected/current) outputs (this uses `Marshal`)
* it now handles out-tests directly in addition to inline-tests, for which
it generates the separate output file ; they are included in the report
- ninja is now tasked with building all the test reports (which shouldn't fail);
for directories, individual reports are concatenated (as before).
Removing intermediate report rules, and out-test rules means that the ninja
file is much simplified.
- then, clerk takes back control, reads the final reports and formats them in a
user-friendly way. Printing the reports may imply running `diff` internally.
In particular, the commands to easily reproduce each test are provided.
Resetting the test results if required is also done directly by clerk, at this
stage.
A few switches are available to customise the output, but I am waiting for some
feedback before deciding what to make available from the CLI.
The `clerk report` command is available to manually explore test reports, but
normally the processing is done directly at the end of `clerk test` (i.e. ninja
will no longer call that command)
2024-06-14 22:05:19 +03:00
|
|
|
out_tests_prepare @ tests
|
2022-02-25 20:00:10 +03:00
|
|
|
in
|
2023-09-13 19:03:43 +03:00
|
|
|
Seq.concat
|
|
|
|
@@ List.to_seq
|
|
|
|
[
|
2023-09-26 12:42:46 +03:00
|
|
|
Seq.return (Nj.comment "");
|
|
|
|
Seq.return def_src;
|
2023-09-24 12:25:34 +03:00
|
|
|
Seq.return include_deps;
|
|
|
|
Option.to_seq module_deps;
|
2023-11-14 18:05:54 +03:00
|
|
|
Option.to_seq expose_module;
|
2023-09-13 19:03:43 +03:00
|
|
|
Seq.return ocaml;
|
2024-03-14 16:03:28 +03:00
|
|
|
List.to_seq ocamlopt;
|
2024-02-13 15:53:00 +03:00
|
|
|
Seq.return python;
|
2023-09-13 19:03:43 +03:00
|
|
|
List.to_seq tests;
|
2023-09-15 18:40:15 +03:00
|
|
|
Seq.return interpret;
|
2023-09-13 19:03:43 +03:00
|
|
|
]
|
|
|
|
|
2023-11-14 18:05:54 +03:00
|
|
|
let gen_build_statements_dir
|
|
|
|
(include_dirs : string list)
|
|
|
|
(items : Scan.item list) : Nj.ninja =
|
|
|
|
let same_dir_modules =
|
2024-04-16 00:00:56 +03:00
|
|
|
List.filter_map
|
|
|
|
(fun item ->
|
|
|
|
Option.map (fun name -> name, item.Scan.file_name) item.Scan.module_def)
|
|
|
|
items
|
2023-09-16 01:55:50 +03:00
|
|
|
in
|
2023-11-14 18:05:54 +03:00
|
|
|
Seq.flat_map
|
|
|
|
(gen_build_statements include_dirs same_dir_modules)
|
|
|
|
(List.to_seq items)
|
2023-09-16 01:55:50 +03:00
|
|
|
|
2023-11-14 18:05:54 +03:00
|
|
|
let dir_test_rules dir subdirs items =
|
|
|
|
let open File in
|
|
|
|
let inputs =
|
|
|
|
List.rev_append
|
|
|
|
(List.rev_map (fun s -> (Var.(!builddir) / s) ^ "@test") subdirs)
|
|
|
|
(List.filter_map
|
|
|
|
(fun item ->
|
|
|
|
if item.Scan.legacy_tests = [] && not item.Scan.has_inline_tests then
|
|
|
|
None
|
|
|
|
else Some ((Var.(!builddir) / item.Scan.file_name) ^ "@test"))
|
|
|
|
items)
|
|
|
|
in
|
|
|
|
List.to_seq
|
|
|
|
[
|
|
|
|
Nj.Comment "";
|
2024-02-12 20:00:27 +03:00
|
|
|
Nj.build "dir-tests"
|
|
|
|
~outputs:[(Var.(!builddir) / dir) ^ "@test"]
|
|
|
|
~inputs
|
|
|
|
~vars:[Var.test_id, [dir]];
|
2023-11-14 18:05:54 +03:00
|
|
|
]
|
|
|
|
|
|
|
|
let build_statements include_dirs dir =
|
2023-09-26 12:42:46 +03:00
|
|
|
Scan.tree dir
|
2023-11-14 18:05:54 +03:00
|
|
|
|> Seq.flat_map
|
|
|
|
@@ fun (dir, subdirs, items) ->
|
|
|
|
Seq.append
|
|
|
|
(gen_build_statements_dir include_dirs items)
|
|
|
|
(dir_test_rules dir subdirs items)
|
2023-09-13 19:03:43 +03:00
|
|
|
|
2024-02-26 12:18:08 +03:00
|
|
|
let gen_ninja_file catala_exe catala_flags build_dir include_dirs test_flags dir
|
|
|
|
=
|
2023-09-13 19:03:43 +03:00
|
|
|
let ( @+ ) = Seq.append in
|
|
|
|
Seq.return
|
|
|
|
(Nj.Comment (Printf.sprintf "File generated by Clerk v.%s\n" version))
|
|
|
|
@+ Seq.return (Nj.Comment "- Global variables - #\n")
|
2024-02-26 12:18:08 +03:00
|
|
|
@+ List.to_seq
|
|
|
|
(base_bindings catala_exe catala_flags build_dir include_dirs test_flags)
|
2023-09-26 12:42:46 +03:00
|
|
|
@+ Seq.return (Nj.Comment "\n- Base rules - #\n")
|
2023-09-13 19:03:43 +03:00
|
|
|
@+ List.to_seq static_base_rules
|
2023-11-20 18:01:06 +03:00
|
|
|
@+ Seq.return (Nj.build "phony" ~outputs:["always"])
|
|
|
|
@+ Seq.return (Nj.Comment "\n- Project-specific build statements - #")
|
2023-11-14 18:05:54 +03:00
|
|
|
@+ build_statements include_dirs dir
|
|
|
|
@+ Seq.return (Nj.build "phony" ~outputs:["test"] ~inputs:[".@test"])
|
2022-02-25 20:00:10 +03:00
|
|
|
|
2022-02-26 21:49:13 +03:00
|
|
|
(** {1 Driver} *)
|
|
|
|
|
2024-06-25 19:29:42 +03:00
|
|
|
(* Last argument is a continuation taking as arguments [build_dir], the
|
|
|
|
[fix_path] function, and the ninja file name *)
|
2023-11-14 18:05:54 +03:00
|
|
|
let ninja_init
|
2024-06-25 19:29:42 +03:00
|
|
|
~config_file
|
2023-11-14 18:05:54 +03:00
|
|
|
~catala_exe
|
|
|
|
~catala_opts
|
|
|
|
~build_dir
|
|
|
|
~include_dirs
|
|
|
|
~color
|
|
|
|
~debug
|
2024-02-26 12:18:08 +03:00
|
|
|
~ninja_output :
|
2024-06-25 19:29:42 +03:00
|
|
|
extra:def Seq.t ->
|
|
|
|
test_flags:string list ->
|
|
|
|
(File.t -> (File.t -> File.t) -> File.t -> 'a) ->
|
|
|
|
'a =
|
2024-03-15 16:23:30 +03:00
|
|
|
let _options = Catala_utils.Global.enforce_options ~debug ~color () in
|
2024-06-25 19:29:42 +03:00
|
|
|
let default_config_file = "clerk.toml" in
|
|
|
|
let set_root_dir dir =
|
|
|
|
Message.debug "Entering directory %a" File.format dir;
|
|
|
|
Sys.chdir dir
|
|
|
|
in
|
|
|
|
(* fix_path adjusts paths specified from the command-line relative to the user
|
|
|
|
cwd to be instead relative to the project root *)
|
|
|
|
let fix_path, config =
|
|
|
|
let from_dir = Sys.getcwd () in
|
|
|
|
match config_file with
|
|
|
|
| None -> (
|
|
|
|
match
|
|
|
|
File.(find_in_parents (fun dir -> exists (dir / default_config_file)))
|
|
|
|
with
|
|
|
|
| Some (root, rel) ->
|
|
|
|
set_root_dir root;
|
|
|
|
( Catala_utils.File.reverse_path ~from_dir ~to_dir:rel,
|
|
|
|
Clerk_config.read default_config_file )
|
|
|
|
| None -> (
|
|
|
|
match
|
|
|
|
File.(
|
|
|
|
find_in_parents (function dir ->
|
|
|
|
exists (dir / "catala.opam") || exists (dir / ".git")))
|
|
|
|
with
|
|
|
|
| Some (root, rel) ->
|
|
|
|
set_root_dir root;
|
|
|
|
( Catala_utils.File.reverse_path ~from_dir ~to_dir:rel,
|
|
|
|
Clerk_config.default )
|
|
|
|
| None -> Fun.id, Clerk_config.default))
|
|
|
|
| Some f ->
|
|
|
|
let root = Filename.dirname f in
|
|
|
|
let config = Clerk_config.read f in
|
|
|
|
set_root_dir root;
|
|
|
|
( (fun d ->
|
|
|
|
let r = Catala_utils.File.reverse_path ~from_dir ~to_dir:root d in
|
|
|
|
Message.debug "%a => %a" File.format d File.format r;
|
|
|
|
r),
|
|
|
|
config )
|
|
|
|
in
|
|
|
|
let build_dir =
|
|
|
|
let dir =
|
|
|
|
match build_dir with None -> config.build_dir | Some dir -> dir
|
|
|
|
in
|
|
|
|
Poll.build_dir ~dir ()
|
2023-11-14 18:05:54 +03:00
|
|
|
in
|
2024-06-25 19:29:42 +03:00
|
|
|
let catala_opts = config.catala_opts @ catala_opts in
|
|
|
|
let include_dirs = config.include_dirs @ include_dirs in
|
2023-09-19 17:26:05 +03:00
|
|
|
let with_ninja_output k =
|
|
|
|
match ninja_output with
|
|
|
|
| Some f -> k f
|
2023-11-14 18:05:54 +03:00
|
|
|
| None when debug -> k File.(build_dir / "clerk.ninja")
|
2023-09-26 12:42:46 +03:00
|
|
|
| None -> File.with_temp_file "clerk_build_" ".ninja" k
|
2023-09-19 17:26:05 +03:00
|
|
|
in
|
2024-02-26 12:18:08 +03:00
|
|
|
fun ~extra ~test_flags k ->
|
2024-04-10 19:39:30 +03:00
|
|
|
Message.debug "building ninja rules...";
|
Generate tests reports from 'clerk test'
This is a proper replacement for the previous shell-based placeholder hack.
Here is a summary:
- `clerk runtest` (normally run by ninja) is much extended:
* besides generating the test@out file, it checks individual tests for success
and can write a report file containing their status, and the positions for
their (expected/current) outputs (this uses `Marshal`)
* it now handles out-tests directly in addition to inline-tests, for which
it generates the separate output file ; they are included in the report
- ninja is now tasked with building all the test reports (which shouldn't fail);
for directories, individual reports are concatenated (as before).
Removing intermediate report rules, and out-test rules means that the ninja
file is much simplified.
- then, clerk takes back control, reads the final reports and formats them in a
user-friendly way. Printing the reports may imply running `diff` internally.
In particular, the commands to easily reproduce each test are provided.
Resetting the test results if required is also done directly by clerk, at this
stage.
A few switches are available to customise the output, but I am waiting for some
feedback before deciding what to make available from the CLI.
The `clerk report` command is available to manually explore test reports, but
normally the processing is done directly at the end of `clerk test` (i.e. ninja
will no longer call that command)
2024-06-14 22:05:19 +03:00
|
|
|
let build_dir =
|
|
|
|
match test_flags with
|
|
|
|
| [] -> build_dir
|
|
|
|
| flags -> File.((build_dir / "test") ^ String.concat "" flags)
|
|
|
|
in
|
2023-09-19 17:26:05 +03:00
|
|
|
with_ninja_output
|
|
|
|
@@ fun nin_file ->
|
|
|
|
File.with_formatter_of_file nin_file (fun nin_ppf ->
|
|
|
|
let ninja_contents =
|
|
|
|
Seq.concat
|
|
|
|
@@ List.to_seq
|
|
|
|
[
|
2024-02-26 12:18:08 +03:00
|
|
|
gen_ninja_file catala_exe catala_opts build_dir include_dirs
|
|
|
|
test_flags ".";
|
2023-09-19 17:26:05 +03:00
|
|
|
Seq.return (Nj.comment "\n - Command-specific targets - #");
|
|
|
|
extra;
|
|
|
|
]
|
|
|
|
in
|
|
|
|
Nj.format nin_ppf ninja_contents);
|
2024-06-25 19:29:42 +03:00
|
|
|
k build_dir fix_path nin_file
|
2023-09-19 17:26:05 +03:00
|
|
|
|
2024-04-19 17:34:53 +03:00
|
|
|
let cleaned_up_env () =
|
|
|
|
let passthrough_vars =
|
|
|
|
["CATALA_BIN="; "CATALA_INCLUDE="; "CATALA_TEST_FLAGS="]
|
|
|
|
in
|
|
|
|
Unix.environment ()
|
|
|
|
|> Array.to_seq
|
|
|
|
|> Seq.filter (fun s ->
|
|
|
|
(not (String.starts_with ~prefix:"CATALA_" s))
|
|
|
|
|| List.exists
|
|
|
|
(fun prefix -> String.starts_with ~prefix s)
|
|
|
|
passthrough_vars
|
|
|
|
||
|
|
|
|
(Message.warning "Ignoring environment variable %s" s;
|
|
|
|
false))
|
|
|
|
|> Array.of_seq
|
|
|
|
|
2023-09-26 12:42:46 +03:00
|
|
|
let ninja_cmdline ninja_flags nin_file targets =
|
2024-04-19 17:34:53 +03:00
|
|
|
("ninja" :: "-f" :: nin_file :: ninja_flags)
|
|
|
|
@ (if Catala_utils.Global.options.debug then ["-v"] else [])
|
|
|
|
@ targets
|
|
|
|
|
|
|
|
let run_ninja ~clean_up_env cmdline =
|
|
|
|
let cmd = List.hd cmdline in
|
|
|
|
let env = if clean_up_env then cleaned_up_env () else Unix.environment () in
|
2024-05-08 13:23:35 +03:00
|
|
|
let npid =
|
|
|
|
Unix.create_process_env cmd (Array.of_list cmdline) env Unix.stdin
|
|
|
|
Unix.stdout Unix.stderr
|
|
|
|
in
|
|
|
|
let return_code =
|
|
|
|
match Unix.waitpid [] npid with
|
|
|
|
| _, Unix.WEXITED n -> n
|
|
|
|
| _, (Unix.WSIGNALED n | Unix.WSTOPPED n) -> 128 - n
|
|
|
|
in
|
Generate tests reports from 'clerk test'
This is a proper replacement for the previous shell-based placeholder hack.
Here is a summary:
- `clerk runtest` (normally run by ninja) is much extended:
* besides generating the test@out file, it checks individual tests for success
and can write a report file containing their status, and the positions for
their (expected/current) outputs (this uses `Marshal`)
* it now handles out-tests directly in addition to inline-tests, for which
it generates the separate output file ; they are included in the report
- ninja is now tasked with building all the test reports (which shouldn't fail);
for directories, individual reports are concatenated (as before).
Removing intermediate report rules, and out-test rules means that the ninja
file is much simplified.
- then, clerk takes back control, reads the final reports and formats them in a
user-friendly way. Printing the reports may imply running `diff` internally.
In particular, the commands to easily reproduce each test are provided.
Resetting the test results if required is also done directly by clerk, at this
stage.
A few switches are available to customise the output, but I am waiting for some
feedback before deciding what to make available from the CLI.
The `clerk report` command is available to manually explore test reports, but
normally the processing is done directly at the end of `clerk test` (i.e. ninja
will no longer call that command)
2024-06-14 22:05:19 +03:00
|
|
|
return_code
|
2023-09-26 12:42:46 +03:00
|
|
|
|
2023-09-19 17:26:05 +03:00
|
|
|
open Cmdliner
|
|
|
|
|
2023-09-19 18:56:18 +03:00
|
|
|
let build_cmd =
|
2024-04-19 17:34:53 +03:00
|
|
|
let run ninja_init (targets : string list) (ninja_flags : string list) =
|
2024-02-26 12:18:08 +03:00
|
|
|
ninja_init ~extra:Seq.empty ~test_flags:[]
|
2024-06-25 19:29:42 +03:00
|
|
|
@@ fun _build_dir fix_path nin_file ->
|
2023-11-14 18:05:54 +03:00
|
|
|
let targets =
|
|
|
|
List.map
|
|
|
|
(fun f ->
|
|
|
|
if String.exists (function '/' | '.' -> true | _ -> false) f then
|
|
|
|
fix_path f
|
|
|
|
else f)
|
|
|
|
targets
|
|
|
|
in
|
2023-09-26 12:42:46 +03:00
|
|
|
let ninja_cmd = ninja_cmdline ninja_flags nin_file targets in
|
2024-04-19 17:34:53 +03:00
|
|
|
Message.debug "executing '%s'..." (String.concat " " ninja_cmd);
|
Generate tests reports from 'clerk test'
This is a proper replacement for the previous shell-based placeholder hack.
Here is a summary:
- `clerk runtest` (normally run by ninja) is much extended:
* besides generating the test@out file, it checks individual tests for success
and can write a report file containing their status, and the positions for
their (expected/current) outputs (this uses `Marshal`)
* it now handles out-tests directly in addition to inline-tests, for which
it generates the separate output file ; they are included in the report
- ninja is now tasked with building all the test reports (which shouldn't fail);
for directories, individual reports are concatenated (as before).
Removing intermediate report rules, and out-test rules means that the ninja
file is much simplified.
- then, clerk takes back control, reads the final reports and formats them in a
user-friendly way. Printing the reports may imply running `diff` internally.
In particular, the commands to easily reproduce each test are provided.
Resetting the test results if required is also done directly by clerk, at this
stage.
A few switches are available to customise the output, but I am waiting for some
feedback before deciding what to make available from the CLI.
The `clerk report` command is available to manually explore test reports, but
normally the processing is done directly at the end of `clerk test` (i.e. ninja
will no longer call that command)
2024-06-14 22:05:19 +03:00
|
|
|
raise (Catala_utils.Cli.Exit_with (run_ninja ~clean_up_env:false ninja_cmd))
|
2023-09-19 18:56:18 +03:00
|
|
|
in
|
|
|
|
let doc =
|
|
|
|
"Low-level build command: can be used to forward build targets or options \
|
|
|
|
directly to Ninja"
|
|
|
|
in
|
|
|
|
Cmd.v (Cmd.info ~doc "build")
|
|
|
|
Term.(
|
|
|
|
const run $ Cli.Global.term ninja_init $ Cli.targets $ Cli.ninja_flags)
|
|
|
|
|
2024-06-19 13:14:26 +03:00
|
|
|
let set_report_verbosity = function
|
|
|
|
| `Summary -> Clerk_report.set_display_flags ~files:`None ~tests:`None ()
|
|
|
|
| `Short ->
|
|
|
|
Clerk_report.set_display_flags ~files:`Failed ~tests:`Failed ~diffs:false ()
|
|
|
|
| `Failures ->
|
|
|
|
if Global.options.debug then Clerk_report.set_display_flags ~files:`All ()
|
|
|
|
| `Verbose -> Clerk_report.set_display_flags ~files:`All ~tests:`All ()
|
|
|
|
|
2023-09-19 17:26:05 +03:00
|
|
|
let test_cmd =
|
|
|
|
let run
|
|
|
|
ninja_init
|
|
|
|
(files_or_folders : string list)
|
|
|
|
(reset_test_outputs : bool)
|
2024-02-26 12:18:08 +03:00
|
|
|
(test_flags : string list)
|
2024-06-19 13:14:26 +03:00
|
|
|
verbosity
|
2024-07-04 15:25:46 +03:00
|
|
|
xml
|
2024-06-27 12:58:53 +03:00
|
|
|
(diff_command : string option option)
|
2024-04-19 17:34:53 +03:00
|
|
|
(ninja_flags : string list) =
|
2024-06-19 13:14:26 +03:00
|
|
|
set_report_verbosity verbosity;
|
2024-06-27 12:58:53 +03:00
|
|
|
Clerk_report.set_display_flags ~diff_command ();
|
Generate tests reports from 'clerk test'
This is a proper replacement for the previous shell-based placeholder hack.
Here is a summary:
- `clerk runtest` (normally run by ninja) is much extended:
* besides generating the test@out file, it checks individual tests for success
and can write a report file containing their status, and the positions for
their (expected/current) outputs (this uses `Marshal`)
* it now handles out-tests directly in addition to inline-tests, for which
it generates the separate output file ; they are included in the report
- ninja is now tasked with building all the test reports (which shouldn't fail);
for directories, individual reports are concatenated (as before).
Removing intermediate report rules, and out-test rules means that the ninja
file is much simplified.
- then, clerk takes back control, reads the final reports and formats them in a
user-friendly way. Printing the reports may imply running `diff` internally.
In particular, the commands to easily reproduce each test are provided.
Resetting the test results if required is also done directly by clerk, at this
stage.
A few switches are available to customise the output, but I am waiting for some
feedback before deciding what to make available from the CLI.
The `clerk report` command is available to manually explore test reports, but
normally the processing is done directly at the end of `clerk test` (i.e. ninja
will no longer call that command)
2024-06-14 22:05:19 +03:00
|
|
|
ninja_init ~extra:Seq.empty ~test_flags
|
2024-06-25 19:29:42 +03:00
|
|
|
@@ fun build_dir fix_path nin_file ->
|
2023-09-19 17:26:05 +03:00
|
|
|
let targets =
|
2023-11-14 18:05:54 +03:00
|
|
|
let fs = if files_or_folders = [] then ["."] else files_or_folders in
|
Generate tests reports from 'clerk test'
This is a proper replacement for the previous shell-based placeholder hack.
Here is a summary:
- `clerk runtest` (normally run by ninja) is much extended:
* besides generating the test@out file, it checks individual tests for success
and can write a report file containing their status, and the positions for
their (expected/current) outputs (this uses `Marshal`)
* it now handles out-tests directly in addition to inline-tests, for which
it generates the separate output file ; they are included in the report
- ninja is now tasked with building all the test reports (which shouldn't fail);
for directories, individual reports are concatenated (as before).
Removing intermediate report rules, and out-test rules means that the ninja
file is much simplified.
- then, clerk takes back control, reads the final reports and formats them in a
user-friendly way. Printing the reports may imply running `diff` internally.
In particular, the commands to easily reproduce each test are provided.
Resetting the test results if required is also done directly by clerk, at this
stage.
A few switches are available to customise the output, but I am waiting for some
feedback before deciding what to make available from the CLI.
The `clerk report` command is available to manually explore test reports, but
normally the processing is done directly at the end of `clerk test` (i.e. ninja
will no longer call that command)
2024-06-14 22:05:19 +03:00
|
|
|
List.map File.(fun f -> (build_dir / fix_path f) ^ "@test") fs
|
2023-09-26 12:42:46 +03:00
|
|
|
in
|
2023-11-14 18:05:54 +03:00
|
|
|
let ninja_cmd = ninja_cmdline ninja_flags nin_file targets in
|
2024-04-19 17:34:53 +03:00
|
|
|
Message.debug "executing '%s'..." (String.concat " " ninja_cmd);
|
Generate tests reports from 'clerk test'
This is a proper replacement for the previous shell-based placeholder hack.
Here is a summary:
- `clerk runtest` (normally run by ninja) is much extended:
* besides generating the test@out file, it checks individual tests for success
and can write a report file containing their status, and the positions for
their (expected/current) outputs (this uses `Marshal`)
* it now handles out-tests directly in addition to inline-tests, for which
it generates the separate output file ; they are included in the report
- ninja is now tasked with building all the test reports (which shouldn't fail);
for directories, individual reports are concatenated (as before).
Removing intermediate report rules, and out-test rules means that the ninja
file is much simplified.
- then, clerk takes back control, reads the final reports and formats them in a
user-friendly way. Printing the reports may imply running `diff` internally.
In particular, the commands to easily reproduce each test are provided.
Resetting the test results if required is also done directly by clerk, at this
stage.
A few switches are available to customise the output, but I am waiting for some
feedback before deciding what to make available from the CLI.
The `clerk report` command is available to manually explore test reports, but
normally the processing is done directly at the end of `clerk test` (i.e. ninja
will no longer call that command)
2024-06-14 22:05:19 +03:00
|
|
|
match run_ninja ~clean_up_env:true ninja_cmd with
|
|
|
|
| 0 ->
|
|
|
|
Message.debug "gathering test results...";
|
|
|
|
let open Clerk_report in
|
|
|
|
let reports = List.flatten (List.map read_many targets) in
|
|
|
|
if reset_test_outputs then
|
|
|
|
let () =
|
2024-07-04 15:25:46 +03:00
|
|
|
if xml then
|
|
|
|
Message.error
|
|
|
|
"Options @{<bold>--xml@} and @{<bold>--reset@} are incompatible";
|
Generate tests reports from 'clerk test'
This is a proper replacement for the previous shell-based placeholder hack.
Here is a summary:
- `clerk runtest` (normally run by ninja) is much extended:
* besides generating the test@out file, it checks individual tests for success
and can write a report file containing their status, and the positions for
their (expected/current) outputs (this uses `Marshal`)
* it now handles out-tests directly in addition to inline-tests, for which
it generates the separate output file ; they are included in the report
- ninja is now tasked with building all the test reports (which shouldn't fail);
for directories, individual reports are concatenated (as before).
Removing intermediate report rules, and out-test rules means that the ninja
file is much simplified.
- then, clerk takes back control, reads the final reports and formats them in a
user-friendly way. Printing the reports may imply running `diff` internally.
In particular, the commands to easily reproduce each test are provided.
Resetting the test results if required is also done directly by clerk, at this
stage.
A few switches are available to customise the output, but I am waiting for some
feedback before deciding what to make available from the CLI.
The `clerk report` command is available to manually explore test reports, but
normally the processing is done directly at the end of `clerk test` (i.e. ninja
will no longer call that command)
2024-06-14 22:05:19 +03:00
|
|
|
let ppf = Message.formatter_of_out_channel stdout () in
|
|
|
|
match List.filter (fun f -> f.successful < f.total) reports with
|
|
|
|
| [] ->
|
|
|
|
Format.fprintf ppf
|
|
|
|
"[@{<green>DONE@}] All tests passed, nothing to reset@."
|
|
|
|
| need_reset ->
|
|
|
|
List.iter
|
|
|
|
(fun f ->
|
|
|
|
let files =
|
|
|
|
List.fold_left
|
|
|
|
(fun files t ->
|
|
|
|
if t.success then files
|
|
|
|
else
|
|
|
|
File.Map.add (fst t.result).Lexing.pos_fname
|
|
|
|
(String.remove_prefix
|
|
|
|
~prefix:File.(build_dir / "")
|
|
|
|
(fst t.expected).Lexing.pos_fname)
|
|
|
|
files)
|
|
|
|
File.Map.empty f.tests
|
|
|
|
in
|
|
|
|
File.Map.iter
|
|
|
|
(fun result expected ->
|
|
|
|
Format.kasprintf Sys.command "cp -f %a %a@." File.format
|
|
|
|
result File.format expected
|
|
|
|
|> ignore)
|
|
|
|
files)
|
|
|
|
need_reset;
|
|
|
|
Format.fprintf ppf
|
|
|
|
"[@{<green>DONE@}] @{<yellow;bold>%d@} test files were \
|
|
|
|
@{<yellow>RESET@}@."
|
|
|
|
(List.length need_reset)
|
|
|
|
in
|
|
|
|
raise (Catala_utils.Cli.Exit_with 0)
|
2024-07-04 15:25:46 +03:00
|
|
|
else if (if xml then print_xml else summary) ~build_dir reports then
|
Generate tests reports from 'clerk test'
This is a proper replacement for the previous shell-based placeholder hack.
Here is a summary:
- `clerk runtest` (normally run by ninja) is much extended:
* besides generating the test@out file, it checks individual tests for success
and can write a report file containing their status, and the positions for
their (expected/current) outputs (this uses `Marshal`)
* it now handles out-tests directly in addition to inline-tests, for which
it generates the separate output file ; they are included in the report
- ninja is now tasked with building all the test reports (which shouldn't fail);
for directories, individual reports are concatenated (as before).
Removing intermediate report rules, and out-test rules means that the ninja
file is much simplified.
- then, clerk takes back control, reads the final reports and formats them in a
user-friendly way. Printing the reports may imply running `diff` internally.
In particular, the commands to easily reproduce each test are provided.
Resetting the test results if required is also done directly by clerk, at this
stage.
A few switches are available to customise the output, but I am waiting for some
feedback before deciding what to make available from the CLI.
The `clerk report` command is available to manually explore test reports, but
normally the processing is done directly at the end of `clerk test` (i.e. ninja
will no longer call that command)
2024-06-14 22:05:19 +03:00
|
|
|
raise (Catala_utils.Cli.Exit_with 0)
|
|
|
|
else raise (Catala_utils.Cli.Exit_with 1)
|
|
|
|
| 1 -> raise (Catala_utils.Cli.Exit_with 10) (* Ninja build failed *)
|
|
|
|
| err -> raise (Catala_utils.Cli.Exit_with err)
|
|
|
|
(* Other Ninja error ? *)
|
2023-09-19 17:26:05 +03:00
|
|
|
in
|
|
|
|
let doc =
|
|
|
|
"Scan the given files or directories for catala tests, build their \
|
|
|
|
requirement and run them all. With $(b,--reset) the expected results are \
|
|
|
|
updated in-place ; otherwise, 0 is returned if the output matches the \
|
|
|
|
reference, or 1 is returned and a diff is printed to stdout"
|
|
|
|
in
|
|
|
|
Cmd.v (Cmd.info ~doc "test")
|
|
|
|
Term.(
|
|
|
|
const run
|
|
|
|
$ Cli.Global.term ninja_init
|
|
|
|
$ Cli.files_or_folders
|
|
|
|
$ Cli.reset_test_outputs
|
2024-02-26 12:18:08 +03:00
|
|
|
$ Cli.test_flags
|
2024-06-19 13:14:26 +03:00
|
|
|
$ Cli.report_verbosity
|
2024-07-04 15:25:46 +03:00
|
|
|
$ Cli.report_xml
|
2024-06-27 12:58:53 +03:00
|
|
|
$ Cli.diff_command
|
2023-09-19 17:26:05 +03:00
|
|
|
$ Cli.ninja_flags)
|
|
|
|
|
|
|
|
let run_cmd =
|
|
|
|
let run
|
|
|
|
ninja_init
|
|
|
|
(files_or_folders : string list)
|
|
|
|
(scope : string)
|
2024-04-19 17:34:53 +03:00
|
|
|
(ninja_flags : string list) =
|
2023-09-19 17:26:05 +03:00
|
|
|
let extra =
|
|
|
|
Seq.cons
|
|
|
|
(Nj.binding Var.scope [scope])
|
|
|
|
(Seq.return
|
|
|
|
(Nj.default
|
2023-10-02 19:24:24 +03:00
|
|
|
(List.map (fun file -> file ^ "@interpret") files_or_folders)))
|
2023-09-19 17:26:05 +03:00
|
|
|
in
|
2024-02-26 12:18:08 +03:00
|
|
|
ninja_init ~extra ~test_flags:[]
|
2024-06-25 19:29:42 +03:00
|
|
|
@@ fun _build_dir _fix_path nin_file ->
|
2023-09-26 12:42:46 +03:00
|
|
|
let ninja_cmd = ninja_cmdline ninja_flags nin_file [] in
|
2024-04-19 17:34:53 +03:00
|
|
|
Message.debug "executing '%s'..." (String.concat " " ninja_cmd);
|
Generate tests reports from 'clerk test'
This is a proper replacement for the previous shell-based placeholder hack.
Here is a summary:
- `clerk runtest` (normally run by ninja) is much extended:
* besides generating the test@out file, it checks individual tests for success
and can write a report file containing their status, and the positions for
their (expected/current) outputs (this uses `Marshal`)
* it now handles out-tests directly in addition to inline-tests, for which
it generates the separate output file ; they are included in the report
- ninja is now tasked with building all the test reports (which shouldn't fail);
for directories, individual reports are concatenated (as before).
Removing intermediate report rules, and out-test rules means that the ninja
file is much simplified.
- then, clerk takes back control, reads the final reports and formats them in a
user-friendly way. Printing the reports may imply running `diff` internally.
In particular, the commands to easily reproduce each test are provided.
Resetting the test results if required is also done directly by clerk, at this
stage.
A few switches are available to customise the output, but I am waiting for some
feedback before deciding what to make available from the CLI.
The `clerk report` command is available to manually explore test reports, but
normally the processing is done directly at the end of `clerk test` (i.e. ninja
will no longer call that command)
2024-06-14 22:05:19 +03:00
|
|
|
raise (Catala_utils.Cli.Exit_with (run_ninja ~clean_up_env:false ninja_cmd))
|
2023-09-19 17:26:05 +03:00
|
|
|
in
|
|
|
|
let doc =
|
|
|
|
"Runs the Catala interpreter on the given files, after building their \
|
|
|
|
dependencies. The scope to be executed must be specified using the \
|
|
|
|
$(i,-s) option."
|
|
|
|
in
|
|
|
|
Cmd.v (Cmd.info ~doc "run")
|
|
|
|
Term.(
|
|
|
|
const run
|
|
|
|
$ Cli.Global.term ninja_init
|
|
|
|
$ Cli.files_or_folders
|
|
|
|
$ Cli.scope
|
|
|
|
$ Cli.ninja_flags)
|
|
|
|
|
|
|
|
let runtest_cmd =
|
Generate tests reports from 'clerk test'
This is a proper replacement for the previous shell-based placeholder hack.
Here is a summary:
- `clerk runtest` (normally run by ninja) is much extended:
* besides generating the test@out file, it checks individual tests for success
and can write a report file containing their status, and the positions for
their (expected/current) outputs (this uses `Marshal`)
* it now handles out-tests directly in addition to inline-tests, for which
it generates the separate output file ; they are included in the report
- ninja is now tasked with building all the test reports (which shouldn't fail);
for directories, individual reports are concatenated (as before).
Removing intermediate report rules, and out-test rules means that the ninja
file is much simplified.
- then, clerk takes back control, reads the final reports and formats them in a
user-friendly way. Printing the reports may imply running `diff` internally.
In particular, the commands to easily reproduce each test are provided.
Resetting the test results if required is also done directly by clerk, at this
stage.
A few switches are available to customise the output, but I am waiting for some
feedback before deciding what to make available from the CLI.
The `clerk report` command is available to manually explore test reports, but
normally the processing is done directly at the end of `clerk test` (i.e. ninja
will no longer call that command)
2024-06-14 22:05:19 +03:00
|
|
|
let run catala_exe catala_opts include_dirs test_flags report out file =
|
2023-11-14 18:05:54 +03:00
|
|
|
let catala_opts =
|
|
|
|
List.fold_left
|
|
|
|
(fun opts dir -> "-I" :: dir :: opts)
|
|
|
|
catala_opts include_dirs
|
|
|
|
in
|
Generate tests reports from 'clerk test'
This is a proper replacement for the previous shell-based placeholder hack.
Here is a summary:
- `clerk runtest` (normally run by ninja) is much extended:
* besides generating the test@out file, it checks individual tests for success
and can write a report file containing their status, and the positions for
their (expected/current) outputs (this uses `Marshal`)
* it now handles out-tests directly in addition to inline-tests, for which
it generates the separate output file ; they are included in the report
- ninja is now tasked with building all the test reports (which shouldn't fail);
for directories, individual reports are concatenated (as before).
Removing intermediate report rules, and out-test rules means that the ninja
file is much simplified.
- then, clerk takes back control, reads the final reports and formats them in a
user-friendly way. Printing the reports may imply running `diff` internally.
In particular, the commands to easily reproduce each test are provided.
Resetting the test results if required is also done directly by clerk, at this
stage.
A few switches are available to customise the output, but I am waiting for some
feedback before deciding what to make available from the CLI.
The `clerk report` command is available to manually explore test reports, but
normally the processing is done directly at the end of `clerk test` (i.e. ninja
will no longer call that command)
2024-06-14 22:05:19 +03:00
|
|
|
Clerk_runtest.run_tests
|
|
|
|
~catala_exe:(Option.value ~default:"catala" catala_exe)
|
|
|
|
~catala_opts ~test_flags ~report ~out file;
|
2023-09-19 17:26:05 +03:00
|
|
|
0
|
|
|
|
in
|
|
|
|
let doc =
|
|
|
|
"Mainly for internal purposes. Runs inline tests from a Catala file, and \
|
|
|
|
outputs their results to stdout"
|
|
|
|
in
|
|
|
|
Cmd.v (Cmd.info ~doc "runtest")
|
|
|
|
Term.(
|
|
|
|
const run
|
|
|
|
$ Cli.catala_exe
|
|
|
|
$ Cli.catala_opts
|
2023-11-14 18:05:54 +03:00
|
|
|
$ Cli.include_dirs
|
2024-02-26 12:18:08 +03:00
|
|
|
$ Cli.test_flags
|
Generate tests reports from 'clerk test'
This is a proper replacement for the previous shell-based placeholder hack.
Here is a summary:
- `clerk runtest` (normally run by ninja) is much extended:
* besides generating the test@out file, it checks individual tests for success
and can write a report file containing their status, and the positions for
their (expected/current) outputs (this uses `Marshal`)
* it now handles out-tests directly in addition to inline-tests, for which
it generates the separate output file ; they are included in the report
- ninja is now tasked with building all the test reports (which shouldn't fail);
for directories, individual reports are concatenated (as before).
Removing intermediate report rules, and out-test rules means that the ninja
file is much simplified.
- then, clerk takes back control, reads the final reports and formats them in a
user-friendly way. Printing the reports may imply running `diff` internally.
In particular, the commands to easily reproduce each test are provided.
Resetting the test results if required is also done directly by clerk, at this
stage.
A few switches are available to customise the output, but I am waiting for some
feedback before deciding what to make available from the CLI.
The `clerk report` command is available to manually explore test reports, but
normally the processing is done directly at the end of `clerk test` (i.e. ninja
will no longer call that command)
2024-06-14 22:05:19 +03:00
|
|
|
$ Cli.runtest_report
|
|
|
|
$ Cli.runtest_out
|
|
|
|
$ Cli.single_file)
|
|
|
|
|
|
|
|
let report_cmd =
|
2024-07-04 15:25:46 +03:00
|
|
|
let run color debug verbosity xml diff_command build_dir files =
|
Generate tests reports from 'clerk test'
This is a proper replacement for the previous shell-based placeholder hack.
Here is a summary:
- `clerk runtest` (normally run by ninja) is much extended:
* besides generating the test@out file, it checks individual tests for success
and can write a report file containing their status, and the positions for
their (expected/current) outputs (this uses `Marshal`)
* it now handles out-tests directly in addition to inline-tests, for which
it generates the separate output file ; they are included in the report
- ninja is now tasked with building all the test reports (which shouldn't fail);
for directories, individual reports are concatenated (as before).
Removing intermediate report rules, and out-test rules means that the ninja
file is much simplified.
- then, clerk takes back control, reads the final reports and formats them in a
user-friendly way. Printing the reports may imply running `diff` internally.
In particular, the commands to easily reproduce each test are provided.
Resetting the test results if required is also done directly by clerk, at this
stage.
A few switches are available to customise the output, but I am waiting for some
feedback before deciding what to make available from the CLI.
The `clerk report` command is available to manually explore test reports, but
normally the processing is done directly at the end of `clerk test` (i.e. ninja
will no longer call that command)
2024-06-14 22:05:19 +03:00
|
|
|
let _options = Catala_utils.Global.enforce_options ~debug ~color () in
|
|
|
|
let build_dir = Option.value ~default:"_build" build_dir in
|
2024-06-19 13:14:26 +03:00
|
|
|
set_report_verbosity verbosity;
|
2024-06-27 12:58:53 +03:00
|
|
|
Clerk_report.set_display_flags ~diff_command ();
|
Generate tests reports from 'clerk test'
This is a proper replacement for the previous shell-based placeholder hack.
Here is a summary:
- `clerk runtest` (normally run by ninja) is much extended:
* besides generating the test@out file, it checks individual tests for success
and can write a report file containing their status, and the positions for
their (expected/current) outputs (this uses `Marshal`)
* it now handles out-tests directly in addition to inline-tests, for which
it generates the separate output file ; they are included in the report
- ninja is now tasked with building all the test reports (which shouldn't fail);
for directories, individual reports are concatenated (as before).
Removing intermediate report rules, and out-test rules means that the ninja
file is much simplified.
- then, clerk takes back control, reads the final reports and formats them in a
user-friendly way. Printing the reports may imply running `diff` internally.
In particular, the commands to easily reproduce each test are provided.
Resetting the test results if required is also done directly by clerk, at this
stage.
A few switches are available to customise the output, but I am waiting for some
feedback before deciding what to make available from the CLI.
The `clerk report` command is available to manually explore test reports, but
normally the processing is done directly at the end of `clerk test` (i.e. ninja
will no longer call that command)
2024-06-14 22:05:19 +03:00
|
|
|
let open Clerk_report in
|
2024-07-04 15:25:46 +03:00
|
|
|
let tests = List.flatten (List.map read_many files) in
|
|
|
|
let success = (if xml then print_xml else summary) ~build_dir tests in
|
Generate tests reports from 'clerk test'
This is a proper replacement for the previous shell-based placeholder hack.
Here is a summary:
- `clerk runtest` (normally run by ninja) is much extended:
* besides generating the test@out file, it checks individual tests for success
and can write a report file containing their status, and the positions for
their (expected/current) outputs (this uses `Marshal`)
* it now handles out-tests directly in addition to inline-tests, for which
it generates the separate output file ; they are included in the report
- ninja is now tasked with building all the test reports (which shouldn't fail);
for directories, individual reports are concatenated (as before).
Removing intermediate report rules, and out-test rules means that the ninja
file is much simplified.
- then, clerk takes back control, reads the final reports and formats them in a
user-friendly way. Printing the reports may imply running `diff` internally.
In particular, the commands to easily reproduce each test are provided.
Resetting the test results if required is also done directly by clerk, at this
stage.
A few switches are available to customise the output, but I am waiting for some
feedback before deciding what to make available from the CLI.
The `clerk report` command is available to manually explore test reports, but
normally the processing is done directly at the end of `clerk test` (i.e. ninja
will no longer call that command)
2024-06-14 22:05:19 +03:00
|
|
|
exit (if success then 0 else 1)
|
|
|
|
in
|
|
|
|
let doc =
|
|
|
|
"Mainly for internal purposes. Reads a test report file and displays a \
|
|
|
|
summary of the results, returning 0 on success and 1 if any test failed."
|
|
|
|
in
|
|
|
|
Cmd.v (Cmd.info ~doc "report")
|
|
|
|
Term.(
|
|
|
|
const run
|
|
|
|
$ Cli.Global.color
|
|
|
|
$ Cli.Global.debug
|
2024-06-19 13:14:26 +03:00
|
|
|
$ Cli.report_verbosity
|
2024-07-04 15:25:46 +03:00
|
|
|
$ Cli.report_xml
|
2024-06-27 12:58:53 +03:00
|
|
|
$ Cli.diff_command
|
Generate tests reports from 'clerk test'
This is a proper replacement for the previous shell-based placeholder hack.
Here is a summary:
- `clerk runtest` (normally run by ninja) is much extended:
* besides generating the test@out file, it checks individual tests for success
and can write a report file containing their status, and the positions for
their (expected/current) outputs (this uses `Marshal`)
* it now handles out-tests directly in addition to inline-tests, for which
it generates the separate output file ; they are included in the report
- ninja is now tasked with building all the test reports (which shouldn't fail);
for directories, individual reports are concatenated (as before).
Removing intermediate report rules, and out-test rules means that the ninja
file is much simplified.
- then, clerk takes back control, reads the final reports and formats them in a
user-friendly way. Printing the reports may imply running `diff` internally.
In particular, the commands to easily reproduce each test are provided.
Resetting the test results if required is also done directly by clerk, at this
stage.
A few switches are available to customise the output, but I am waiting for some
feedback before deciding what to make available from the CLI.
The `clerk report` command is available to manually explore test reports, but
normally the processing is done directly at the end of `clerk test` (i.e. ninja
will no longer call that command)
2024-06-14 22:05:19 +03:00
|
|
|
$ Cli.build_dir
|
2024-07-04 15:25:46 +03:00
|
|
|
$ Cli.files)
|
2023-09-19 19:21:14 +03:00
|
|
|
|
Generate tests reports from 'clerk test'
This is a proper replacement for the previous shell-based placeholder hack.
Here is a summary:
- `clerk runtest` (normally run by ninja) is much extended:
* besides generating the test@out file, it checks individual tests for success
and can write a report file containing their status, and the positions for
their (expected/current) outputs (this uses `Marshal`)
* it now handles out-tests directly in addition to inline-tests, for which
it generates the separate output file ; they are included in the report
- ninja is now tasked with building all the test reports (which shouldn't fail);
for directories, individual reports are concatenated (as before).
Removing intermediate report rules, and out-test rules means that the ninja
file is much simplified.
- then, clerk takes back control, reads the final reports and formats them in a
user-friendly way. Printing the reports may imply running `diff` internally.
In particular, the commands to easily reproduce each test are provided.
Resetting the test results if required is also done directly by clerk, at this
stage.
A few switches are available to customise the output, but I am waiting for some
feedback before deciding what to make available from the CLI.
The `clerk report` command is available to manually explore test reports, but
normally the processing is done directly at the end of `clerk test` (i.e. ninja
will no longer call that command)
2024-06-14 22:05:19 +03:00
|
|
|
let main_cmd =
|
|
|
|
Cmd.group Cli.info [build_cmd; test_cmd; run_cmd; runtest_cmd; report_cmd]
|
2023-10-09 12:23:50 +03:00
|
|
|
|
|
|
|
let main () =
|
|
|
|
try exit (Cmdliner.Cmd.eval' ~catch:false main_cmd) with
|
|
|
|
| Catala_utils.Cli.Exit_with n -> exit n
|
|
|
|
| Message.CompilerError content ->
|
|
|
|
let bt = Printexc.get_raw_backtrace () in
|
|
|
|
Message.Content.emit content Error;
|
2024-03-15 16:23:30 +03:00
|
|
|
if Catala_utils.Global.options.debug then
|
2023-10-09 12:23:50 +03:00
|
|
|
Printexc.print_raw_backtrace stderr bt;
|
|
|
|
exit Cmd.Exit.some_error
|
|
|
|
| Sys_error msg ->
|
|
|
|
let bt = Printexc.get_raw_backtrace () in
|
|
|
|
Message.Content.emit
|
|
|
|
(Message.Content.of_string ("System error: " ^ msg))
|
|
|
|
Error;
|
|
|
|
if Printexc.backtrace_status () then Printexc.print_raw_backtrace stderr bt;
|
|
|
|
exit Cmd.Exit.internal_error
|
|
|
|
| e ->
|
|
|
|
let bt = Printexc.get_raw_backtrace () in
|
|
|
|
Message.Content.emit
|
|
|
|
(Message.Content.of_string ("Unexpected error: " ^ Printexc.to_string e))
|
|
|
|
Error;
|
|
|
|
if Printexc.backtrace_status () then Printexc.print_raw_backtrace stderr bt;
|
|
|
|
exit Cmd.Exit.internal_error
|