class Vanagon::Component::DSL

Public Class Methods

new(name, settings, platform) click to toggle source

Constructor for the DSL object

@param name [String] name of the component @param settings [Hash] settings to use in building the component @param platform [Vanagon::Platform] platform to build the component for @return [Vanagon::Component::DSL] A DSL object to describe the {Vanagon::Component}

# File lib/vanagon/component/dsl.rb, line 16
def initialize(name, settings, platform)
  @name = name
  @component = Vanagon::Component.new(@name, settings, platform)
end

Public Instance Methods

_component() click to toggle source

Accessor for the component.

@return [Vanagon::Component] the component the DSL methods will be acting against

# File lib/vanagon/component/dsl.rb, line 32
def _component
  @component
end
add_debian_activate_triggers(activate_name) click to toggle source

Adds activate trigger name to be watched

@param activate_name [String] the activate trigger name

# File lib/vanagon/component/dsl.rb, line 502
def add_debian_activate_triggers(activate_name)
  @component.activate_triggers << OpenStruct.new(:activate_name => activate_name)
end
add_debian_interest_triggers(pkg_state, scripts, interest_name) click to toggle source

Adds interest trigger based on the specified packaging state and interest name.

@param pkg_state [String, Array] the package state during which the scripts should execute.

Accepts either a single string ("install" or "upgrade"), or an Array of Strings (["install", "upgrade"]).

@param scripts [Array] the scripts to run for the interest trigger @param interest_name [String] the name of the interest trigger

# File lib/vanagon/component/dsl.rb, line 492
def add_debian_interest_triggers(pkg_state, scripts, interest_name)
  pkg_state = Array(pkg_state)
  scripts = Array(scripts)
  check_pkg_state_array(pkg_state)
  @component.interest_triggers << OpenStruct.new(:pkg_state => pkg_state, :scripts => scripts, :interest_name => interest_name)
end
add_postinstall_action(pkg_state, scripts) click to toggle source

Adds action to run during the postinstall phase of packaging

@param pkg_state [Array] the state in which the scripts should execute. Can be

one or multiple of 'install' and 'upgrade'.

@param scripts [Array] the Bourne shell compatible scriptlet(s) to execute

# File lib/vanagon/component/dsl.rb, line 521
def add_postinstall_action(pkg_state, scripts)
  pkg_state = Array(pkg_state)
  scripts = Array(scripts)
  check_pkg_state_array(pkg_state)
  @component.postinstall_actions << OpenStruct.new(:pkg_state => pkg_state, :scripts => scripts)
end
add_postinstall_required_action(pkg_state, scripts) click to toggle source

Add post installation action that must exit successfully before restarting the service

@param pkg_state [Array] the state in which the scripts should execute. Can be

one or multiple of 'install' and 'upgrade'.

@param scripts [Array] the Bourne shell compatible scriptlet(s) to execute

# File lib/vanagon/component/dsl.rb, line 511
def add_postinstall_required_action(pkg_state, scripts)
  check_pkg_state_array(pkg_state)
  @component.postinstall_required_actions << OpenStruct.new(:pkg_state => Array(pkg_state), :scripts => Array(scripts))
end
add_postremove_action(pkg_state, scripts) click to toggle source

Adds action to run during the postremoval phase of packaging

@param pkg_state [Array] the state in which the scripts should execute. Can be

one or multiple of 'removal' and 'upgrade'.

@param scripts [Array] the Bourne shell compatible scriptlet(s) to execute

# File lib/vanagon/component/dsl.rb, line 559
def add_postremove_action(pkg_state, scripts)
  pkg_state = Array(pkg_state)
  scripts = Array(scripts)

  if pkg_state.empty? || !(pkg_state - ["upgrade", "removal"]).empty?
    raise Vanagon::Error, "#{pkg_state} should be an array containing one or more of ['removal', 'upgrade']"
  end
  @component.postremove_actions << OpenStruct.new(:pkg_state => pkg_state, :scripts => scripts)
end
add_preinstall_action(pkg_state, scripts) click to toggle source

Adds action to run during the preinstall phase of packaging

