From 1b3e459ada8714db1ab30661a636e2f96c37eb9c Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Sun, 23 Jan 2022 19:38:21 -0500 Subject: [PATCH] Rework Cli, fix a couple Task items --- bin/rscons | 2 +- lib/rscons/cli.rb | 283 +++++++++++++++++++++++-------------------- lib/rscons/script.rb | 32 ++--- lib/rscons/task.rb | 8 +- rb/build_dist.rb | 2 +- 5 files changed, 175 insertions(+), 152 deletions(-) diff --git a/bin/rscons b/bin/rscons index d915827..f3b5d40 100755 --- a/bin/rscons +++ b/bin/rscons @@ -3,5 +3,5 @@ require "rscons/cli" if __FILE__ == $0 - Rscons::Cli.run(ARGV) + Rscons::Cli.new.run(ARGV) end diff --git a/lib/rscons/cli.rb b/lib/rscons/cli.rb index 03ed9c1..8ba2a50 100644 --- a/lib/rscons/cli.rb +++ b/lib/rscons/cli.rb @@ -1,8 +1,154 @@ require "rscons" require "optparse" -# CLI usage string. -USAGE = < io + $stderr.puts io.message + $stderr.puts usage + exit 2 + end + end + + private + + def parse_task_options(task, argv) + end + + def parse_tasks_and_options(argv) + tasks_and_options = [] + while argv.size > 0 + task = argv.shift + task_options = parse_task_options(task, argv) + tasks_and_options << [task, task_options] + end + tasks_and_options + end + + def run_toplevel(argv) + rsconscript = nil + do_help = false + + OptionParser.new do |opts| + + opts.on("-b", "--build DIR") do |build_dir| + Rscons.application.build_dir = build_dir + end + + opts.on("-f FILE") do |f| + rsconscript = f + end + + opts.on("-F", "--show-failure") do + Rscons.application.show_failure + return 0 + end + + opts.on("-h", "--help") do + do_help = true + end + + opts.on("-j NTHREADS") do |n_threads| + Rscons.application.n_threads = n_threads.to_i + end + + opts.on("-r", "--color MODE") do |color_mode| + case color_mode + when "off" + Rscons.application.do_ansi_color = false + when "force" + Rscons.application.do_ansi_color = true + end + end + + opts.on("-v", "--verbose") do + Rscons.application.verbose = true + end + + opts.on("--version") do + puts "Rscons version #{Rscons::VERSION}" + return 0 + end + + end.order!(argv) + + # Set vars before loading the build script so the build script can + # refer to them. + argv.each do |arg| + if arg =~ /^([^=]+)=(.*)$/ + Rscons.application.vars[$1] = $2 + end + end + + # Find the build script. + if rsconscript + unless File.exists?(rsconscript) + $stderr.puts "Cannot read #{rsconscript}" + return 1 + end + else + rsconscript = DEFAULT_RSCONSCRIPTS.find do |f| + File.exists?(f) + end + end + + # Load the build script. + if rsconscript + @script.load(rsconscript) + end + + # Do help after loading the build script (if found) so that any + # script-defined tasks and task options can be displayed. + if do_help + puts usage + return 0 + end + + # Anything else requires a build script, so complain if we didn't find + # one. + unless rsconscript + $stderr.puts "Could not find the Rsconscript to execute." + $stderr.puts "Looked for: #{DEFAULT_RSCONSCRIPTS.join(", ")}" + return 1 + end + + # Parse the rest of the command line. This is done after loading the + # build script so that script-defined tasks and task options can be + # taken into account. + tasks_and_params = parse_tasks_and_options(argv) + + # If no user specified tasks, run "default" task. + if tasks_and_params.empty? + tasks_and_params << ["default"] + end + + # Finally, with the script fully loaded and command-line parsed, run + # the application to execute all required tasks. + Rscons.application.run(@script, tasks_and_params) + end + + def usage + usage = < io - $stderr.puts io.message - $stderr.puts USAGE - exit 2 + Task[].each do |name, task| + if task.desc + usage += %[ #{sprintf("%-27s", name)} #{task.desc}\n] end end - - private - - def parse_tasks_and_params(argv) - tasks_and_params = [] - argv.each do |arg| - if arg.start_with?("-") - tasks_and_params[-1] << arg - else - tasks_and_params << [arg] - end - end - tasks_and_params - end - - def run_toplevel(argv) - rsconscript = nil - do_help = false - - OptionParser.new do |opts| - - opts.on("-b", "--build DIR") do |build_dir| - Rscons.application.build_dir = build_dir - end - - opts.on("-f FILE") do |f| - rsconscript = f - end - - opts.on("-F", "--show-failure") do - Rscons.application.show_failure - exit 0 - end - - opts.on("-h", "--help") do - do_help = true - end - - opts.on("-j NTHREADS") do |n_threads| - Rscons.application.n_threads = n_threads.to_i - end - - opts.on("-r", "--color MODE") do |color_mode| - case color_mode - when "off" - Rscons.application.do_ansi_color = false - when "force" - Rscons.application.do_ansi_color = true - end - end - - opts.on("-v", "--verbose") do - Rscons.application.verbose = true - end - - opts.on("--version") do - puts "Rscons version #{Rscons::VERSION}" - exit 0 - end - - end.order!(argv) - - tasks_and_params = parse_tasks_and_params(argv) - - if tasks_and_params.empty? - tasks_and_params << ["default"] - end - - argv.each do |arg| - if arg =~ /^([^=]+)=(.*)$/ - Rscons.application.vars[$1] = $2 - end - end - - if rsconscript - unless File.exists?(rsconscript) - $stderr.puts "Cannot read #{rsconscript}" - exit 1 - end - else - rsconscript = DEFAULT_RSCONSCRIPTS.find do |f| - File.exists?(f) - end - end - - if rsconscript - script = Script.new - script.load(rsconscript) - end - - if do_help - puts USAGE - exit 0 - end - - unless rsconscript - $stderr.puts "Could not find the Rsconscript to execute." - $stderr.puts "Looked for: #{DEFAULT_RSCONSCRIPTS.join(", ")}" - exit 1 - end - - exit Rscons.application.run(script, tasks_and_params) - end - + usage end + end end diff --git a/lib/rscons/script.rb b/lib/rscons/script.rb index 561ba17..c9d253b 100644 --- a/lib/rscons/script.rb +++ b/lib/rscons/script.rb @@ -283,26 +283,10 @@ module Rscons # before calling a normal task (default: true). attr_accessor :autoconf - # @return [Hash] - # Tasks. - attr_reader :tasks - # Construct a Script. def initialize @autoconf = true - @tasks = {} - end - - # Load a script from the specified file. - # - # @param path [String] - # File name of the rscons script to load. - # - # @return [void] - def load(path) - script_contents = File.read(path, mode: "rb") - dsl = TopLevelDsl.new(self) - dsl.instance_eval do + TopLevelDsl.new(self).instance_eval do task("clean", desc: "Remove build artifacts (but not configuration)", autoconf: false) do @@ -318,7 +302,7 @@ module Rscons autoconf: false) do Rscons.application.distclean end - task("install" + task("install", desc: "Install project to configured installation prefix") task("uninstall", desc: "Uninstall project", @@ -326,7 +310,17 @@ module Rscons Rscons.application.uninstall end end - dsl.instance_eval(script_contents, path, 1) + end + + # Load a script from the specified file. + # + # @param path [String] + # File name of the rscons script to load. + # + # @return [void] + def load(path) + script_contents = File.read(path, mode: "rb") + TopLevelDsl.new(self).instance_eval(script_contents, path, 1) end # Perform configure action. diff --git a/lib/rscons/task.rb b/lib/rscons/task.rb index 502e519..e724f43 100644 --- a/lib/rscons/task.rb +++ b/lib/rscons/task.rb @@ -13,7 +13,7 @@ module Rscons # @return [Hash, Task, nil] # Hash of all tasks if name is nil, otherwise Task with the given name, # if found. - def [](name) + def [](name = nil) if name if task = tasks[name] task @@ -126,6 +126,12 @@ module Rscons if options.include?(:autoconf) @autoconf = options[:autoconf] end + if options.include?(:desc) + @desc = options[:desc] + end + if options.include?(:deps) + @deps += options[:deps] + end if block if env = Environment.open_environment @actions << proc do diff --git a/rb/build_dist.rb b/rb/build_dist.rb index 914800b..b8992b2 100755 --- a/rb/build_dist.rb +++ b/rb/build_dist.rb @@ -88,7 +88,7 @@ unless File.exists?(script) end load script if __FILE__ == $0 - Rscons::Cli.run(ARGV) + Rscons::Cli.new.run(ARGV) end #==>#{encoded_compressed_script} EOF