Class: Vanagon::Component
- Inherits:
-
Object
- Object
- Vanagon::Component
- Includes:
- HashableAttributes, Utilities
- Defined in:
- lib/vanagon/component.rb,
lib/vanagon/component/dsl.rb,
lib/vanagon/component/rules.rb,
lib/vanagon/component/source.rb,
lib/vanagon/extensions/hashable.rb,
lib/vanagon/component/source/git.rb,
lib/vanagon/component/source/http.rb,
lib/vanagon/component/source/local.rb,
lib/vanagon/component/source/rewrite.rb
Defined Under Namespace
Instance Attribute Summary collapse
-
#activate_triggers ⇒ Object
activate_triggers is a one-dimentional Array of Strings, describing scripts that should be executed when a package identifies an activate trigger.
-
#build ⇒ Object
build will hold an Array of the commands required to build a given component.
-
#build_dir ⇒ Object
the optional name of a directory to build a component in; most likely to be used for cmake projects, which do not like to be configured or compiled in their own top-level directories.
-
#build_requires ⇒ Object
build_requires holds an Array with a list of the dependencies that a given component needs satisfied before it can be built.
-
#check ⇒ Object
check will hold an Array of the commands required to validate/test a given component.
-
#cleanup_source ⇒ Object
cleanup_source contains whatever value a given component’s Source has specified as instructions for cleaning up after a build is completed.
-
#configure ⇒ Object
how should this component be configured?.
-
#conflicts ⇒ Object
conflicts holds an Array of OpenStructs that describe a package that a given component will replace on installation.
-
#directories ⇒ Object
directories holds an Array with a list of expected directories that will be packed into the resulting artifact’s bill of materials.
-
#dirname ⇒ Object
holds the expected directory name of a given component, once it’s been unpacked/decompressed.
-
#environment ⇒ Object
holds a Vanagon::Environment object, to map out any desired environment variables that should be rendered into the Makefile.
-
#extract_with ⇒ Array
The specific tool or command line invocations that should be used to extract a given component’s primary source.
-
#files ⇒ Set
readonly
Retrieve all items from @files not marked as configuration files.
-
#homepage ⇒ Object
Returns the value of attribute homepage.
-
#install ⇒ Object
install will hold an Array of the commands required to install a given component.
-
#install_only ⇒ Object
When dealing with compiled artifacts generated by setting ‘project.generate_archives true`, you only need to install the component.
-
#install_triggers ⇒ Object
install_triggers is a one-dimensional Array of OpenStructs, describing scripts that should be executed when a package is installed or upgraded.
-
#interest_triggers ⇒ Object
interest_triggers is a one-dimensional Array of OpenStructs, describing scripts that should be executed when a package identifies an interest trigger.
-
#license ⇒ Object
Returns the value of attribute license.
-
#mirrors ⇒ Set
A list of unique mirror URIs that should be used to retrieve the upstream source before attempting to retrieve from whatever URI was defined for #uri.
-
#name ⇒ Object
The name, version, primary source, supplementary sources, associated patches, upstream URL (for fetching the source), homepage, and license of a given component.
-
#options ⇒ Object
used to hold the checksum settings or other weirdo metadata related to building a given component (git ref, sha, etc.).
-
#patches ⇒ Object
Returns the value of attribute patches.
-
#platform ⇒ Object
the platform that a given component will be built for – due to the fact that Ruby is pass-by-reference, it’s usually just a reference to the same Platform object that the overall Project object also contains.
-
#postinstall_actions ⇒ Object
postinstall_actions is a two-dimensional Array, describing scripts that should be executed after a given component is installed.
-
#postinstall_required_actions ⇒ Object
postinstall_required_actions is a two-dimensional Array, describing scripts that must be executed successfully after a given component is installed.
-
#postremove_actions ⇒ Object
preinstall_actions is a two-dimensional Array, describing scripts that should be executed after a given component is uninstalled.
-
#preinstall_actions ⇒ Object
preinstall_actions is a two-dimensional Array, describing scripts that should be executed before a given component is installed.
-
#preremove_actions ⇒ Object
preremove_actions is a two-dimensional Array, describing scripts that should be executed before a given component is uninstalled.
-
#provides ⇒ Object
provides holds an Array of OpenStructs that describe any capabilities that a given component will provide beyond the its filesystem payload.
-
#replaces ⇒ Object
replaces holds an Array of OpenStructs that describe a package that a given component will replace on installation.
-
#requires ⇒ Object
requires holds an Array with a list of all dependencies that a given component needs satisfied before it can be installed.
-
#service ⇒ Object
holds an OpenStruct describing all of the particular details about how any services associated with a given component should be defined.
-
#settings ⇒ Object
holds a OpenStruct, or an Array, or maybe it’s a Hash? It’s often overloaded as a freeform key-value lookup for platforms that require additional configuration beyond the “basic” component attributes.
-
#source ⇒ Object
Returns the value of attribute source.
-
#sources ⇒ Object
Returns the value of attribute sources.
-
#url ⇒ Object
Returns the value of attribute url.
-
#version ⇒ Object
Returns the value of attribute version.
Class Method Summary collapse
-
.load_component(name, configdir, settings, platform) ⇒ Vanagon::Component
Loads a given component from the configdir.
Instance Method Summary collapse
-
#add_file(file) ⇒ Set?
Adds the given file to the list of files and returns @files.
-
#add_rpm_ghost_file(file) ⇒ Set?
Adds the given file to the list of %ghost files to be added to an rpm spec’s %files.
-
#configfiles ⇒ Set
Retrieve all items from @files explicitly marked as configuration files.
-
#delete_file(file) ⇒ Set?
Deletes the given file from the list of files and returns @files.
- #environment_variables ⇒ Object
-
#fetch_mirrors(options) ⇒ Boolean
Retrieve upstream source file from a mirror, by randomly iterating through #mirrors until there’s no more mirrors left.
-
#fetch_url(options) ⇒ Boolean
Retrieve upstream source file from the canonical URL.
-
#force_version ⇒ Object
Force version determination for components.
-
#get_build_dir ⇒ Object
Expands the build directory.
- #get_dependency_hash ⇒ Object
- #get_environment ⇒ String deprecated Deprecated.
-
#get_patches(patch_root) ⇒ Object
Fetches patches if any are provided for the project.
-
#get_source(workdir) ⇒ Object
Fetches the primary source for the component.
-
#get_sources(workdir) ⇒ Object
Fetches secondary sources for the component.
-
#initialize(name, settings, platform) ⇒ Vanagon::Component
constructor
Component constructor.
-
#rpm_ghost_files ⇒ Array
Retrieve all the files intended as %ghost entries for an rpm spec %files section.
- #rules(project, platform) ⇒ Object
Methods included from HashableAttributes
Methods included from Utilities
#erb_file, #erb_string, #ex, #find_program_on_path, #get_md5sum, #get_sum, #http_request, #http_request_code, #http_request_generic, #local_command, #remote_ssh_command, #retry_with_timeout, #rsync_from, #rsync_to, #ssh_command
Constructor Details
#initialize(name, settings, platform) ⇒ Vanagon::Component
Component constructor.
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/vanagon/component.rb', line 158 def initialize(name, settings, platform) # rubocop:disable Metrics/AbcSize @name = name @settings = settings @platform = platform @options = {} @build_requires = [] @requires = [] @configure = [] @install = [] @build = [] @check = [] @patches = [] @files = Set.new @ghost_files = Set.new @directories = [] @replaces = [] @provides = [] @conflicts = [] @environment = Vanagon::Environment.new @sources = [] @preinstall_actions = [] @install_triggers = [] @interest_triggers = [] @activate_triggers = [] @postinstall_required_actions = [] @postinstall_actions = [] @preremove_actions = [] @postremove_actions = [] @install_only = false @service = [] end |
Instance Attribute Details
#activate_triggers ⇒ Object
activate_triggers is a one-dimentional Array of Strings, describing scripts that should be executed when a package identifies an activate trigger
108 109 110 |
# File 'lib/vanagon/component.rb', line 108 def activate_triggers @activate_triggers end |
#build ⇒ Object
build will hold an Array of the commands required to build a given component
50 51 52 |
# File 'lib/vanagon/component.rb', line 50 def build @build end |
#build_dir ⇒ Object
the optional name of a directory to build a component in; most likely to be used for cmake projects, which do not like to be configured or compiled in their own top-level directories.
47 48 49 |
# File 'lib/vanagon/component.rb', line 47 def build_dir @build_dir end |
#build_requires ⇒ Object
build_requires holds an Array with a list of the dependencies that a given component needs satisfied before it can be built.
84 85 86 |
# File 'lib/vanagon/component.rb', line 84 def build_requires @build_requires end |
#check ⇒ Object
check will hold an Array of the commands required to validate/test a given component
53 54 55 |
# File 'lib/vanagon/component.rb', line 53 def check @check end |
#cleanup_source ⇒ Object
cleanup_source contains whatever value a given component’s Source has specified as instructions for cleaning up after a build is completed. usually a String, but not required to be.
124 125 126 |
# File 'lib/vanagon/component.rb', line 124 def cleanup_source @cleanup_source end |
#configure ⇒ Object
how should this component be configured?
43 44 45 |
# File 'lib/vanagon/component.rb', line 43 def configure @configure end |
#conflicts ⇒ Object
conflicts holds an Array of OpenStructs that describe a package that a given component will replace on installation.
96 97 98 |
# File 'lib/vanagon/component.rb', line 96 def conflicts @conflicts end |
#directories ⇒ Object
directories holds an Array with a list of expected directories that will be packed into the resulting artifact’s bill of materials.
81 82 83 |
# File 'lib/vanagon/component.rb', line 81 def directories @directories end |
#dirname ⇒ Object
holds the expected directory name of a given component, once it’s been unpacked/decompressed. For git repos, it’s usually the directory that they were cloned to. For the outlying flat files, it’ll end up being defined explicitly as the string ‘./’
38 39 40 |
# File 'lib/vanagon/component.rb', line 38 def dirname @dirname end |
#environment ⇒ Object
holds a Vanagon::Environment object, to map out any desired environment variables that should be rendered into the Makefile
60 61 62 |
# File 'lib/vanagon/component.rb', line 60 def environment @environment end |
#extract_with ⇒ Array
Returns the specific tool or command line invocations that should be used to extract a given component’s primary source.
41 42 43 |
# File 'lib/vanagon/component.rb', line 41 def extract_with @extract_with end |
#files ⇒ Set (readonly)
Retrieve all items from @files not marked as configuration files
|
# File 'lib/vanagon/component.rb', line 11
|
#homepage ⇒ Object
Returns the value of attribute homepage.
28 29 30 |
# File 'lib/vanagon/component.rb', line 28 def homepage @homepage end |
#install ⇒ Object
install will hold an Array of the commands required to install a given component
56 57 58 |
# File 'lib/vanagon/component.rb', line 56 def install @install end |
#install_only ⇒ Object
When dealing with compiled artifacts generated by setting ‘project.generate_archives true`, you only need to install the component. By setting install_only to true the component ’build’ will exclude the unpack, patch, configure, build, and check steps.
130 131 132 |
# File 'lib/vanagon/component.rb', line 130 def install_only @install_only end |
#install_triggers ⇒ Object
install_triggers is a one-dimensional Array of OpenStructs, describing scripts that should be executed when a package is installed or upgraded
102 103 104 |
# File 'lib/vanagon/component.rb', line 102 def install_triggers @install_triggers end |
#interest_triggers ⇒ Object
interest_triggers is a one-dimensional Array of OpenStructs, describing scripts that should be executed when a package identifies an interest trigger
105 106 107 |
# File 'lib/vanagon/component.rb', line 105 def interest_triggers @interest_triggers end |
#license ⇒ Object
Returns the value of attribute license.
27 28 29 |
# File 'lib/vanagon/component.rb', line 27 def license @license end |
#mirrors ⇒ Set
Returns a list of unique mirror URIs that should be used to retrieve the upstream source before attempting to retrieve from whatever URI was defined for #uri. If no mirrors are set and the deprecated rewrite system has been configured, this will return rewritten URIs.
247 248 249 |
# File 'lib/vanagon/component.rb', line 247 def mirrors @mirrors end |
#name ⇒ Object
The name, version, primary source, supplementary sources, associated patches, upstream URL (for fetching the source), homepage, and license of a given component
20 21 22 |
# File 'lib/vanagon/component.rb', line 20 def name @name end |
#options ⇒ Object
used to hold the checksum settings or other weirdo metadata related to building a given component (git ref, sha, etc.). Probably conflicts or collides with #settings to some degree.
70 71 72 |
# File 'lib/vanagon/component.rb', line 70 def @options end |
#patches ⇒ Object
Returns the value of attribute patches.
24 25 26 |
# File 'lib/vanagon/component.rb', line 24 def patches @patches end |
#platform ⇒ Object
the platform that a given component will be built for – due to the fact that Ruby is pass-by-reference, it’s usually just a reference to the same Platform object that the overall Project object also contains. This is a definite code smell, and should be slated for refactoring ASAP because it’s going to have weird side-effects if the underlying pass-by-reference assumptions change.
77 78 79 |
# File 'lib/vanagon/component.rb', line 77 def platform @platform end |
#postinstall_actions ⇒ Object
postinstall_actions is a two-dimensional Array, describing scripts that should be executed after a given component is installed.
114 115 116 |
# File 'lib/vanagon/component.rb', line 114 def postinstall_actions @postinstall_actions end |
#postinstall_required_actions ⇒ Object
postinstall_required_actions is a two-dimensional Array, describing scripts that must be executed successfully after a given component is installed.
111 112 113 |
# File 'lib/vanagon/component.rb', line 111 def postinstall_required_actions @postinstall_required_actions end |
#postremove_actions ⇒ Object
preinstall_actions is a two-dimensional Array, describing scripts that should be executed after a given component is uninstalled.
120 121 122 |
# File 'lib/vanagon/component.rb', line 120 def postremove_actions @postremove_actions end |
#preinstall_actions ⇒ Object
preinstall_actions is a two-dimensional Array, describing scripts that should be executed before a given component is installed.
99 100 101 |
# File 'lib/vanagon/component.rb', line 99 def preinstall_actions @preinstall_actions end |
#preremove_actions ⇒ Object
preremove_actions is a two-dimensional Array, describing scripts that should be executed before a given component is uninstalled.
117 118 119 |
# File 'lib/vanagon/component.rb', line 117 def preremove_actions @preremove_actions end |
#provides ⇒ Object
provides holds an Array of OpenStructs that describe any capabilities that a given component will provide beyond the its filesystem payload.
93 94 95 |
# File 'lib/vanagon/component.rb', line 93 def provides @provides end |
#replaces ⇒ Object
replaces holds an Array of OpenStructs that describe a package that a given component will replace on installation.
90 91 92 |
# File 'lib/vanagon/component.rb', line 90 def replaces @replaces end |
#requires ⇒ Object
requires holds an Array with a list of all dependencies that a given component needs satisfied before it can be installed.
87 88 89 |
# File 'lib/vanagon/component.rb', line 87 def requires @requires end |
#service ⇒ Object
holds an OpenStruct describing all of the particular details about how any services associated with a given component should be defined.
32 33 34 |
# File 'lib/vanagon/component.rb', line 32 def service @service end |
#settings ⇒ Object
holds a OpenStruct, or an Array, or maybe it’s a Hash? It’s often overloaded as a freeform key-value lookup for platforms that require additional configuration beyond the “basic” component attributes. it’s pretty heavily overloaded and should maybe be refactored before Vanagon 1.0.0 is tagged.
66 67 68 |
# File 'lib/vanagon/component.rb', line 66 def settings @settings end |
#source ⇒ Object
Returns the value of attribute source.
22 23 24 |
# File 'lib/vanagon/component.rb', line 22 def source @source end |
#sources ⇒ Object
Returns the value of attribute sources.
23 24 25 |
# File 'lib/vanagon/component.rb', line 23 def sources @sources end |
#url ⇒ Object
Returns the value of attribute url.
25 26 27 |
# File 'lib/vanagon/component.rb', line 25 def url @url end |
#version ⇒ Object
Returns the value of attribute version.
21 22 23 |
# File 'lib/vanagon/component.rb', line 21 def version @version end |
Class Method Details
.load_component(name, configdir, settings, platform) ⇒ Vanagon::Component
Loads a given component from the configdir
140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/vanagon/component.rb', line 140 def self.load_component(name, configdir, settings, platform) compfile = File.join(configdir, "#{name}.rb") dsl = Vanagon::Component::DSL.new(name, settings, platform) dsl.instance_eval(File.read(compfile), compfile, 1) dsl._component rescue StandardError => e VanagonLogger.error "Error loading project '#{name}' using '#{compfile}':" VanagonLogger.error e VanagonLogger.error e.backtrace.join("\n") raise e end |
Instance Method Details
#add_file(file) ⇒ Set?
Adds the given file to the list of files and returns @files.
195 196 197 |
# File 'lib/vanagon/component.rb', line 195 def add_file(file) @files.add file end |
#add_rpm_ghost_file(file) ⇒ Set?
Adds the given file to the list of %ghost files to be added to an rpm spec’s %files.
205 206 207 |
# File 'lib/vanagon/component.rb', line 205 def add_rpm_ghost_file(file) @ghost_files.add file end |
#configfiles ⇒ Set
Retrieve all items from @files explicitly marked as configuration files
230 231 232 |
# File 'lib/vanagon/component.rb', line 230 def configfiles @files.select(&:configfile?) end |
#delete_file(file) ⇒ Set?
Deletes the given file from the list of files and returns @files.
216 217 218 |
# File 'lib/vanagon/component.rb', line 216 def delete_file(file) @files.delete_if { |this_file| this_file.path == file } end |
#environment_variables ⇒ Object
437 438 439 |
# File 'lib/vanagon/component.rb', line 437 def environment_variables environment.map { |key, value| %(export #{key}="#{value}") } end |
#fetch_mirrors(options) ⇒ Boolean
Retrieve upstream source file from a mirror, by randomly iterating through #mirrors until there’s no more mirrors left. Will #warn if the mirror’s URI cannot be resolved or if the URI cannot be retrieved. Does not suppress any errors from Vanagon::Component::Source.
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 |
# File 'lib/vanagon/component.rb', line 261 def fetch_mirrors() mirrors.to_a.shuffle.each do |mirror| begin VanagonLogger.info %(Attempting to fetch from mirror URL "#{mirror}") @source = Vanagon::Component::Source.source(mirror, **) return true if source.fetch rescue Vanagon::InvalidSource # This means that the URL was not a git repo or a valid downloadable file, # which means either the URL is incorrect, or we don't have access to that # resource. Return false, so that the pkg.url value can be used instead. VanagonLogger.error %(Invalid source "#{mirror}") rescue SocketError # SocketError means that there was no DNS/name resolution # for whatever remote protocol the mirror tried to use. VanagonLogger.error %(Unable to resolve mirror URL "#{mirror}") rescue StandardError # Source retrieval does not consistently return a meaningful # namespaced error message, which means we're brute-force rescuing # StandardError. Also, we want to handle other unexpected things when # we try reaching out to the URL, so that we can gracefully return # false and fall back to fetching the pkg.url value instead. VanagonLogger.error %(Unable to retrieve mirror URL "#{mirror}") end end false end |
#fetch_url(options) ⇒ Boolean
Retrieve upstream source file from the canonical URL. Does not suppress any errors from Vanagon::Component::Source.
293 294 295 296 297 298 299 300 |
# File 'lib/vanagon/component.rb', line 293 def fetch_url() VanagonLogger.info %(Attempting to fetch from canonical URL "#{url}") @source = Vanagon::Component::Source.source(url, **) # Explicitly coerce the return value of #source.fetch, # because each subclass of Vanagon::Component::Source returns # an inconsistent value if #fetch is successful. !!source.fetch end |
#force_version ⇒ Object
Force version determination for components
If the component doesn’t already have a version set (which normally happens for git sources), the source will be fetched into a temporary directory to attempt to figure out the version if the source type supports :version. This directory will be cleaned once the get_sources method returns
407 408 409 410 411 412 413 414 415 |
# File 'lib/vanagon/component.rb', line 407 def force_version if @version.nil? Dir.mktmpdir do |dir| get_source(dir) end end raise Vanagon::Error, "Unable to determine source version for component #{@name}!" if @version.nil? @version end |
#get_build_dir ⇒ Object
Expands the build directory
347 348 349 350 351 352 353 |
# File 'lib/vanagon/component.rb', line 347 def get_build_dir if @build_dir File.join(@dirname, @build_dir) else @dirname end end |
#get_dependency_hash ⇒ Object
355 356 357 |
# File 'lib/vanagon/component.rb', line 355 def get_dependency_hash { name => { 'version' => version, 'url' => url, 'ref' => [:ref] }.delete_if { |_, v| !v } } end |
#get_environment ⇒ String
Prints the environment in a way suitable for use in a Makefile or shell script. This is deprecated, because all Env. Vars. are moving directly into the Makefile (and out of recipe subshells).
423 424 425 426 427 428 429 430 431 432 433 434 435 |
# File 'lib/vanagon/component.rb', line 423 def get_environment VanagonLogger.info <<-WARNING.undent #get_environment is deprecated; environment variables have been moved into the Makefile, and should not be used within a Makefile's recipe. The #get_environment method will be removed by Vanagon 1.0.0. WARNING if environment.empty? ": no environment variables defined" else environment_variables end end |
#get_patches(patch_root) ⇒ Object
Fetches patches if any are provided for the project.
387 388 389 390 391 392 393 394 395 396 397 398 |
# File 'lib/vanagon/component.rb', line 387 def get_patches(patch_root) return if @patches.empty? @patches.each do |patch| patch_assembly_path = File.join(patch_root, patch.assembly_path) if File.exist?(patch_assembly_path) raise Vanagon::Error, "Duplicate patch files detected, '#{patch.origin_path}' would have overwritten '#{patch.assembly_path}'. Ensure all patch file names within a component are unique." end patch_target_directory = File.dirname(patch_assembly_path) FileUtils.mkdir_p(patch_target_directory) FileUtils.cp(patch.origin_path, patch_assembly_path) end end |
#get_source(workdir) ⇒ Object
Fetches the primary source for the component. As a side effect, also sets @extract_with, @dirname and @version for the component for use in the makefile template
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 |
# File 'lib/vanagon/component.rb', line 317 def get_source(workdir) # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity opts = .merge({ workdir: workdir, dirname: dirname }) if url || !mirrors.empty? if ENV['VANAGON_USE_MIRRORS'] == 'n' or ENV['VANAGON_USE_MIRRORS'] == 'false' fetch_url(opts) else fetch_mirrors(opts) || fetch_url(opts) end source.verify extract_with << source.extract(platform.tar) if source.respond_to? :extract @cleanup_source = source.cleanup if source.respond_to?(:cleanup) @dirname ||= source.dirname # Git based sources probably won't set the version, so we load it if it hasn't been already set if source.respond_to?(:version) @version ||= source.version end else VanagonLogger.info "No source given for component '#{@name}'" # If there is no source, we don't want to try to change directories, so we just change to the current directory. @dirname = './' # If there is no source, there is nothing to do to extract extract_with << ': no source, so nothing to extract' end end |
#get_sources(workdir) ⇒ Object
Fetches secondary sources for the component. These are just dumped into the workdir currently.
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 |
# File 'lib/vanagon/component.rb', line 362 def get_sources(workdir) # rubocop:disable Metrics/AbcSize sources.each do |source| src = Vanagon::Component::Source.source( source.url, workdir: workdir, ref: source.ref, sum: source.sum ) src.fetch src.verify if source.erb erb_file(src.file, File.join(File.dirname(src.file), File.basename(src.file, ".erb")), true) end # set src.file to only be populated with the basename instead of entire file path src.file = File.basename(src.url) extract_with << src.extract(platform.tar) if src.respond_to? :extract end end |
#rpm_ghost_files ⇒ Array
Retrieve all the files intended as %ghost entries for an rpm spec %files section.
238 239 240 |
# File 'lib/vanagon/component.rb', line 238 def rpm_ghost_files @ghost_files.to_a end |