@param pkg_state [String, Array] the package state during which the scripts should execute.

Accepts either a single string ("install" or "upgrade"), or an Array of Strings (["install", "upgrade"]).

@param scripts [Array] the Bourne shell compatible scriptlet(s) to execute

# File lib/vanagon/component/dsl.rb, line 466
def add_preinstall_action(pkg_state, scripts)
  pkg_state = Array(pkg_state)
  scripts = Array(scripts)
  check_pkg_state_array(pkg_state)
  @component.preinstall_actions << OpenStruct.new(:pkg_state => pkg_state, :scripts => scripts)
end
add_preremove_action(pkg_state, scripts) click to toggle source

Adds action to run during the preremoval phase of packaging

@param pkg_state [Array] the state in which the scripts should execute. Can be

one or multiple of 'removal' and 'upgrade'.

@param scripts [Array] the Bourne shell compatible scriptlet(s) to execute

# File lib/vanagon/component/dsl.rb, line 533
def add_preremove_action(pkg_state, scripts)
  pkg_state = Array(pkg_state)
  scripts = Array(scripts)

  if pkg_state.empty? || !(pkg_state - ["upgrade", "removal"]).empty?
    raise Vanagon::Error, "#{pkg_state} should be an array containing one or more of ['removal', 'upgrade']"
  end
  @component.preremove_actions << OpenStruct.new(:pkg_state => pkg_state, :scripts => scripts)
end
add_rpm_ghost_file(path) click to toggle source

Add a %ghost entry to the rpm %files section. This indicates a file that is tracked in the rpm database (the package manages it), but not installed. Used, for example, when setting up alternative packages for use with update-alternatives.

@param path [String] installed path of the file.

# File lib/vanagon/component/dsl.rb, line 299
def add_rpm_ghost_file(path)
  @component.add_rpm_ghost_file(Vanagon::Common::Pathname.file(path))
end
add_rpm_install_triggers(pkg_state, scripts, pkg) click to toggle source

Adds trigger for scripts to be run on specified pkg_state.

@param pkg_state [String, Array] the package state during which the scripts should execute.

Accepts either a single string ("install" or "upgrade"), or an Array of Strings (["install", "upgrade"]).

@param scripts [Array] the rpm pkg scriptlet(s) to execute @param pkg [String] the package the trigger will be set in

# File lib/vanagon/component/dsl.rb, line 479
def add_rpm_install_triggers(pkg_state, scripts, pkg)
  pkg_state = Array(pkg_state)
  scripts = Array(scripts)
  check_pkg_state_array(pkg_state)
  @component.install_triggers << OpenStruct.new(:pkg_state => pkg_state, :scripts => scripts, :pkg => pkg)
end
add_source(uri, options = {}) click to toggle source

This will add a source to the project and put it in the workdir alongside the other sources

@param uri [String] uri of the source @param [Hash] options optional keyword arguments used to instatiate a new source

@option opts [String] :sum
@option opts [String] :ref
@option opts [Bool] :erb set to 'true' to specify that the source file should be
  translated by erb
# File lib/vanagon/component/dsl.rb, line 403
def add_source(uri, options = {})
  @component.sources << OpenStruct.new(options.merge({ url: uri }))
end
apply_patch(patch, options = {}) click to toggle source

Add a patch to the list of patches to apply to the component’s source after unpacking

@param patch [String] Path to the patch that should be applied @param options [Hash] options controlling the patch @option namespace [String] Namespace for package patches @option destination [String] Path to the location where the patch should be applied @option strip [String, Integer] directory levels to skip in applying patch @option fuzz [String, Integer] levels of context miss to ignore in applying patch @option after [String] the location in the makefile where the patch command should be run

# File lib/vanagon/component/dsl.rb, line 95
def apply_patch(patch, options = {})
  @component.patches << Vanagon::Patch.new(patch, @component, options)
end
build() { || ... } click to toggle source

Set or add to the build call for the component. The commands required to build the component before testing/installing it.

@param block [Proc] the command(s) required to build the component

# File lib/vanagon/component/dsl.rb, line 68
def build(&block)
  @component.build << yield
