lib/iapi-idlc-sdk-pfm/settings.rb
module Pfm # == +PFM+ Settings # Top level settings defined and loaded here. This class loads the user config file # located at +.pfm/config+ # # +AWS_REGION+ <em>default -> 'us-east-1'</em> # # * The AWS region to work in. This will eventually become the AWS_REGION environment variable and can be used with other AWS API operations. # # +RUBOCOP_RULES_FILE+ <em>default -> '.rubocop.yml'</em> # # * Set the path to the global +.rubocop.yml+ rules file. This file will be used for all server builds when running syntax checks. # # +FOODCRITIC_RULES_FILE+ <em>default -> '.foodcritic'</em> # # * Set the path to the global +.foodcritic+ rules file. This file will be used for all server builds when running semantics checks. # # +BUILD_BASE_DIR+ <em>default -> 'builds'</em> # # * Set the root path to the builds directory. This should be where top level server builds are located. Ex: # . # ├── builds # │ ├── app-axpdb # │ └── app-axpwa # # +INF_BASE_DIR+ <em>default -> 'inf'</em> # # * Set the path to the top level infrastructure directory. Ex: # . # ├── inf # │ ├── env # │ ├── tasks # │ └── tf # # +PUBLISH_BUCKET+ <em>default -> ''</em> # # * The top level bucket where deployment packages are stored in S3. # # +PUBLISH_PREFIX+ <em>default -> ''</em> # # * The prefix to the deployment package storage location. Ex: # +s3://PUBLISH_BUCKET/PUBLISH_PREFIX/package.name+ # # +PACKER_VERSION+ <em>default -> 'default from packer/binary' # # * The version of Hashicorp Packer to use for builds # # +TERRAFORM_VERSION+ <em>default -> 'default from terraform/binary' # # * The version of Hashicorp Terraform to use for deployments # # Note that if you change these settings from the default, be sure you commit # the +.pfm/config+ file. # # == Example Configuration File # An example +.pfm/config+ file might look like this: # --- # AWS_REGION: 'us-east-1' # RUBOCOP_RULES_FILE: '.pfm/.rubocop.yml' # FOODCRITIC_RULES_FILE: '.pfm/.foodcritic' # BUILD_BASE_DIR: 'builds' # INF_BASE_DIR: 'inf' # PUBLISH_BUCKET: 'dev-publish' # PUBLISH_PREFIX: 'axp' # PACKER_VERSION: '1.0.4' # TERRAFORM_VERSION: '0.8.7' class Settings # Defines an individual setting class Setting attr_reader :value def initialize(value, required = false) @value = value @required = required end def required? @required end def defined? !@value.nil? end def to_s @value.to_s end end # @return [Map] returns the map of Pfm::Settings::Setting objects attr_reader :settings attr_reader :config_directory attr_reader :run_dir def initialize(expand = false) @run_dir = Dir.pwd @config_directory = config_dir @expand = expand @settings = {} # Required @settings['AWS_REGION'] = Setting.new(ENV['AWS_REGION'], true) @settings['RUBOCOP_RULES_FILE'] = Setting.new('.rubocop.yml', true) @settings['FOODCRITIC_RULES_FILE'] = Setting.new('.foodcritic', true) @settings['BUILD_BASE_DIR'] = Setting.new('builds', true) @settings['INF_BASE_DIR'] = Setting.new('inf', true) @settings['PACKER_VERSION'] = Setting.new(::Packer::Binary.config.version, true) @settings['TERRAFORM_VERSION'] = Setting.new(::Terraform::Binary.config.version, true) # Optional Defaults @settings['PUBLISH_BUCKET'] = Setting.new('') @settings['PUBLISH_PREFIX'] = Setting.new('') load_config end # load the config file and resolve file paths if set def load_config if config_exists? require 'yaml' YAML.load_file(config_file).each do |key, value| msg("WARNING: unrecognized config key: '#{key}'") unless @settings.key? key next unless @settings.key? key required = @settings[key].required? @settings[key] = Setting.new(value, required) end # Also load each setting into the environment @settings.each { |key, setting| ENV[key] = setting.value } # Resolve paths if set resolve_paths if @expand else create_config load_config end end # Saves a new configuration to disk # @param settings [Map<Pfm::Settings::Setting>] a new map of Pfm::Settings::Setting objects def save_config(settings) @settings = settings write_config end # returns a simple map of Pfm::Settings.settings[key] => Pfm::Settings.setting[key].to_s # @return [Map<String>] def settings_strings map = {} @settings.each do |key, setting| map[key] = setting.to_s end map end private # create the config directory and file if they don't already exist def create_config return if config_exists? FileUtils.mkdir_p config_dir FileUtils.touch config_file write_config end # expands variables like '.' and '~' in settings values paths def resolve_paths @settings.each do |key, setting| required = @settings[key].required? @settings[key] = Setting.new(File.realpath(setting.value), required) if File.exist? setting.value end end # writes the @settings attribute to disk def write_config config_string = '---' @settings.each do |key, setting| config_string += "\n#{key}: '#{setting.value}'" end config_string += "\n" File.open(config_file, 'w') { |file| file.write(config_string) } end def config_exists? File.exist? config_file end def config_dir "#{@run_dir}/.pfm" end def config_file "#{config_dir}/config" end end end