Skip to content
This repository has been archived by the owner on May 10, 2018. It is now read-only.

Commit

Permalink
Merge pull request #315 from travis-ci/sf-refactor-build-config
Browse files Browse the repository at this point in the history
Refactor build config
  • Loading branch information
BanzaiMan committed Jan 3, 2014
2 parents f357a2d + ea466d8 commit 434421d
Show file tree
Hide file tree
Showing 24 changed files with 895 additions and 783 deletions.
1 change: 0 additions & 1 deletion lib/travis/api/v1/http/repository.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ class Repository

def initialize(repository, options = {})
@repository = repository
@options = options.symbolize_keys.slice(*::Build.matrix_keys_for(options))
end

def data
Expand Down
1 change: 0 additions & 1 deletion lib/travis/api/v2/http/repository.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ class Repository

def initialize(repository, options = {})
@repository = repository
@options = options.symbolize_keys.slice(*::Build.matrix_keys_for(options))
end

def data
Expand Down
1 change: 0 additions & 1 deletion lib/travis/event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ module Event
require 'travis/event/config'
require 'travis/event/handler'
require 'travis/event/subscription'
require 'travis/event/secure_config'

SUBSCRIBERS = %w(metrics)

Expand Down
4 changes: 3 additions & 1 deletion lib/travis/event/config.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require 'travis/secure_config'

module Travis
module Event
class Config
Expand Down Expand Up @@ -94,7 +96,7 @@ def notification_values(type, key)
end

def notifications
Travis::Event::SecureConfig.decrypt(config.fetch(:notifications, {}), secure_key)
Travis::SecureConfig.decrypt(config.fetch(:notifications, {}), secure_key)
end

def normalize_array(values)
Expand Down
74 changes: 0 additions & 74 deletions lib/travis/event/secure_config.rb

This file was deleted.

100 changes: 6 additions & 94 deletions lib/travis/model/build.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
# TODO probably should be cleaned up and moved to
# travis/notification)
class Build < Travis::Model
require 'travis/model/build/config'
require 'travis/model/build/denormalize'
require 'travis/model/build/matrix'
require 'travis/model/build/metrics'
Expand All @@ -46,7 +47,6 @@ class Build < Travis::Model
require 'travis/model/env_helpers'

include Matrix, States, SimpleStates
include Travis::Model::EnvHelpers

belongs_to :commit
belongs_to :request
Expand Down Expand Up @@ -178,64 +178,12 @@ def secure_env_enabled?
end
alias addons_enabled? secure_env_enabled?

# sometimes the config is not deserialized and is returned
# as a string, this is a work around for now :(
def config
deserialized = self['config']
if deserialized.is_a?(String)
logger.warn "Attribute config isn't YAML. Current serialized attributes: #{Build.serialized_attributes}"
deserialized = YAML.load(deserialized)
end
deserialized
rescue Psych::SyntaxError => e
logger.warn "[build id:#{id}] Config could not be deserialized due to #{e.message}"
{}
end

def config=(config)
super(config ? normalize_config(config) : {})
super(Config.new(config, multi_os: multi_os_enabled?).normalize)
end

def obfuscated_config
config.dup.tap do |config|
config.delete(:source_key)
next unless config[:env]
config[:env] = [config[:env]] unless config[:env].is_a?(Array)
if config[:env]
config[:env] = config[:env].map do |env|
env = normalize_env_hashes(env)
obfuscate_env(env).join(' ')
end
end
end
end

def normalize_env_hashes(lines)
process_line = ->(line) do
if line.is_a?(Hash)
env_hash_to_string(line)
elsif line.is_a?(Array)
line.map do |line|
env_hash_to_string(line)
end
else
line
end
end


if lines.is_a?(Array)
lines.map { |env| process_line.(env) }
else
process_line.(lines)
end
end

def env_hash_to_string(hash)
return hash unless hash.is_a?(Hash)
return hash if hash.has_key?(:secure)

hash.map { |k,v| "#{k}=#{v}" }.join(' ')
Config.new(config, key_fetcher: lambda { self.repository.key }).obfuscate
end

def cancelable?
Expand All @@ -257,42 +205,8 @@ def on_default_branch?

private

def normalize_env_values(values)
env = values
global = nil

if env.is_a?(Hash) && (env[:global] || env[:matrix])
global = env[:global]
env = env[:matrix]
end

if env
env = [env] unless env.is_a?(Array)
env = normalize_env_hashes(env)
end

if global
global = [global] unless global.is_a?(Array)
global = normalize_env_hashes(global)
end

{ env: env, global: global }
end