end
build_dir(path) click to toggle source

Set a build dir relative to the source directory.

The build dir will be created before the configure block runs and configure/build/install commands will be run in the build dir.

@example

pkg.build_dir "build"
pkg.source "my-cmake-project" # Will create the path "my-cmake-project/build"
pkg.configure { ["cmake .."] }
pkg.build { ["make -j 3"] }
pkg.install { ["make install"] }

@param path [String] The build directory to use for building the project

# File lib/vanagon/component/dsl.rb, line 365
def build_dir(path)
  if Pathname.new(path).relative?
    @component.build_dir = path
  else
    raise Vanagon::Error, "build_dir should be a relative path, but '#{path}' looks to be absolute."
  end
end
build_requires(build_requirement) click to toggle source

build_requires adds a requirements to the list of build time dependencies that will need to be fetched from an external source before this component can be built. build_requires can also be satisfied by other components in the same project.

@param build_requirement [String] a library or other component that is required to build the current component

# File lib/vanagon/component/dsl.rb, line 127
def build_requires(build_requirement)
  @component.build_requires << build_requirement
end
check() { || ... } click to toggle source

Set or add to the check call for the component. The commands required to test the component before installing it.

@param block [Proc] the command(s) required to test the component

# File lib/vanagon/component/dsl.rb, line 75
def check(&block)
  @component.check << yield
end
check_pkg_state_array(pkg_state) click to toggle source

Checks that the array of pkg_state is valid (install AND/OR upgrade). Returns vanagon error if invalid

@param pkg_state [Array] array of pkg_state input to test

# File lib/vanagon/component/dsl.rb, line 455
def check_pkg_state_array(pkg_state)
  if pkg_state.empty? || (pkg_state - ["install", "upgrade"]).any?
    raise Vanagon::Error, "#{pkg_state} should be an array containing one or more of ['install', 'upgrade']"
  end
end
clone_option(option, value) click to toggle source

Sets clone option for git repository

@param option for cloning and value

# File lib/vanagon/component/dsl.rb, line 346
def clone_option(option, value)
  option_sym = option.to_sym
  @component.options[:clone_options] ||= {}
  @component.options[:clone_options][option_sym] = value
end
component(name) { |self, settings, platform| ... } click to toggle source

Primary way of interacting with the DSL

@param name [String] name of the componennt @param block [Proc] DSL definition of the component to call

# File lib/vanagon/component/dsl.rb, line 25
def component(name, &block)
  yield(self, @component.settings, @component.platform)
end
configfile(file, mode: nil, owner: nil, group: nil) click to toggle source

Marks a file as a configfile to ensure that it is not overwritten on upgrade if it has been modified

@param file [String] name of the configfile

# File lib/vanagon/component/dsl.rb, line 260
def configfile(file, mode: nil, owner: nil, group: nil)
  # I AM SO SORRY
  @component.delete_file file
  if @component.platform.name =~ /solaris-10|osx/
    @component.install << "mv '#{file}' '#{file}.pristine'"
    @component.add_file Vanagon::Common::Pathname.configfile("#{file}.pristine", mode: mode, owner: owner, group: group)
  else
    @component.add_file Vanagon::Common::Pathname.configfile(file, mode: mode, owner: owner, group: group)
  end
end
configure() { || ... } click to toggle source

Set or add to the configure call for the component. The commands required to configure the component before building it.

@param block [Proc] the command(s) required to configure the component

# File lib/vanagon/component/dsl.rb, line 61
def configure(&block)
  @component.configure << yield
end
conflicts(pkgname, version = nil) click to toggle source

Indicates that this component conflicts with another package, so both cannot be installed at the same time. Conflicts can be collected and used by the project and package.

@param pkgname [String] name of the package which conflicts with this component @param version [String] the version of the package that conflicts with this component

# File lib/vanagon/component/dsl.rb, line 161
def conflicts(pkgname, version = nil)
  @component.conflicts << OpenStruct.new(:pkgname => pkgname, :version => version)
end
directory(dir, mode: nil, owner: nil, group: nil) click to toggle source

