11use anyhow:: Result ;
2- use clap:: { Parser , ValueEnum } ;
3- use clap_verbosity_flag:: InfoLevel ;
2+ use clap:: Parser ;
43use log:: LevelFilter ;
54use regex:: Regex ;
65use std:: io:: Write ;
76
8- use rewatch:: { build, cmd, lock, watcher} ;
9-
10- #[ derive( Debug , Clone , ValueEnum ) ]
11- enum Command {
12- /// Build using Rewatch
13- Build ,
14- /// Build, then start a watcher
15- Watch ,
16- /// Clean the build artifacts
17- Clean ,
18- /// Format the code
19- Format ,
20- /// Dump
21- Dump ,
22- }
23-
24- /// Rewatch is an alternative build system for the Rescript Compiler bsb (which uses Ninja internally). It strives
25- /// to deliver consistent and faster builds in monorepo setups with multiple packages, where the
26- /// default build system fails to pick up changed interfaces across multiple packages.
27- #[ derive( Parser , Debug ) ]
28- #[ command( version) ]
29- struct Args {
30- #[ arg( value_enum, default_value_t = Command :: Build ) ]
31- command : Command ,
32-
33- /// The relative path to where the main rescript.json resides. IE - the root of your project.
34- #[ arg( default_value = "." ) ]
35- folder : String ,
36-
37- /// Filter allows for a regex to be supplied which will filter the files to be compiled. For
38- /// instance, to filter out test files for compilation while doing feature work.
39- #[ arg( short, long) ]
40- filter : Option < String > ,
41-
42- /// This allows one to pass an additional command to the watcher, which allows it to run when
43- /// finished. For instance, to play a sound when done compiling, or to run a test suite.
44- /// NOTE - You may need to add '--color=always' to your subcommand in case you want to output
45- /// colour as well
46- #[ arg( short, long) ]
47- after_build : Option < String > ,
48-
49- // Disable timing on the output
50- #[ arg( short, long, default_value = "false" , num_args = 0 ..=1 ) ]
51- no_timing : bool ,
52-
53- /// Verbosity:
54- /// -v -> Debug
55- /// -vv -> Trace
56- /// -q -> Warn
57- /// -qq -> Error
58- /// -qqq -> Off.
59- /// Default (/ no argument given): 'info'
60- #[ command( flatten) ]
61- verbose : clap_verbosity_flag:: Verbosity < InfoLevel > ,
62-
63- /// This creates a source_dirs.json file at the root of the monorepo, which is needed when you
64- /// want to use Reanalyze
65- #[ arg( short, long, default_value_t = false , num_args = 0 ..=1 ) ]
66- create_sourcedirs : bool ,
67-
68- /// This prints the compiler arguments. It expects the path to a rescript.json file.
69- /// This also requires --bsc-path and --rescript-version to be present
70- #[ arg( long) ]
71- compiler_args : Option < String > ,
72-
73- /// This is the flag to also compile development dependencies
74- /// It's important to know that we currently do not discern between project src, and
75- /// dependencies. So enabling this flag will enable building _all_ development dependencies of
76- /// _all_ packages
77- #[ arg( long, default_value_t = false , num_args = 0 ..=1 ) ]
78- dev : bool ,
79-
80- /// To be used in conjunction with compiler_args
81- #[ arg( long) ]
82- rescript_version : Option < String > ,
83-
84- /// A custom path to bsc
85- #[ arg( long) ]
86- bsc_path : Option < String > ,
87-
88- /// Use the legacy build system.
89- ///
90- /// After this flag is encountered, the rest of the command line arguments are passed to the legacy build system.
91- #[ arg( long, allow_hyphen_values = true , num_args = 0 ..) ]
92- legacy : Option < Vec < String > > ,
93- }
7+ use rewatch:: { build, cli, cmd, lock, watcher} ;
948
959fn main ( ) -> Result < ( ) > {
96- let args = Args :: parse ( ) ;
97-
98- if let Some ( legacy_args) = args. legacy {
99- let code = build:: pass_through_legacy ( legacy_args) ;
100- std:: process:: exit ( code) ;
101- }
10+ let args = cli:: Cli :: parse ( ) ;
10211
10312 let log_level_filter = args. verbose . log_level_filter ( ) ;
10413
@@ -108,19 +17,27 @@ fn main() -> Result<()> {
10817 . target ( env_logger:: fmt:: Target :: Stdout )
10918 . init ( ) ;
11019
111- let filter = args
112- . filter
113- . map ( |filter| Regex :: new ( filter. as_ref ( ) ) . expect ( "Could not parse regex" ) ) ;
20+ let command = args. command . unwrap_or ( cli:: Command :: Build ( args. build_args ) ) ;
11421
115- match args. compiler_args {
116- None => ( ) ,
117- Some ( path) => {
22+ // handle legacy and compiler args early, because we don't need a lock for them
23+ match command {
24+ cli:: Command :: Legacy { legacy_args } => {
25+ let code = build:: pass_through_legacy ( legacy_args) ;
26+ std:: process:: exit ( code) ;
27+ }
28+ cli:: Command :: CompilerArgs {
29+ path,
30+ dev,
31+ rescript_version,
32+ bsc_path,
33+ } => {
11834 println ! (
11935 "{}" ,
120- build:: get_compiler_args( & path, args . rescript_version, args . bsc_path, args . dev) ?
36+ build:: get_compiler_args( & path, rescript_version, bsc_path, dev) ?
12137 ) ;
12238 std:: process:: exit ( 0 ) ;
12339 }
40+ _ => ( ) ,
12441 }
12542
12643 // The 'normal run' mode will show the 'pretty' formatted progress. But if we turn off the log
@@ -132,48 +49,58 @@ fn main() -> Result<()> {
13249 println ! ( "Could not start Rewatch: {e}" ) ;
13350 std:: process:: exit ( 1 )
13451 }
135- lock:: Lock :: Aquired ( _) => match args. command {
136- Command :: Clean => build:: clean:: clean ( & args. folder , show_progress, args. bsc_path ) ,
137- Command :: Build => {
52+ lock:: Lock :: Aquired ( _) => match command {
53+ cli:: Command :: Clean { bsc_path } => build:: clean:: clean ( & args. folder , show_progress, bsc_path) ,
54+ cli:: Command :: Build ( build_args) => {
55+ let filter = build_args
56+ . filter
57+ . map ( |filter| Regex :: new ( filter. as_ref ( ) ) . expect ( "Could not parse regex" ) ) ;
13858 match build:: build (
13959 & filter,
14060 & args. folder ,
14161 show_progress,
142- args . no_timing ,
143- args . create_sourcedirs ,
144- args . bsc_path ,
145- args . dev ,
62+ build_args . no_timing ,
63+ build_args . create_sourcedirs ,
64+ build_args . bsc_path ,
65+ build_args . dev ,
14666 ) {
14767 Err ( e) => {
14868 println ! ( "{e}" ) ;
14969 std:: process:: exit ( 1 )
15070 }
15171 Ok ( _) => {
152- if let Some ( args_after_build) = args . after_build {
72+ if let Some ( args_after_build) = build_args . after_build {
15373 cmd:: run ( args_after_build)
15474 }
15575 std:: process:: exit ( 0 )
15676 }
15777 } ;
15878 }
159- Command :: Watch => {
79+ cli:: Command :: Watch ( watch_args) => {
80+ let filter = watch_args
81+ . filter
82+ . map ( |filter| Regex :: new ( filter. as_ref ( ) ) . expect ( "Could not parse regex" ) ) ;
16083 watcher:: start (
16184 & filter,
16285 show_progress,
16386 & args. folder ,
164- args . after_build ,
165- args . create_sourcedirs ,
166- args . dev ,
87+ watch_args . after_build ,
88+ watch_args . create_sourcedirs ,
89+ watch_args . dev ,
16790 ) ;
16891
16992 Ok ( ( ) )
17093 }
171- Command :: Format => {
172- todo ! ( "Format not implemented yet" ) ;
173- }
174- Command :: Dump => {
175- todo ! ( "Dump not implemented yet" ) ;
176- }
94+ cli:: Command :: CompilerArgs { .. } | cli:: Command :: Legacy { .. } => {
95+ unreachable ! ( "command already handled" )
96+ } // Command::Format => {
97+ // let code = build::pass_through_legacy(vec!["format".to_owned()]);
98+ // std::process::exit(code);
99+ // }
100+ // Command::Dump => {
101+ // let code = build::pass_through_legacy(vec!["dump".to_owned()]);
102+ // std::process::exit(code);
103+ // }
177104 } ,
178105 }
179106}
0 commit comments