X-Git-Url: http://nitlanguage.org diff --git a/src/toolcontext.nit b/src/toolcontext.nit index 6cc8889..5b9d020 100644 --- a/src/toolcontext.nit +++ b/src/toolcontext.nit @@ -90,9 +90,9 @@ class ToolContext for m in messages do if opt_no_color.value then - stderr.write("{m}\n") + sys.stderr.write("{m}\n") else - stderr.write("{m.to_color_string}\n") + sys.stderr.write("{m.to_color_string}\n") end end @@ -134,6 +134,33 @@ class ToolContext end end + # Executes a program while checking if it's available and if the execution ended correctly + # + # Stops execution and prints errors if the program isn't available or didn't end correctly + fun exec_and_check(args: Array[String], error: String) + do + var prog = args.first + args.remove_at 0 + + # Is the wanted program available? + var proc_which = new IProcess.from_a("which", [prog]) + proc_which.wait + var res = proc_which.status + if res != 0 then + print "{error}: executable \"{prog}\" not found" + exit 1 + end + + # Execute the wanted program + var proc = new Process.from_a(prog, args) + proc.wait + res = proc.status + if res != 0 then + print "{error}: execution of \"{prog} {args.join(" ")}\" failed" + exit 1 + end + end + # Global OptionContext var option_context: OptionContext = new OptionContext @@ -180,6 +207,13 @@ class ToolContext # eg. `"Usage: tool [OPTION]... [FILE]...\nDo some things."` var tooldescription: String writable = "Usage: [OPTION]... [ARG]..." + # Does `process_options` should accept an empty sequence of arguments. + # ie. nothing except options. + # Is `false` by default. + # + # If required, if should be set by the client before calling `process_options` + var accept_no_arguments writable = false + # print the full usage of the tool. # Is called by `process_option` on `--help`. # It also could be called by the client. @@ -190,7 +224,7 @@ class ToolContext end # Parse and process the options given on the command line - fun process_options + fun process_options(args: Sequence[String]) do self.opt_warn.value = 1 @@ -215,6 +249,12 @@ class ToolContext exit 1 end + if option_context.rest.is_empty and not accept_no_arguments then + print tooldescription + print "Use --help for help" + exit 1 + end + # Set verbose level verbose_level = opt_verbose.value @@ -225,5 +265,31 @@ class ToolContext # Make sure the output directory exists log_directory.mkdir end + + nit_dir = compute_nit_dir + end + + # The identified root directory of the Nit project + var nit_dir: nullable String + + private fun compute_nit_dir: nullable String + do + # a environ variable has precedence + var res = "NIT_DIR".environ + if not res.is_empty then return res + + # find the runpath of the program from argv[0] + res = "{sys.program_name.dirname}/.." + if res.file_exists and "{res}/src/nit.nit".file_exists then return res.simplify_path + + # find the runpath of the process from /proc + var exe = "/proc/self/exe" + if exe.file_exists then + res = exe.realpath + res = res.dirname.join_path("..") + if res.file_exists and "{res}/src/nit.nit".file_exists then return res.simplify_path + end + + return null end end