Adds a directory to the list of directories provided by the project, to be included in any packages of the project

@param dir [String] directory to add to the project @param mode [String] octal mode to apply to the directory @param owner [String] owner of the directory @param group [String] group of the directory

# File lib/vanagon/component/dsl.rb, line 413
def directory(dir, mode: nil, owner: nil, group: nil) # rubocop:disable Metrics/AbcSize
  install_flags = ['-d']
  if @component.platform.is_windows?
    unless mode.nil? && owner.nil? && group.nil?
      VanagonLogger.info "You're trying to set the mode, owner, or group for windows. I don't know how to do that, ignoring!"
    end
  else
    install_flags << "-m '#{mode}'" unless mode.nil?
  end
  @component.install << "#{@component.platform.install} #{install_flags.join(' ')} '#{dir}'"
  @component.directories << Vanagon::Common::Pathname.new(dir, mode: mode, owner: owner, group: group)
end
dirname(path) click to toggle source

Set a source dir

The build dir will be created when the source archive is unpacked. This should be used when the unpacked directory name does not match the source archive name.

@example

pkg.url "http://the-internet.com/a-silly-name-that-unpacks-into-not-this.tar.gz"
pkg.dirname "really-cool-directory"
pkg.configure { ["cmake .."] }
pkg.build { ["make -j 3"] }
pkg.install { ["make install"] }

@param path [String] The build directory to use for building the project

# File lib/vanagon/component/dsl.rb, line 387
def dirname(path)
  if Pathname.new(path).relative?
    @component.dirname = path
  else
    raise Vanagon::Error, "dirname should be a relative path, but '#{path}' looks to be absolute."
  end
end
environment(*env) click to toggle source

Adds a set of environment overrides to the environment for a component. This environment is included in the configure, build and install steps.

@param env [Hash] mapping of keys to values to add to the environment for the component

# File lib/vanagon/component/dsl.rb, line 430
      def environment(*env)
        if env.size == 1 && env.first.is_a?(Hash)
          VanagonLogger.info <<-WARNING.undent
            the component DSL method signature #environment({Key => Value}) is deprecated
            and will be removed by Vanagon 1.0.0.

            Please update your project configurations to use the form:
              #environment(key, value)
          WARNING
          return @component.environment.merge!(env.first)
        elsif env.size == 2
          return @component.environment[env.first] = env.last
        end
        raise ArgumentError, <<-WARNING.undent
          component DSL method #environment only accepts a single Hash (deprecated)
          or a key-value pair (preferred):
            environment({"KEY" => "value"})
            environment("KEY", "value")
        WARNING
      end
get_version_forced() click to toggle source

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

@raise Vanagon::Error raises a vanagon error if we’re unable to determine the version

# File lib/vanagon/component/dsl.rb, line 550
def get_version_forced
  @component.force_version
end
homepage(homepage) click to toggle source

Set the homepage for the component

@param homepage

# File lib/vanagon/component/dsl.rb, line 580
def homepage(homepage)
  @component.homepage = homepage
end
install() { || ... } click to toggle source

Set or add to the install call for the component. The commands required to install the component.

@param block [Proc] the command(s) required to install the component

# File lib/vanagon/component/dsl.rb, line 82
def install(&block)
  @component.install << yield
end
install_configfile(source, target, mode: '0644', owner: nil, group: nil) click to toggle source

Shorthand to install a file and mark it as a configfile

@param source [String] path to the configfile to copy @param target [String] path to the desired target of the configfile

# File lib/vanagon/component/dsl.rb, line 275
def install_configfile(source, target, mode: '0644', owner: nil, group: nil)
  install_file(source, target, mode: mode, owner: owner, group: group)
  configfile(target, mode: mode, owner: owner, group: group)
end
install_file(source, target, mode: nil, owner: nil, group: nil) click to toggle source

Copies a file from source to target during the install phase of the component

@param source [String] path to the file to copy @param target [String] path to the desired target of the file @param owner [String] owner of the file @param group [String] group owner of the file

