Class: Autoproj::CLI::Locate
- Inherits:
-
InspectionTool
- Object
- Base
- InspectionTool
- Autoproj::CLI::Locate
- Defined in:
- lib/autoproj/cli/locate.rb
Overview
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).
Defined Under Namespace
Constant Summary collapse
- RESOLUTION_MODES =
%i[source_dir build_dir prefix_dir log]
Instance Attribute Summary collapse
-
#package_sets ⇒ Object
readonly
Returns the value of attribute package_sets.
-
#packages ⇒ Object
readonly
Returns the value of attribute packages.
Attributes inherited from Base
Instance Method Summary collapse
-
#build_dir_of(selection) ⇒ Object
Returns the build directory for a given selection.
-
#find_package_set(selection) ⇒ PackageSet?
Find a package set that matches a given selection.
- #find_packages(selection) ⇒ Object
- #find_packages_with_directory_shortnames(selection) ⇒ Object
-
#initialize(ws = Workspace.default, installation_manifest: try_loading_installation_manifest(ws)) ⇒ Locate
constructor
Create the locate CLI interface.
- #initialize_from_workspace ⇒ Object
-
#logs_of(selection, log: nil) ⇒ Object
Resolve logs available for what points to the given selection.
-
#prefix_dir_of(selection) ⇒ Object
Returns the prefix directory for a given selection.
-
#resolve_package(selection) ⇒ PackageDefinition
Resolve the package that matches a given selection.
- #run(selections, cache: !!packages,, mode: :source_dir, log: nil) ⇒ Object
-
#select_log_file(log_files) ⇒ Object
Interactively select a log file among a list.
-
#source_dir_of(selection) ⇒ Object
Returns the source directory for a given selection.
-
#try_loading_installation_manifest(ws = self.ws) ⇒ Object
Load the installation manifest.
- #update_from_installation_manifest(installation_manifest) ⇒ Object
- #validate_options(selections, options = Hash.new) ⇒ Object
-
#workspace_dir?(selection) ⇒ Boolean
Tests whether ‘selection’ points to one of the workspace’s root directories.
Methods inherited from InspectionTool
#finalize_setup, #initialize_and_load
Methods inherited from Base
#export_env_sh, #normalize_command_line_package_selection, #notify_env_sh_updated, #resolve_selection, #resolve_user_selection, validate_options, #validate_user_selection
Methods included from Ops::Tools
#common_options, #create_autobuild_package, #load_autoprojrc, #load_main_initrb
Constructor Details
#initialize(ws = Workspace.default, installation_manifest: try_loading_installation_manifest(ws)) ⇒ Locate
Create the locate CLI interface
25 26 27 28 29 30 31 32 |
# 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 |
Instance Attribute Details
#package_sets ⇒ Object (readonly)
Returns the value of attribute package_sets.
13 14 15 |
# File 'lib/autoproj/cli/locate.rb', line 13 def package_sets @package_sets end |
#packages ⇒ Object (readonly)
Returns the value of attribute packages.
12 13 14 |
# File 'lib/autoproj/cli/locate.rb', line 12 def packages @packages end |
Instance Method Details
#build_dir_of(selection) ⇒ Object
Returns the build directory for a given selection
219 220 221 222 223 224 225 226 227 228 229 230 231 232 |
# 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 |
#find_package_set(selection) ⇒ PackageSet?
Find a package set that matches a given selection
51 52 53 54 55 56 57 58 |
# 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_packages(selection) ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# 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 |
#find_packages_with_directory_shortnames(selection) ⇒ Object
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# 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 |
#initialize_from_workspace ⇒ Object
100 101 102 103 104 105 106 |
# 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 |
#logs_of(selection, log: nil) ⇒ Object
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,
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
# 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 |
#prefix_dir_of(selection) ⇒ Object
Returns the prefix directory for a given selection
205 206 207 208 209 210 211 212 213 |
# 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 |
#resolve_package(selection) ⇒ PackageDefinition
Resolve the package that matches a given selection
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# 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 |
#run(selections, cache: !!packages,, mode: :source_dir, log: nil) ⇒ Object
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# 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.(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 |
#select_log_file(log_files) ⇒ Object
Interactively select a log file among a list
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 |
# 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 |
#source_dir_of(selection) ⇒ Object
Returns the source directory for a given selection
192 193 194 195 196 197 198 199 200 |
# 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 |
#try_loading_installation_manifest(ws = self.ws) ⇒ Object
Load the installation manifest
40 41 42 43 |
# 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 |
#update_from_installation_manifest(installation_manifest) ⇒ Object
34 35 36 37 |
# 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 |
#validate_options(selections, options = Hash.new) ⇒ Object
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/autoproj/cli/locate.rb', line 108 def (selections, = Hash.new) selections, = super mode = if .delete(:build) :build_dir elsif .delete(:prefix) :prefix_dir elsif (log_type = [:log]) .delete(:log) if log_type == "log" :log else :source_dir end [:mode] ||= mode selections << ws.root_dir if selections.empty? [selections, ] end |
#workspace_dir?(selection) ⇒ Boolean
Tests whether ‘selection’ points to one of the workspace’s root directories
187 188 189 |
# File 'lib/autoproj/cli/locate.rb', line 187 def workspace_dir?(selection) selection == "#{ws.root_dir}/" || selection == "#{ws.prefix_dir}/" end |