Parse task parameters; handle configure task specially

This commit is contained in:
Josh Holtrop 2022-01-25 22:20:29 -05:00
parent 55dc22db05
commit b1b94595f6
6 changed files with 83 additions and 63 deletions

View File

@ -42,8 +42,8 @@ module Rscons
#
# @param script [Script]
# The script.
# @param tasks_and_params [Array<Array<String>>]
# List of task(s) to execute and possibly parameter(s) for them.
# @param tasks [Array<String>]
# List of task(s) to execute.
# @param options [Hash]
# Optional parameters.
# @option sub_op [Boolean]
@ -51,13 +51,12 @@ module Rscons
#
# @return [Integer]
# Process exit code (0 on success).
def run(script, tasks_and_params, options = {})
def run(script, tasks, options = {})
@script = script
Cache.instance["failed_commands"] = []
begin
tasks_and_params.each do |task_and_params|
task_name, *task_params = task_and_params
Task[task_name].check_execute
tasks.each do |task|
Task[task].check_execute
end
0
rescue RsconsError => e
@ -140,8 +139,7 @@ module Rscons
#
# @return [void]
def configure
options = {project_name: @script.project_name}
co = ConfigureOp.new(options)
co = ConfigureOp.new(@script)
begin
@script.configure(co)
rescue RsconsError => e

View File

