diff --git a/lib/rscons.rb b/lib/rscons.rb index bfe4204..eba02c6 100644 --- a/lib/rscons.rb +++ b/lib/rscons.rb @@ -1,4 +1,5 @@ require_relative "rscons/ansi" +require_relative "rscons/application" require_relative "rscons/build_target" require_relative "rscons/builder" require_relative "rscons/cache" @@ -48,18 +49,13 @@ module Rscons class << self - # @return [Integer] - # The number of threads to use when scheduling subprocesses. - attr_accessor :n_threads - - # @return [Boolean] - # Whether to output ANSI color escape sequences. - attr_accessor :do_ansi_color - - # @since 1.16.0 - # @return [VarSet] - # Access any variables set on the rscons command-line. - attr_reader :vars + # Access the Application singleton. + # + # @return [Application] + # The Application singleton. + def application + @application ||= Application.new + end # Remove all generated files. # @@ -200,46 +196,8 @@ module Rscons end.sort end - private - - # Determine the number of threads to use by default. - # - # @return [Integer] - # The number of threads to use by default. - def determine_n_threads - # If the user specifies the number of threads in the environment, then - # respect that. - if ENV["RSCONS_NTHREADS"] =~ /^(\d+)$/ - return $1.to_i - end - - # Otherwise try to figure out how many threads are available on the - # host hardware. - begin - case RbConfig::CONFIG["host_os"] - when /linux/ - return File.read("/proc/cpuinfo").scan(/^processor\s*:/).size - when /mswin|mingw/ - if `wmic cpu get NumberOfLogicalProcessors /value` =~ /NumberOfLogicalProcessors=(\d+)/ - return $1.to_i - end - when /darwin/ - if `sysctl -n hw.ncpu` =~ /(\d+)/ - return $1.to_i - end - end - rescue - end - - # If we can't figure it out, default to 1. - 1 - end - end - @n_threads = determine_n_threads - @vars = VarSet.new - end # Unbuffer $stdout diff --git a/lib/rscons/ansi.rb b/lib/rscons/ansi.rb index 6952fd0..e9b84a2 100644 --- a/lib/rscons/ansi.rb +++ b/lib/rscons/ansi.rb @@ -12,7 +12,7 @@ module Rscons # # @return [void] def write(io, *message) - do_color = Rscons.do_ansi_color + do_color = Rscons.application.do_ansi_color if do_color.nil? do_color = do_ansi?(io) end diff --git a/lib/rscons/application.rb b/lib/rscons/application.rb new file mode 100644 index 0000000..4f4caae --- /dev/null +++ b/lib/rscons/application.rb @@ -0,0 +1,72 @@ +module Rscons + + # Functionality for an instance of the rscons application invocation. + class Application + + # @return [Boolean] + # Whether to output ANSI color escape sequences. + attr_accessor :do_ansi_color + + # @return [Integer] + # The number of threads to use when scheduling subprocesses. + attr_accessor :n_threads + + # @return [VarSet] + # Access any variables set on the rscons command-line. + attr_reader :vars + + def initialize + @vars = VarSet.new + @n_threads = determine_n_threads + end + + # Run the specified operation. + # + # @param operation [String] + # The operation to perform (e.g. "clean", "configure", "build", etc...) + # + # @return [Integer] + # Process exit code (0 on success). + def run(operation) + # TODO + 0 + end + + private + + # Determine the number of threads to use by default. + # + # @return [Integer] + # The number of threads to use by default. + def determine_n_threads + # If the user specifies the number of threads in the environment, then + # respect that. + if ENV["RSCONS_NTHREADS"] =~ /^(\d+)$/ + return $1.to_i + end + + # Otherwise try to figure out how many threads are available on the + # host hardware. + begin + case RbConfig::CONFIG["host_os"] + when /linux/ + return File.read("/proc/cpuinfo").scan(/^processor\s*:/).size + when /mswin|mingw/ + if `wmic cpu get NumberOfLogicalProcessors /value` =~ /NumberOfLogicalProcessors=(\d+)/ + return $1.to_i + end + when /darwin/ + if `sysctl -n hw.ncpu` =~ /(\d+)/ + return $1.to_i + end + end + rescue + end + + # If we can't figure it out, default to 1. + 1 + end + + end + +end diff --git a/lib/rscons/cli.rb b/lib/rscons/cli.rb index 090712a..cf1c8b5 100644 --- a/lib/rscons/cli.rb +++ b/lib/rscons/cli.rb @@ -22,7 +22,7 @@ Configure options: --prefix=PREFIX Set installation prefix (default: /usr/local) Build options: - -j N, --nthreads=N Set number of threads (local default: #{Rscons.n_threads}) + -j N, --nthreads=N Set number of threads (local default: #{Rscons.application.n_threads}) EOF @@ -44,56 +44,45 @@ module Rscons def run(argv) argv = argv.dup rsconsfile = nil + do_help = false OptionParser.new do |opts| opts.banner = "Usage: #{$0} [options]" - opts.on("-f FILE", "Execute FILE (default Rsconsfile)") do |f| + opts.on("-f FILE") do |f| rsconsfile = f end - opts.on("-j NTHREADS", "Use NTHREADS parallel jobs (local default #{Rscons.n_threads})") do |n_threads| - Rscons.n_threads = n_threads.to_i + opts.on("-j NTHREADS") do |n_threads| + Rscons.application.n_threads = n_threads.to_i end - opts.on("-r", "--color MODE", "Set color mode (off, auto, force)") do |color_mode| + opts.on("-r", "--color MODE") do |color_mode| case color_mode when "off" - Rscons.do_ansi_color = false + Rscons.application.do_ansi_color = false when "force" - Rscons.do_ansi_color = true + Rscons.application.do_ansi_color = true end end - opts.on("--version", "Show version") do + opts.on("--version") do puts "Rscons version #{Rscons::VERSION}" exit 0 end - opts.on("-h", "--help", "Show this help.") do - puts USAGE - exit 0 + opts.on("-h", "--help") do + do_help = true end end.order!(argv) - if argv.empty? - puts USAGE - exit 0 - end - - case argv.first - when "clean" - Rscons.clean - exit 0 - when "configure" - # TODO - exit 0 - end + # Retrieve the operation, or default to build. + operation = argv.shift || "build" argv.each do |arg| if arg =~ /^([^=]+)=(.*)$/ - Rscons.vars[$1] = $2 + Rscons.application.vars[$1] = $2 end end @@ -113,13 +102,15 @@ module Rscons end end - begin - load rsconsfile - rescue Rscons::BuildError => e - exit 1 - end + script = Script.new + script.load(rsconsfile) - exit 0 + if do_help + puts USAGE + exit 0 + else + exit Rscons.application.run(operation) + end end end diff --git a/lib/rscons/environment.rb b/lib/rscons/environment.rb index c844ee8..4586f87 100644 --- a/lib/rscons/environment.rb +++ b/lib/rscons/environment.rb @@ -19,7 +19,8 @@ module Rscons # @return [Integer] # The number of threads to use for this Environment. If nil (the - # default), the global Rscons.n_threads default value will be used. + # default), the global Rscons.application.n_threads default value will be + # used. attr_writer :n_threads # Set the build root. @@ -871,7 +872,7 @@ module Rscons # @return [Integer] # Number of threads to use for parallelized builds in this Environment. def n_threads - @n_threads || Rscons.n_threads + @n_threads || Rscons.application.n_threads end # Print the builder run message, depending on the Environment's echo mode. diff --git a/lib/rscons/script.rb b/lib/rscons/script.rb index 16f905f..046d3cd 100644 --- a/lib/rscons/script.rb +++ b/lib/rscons/script.rb @@ -4,22 +4,30 @@ module Rscons # the DSL for the build script to use. class Script - class << self + # @return [String, nil] + # Project name. + attr_accessor :project_name - # Load a script from the specified file. - # - # @param path [String] - # File name of the rscons script to load. - # - # @return [Script] - # The loaded script state. - def load(path) - script_contents = File.read(path, mode: "rb") - script = Script.new - script.instance_eval(script_contents, path, 1) - script - end + # @return [Boolean] + # Whether to autoconfigure if the user does not explicitly perform a + # configure operation before building (default: true). + attr_accessor :autoconf + # Construct a Script. + def initialize + @project_name = nil + @autoconf = true + 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") + self.instance_eval(script_contents, path, 1) end end diff --git a/spec/rscons/application_spec.rb b/spec/rscons/application_spec.rb new file mode 100644 index 0000000..ab45b42 --- /dev/null +++ b/spec/rscons/application_spec.rb @@ -0,0 +1,71 @@ +module Rscons + describe Application do + + describe ".determine_n_threads" do + context "when specified by environment variable" do + before(:each) do + expect(ENV).to receive(:[]).with("RSCONS_NTHREADS").and_return("3") + end + it "returns the user-specified number of threads to use" do + expect(Rscons.application.__send__(:determine_n_threads)).to eq(3) + end + end + + context "when not specified by environment variable" do + before(:each) do + expect(ENV).to receive(:[]).with("RSCONS_NTHREADS").and_return(nil) + end + + context "on Linux" do + before(:each) do + expect(RbConfig::CONFIG).to receive(:[]).with("host_os").and_return("linux") + end + it "returns the number of processors from /proc/cpuinfo" do + expect(File).to receive(:read).with("/proc/cpuinfo").and_return(<