2021-04-10 15:33:40 +02:00
use std ::{
2021-08-24 10:23:37 +02:00
env ,
ffi ::OsString ,
fs ::File ,
io ::{ BufRead , BufReader } ,
path ::Path ,
2021-04-10 15:33:40 +02:00
} ;
2021-08-24 10:23:37 +02:00
use clap ::{ crate_version , App , Arg , ArgMatches } ;
2021-07-16 16:10:03 +02:00
use color_eyre ::eyre ::{ Context , Report , Result } ;
2021-07-30 18:24:05 +02:00
2021-08-24 10:23:37 +02:00
pub fn get_args ( ) -> Result < ArgMatches < 'static > > {
let app = App ::new ( " watchexec " )
2021-04-10 15:33:40 +02:00
. version ( crate_version! ( ) )
. about ( " Execute commands when watched files change " )
2021-07-16 16:10:03 +02:00
. after_help ( " Use @argfile as first argument to load arguments from the file `argfile` (one argument per line) which will be inserted in place of the @argfile (further arguments on the CLI will override or add onto those in the file). " )
2021-04-10 15:33:40 +02:00
. arg ( Arg ::with_name ( " command " )
. help ( " Command to execute " )
. multiple ( true )
. required ( true ) )
. arg ( Arg ::with_name ( " extensions " )
2021-04-10 19:06:32 +02:00
. help ( " Comma-separated list of file extensions to watch (e.g. js,css,html) " )
2021-04-10 15:33:40 +02:00
. short ( " e " )
. long ( " exts " )
. takes_value ( true ) )
. arg ( Arg ::with_name ( " path " )
. help ( " Watch a specific file or directory " )
. short ( " w " )
. long ( " watch " )
. number_of_values ( 1 )
. multiple ( true )
. takes_value ( true ) )
. arg ( Arg ::with_name ( " clear " )
. help ( " Clear screen before executing command " )
. short ( " c " )
. long ( " clear " ) )
2021-04-10 18:16:50 +02:00
. arg ( Arg ::with_name ( " on-busy-update " )
2021-04-10 19:06:32 +02:00
. help ( " Select the behaviour to use when receiving events while the command is running. Current default is queue, will change to do-nothing in 2.0. " )
. takes_value ( true )
2021-04-10 18:16:50 +02:00
. possible_values ( & [ " do-nothing " , " queue " , " restart " , " signal " ] )
. long ( " on-busy-update " ) )
2021-04-10 15:33:40 +02:00
. arg ( Arg ::with_name ( " restart " )
2021-04-10 18:16:50 +02:00
. help ( " Restart the process if it's still running. Shorthand for --on-busy-update=restart " )
2021-04-10 15:33:40 +02:00
. short ( " r " )
. long ( " restart " ) )
. arg ( Arg ::with_name ( " signal " )
. help ( " Send signal to process upon changes, e.g. SIGHUP " )
. short ( " s " )
. long ( " signal " )
. takes_value ( true )
. number_of_values ( 1 )
. value_name ( " signal " ) )
. arg ( Arg ::with_name ( " kill " )
. hidden ( true )
. short ( " k " )
. long ( " kill " ) )
. arg ( Arg ::with_name ( " debounce " )
2021-07-21 13:44:24 +02:00
. help ( " Set the timeout between detected change and command execution, defaults to 100ms " )
2021-04-10 15:33:40 +02:00
. takes_value ( true )
. value_name ( " milliseconds " )
. short ( " d " )
. long ( " debounce " ) )
2021-08-24 10:23:37 +02:00
2021-04-10 15:33:40 +02:00
. arg ( Arg ::with_name ( " verbose " )
. help ( " Print debugging messages to stderr " )
. short ( " v " )
. long ( " verbose " ) )
. arg ( Arg ::with_name ( " changes " )
. help ( " Only print path change information. Overridden by --verbose " )
. long ( " changes-only " ) )
2021-08-24 10:23:37 +02:00
2021-04-10 15:33:40 +02:00
. arg ( Arg ::with_name ( " filter " )
. help ( " Ignore all modifications except those matching the pattern " )
. short ( " f " )
. long ( " filter " )
. number_of_values ( 1 )
. multiple ( true )
. takes_value ( true )
. value_name ( " pattern " ) )
. arg ( Arg ::with_name ( " ignore " )
. help ( " Ignore modifications to paths matching the pattern " )
. short ( " i " )
. long ( " ignore " )
. number_of_values ( 1 )
. multiple ( true )
. takes_value ( true )
. value_name ( " pattern " ) )
. arg ( Arg ::with_name ( " no-vcs-ignore " )
. help ( " Skip auto-loading of .gitignore files for filtering " )
. long ( " no-vcs-ignore " ) )
. arg ( Arg ::with_name ( " no-ignore " )
. help ( " Skip auto-loading of ignore files (.gitignore, .ignore, etc.) for filtering " )
. long ( " no-ignore " ) )
. arg ( Arg ::with_name ( " no-default-ignore " )
. help ( " Skip auto-ignoring of commonly ignored globs " )
. long ( " no-default-ignore " ) )
. arg ( Arg ::with_name ( " postpone " )
. help ( " Wait until first change to execute command " )
. short ( " p " )
. long ( " postpone " ) )
. arg ( Arg ::with_name ( " poll " )
. help ( " Force polling mode (interval in milliseconds) " )
. long ( " force-poll " )
. value_name ( " interval " ) )
2021-04-10 16:36:10 +02:00
. arg ( Arg ::with_name ( " shell " )
. help ( if cfg! ( windows ) {
" Use a different shell, or `none`. Try --shell=powershell, which will become the default in 2.0. "
} else {
" Use a different shell, or `none`. E.g. --shell=bash "
} )
2021-04-10 19:29:55 +02:00
. takes_value ( true )
2021-04-10 16:36:10 +02:00
. long ( " shell " ) )
// -n short form will not be removed, and instead become a shorthand for --shell=none
2021-04-10 15:33:40 +02:00
. arg ( Arg ::with_name ( " no-shell " )
2021-04-10 16:36:38 +02:00
. help ( " Do not wrap command in a shell. Deprecated: use --shell=none instead. " )
2021-04-10 15:33:40 +02:00
. short ( " n " )
. long ( " no-shell " ) )
. arg ( Arg ::with_name ( " no-meta " )
. help ( " Ignore metadata changes " )
. long ( " no-meta " ) )
. arg ( Arg ::with_name ( " no-environment " )
2021-04-10 17:21:38 +02:00
. help ( " Do not set WATCHEXEC_*_PATH environment variables for the command " )
2021-04-10 15:33:40 +02:00
. long ( " no-environment " ) )
2021-07-21 14:56:35 +02:00
. arg ( Arg ::with_name ( " no-process-group " )
. help ( " Do not use a process group when running the command " )
. long ( " no-process-group " ) )
2021-04-10 15:33:40 +02:00
. arg ( Arg ::with_name ( " once " ) . short ( " 1 " ) . hidden ( true ) )
. arg ( Arg ::with_name ( " watch-when-idle " )
2021-04-10 18:16:50 +02:00
. help ( " Deprecated alias for --on-busy-update=do-nothing, which will become the default in 2.0. " )
2021-04-10 15:33:40 +02:00
. short ( " W " )
2021-07-30 19:11:42 +02:00
. long ( " watch-when-idle " ) )
. arg ( Arg ::with_name ( " notif " )
. help ( " Send a desktop notification when watchexec notices a change (experimental, behaviour may change) " )
. short ( " N " )
. long ( " notify " ) ) ;
2021-04-10 15:33:40 +02:00
2021-08-24 10:23:37 +02:00
let mut raw_args : Vec < OsString > = env ::args_os ( ) . collect ( ) ;
2021-04-10 15:33:40 +02:00
2021-08-24 10:23:37 +02:00
if let Some ( first ) = raw_args . get ( 1 ) . and_then ( | s | s . to_str ( ) ) {
if let Some ( arg_path ) = first . strip_prefix ( '@' ) . map ( Path ::new ) {
let arg_file = BufReader ::new (
File ::open ( arg_path )
. wrap_err_with ( | | format! ( " Failed to open argument file {:?} " , arg_path ) ) ? ,
) ;
2021-04-10 15:33:40 +02:00
2021-08-24 10:23:37 +02:00
let mut more_args : Vec < OsString > = arg_file
. lines ( )
. map ( | l | l . map ( OsString ::from ) . map_err ( Report ::from ) )
. collect ::< Result < _ > > ( ) ? ;
2021-04-10 15:33:40 +02:00
2021-08-24 10:23:37 +02:00
more_args . insert ( 0 , raw_args . remove ( 0 ) ) ;
more_args . extend ( raw_args . into_iter ( ) . skip ( 1 ) ) ;
raw_args = more_args ;
}
}
2021-04-10 16:36:10 +02:00
2021-08-24 10:23:37 +02:00
Ok ( app . get_matches_from ( raw_args ) )
2021-04-10 16:36:10 +02:00
}