# File lib/vanagon/component/dsl.rb, line 241
def install_file(source, target, mode: nil, owner: nil, group: nil) # rubocop:disable Metrics/AbcSize
  @component.install << "#{@component.platform.install} -d '#{File.dirname(target)}'"
  @component.install << "#{@component.platform.copy} -p '#{source}' '#{target}'"

  if @component.platform.is_windows?
    unless mode.nil? && owner.nil? && group.nil?
      VanagonLogger.info "You're trying to set the mode, owner, or group for windows. I don't know how to do that, ignoring!"
    end
  else
    mode ||= '0644'
    @component.install << "chmod #{mode} '#{target}'"
  end
  @component.add_file Vanagon::Common::Pathname.file(target, mode: mode, owner: owner, group: group)
end
install_only(install_only) click to toggle source
# File lib/vanagon/component/dsl.rb, line 573
def install_only(install_only)
  @component.install_only = install_only
end
install_service(service_file, default_file = nil, service_name = @component.name, **options) click to toggle source

install_service adds the commands to install the various files on disk during the package build and registers the service with the project

@param service_file [String] path to the service file relative to the source @param default_file [String] path to the default file relative to the source @param service_name [String] name of the service @param options optional extra parameters

service_type [String] type of the service (network, application, system, etc)
init_system [String] the init system on which to install service (sysv, systemd)
link_target [String] executable service file should be linked to
# File lib/vanagon/component/dsl.rb, line 175
def install_service(service_file, default_file = nil, service_name = @component.name, **options) # rubocop:disable Metrics/AbcSize
  init_system = options[:init_system] || @component.platform.servicetype
  servicedir = @component.platform.get_service_dir(init_system)

  case init_system
  when "sysv"
    target_service_file = File.join(servicedir, service_name)
    target_default_file = File.join(@component.platform.defaultdir, service_name)
    target_mode = '0755'
    default_mode = '0644'
  when "systemd"
    target_service_file = File.join(servicedir, "#{service_name}.service")
    target_default_file = File.join(@component.platform.defaultdir, service_name)
    target_mode = '0644'
    default_mode = '0644'
  when "launchd"
    target_service_file = File.join(servicedir, "#{service_name}.plist")
    target_mode = '0644'
    default_mode = '0644'
  when "smf"
    # modify version in smf manifest so service gets restarted after package upgrade
    @component.install << %{#{@component.platform.sed} -ri 's/(<service.*version=)(".*")/\\1"#{Time.now.to_i}"/' #{service_file}}
    target_service_file = File.join(servicedir, options[:service_type].to_s, "#{service_name}.xml")
    target_default_file = File.join(@component.platform.defaultdir, service_name)
    target_mode = '0644'
    default_mode = '0755'
  when "aix"
    @component.service << OpenStruct.new(:name => service_name, :service_command => File.read(service_file).chomp)
    # Return here because there is no file to install, just a string read in
    return
  when "windows"
    @component.service << OpenStruct.new( \
      :bindir_id => "#{service_name.gsub(/[^A-Za-z0-9]/, '').upcase}BINDIR", \
      :service_file => service_file, \
      :component_group_id => "#{service_name.gsub(/[^A-Za-z0-9]/, '')}Component" \
    )
    # return here as we are just collecting the name of the service file to put into the harvest filter list.
    return
  else
    fail "Don't know how to install the #{init_system}. Please teach #install_service how to do this."
  end

  # Install the service and default files
  if options[:link_target]
    install_file(service_file, options[:link_target], mode: target_mode)
    link options[:link_target], target_service_file
  else
    install_file(service_file, target_service_file, mode: target_mode)
  end

  if default_file
    install_file(default_file, target_default_file, mode: default_mode)
    configfile target_default_file
  end

  # Register the service for use in packaging
  @component.service << OpenStruct.new(:name => service_name, :service_file => target_service_file,
                                       :type => options[:service_type], :init_system => init_system)
end
license(license) click to toggle source
# File lib/vanagon/component/dsl.rb, line 569
def license(license)
  @component.license = license
end
load_from_json(file) click to toggle source

Loads and parses json from a file. Will treat the keys in the json as methods to invoke on the component in question

@param file [String] Path to the json file @raise [RuntimeError] exceptions are raised if there is no file,

if it refers to methods that don't exist, or if it does not contain a Hash
# File lib/vanagon/component/dsl.rb, line 105
def load_from_json(file)
  if File.exist?(file)
    data = JSON.parse(File.read(file))
    raise "Hash required. Got '#{data.class}' when parsing '#{file}'" unless data.is_a?(Hash)
    data.each do |key, value|
      if self.respond_to?(key)
        self.send(key, value)
      else
        fail "Component does not have a '#{key}' method to invoke. Maybe your bespoke json has a typo?"
      end
    end
  else
    fail "Cannot load component data from '#{file}'. It does not exist."
  end
end
md5sum(value)
Alias for: sum
method_missing(method_name, *args) click to toggle source

All purpose getter. This object, which is passed to the component block, won’t have easy access to the attributes of the @component, so we make a getter for each attribute.

We only magically handle get_ methods, any other methods just get the standard method_missing treatment.

Calls superclass method
# File lib/vanagon/component/dsl.rb, line 43
def method_missing(method_name, *args)
  attribute_match = method_name.to_s.match(/get_(.*)/)
  if attribute_match
    attribute = attribute_match.captures.first
  else
    super
  end

  @component.send(attribute)
end
mirror(url) click to toggle source

Sets a mirror url for the source of this component

@param url [String] a mirror url to use as the source for this component.

Can be called more than once to add multiple mirror URLs.
# File lib/vanagon/component/dsl.rb, line 322
def mirror(url)
  @component.mirrors << url
end
provides(provide, version = nil) click to toggle source

Indicates that this component provides a system level package. Provides can be collected and used by the project and package.

@param provide [String] a package that is provided with this component @param version [String] the version of the package that is provided with this component

# File lib/vanagon/component/dsl.rb, line 151
def provides(provide, version = nil)
  @component.provides << OpenStruct.new(:provide => provide, :version => version)
end
ref(the_ref) click to toggle source

Sets the ref of the source for use in a git source

@param the_ref [String] ref, sha, branch or tag to checkout for a git source

# File lib/vanagon/component/dsl.rb, line 339
def ref(the_ref)
  @component.options[:ref] = the_ref
end
replaces(replacement, version = nil) click to toggle source

Indicates that this component replaces a system level package. Replaces can be collected and used by the project and package.

@param replacement [String] a package that is replaced with this component @param version [String] the version of the package that is replaced

# File lib/vanagon/component/dsl.rb, line 143
def replaces(replacement, version = nil)
  @component.replaces << OpenStruct.new(:replacement => replacement, :version => version)
end
requires(requirement, version = nil) click to toggle source

requires adds a requirement to the list of runtime requirements for the component

@param requirement [String] a package that is required at runtime for this component

# File lib/vanagon/component/dsl.rb, line 135
def requires(requirement, version = nil)
  @component.requires << OpenStruct.new(:requirement => requirement, :version => version)
end
respond_to_missing?(method_name, include_private = false) click to toggle source
Calls superclass method
# File lib/vanagon/component/dsl.rb, line 54
def respond_to_missing?(method_name, include_private = false)
  method_name.to_s.start_with?('get_') || super
end
sha1sum(value)
Alias for: sum
sha256sum(value)
Alias for: sum
sha512sum(value)
Alias for: sum
sum(value) click to toggle source
# File lib/vanagon/component/dsl.rb, line 326
def sum(value)
  type = __callee__.to_s.gsub(/sum$/, '')
  @component.options[:sum] = value
  @component.options[:sum_type] = type
end
Also aliased as: md5sum, sha1sum, sha256sum, sha512sum
url(uri) click to toggle source

Sets the canonical URL or URI for the upstream source of this component

@param uri [String, URI] a URL or URI describing a canonical location

for a component's source code or artifact
# File lib/vanagon/component/dsl.rb, line 314
def url(uri)
  @component.url = uri.to_s
end
version(ver) click to toggle source

Sets the version for the component

@param ver [String] version of the component

# File lib/vanagon/component/dsl.rb, line 306
def version(ver)
  @component.version = ver
end