Rework Cli, fix a couple Task items

This commit is contained in:
Josh Holtrop 2022-01-23 19:38:21 -05:00
parent 125ab4c171
commit 1b3e459ada
5 changed files with 175 additions and 152 deletions

View File

@ -3,5 +3,5 @@
require "rscons/cli"
if __FILE__ == $0
Rscons::Cli.run(ARGV)
Rscons::Cli.new.run(ARGV)
end

View File

@ -1,31 +1,17 @@
require "rscons"
require "optparse"
# CLI usage string.
USAGE = <<EOF
Usage: #{$0} [global options] [task] [task options]
Global options:
-b BUILD, --build=BUILD Set build directory (default: build)
-f FILE Use FILE as Rsconscript
-F, --show-failure Show failed command log from previous build and exit
-h, --help Show rscons help and exit
-j N, --nthreads=N Set number of threads (local default: #{Rscons.application.n_threads})
-r COLOR, --color=COLOR Set color mode (off, auto, force)
-v, --verbose Run verbosely
--version Show rscons version and exit
Tasks:
EOF
module Rscons
# Command-Line Interface functionality.
module Cli
class Cli
# Default files to look for to execute if none specified.
DEFAULT_RSCONSCRIPTS = %w[Rsconscript Rsconscript.rb]
class << self
# Create an instance of the rscons command-line interpreter.
def initialize
@script = Script.new
end
# Run the Rscons CLI.
#
@ -39,23 +25,24 @@ module Rscons
exit run_toplevel(argv)
rescue OptionParser::InvalidOption => io
$stderr.puts io.message
$stderr.puts USAGE
$stderr.puts usage
exit 2
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]
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_params
tasks_and_options
end
def run_toplevel(argv)
@ -74,7 +61,7 @@ module Rscons
opts.on("-F", "--show-failure") do
Rscons.application.show_failure
exit 0
return 0
end
opts.on("-h", "--help") do
@ -100,27 +87,24 @@ module Rscons
opts.on("--version") do
puts "Rscons version #{Rscons::VERSION}"
exit 0
return 0
end
end.order!(argv)
tasks_and_params = parse_tasks_and_params(argv)
if tasks_and_params.empty?
tasks_and_params << ["default"]
end
# 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}"
exit 1
return 1
end
else
rsconscript = DEFAULT_RSCONSCRIPTS.find do |f|
@ -128,25 +112,64 @@ module Rscons
end
end
# Load the build script.
if rsconscript
script = Script.new
script.load(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
exit 0
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(", ")}"
exit 1
return 1
end
exit Rscons.application.run(script, tasks_and_params)
# 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 = <<EOF
Usage: #{$0} [global options] [task] [task options]
Global options:
-b BUILD, --build=BUILD Set build directory (default: build)
-f FILE Use FILE as Rsconscript
-F, --show-failure Show failed command log from previous build and exit
-h, --help Show rscons help and exit
-j N, --nthreads=N Set number of threads (local default: #{Rscons.application.n_threads})
-r COLOR, --color=COLOR Set color mode (off, auto, force)
-v, --verbose Run verbosely
--version Show rscons version and exit
Tasks:
EOF
Task[].each do |name, task|
if task.desc
usage += %[ #{sprintf("%-27s", name)} #{task.desc}\n]
end
end
usage
end
end
end

View File

@ -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.

View File

@ -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

View File

@ -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