# # Copyright:: Copyright (c) 2012 Opscode, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require 'ohai' o = Ohai::System.new o.require_plugin('os') o.require_plugin('platform') o.require_plugin('linux/cpu') if o.os == 'linux' o.require_plugin('kernel') OHAI = o require 'omnibus/library' require 'omnibus/reports' require 'omnibus/config' require 'omnibus/software' require 'omnibus/project' require 'omnibus/fetchers' require 'omnibus/health_check' require 'omnibus/build_version' require 'omnibus/overrides' require 'omnibus/version' require 'pathname' module Omnibus DEFAULT_CONFIG_FILENAME = 'omnibus.rb'.freeze # Configure Omnibus. # # After this has been called, the {Omnibus::Config} object is # available as `Omnibus.config`. # # @return [void] # # @deprecated Use {#load_configuration} if you need to process a # config file, followed by {#process_configuration} to act upon it. def self.configure load_configuration process_configuration end # Convenience method for access to the Omnibus::Config object. # Provided for backward compatibility. # # @ return [Omnibus::Config] # # @deprecated Just refer to {Omnibus::Config} directly. def self.config Config end # Load in an Omnibus configuration file. Values will be merged with # and override the defaults defined in {Omnibus::Config}. # # @param file [String] path to a configuration file to load # # @return [void] def self.load_configuration(file=nil) if file Config.from_file(file) end end # Processes the configuration to construct the dependency tree of # projects and software. # # @return [void] def self.process_configuration Config.validate process_dsl_files generate_extra_rake_tasks end # All {Omnibus::Project} instances that have been created. # # @return [Array] def self.projects @projects ||= [] end # Names of all the {Omnibus::Project} instances that have been created. # # @return [Array] def self.project_names projects.map{|p| p.name} end # Load the {Omnibus::Project} instance with the given name. # # @param name [String] # @return {Omnibus::Project} def self.project(name) projects.find{ |p| p.name == name} end # The absolute path to the Omnibus project/repository directory. # # @return [String] # # @deprecated Call {Omnibus::Config.project_root} instead. We need # to be able to easily tweak this at runtime via the CLI tool. def self.project_root Config.project_root end # The source root is the path to the root directory of the `omnibus` gem. # # @return [Pathname] def self.source_root @source_root ||= Pathname.new(File.expand_path("../..", __FILE__)) end # The source root is the path to the root directory of the `omnibus-software` # gem. # # @return [Pathname] def self.omnibus_software_root @omnibus_software_root ||= begin if spec = Gem::Specification.find_all_by_name('omnibus-software').first Pathname.new(spec.gem_dir) else nil end end end # Return paths to all configured {Omnibus::Project} DSL files. # # @return [Array] def self.project_files ruby_files(File.join(project_root, Config.project_dir)) end # Return paths to all configured {Omnibus::Software} DSL files. # # @return [Array] def self.software_files ruby_files(File.join(project_root, Config.software_dir)) end # Backward compat alias # # @todo print a deprecation message class << self alias :root :project_root end private # Generates {Omnibus::Project}s for each project DSL file in # `project_specs`. All projects are then accessible at # {Omnibus#projects} # # @return [void] # # @see Omnibus::Project def self.expand_projects project_files.each do |spec| Omnibus.projects << Omnibus::Project.load(spec) end end # Generate {Omnibus::Software} objects for all software DSL files in # `software_specs`. # # @param overrides [Hash] a hash of version override information. # @param software_files [Array] # @return [void] # # @see Omnibus::Overrides#overrides def self.expand_software(overrides, software_files) unless overrides.is_a? Hash raise ArgumentError, "Overrides argument must be a hash! You passed #{overrides.inspect}." end # TODO: Why are we doing a full Cartesian product of (projects x # software) without regard for the actual dependencies of the # projects? software_files.each do |f| Omnibus.projects.each do |p| s = Omnibus::Software.load(f, p, overrides) Omnibus.component_added(s) if p.dependency?(s) end end end # Processes all configured {Omnibus::Project} and # {Omnibus::Software} DSL files. # # @return [void] def self.process_dsl_files # Do projects first expand_projects # Then do software final_software_files = prefer_local_software(omnibus_software_files, software_files) overrides = Config.override_file ? Omnibus::Overrides.overrides : {} expand_software(overrides, final_software_files) end # Creates some additional Rake tasks beyond those generated in the # process of reading in the DSL files. # # @return [void] # # @todo Not so sure I like how this is being done, but at least it # isolates the Rake stuff. def self.generate_extra_rake_tasks require 'omnibus/clean_tasks' end # Return a list of all the Ruby files (i.e., those with an "rb" # extension) in the given directory # # @param dir [String] # @return [Array] def self.ruby_files(dir) Dir.glob("#{dir}/*.rb") end # Retrieve the fully-qualified paths to every software definition # file bundled in the {https://github.com/opscode/omnibus-software omnibus-software} gem. # # @return [Array] the list of paths. Will be empty if the # `omnibus-software` gem is not in the gem path. def self.omnibus_software_files if omnibus_software_root Dir.glob(File.join(omnibus_software_root, 'config', 'software', '*.rb')) else [] end end # Given a list of software definitions from `omnibus-software` itself, and a # list of software files local to the current project, create a # single list of software definitions. If the software was defined # in both sets, the locally-defined one ends up in the final list. # # The base name of the software file determines what software it # defines. # # @param omnibus_files [Array] # @param local_files [Array] # @return [Array] def self.prefer_local_software(omnibus_files, local_files) base = software_map(omnibus_files) local = software_map(local_files) base.merge(local).values end # Given a list of file paths, create a map of the basename (without # extension) to the complete path. # # @param files [Array] # @return [Hash] def self.software_map(files) files.each_with_object({}) do |file, collection| software_name = File.basename(file, ".*") collection[software_name] = file end end end