@ -32,17 +32,36 @@ module Rscons
private
def parse_task_options(task, argv)
def parse_task_params(task, argv)
while argv.size > 0
if argv[0].start_with?("-")
valid_arg = false
if argv[0] =~ /^--(\S+?)(?:=(.*))$/
param_name, value = $1, $2
if param = Task[task].params[param_name]
param.value = value || argv[0]
argv.slice!(0)
valid_arg = true
end
end
unless valid_arg
$stderr.puts "Invalid task '#{task}' argument '#{argv[0].split("=").first}'"
exit 2
end
else
return
end
end
end
def parse_tasks_and_options(argv)
tasks_and_options = []
def parse_tasks_and_params(argv)
tasks = []
while argv.size > 0
task = argv.shift
task_options = parse_task_options(task, argv)
tasks_and_options << [task, task_options]
parse_task_params(task, argv)
tasks << task
end
tasks_and_options
tasks
end
def run_toplevel(argv)
@ -135,16 +154,16 @@ module Rscons
# 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)
tasks = parse_tasks_and_params(argv)
# If no user specified tasks, run "default" task.
if tasks_and_params.empty?
tasks_and_params << ["default"]
if tasks.empty?
tasks << "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)
Rscons.application.run(@script, tasks)
end
def usage
@ -167,7 +186,11 @@ EOF
if task.desc
usage += %[ #{sprintf("%-27s", name)} #{task.desc}\n]
task.params.each do |name, param|
usage += %[ #{sprintf("%-25s", "--#{param.cli_option}")} #{param.description}\n]
arg_text = "--#{name}"
if param.takes_arg
arg_text += "=#{name.upcase}"
end
usage += %[ #{sprintf("%-25s", "#{arg_text}")} #{param.description}\n]
end
end
end

View File

@ -7,29 +7,26 @@ module Rscons
# Create a ConfigureOp.
#
# @param options [Hash]
# Optional parameters.
# @option options [String] :prefix
# Install prefix.
# @option options [String] :project_name
# Project name.
def initialize(options)
# Default options.
options[:prefix] ||= "/usr/local"
# @param script [Script]
# Build script.
def initialize(script)
@work_dir = "#{Rscons.application.build_dir}/_configure"
FileUtils.mkdir_p(@work_dir)
@log_fh = File.open("#{@work_dir}/config.log", "wb")
cache = Cache.instance
cache["failed_commands"] = []
cache["configuration_data"] = {}
cache["configuration_data"]["prefix"] = options[:prefix]
if project_name = options[:project_name]
if project_name = script.project_name
Ansi.write($stdout, "Configuring ", :cyan, project_name, :reset, "...\n")
else
$stdout.puts "Configuring project..."
end
Ansi.write($stdout, "Setting prefix... ", :green, options[:prefix], :reset, "\n")
store_merge("prefix" => options[:prefix])
vars = {}
Task["configure"].params.each do |name, param|
Ansi.write($stdout, "Setting #{name}... ", :green, param.value, :reset, "\n")
vars[name] = param.value
end
store_merge(vars)
end
# Close the log file handle.

View File

@ -43,12 +43,12 @@ module Rscons
# Param name.
# @param value [String, nil]
# Param value.
# @param cli_option [String]
# Param CLI option text.
# @param takes_arg [String]
# Whether the parameter takes an argument.
# @param description [String]
# Param description.
def param(name, value, cli_option, description)
Task::Param.new(name, value, cli_option, description)
def param(name, value, takes_arg, description)
Task::Param.new(name, value, takes_arg, description)
end
# Return path components from the PATH variable.
@ -309,9 +309,7 @@ module Rscons
task("configure",
desc: "Configure the project",
autoconf: false,
params: [param("prefix", "/usr/local", "prefix=PREFIX", "Set installation prefix (default: /usr/local)")]) do
Rscons.application.configure
end
params: [param("prefix", "/usr/local", true, "Set installation prefix (default: /usr/local)")])
task("distclean",
desc: "Remove build directory and configuration",
autoconf: false) do
@ -339,10 +337,12 @@ module Rscons
end
# Perform configure action.
def configure(configure_op, action)
def configure(configure_op)
cdsl = ConfigureDsl.new(self, configure_op)
Task["configure"].actions.each do |action|
cdsl.instance_eval(&action)
end
end
end

View File

@ -56,17 +56,17 @@ module Rscons
# Param name.
attr_reader :name
# @return [String]
# Param CLI option text.
attr_reader :cli_option
# @return [String]
# Param description.
attr_reader :description
# @return [Boolean]
# Whether the parameter takes an argument.
attr_reader :takes_arg
# @return [String, nil]
# Param value.
attr_reader :value
attr_accessor :value
# Construct a Param.
#
@ -74,19 +74,23 @@ module Rscons
# Param name.
# @param value [String, nil]
# Param value.
# @param cli_option [String]
# Param CLI option text.
# @param takes_arg [String]
# Whether the parameter takes an argument.
# @param description [String]
# Param description.
def initialize(name, value, cli_option, description)
def initialize(name, value, takes_arg, description)
@name = name
@value = value
@cli_option = cli_option
@takes_arg = takes_arg
@description = description
end
end
# @return [Array<Proc>]
# Task action blocks.
attr_reader :actions
# @return [Boolean]
# Whether to automatically configure before running this task.
attr_reader :autoconf
@ -138,11 +142,16 @@ module Rscons
end
end
@deps.each do |dep|
Task[dep].check_execute
end
if @name == "configure"
Rscons.application.configure
else
@actions.each do |action|
action[]
end
end
end
# Check if the task has been executed, and if not execute it.
#

View File

@ -410,7 +410,7 @@ EOF
expect(File.exists?("#{prefix}/bin/program.exe")).to be_truthy
expect(File.exists?("build/e.1/src/one/one.c.o")).to be_falsey
result = run_rscons(args: %w[-f install.rb uninstall -v])
result = run_rscons(args: %w[-f install.rb -v uninstall])
expect(result.stderr).to eq ""
expect(result.stdout).to match %r{Removing #{prefix}/bin/program.exe}
expect(Dir.entries(prefix)).to match_array %w[. ..]
@ -2434,13 +2434,6 @@ EOF
expect(result.stdout).to match /gcc.*-o.*simple/
end
it "echoes commands by default with -v after build operation" do
test_dir('simple')
result = run_rscons(args: %w[build -v])
expect(result.stderr).to eq ""
expect(result.stdout).to match /gcc.*-o.*simple/
end
it "prints operation start time" do
test_dir("simple")
result = run_rscons(args: %w[-v])
@ -2597,7 +2590,7 @@ EOF
result = run_rscons(args: %w[-f install.rb install])
expect(result.stderr).to eq ""
result = run_rscons(args: %w[-f install.rb uninstall -v])
result = run_rscons(args: %w[-f install.rb -v uninstall])
expect(result.stderr).to eq ""
expect(result.stdout).to match %r{Removing #{prefix}/bin/program.exe}
expect(File.exists?("#{prefix}/bin/program.exe")).to be_falsey
@ -2615,7 +2608,7 @@ EOF
result = run_rscons(args: %w[-f install.rb install])
expect(result.stderr).to eq ""
result = run_rscons(args: %w[-f install.rb uninstall -v])
result = run_rscons(args: %w[-f install.rb -v uninstall])
expect(result.stderr).to eq ""
expect(result.stdout).to match %r{Removing #{prefix}/bin/program.exe}
expect(File.exists?("#{prefix}/bin/program.exe")).to be_falsey
@ -2623,7 +2616,7 @@ EOF
FileUtils.mkdir_p("#{prefix}/bin")
File.open("#{prefix}/bin/program.exe", "w") {|fh| fh.write("hi")}
result = run_rscons(args: %w[-f install.rb uninstall -v])
result = run_rscons(args: %w[-f install.rb -v uninstall])
expect(result.stderr).to eq ""
expect(result.stdout).to_not match /Removing/
end