class Autoproj::CLI::Locate
Deal with locating a package source or build directory in an existing workspace
It is based on a installation manifest file, a YAML file generated to list that information and thus avoid loading the Autoproj
configuration (which takes fairly long).
Constants
- RESOLUTION_MODES
Attributes
Public Class Methods
Source
# File lib/autoproj/cli/locate.rb, line 25 def initialize(ws = Workspace.default, installation_manifest: try_loading_installation_manifest(ws)) super(ws) ws.load_config if installation_manifest update_from_installation_manifest(installation_manifest) end end
Create the locate CLI
interface
@param [Workspace] ws the workspace we’re working on @param [InstallationManifest,nil] installation_manifest the
manifest. If nil, loads the whole autoproj configuration and rebuilds the manifest
Autoproj::CLI::Base::new
Public Instance Methods
Source
# File lib/autoproj/cli/locate.rb, line 219 def build_dir_of(selection) if workspace_dir?(selection) raise NoSuchDir, "#{selection} points to the workspace itself, which has no build dir" elsif find_package_set(selection) raise NoSuchDir, "#{selection} is a package set, and package sets do not have build directories" else pkg = resolve_package(selection) if pkg.respond_to?(:builddir) && pkg.builddir pkg.builddir else raise NoSuchDir, "#{selection} resolves to the package #{pkg.name}, which does not have a build directory" end end end
Returns the build directory for a given selection
@raise [NoSuchDir] if the selection points to a package set,
or to a package that has no build directory
Source
# File lib/autoproj/cli/locate.rb, line 51 def find_package_set(selection) package_sets.find do |pkg_set| name = pkg_set.name name == selection || selection.start_with?("#{pkg_set.raw_local_dir}/") || selection.start_with?("#{pkg_set.user_local_dir}/") end end
Find a package set that matches a given selection
@param [String] selection a string that is matched against the
package set name and its various directories. Directories are matched against the full path and must end with /
@return [PackageSet,nil]
Source
# File lib/autoproj/cli/locate.rb, line 60 def find_packages(selection) selection_rx = Regexp.new(Regexp.quote(selection)) candidates = [] packages.each do |pkg| name = pkg.name if name == selection || selection.start_with?("#{pkg.srcdir}/") return [pkg] elsif pkg.respond_to?(:builddir) && pkg.builddir && selection.start_with?("#{pkg.builddir}/") return [pkg] elsif name =~ selection_rx candidates << pkg end end candidates end
Source
# File lib/autoproj/cli/locate.rb, line 76 def find_packages_with_directory_shortnames(selection) *directories, basename = *selection.split("/") dirname_rx = directories .map { |d| "#{Regexp.quote(d)}\\w*" } .join("/") rx = Regexp.new("#{dirname_rx}/#{Regexp.quote(basename)}") rx_strict = Regexp.new("#{dirname_rx}/#{Regexp.quote(basename)}$") candidates = [] candidates_strict = [] packages.each do |pkg| name = pkg.name candidates << pkg if name =~ rx candidates_strict << pkg if name =~ rx_strict end if candidates.size > 1 && candidates_strict.size == 1 candidates_strict else candidates end end
Source
# File lib/autoproj/cli/locate.rb, line 100 def initialize_from_workspace initialize_and_load finalize_setup # this exports the manifest @packages = ws.manifest.each_autobuild_package.to_a @package_sets = ws.manifest.each_package_set.to_a end
Source
# File lib/autoproj/cli/locate.rb, line 239 def logs_of(selection, log: nil) if workspace_dir?(selection) || (pkg_set = find_package_set(selection)) return [] if log && log != "import" name = if pkg_set then pkg_set.name else "autoproj main configuration" end import_log = File.join(ws.log_dir, "#{name}-import.log") if File.file?(import_log) [import_log] else [] end else pkg = resolve_package(selection) Dir.enum_for(:glob, File.join(pkg.logdir, "#{pkg.name}-#{log || '*'}.log")).to_a end end
Resolve logs available for what points to the given selection
The workspace is resolved as the main configuration
If ‘log’ is nil and multiple logs are available,
Source
# File lib/autoproj/cli/locate.rb, line 205 def prefix_dir_of(selection) if workspace_dir?(selection) ws.prefix_dir elsif find_package_set(selection) raise NoSuchDir, "#{selection} is a package set, and package sets do not have prefixes" else resolve_package(selection).prefix end end
Returns the prefix directory for a given selection
@raise [NoSuchDir] if the selection points to a package set
Source
# File lib/autoproj/cli/locate.rb, line 163 def resolve_package(selection) matching_packages = find_packages(selection) if matching_packages.empty? matching_packages = find_packages_with_directory_shortnames(selection) end if matching_packages.size > 1 # If there is more than one candidate, check if there are some that are not # present on disk present = matching_packages.find_all { |pkg| File.directory?(pkg.srcdir) } matching_packages = present if present.size == 1 end if matching_packages.empty? raise CLIInvalidArguments, "cannot find '#{selection}' in the current autoproj installation" elsif matching_packages.size > 1 raise CLIAmbiguousArguments, "multiple packages match '#{selection}' in the current autoproj installation: #{matching_packages.map(&:name).sort.join(', ')}" else matching_packages.first end end
Resolve the package that matches a given selection
@return [PackageDefinition] @raise [CLIInvalidArguments] if nothing matches @raise [AmbiguousSelection] if the selection is ambiguous
Source
# File lib/autoproj/cli/locate.rb, line 127 def run(selections, cache: !!packages, mode: :source_dir, log: nil) if !RESOLUTION_MODES.include?(mode) raise ArgumentError, "'#{mode}' was expected to be one of #{RESOLUTION_MODES}" elsif !cache initialize_from_workspace end selections.each do |string| string = "#{File.expand_path(string)}/" if File.directory?(string) if mode == :source_dir puts source_dir_of(string) elsif mode == :build_dir puts build_dir_of(string) elsif mode == :prefix_dir puts prefix_dir_of(string) elsif mode == :log if (all_logs = (log == "all")) log = nil end result = logs_of(string, log: log) if (result.size == 1) || all_logs result.each { |p| puts p } elsif result.size > 1 puts select_log_file(result) elsif result.empty? raise NotFound, "no logs found for #{string}" end end end end
Source
# File lib/autoproj/cli/locate.rb, line 261 def select_log_file(log_files) require "tty/prompt" log_files = log_files.map do |path| [path, File.stat(path).mtime] end.sort_by(&:last).reverse choices = Hash.new log_files.each do |path, mtime| if path =~ /-(\w+)\.log/ choices["(#{mtime}) #{$1}"] = path else choices["(#{mtime}) #{path}"] = path end end prompt = TTY::Prompt.new begin prompt.select("Select the log file", choices) rescue TTY::Reader::InputInterrupt raise Interrupt end end
Interactively select a log file among a list
Source
# File lib/autoproj/cli/locate.rb, line 192 def source_dir_of(selection) if workspace_dir?(selection) ws.root_dir elsif (pkg_set = find_package_set(selection)) pkg_set.user_local_dir else resolve_package(selection).srcdir end end
Returns the source directory for a given selection
Source
# File lib/autoproj/cli/locate.rb, line 40 def try_loading_installation_manifest(ws = self.ws) Autoproj::InstallationManifest.from_workspace_root(ws.root_dir) rescue ConfigError end
Load the installation manifest
Source
# File lib/autoproj/cli/locate.rb, line 34 def update_from_installation_manifest(installation_manifest) @packages = installation_manifest.each_package.to_a @package_sets = installation_manifest.each_package_set.to_a end
Source
# File lib/autoproj/cli/locate.rb, line 108 def validate_options(selections, options = Hash.new) selections, options = super mode = if options.delete(:build) :build_dir elsif options.delete(:prefix) :prefix_dir elsif (log_type = options[:log]) options.delete(:log) if log_type == "log" :log else :source_dir end options[:mode] ||= mode selections << ws.root_dir if selections.empty? [selections, options] end
Autoproj::CLI::Base#validate_options
Source
# File lib/autoproj/cli/locate.rb, line 187 def workspace_dir?(selection) selection == "#{ws.root_dir}/" || selection == "#{ws.prefix_dir}/" end
Tests whether ‘selection’ points to one of the workspace’s root directories