def normalize_config(config)
config = config.deep_symbolize_keys
if config[:env]
result = normalize_env_values(config[:env])
if result[:env]
config[:env] = result[:env]
else
config.delete(:env)
end

config[:global_env] = result[:global] if result[:global]
end
config
def multi_os_enabled?
Travis::Features.enabled_for_all?(:multi_os) || repository && Travis::Features.active?(:multi_os, repository)
end

def last_finished_state_on_branch
Expand All @@ -301,8 +215,6 @@ def last_finished_state_on_branch

def to_postgres_array(ids)
ids = ids.compact.uniq
unless ids.empty?
"{#{ids.map { |id| id.to_i.to_s }.join(',')}}"
end
"{#{ids.map { |id| id.to_i.to_s }.join(',')}}" unless ids.empty?
end
end
66 changes: 66 additions & 0 deletions lib/travis/model/build/config.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
require 'travis/model/build/config/env'
require 'travis/model/build/config/language'
require 'travis/model/build/config/matrix'
require 'travis/model/build/config/obfuscate'

class Build
class Config
NORMALIZERS = [Env, Language]

DEFAULT_LANG = 'ruby'

ENV_KEYS = [:rvm, :gemfile, :env, :otp_release, :php, :node_js, :scala, :jdk, :python, :perl, :compiler, :go, :xcode_sdk, :xcode_scheme, :ghc]

EXPANSION_KEYS_FEATURE = [:os]

EXPANSION_KEYS_LANGUAGE = {
'c' => [:compiler],
'clojure' => [:lein, :jdk],
'cpp' => [:compiler],
'erlang' => [:otp_release],
'go' => [:go],
'groovy' => [:jdk],
'haskell' => [:ghc],
'java' => [:jdk],
'node_js' => [:node_js],
'objective-c' => [:rvm, :gemfile, :xcode_sdk, :xcode_scheme],
'perl' => [:perl],
'php' => [:php],
'python' => [:python],
'ruby' => [:rvm, :gemfile, :jdk],
'scala' => [:scala, :jdk]
}

EXPANSION_KEYS_UNIVERSAL = [:env, :branch]

def self.matrix_keys_for(config, options = {})
keys = matrix_keys(config, options)
keys & config.keys.map(&:to_sym)
end

def self.matrix_keys(config, options = {})
lang = Array(config.symbolize_keys[:language]).first
keys = ENV_KEYS
keys &= EXPANSION_KEYS_LANGUAGE.fetch(lang, EXPANSION_KEYS_LANGUAGE[DEFAULT_LANG])
keys << :os if options[:multi_os]
keys | EXPANSION_KEYS_UNIVERSAL
end

attr_reader :config, :options

def initialize(config, options = {})
@config = (config || {}).deep_symbolize_keys
@options = options
end

def normalize
NORMALIZERS.inject(config) do |config, normalizer|
normalizer.new(config, options).run
end
end

def obfuscate
Obfuscate.new(config, options).run
end
end
end
50 changes: 50 additions & 0 deletions lib/travis/model/build/config/env.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
require 'core_ext/hash/compact'

class Build
class Config
class Env < Struct.new(:config, :options)
def run
case config[:env]
when Hash
config.merge(normalize_hash(config[:env])).compact
when Array
config.merge(env: config[:env].map { |value| normalize_value(value) })
else
config
end
end

def normalize_hash(env)
if env[:global] || env[:matrix]
{ global_env: normalize_values(env[:global]), env: normalize_values(env[:matrix]) }
else
{ env: normalize_values(env) }
end
end

def normalize_values(values)
values = [values].compact unless values.is_a?(Array)
values.map { |value| normalize_value(value) } unless values.empty?
end

def normalize_value(value)
case value
when Hash
to_env_var(value)
when Array
value.map { |value| to_env_var(value) }
else
value
end
end

def to_env_var(hash)
if hash.is_a?(Hash) && !hash.key?(:secure)
hash.map { |name, value| "#{name}=#{value}" }.join(' ')
else
hash
end
end
end
end
end
27 changes: 27 additions & 0 deletions lib/travis/model/build/config/language.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
require 'active_support/core_ext/array/wrap'

class Build
class Config
class Language < Struct.new(:config, :options)
def run
config[:language] = Array.wrap(config[:language]).first || DEFAULT_LANG
config.select { |key, value| include_key?(key) }
end

private

def include_key?(key)
matrix_keys.include?(key) || !known_env_key?(key)
end

def matrix_keys
Config.matrix_keys(config, options)
end

def known_env_key?(key)
(ENV_KEYS | EXPANSION_KEYS_FEATURE).include?(key)
end
end
end
end

Loading

0 comments on commit 434421d

Please sign in to comment.