config-factory 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1c37c92cb2e03fac96a921680f19865fa0caceb0
4
+ data.tar.gz: 1df74e155e1c9b087595ce54d495b7718daf4045
5
+ SHA512:
6
+ metadata.gz: e0616e9f0628f6cfc0fb6fe26b6594cf760225203998eb72225d85b8ef14584778e49960c9ef41b363a2b5c13194f4b0421ca494186d685667c87fa449cce954
7
+ data.tar.gz: 25b40edecf4cd5d8eb4e82de174f69bc230de9d4818fd66c3bf3a442e296d8141abfa2fc507f31621b440e2941e65456bb54bd424306d471cf8623f8cd702778
@@ -0,0 +1,42 @@
1
+ # Ruby defaults
2
+
3
+ /.bundle/
4
+ /.yardoc
5
+ /Gemfile.lock
6
+ /_yardoc/
7
+ /coverage/
8
+ /doc/
9
+ /pkg/
10
+ /spec/reports/
11
+ /tmp/
12
+ *.bundle
13
+ *.so
14
+ *.o
15
+ *.a
16
+ mkmf.log
17
+
18
+ # Gem
19
+
20
+ *.gem
21
+
22
+ # Logs
23
+
24
+ /log/
25
+
26
+ # IntellJ
27
+
28
+ *.iml
29
+ *.ipr
30
+ *.iws
31
+ *.ids
32
+ .rakeTasks
33
+
34
+ # Emacs
35
+
36
+ *~
37
+ \#*
38
+ .#*
39
+
40
+ # Mac OS
41
+
42
+ .DS_Store
@@ -0,0 +1,24 @@
1
+ # Disable compact style check for example.rb
2
+ Style/ClassAndModuleChildren:
3
+ Exclude:
4
+ - 'example.rb'
5
+
6
+ # Disable line-length check; it's too easy for the cure to be worse than the disease
7
+ Metrics/LineLength:
8
+ Enabled: False
9
+
10
+ # Disable problematic module documentation check (see https://github.com/bbatsov/rubocop/issues/947)
11
+ Style/Documentation:
12
+ Enabled: false
13
+
14
+ # Allow one line around class body (Style/EmptyLines will still disallow two or more)
15
+ Style/EmptyLinesAroundClassBody:
16
+ Enabled: false
17
+
18
+ # Allow one line around module body (Style/EmptyLines will still disallow two or more)
19
+ Style/EmptyLinesAroundModuleBody:
20
+ Enabled: false
21
+
22
+ # Allow one line around block body (Style/EmptyLines will still disallow two or more)
23
+ Style/EmptyLinesAroundBlockBody:
24
+ Enabled: false
@@ -0,0 +1 @@
1
+ 2.2.3
@@ -0,0 +1,2 @@
1
+ language: ruby
2
+
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 The Regents of the University of California
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,85 @@
1
+ # config-factory
2
+
3
+ [![Build Status](https://travis-ci.org/dmolesUC3/config-factory.svg?branch=master)](https://travis-ci.org/dmolesUC3/config-factory)
4
+ [![Code Climate](https://codeclimate.com/github/dmolesUC3/config-factory.svg)](https://codeclimate.com/github/dmolesUC3/config-factory)
5
+ [![Inline docs](http://inch-ci.org/github/dmolesUC3/config-factory.svg)](http://inch-ci.org/github/dmolesUC3/config-factory)
6
+ [![Gem Version](https://img.shields.io/gem/v/config-factory.svg)](https://github.com/dmolesUC3/config-factory/releases)
7
+
8
+ A gem for creating configuration classes using the
9
+ [Abstract Factory](https://web.archive.org/web/20111109224959/http://www.informit.com/articles/article.aspx?p=1398599),
10
+ pattern, with run-time configuration provided by hashes or YAML files.
11
+
12
+ ## Example
13
+
14
+ ```ruby
15
+ class SourceConfig
16
+ include Config::Factory
17
+ key :protocol
18
+ end
19
+
20
+ class OAISourceConfig < SourceConfig
21
+ protocol 'OAI'
22
+
23
+ def initialize(oai_base_url:, metadata_prefix:, set: nil, seconds_granularity: false)
24
+ end
25
+ end
26
+
27
+ class ResyncSourceConfig < SourceConfig
28
+ protocol 'Resync'
29
+
30
+ def initialize(capability_list_url:)
31
+ end
32
+ end
33
+ ```
34
+
35
+ ### Single-environment example
36
+
37
+ Configuration file:
38
+
39
+ ```YAML
40
+ source:
41
+ protocol: OAI
42
+ oai_base_url: http://oai.example.org/oai
43
+ metadata_prefix: some_prefix
44
+ set: some_set
45
+ seconds_granularity: true
46
+ ```
47
+
48
+ Loading:
49
+
50
+ ```ruby
51
+ environment = Environment.load_file('spec/data/single-environment.yml')
52
+ # => #<Config::Factory::Environment:0x007fe8d3883240 @name=:production, @configs={"source"=>{"protocol"=>"OAI", "oai_base_url"=>"http://oai.example.org/oai", "metadata_prefix"=>"some_prefix", "set"=>"some_set", "seconds_granularity"=>true}}>
53
+ source_config = SourceConfig.for_environment(environment, :source)
54
+ # => #<OAISourceConfig:0x007fe8d38b3990 @oai_base_url="http://oai.example.org/oai", @metadata_prefix="some_prefix", @set="some_set", @seconds_granularity=true>
55
+ ```
56
+
57
+ ### Multiple-environment example
58
+
59
+ Configuration file:
60
+
61
+ ```YAML
62
+ test:
63
+ source:
64
+ protocol: Resync
65
+ capability_list_url: http://localhost:8888/capabilitylist.xml
66
+
67
+ production:
68
+ source:
69
+ protocol: OAI
70
+ oai_base_url: http://oai.example.org/oai
71
+ metadata_prefix: some_prefix
72
+ set: some_set
73
+ seconds_granularity: true
74
+ ```
75
+
76
+ Loading:
77
+
78
+ ```ruby
79
+ environments = Environments.load_file('spec/data/multiple_environments.yml')
80
+ # => {:test=>#<Config::Factory::Environment:0x007fe8d3863dc8 @name=:test, @configs={"source"=>{"protocol"=>"Resync", "capability_list_url"=>"http://localhost:8888/capabilitylist.xml"}}>, :production=>#<Config::Factory::Environment:0x007fe8d3863be8 @name=:production, @configs={"source"=>{"protocol"=>"OAI", "oai_base_url"=>"http://oai.example.org/oai", "metadata_prefix"=>"some_prefix", "set"=>"some_set", "seconds_granularity"=>true}}>}
81
+ test_env = environments[:test]
82
+ # => #<Config::Factory::Environment:0x007fe8d383a400 @name=:test, @configs={"source"=>{"protocol"=>"Resync", "capability_list_url"=>"http://localhost:8888/capabilitylist.xml"}}>
83
+ source_config = SourceConfig.for_environment(test_env, :source)
84
+ # => #<ResyncSourceConfig:0x007fe8d48180c0 @capability_list_url="http://localhost:8888/capabilitylist.xml">
85
+ ```
@@ -0,0 +1,49 @@
1
+ # ------------------------------------------------------------
2
+ # RSpec
3
+
4
+ require 'rspec/core'
5
+ require 'rspec/core/rake_task'
6
+
7
+ namespace :spec do
8
+
9
+ desc 'Run all unit tests'
10
+ RSpec::Core::RakeTask.new(:unit) do |task|
11
+ task.rspec_opts = %w(--color --format documentation --order default)
12
+ task.pattern = 'unit/**/*_spec.rb'
13
+ end
14
+
15
+ task all: [:unit]
16
+ end
17
+
18
+ desc 'Run all tests'
19
+ task spec: 'spec:all'
20
+
21
+ # ------------------------------------------------------------
22
+ # Coverage
23
+
24
+ desc 'Run all unit tests with coverage'
25
+ task :coverage do
26
+ ENV['COVERAGE'] = 'true'
27
+ Rake::Task['spec:unit'].execute
28
+ end
29
+
30
+ # ------------------------------------------------------------
31
+ # RuboCop
32
+
33
+ require 'rubocop/rake_task'
34
+ RuboCop::RakeTask.new
35
+
36
+ # ------------------------------------------------------------
37
+ # TODOs
38
+
39
+ desc 'List TODOs (from spec/todo.rb)'
40
+ RSpec::Core::RakeTask.new(:todo) do |task|
41
+ task.rspec_opts = %w(--color --format documentation --order default)
42
+ task.pattern = 'todo.rb'
43
+ end
44
+
45
+ # ------------------------------------------------------------
46
+ # Defaults
47
+
48
+ desc 'Run unit tests, check test coverage, run acceptance tests, check code style'
49
+ task default: [:coverage, :rubocop]
@@ -0,0 +1,32 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ require 'uri'
6
+ require 'config/factory/module_info'
7
+
8
+ Gem::Specification.new do |spec|
9
+ spec.name = Config::Factory::NAME
10
+ spec.version = Config::Factory::VERSION
11
+ spec.authors = ['David Moles']
12
+ spec.email = ['david.moles@ucop.edu']
13
+ spec.summary = 'A gem for creating configuration classes using the Abstract Factory pattern.'
14
+ spec.description = 'A gem for creating configuration classes using the Abstract Factory pattern, with run-time configuration provided by hashes or YAML files.'
15
+ spec.license = 'MIT'
16
+
17
+ origin_uri = URI(`git config --get remote.origin.url`.chomp)
18
+ spec.homepage = URI::HTTP.build(host: origin_uri.host, path: origin_uri.path.chomp('.git')).to_s
19
+
20
+ spec.files = `git ls-files -z`.split("\x0")
21
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
22
+
23
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
24
+ spec.require_paths = ['lib']
25
+
26
+ spec.add_development_dependency 'bundler', '~> 1.7'
27
+ spec.add_development_dependency 'rake', '~> 10.4'
28
+ spec.add_development_dependency 'rspec', '~> 3.2'
29
+ spec.add_development_dependency 'simplecov', '~> 0.9.2'
30
+ spec.add_development_dependency 'simplecov-console', '~> 0.2.0'
31
+ spec.add_development_dependency 'rubocop', '~> 0.35.1'
32
+ end
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'config/factory'
4
+ include Config::Factory
5
+
6
+ # Configuration classes
7
+
8
+ class SourceConfig
9
+ include Config::Factory
10
+ key :protocol
11
+ end
12
+
13
+ class OAISourceConfig < SourceConfig
14
+ protocol 'OAI'
15
+
16
+ def initialize(oai_base_url:, metadata_prefix:, set: nil, seconds_granularity: false)
17
+ @oai_base_url = oai_base_url
18
+ @metadata_prefix = metadata_prefix
19
+ @set = set
20
+ @seconds_granularity = seconds_granularity
21
+ end
22
+ end
23
+
24
+ class ResyncSourceConfig < SourceConfig
25
+ protocol 'Resync'
26
+
27
+ def initialize(capability_list_url:)
28
+ @capability_list_url = capability_list_url
29
+ end
30
+ end
31
+
32
+ # Single-environment example
33
+
34
+ env = Environment.load_file('spec/data/single-environment.yml')
35
+ source_config = SourceConfig.for_environment(env, :source)
36
+ puts source_config
37
+ # => #<OAISourceConfig:0x007fe8d38b3990 @oai_base_url="http://oai.example.org/oai", @metadata_prefix="some_prefix", @set="some_set", @seconds_granularity=true>
38
+
39
+ # Multiple-environment example
40
+
41
+ envs = Environments.load_file('spec/data/multiple-environments.yml')
42
+ env = envs[:test]
43
+ source_config = SourceConfig.for_environment(env, :source)
44
+ puts source_config
45
+ # => #<ResyncSourceConfig:0x007fe8d48180c0 @capability_list_url="http://localhost:8888/capabilitylist.xml">
@@ -0,0 +1,5 @@
1
+ module Config
2
+ module Factory
3
+ Dir.glob(File.expand_path('../factory/*.rb', __FILE__)).sort.each(&method(:require))
4
+ end
5
+ end
@@ -0,0 +1,45 @@
1
+ module Config
2
+ module Factory
3
+ def self.included(base)
4
+ base.extend(AbstractFactory)
5
+ end
6
+
7
+ module AbstractFactory
8
+ attr_reader :product_key
9
+
10
+ def key(k)
11
+ @product_key = k
12
+ registry = products
13
+ define_singleton_method(k) do |v|
14
+ registry[v] = self
15
+ end
16
+ end
17
+
18
+ def for_environment(env, key)
19
+ arg_hash = env.args_for(key)
20
+ build_from(arg_hash)
21
+ end
22
+
23
+ def build_from(arg_hash)
24
+ args = deep_symbolize_keys(arg_hash)
25
+ key_value = args.delete(product_key)
26
+ product_class = products[key_value]
27
+ fail ArgumentError, "No #{name} product class found for #{product_key}: #{key_value}" unless product_class
28
+ product_class.new(args)
29
+ end
30
+
31
+ private
32
+
33
+ def deep_symbolize_keys(val)
34
+ return val unless val.is_a?(Hash)
35
+ val.map do |k, v|
36
+ [k.respond_to?(:to_sym) ? k.to_sym : k, deep_symbolize_keys(v)]
37
+ end.to_h
38
+ end
39
+
40
+ def products
41
+ @products ||= {}
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,35 @@
1
+ module Config
2
+ module Factory
3
+ class Environment
4
+
5
+ attr_reader :name
6
+
7
+ def initialize(name:, configs:)
8
+ self.name = name
9
+ @configs = configs
10
+ end
11
+
12
+ def args_for(config_name)
13
+ config_name = config_name.to_s unless config_name.is_a?(String)
14
+ @configs[config_name]
15
+ end
16
+
17
+ def self.load_file(path)
18
+ hash = YAML.load_file(path)
19
+ load_hash(hash)
20
+ end
21
+
22
+ def self.load_hash(hash)
23
+ Environment.new(name: Environments::DEFAULT_ENVIRONMENT, configs: hash)
24
+ end
25
+
26
+ private
27
+
28
+ def name=(v)
29
+ fail ArgumentError, 'Environment name must be a symbol' unless v && v.is_a?(Symbol)
30
+ @name = v
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,25 @@
1
+ require 'yaml'
2
+ require_relative 'environment'
3
+
4
+ module Config
5
+ module Factory
6
+ module Environments
7
+ DEFAULT_ENVIRONMENT = :production
8
+ STANDARD_ENVIRONMENTS = [:defaults, :development, :test, :stage, :staging, :production].freeze
9
+ STANDARD_ENVIRONMENTS_NOT_FOUND = "No standard environment tags (#{STANDARD_ENVIRONMENTS.join(', ')}) found; is this really a multiple-environment configuration?"
10
+
11
+ def self.load_file(path)
12
+ hash = YAML.load_file(path)
13
+ load_hash(hash)
14
+ end
15
+
16
+ def self.load_hash(hash)
17
+ warn STANDARD_ENVIRONMENTS_NOT_FOUND unless STANDARD_ENVIRONMENTS.any? { |k| hash.key?(k.to_s) }
18
+ hash.map do |k, v|
19
+ k2 = k.to_sym
20
+ [k2, Environment.new(name: k2, configs: v)]
21
+ end.to_h
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,35 @@
1
+ require 'logger'
2
+
3
+ module Config
4
+ module Factory
5
+
6
+ class << self
7
+ attr_writer :log
8
+ end
9
+
10
+ # Gets the logger for the module. Default logger logs to `$stdout`.
11
+ # @return [Logger] the logger
12
+ def self.log
13
+ self.log_device = $stdout unless @log
14
+ @log
15
+ end
16
+
17
+ # Sets the log device. Defaults to `$stdout`
18
+ # @param value [IO] the log device
19
+ def self.log_device=(value)
20
+ @log = new_logger(logdev: value)
21
+ end
22
+
23
+ private
24
+
25
+ def self.new_logger(logdev:, level: Logger::DEBUG, shift_age: 10, shift_size: 1024 * 1024)
26
+ logger = Logger.new(logdev, shift_age, shift_size)
27
+ logger.level = level
28
+ logger.formatter = proc do |severity, datetime, progname, msg|
29
+ "#{datetime.to_time.utc} #{severity} -#{progname}- #{msg}\n"
30
+ end
31
+ logger
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,12 @@
1
+ module Config
2
+ module Factory
3
+ # The name of this gem
4
+ NAME = 'config-factory'
5
+
6
+ # The version of this gem
7
+ VERSION = '0.0.1'
8
+
9
+ # The copyright notice for this gem
10
+ COPYRIGHT = 'Copyright (c) 2015 The Regents of the University of California'
11
+ end
12
+ end
@@ -0,0 +1,7 @@
1
+ inherit_from: ../.rubocop.yml
2
+
3
+ Metrics/MethodLength:
4
+ Enabled: false
5
+
6
+ Metrics/ModuleLength:
7
+ Enabled: false
@@ -0,0 +1,52 @@
1
+ defaults: &defaults
2
+ source:
3
+ protocol: OAI
4
+ oai_base_url: http://oai.example.org/oai
5
+ metadata_prefix: some_prefix
6
+ set: some_set
7
+ seconds_granularity: true
8
+ index:
9
+ adapter: solr
10
+ url: http://solr.example.org/
11
+ proxy: http://foo:bar@proxy.example.com/
12
+ open_timeout: 120
13
+ read_timeout: 300
14
+
15
+ development:
16
+ <<: *defaults
17
+ db:
18
+ adapter: mysql2
19
+ encoding: utf8
20
+ pool: 5
21
+ database: example_pord
22
+ host: mysql-dev.example.org
23
+ port: 3306
24
+ index:
25
+ adapter: solr
26
+ url: http://solr-dev.example.org/
27
+ proxy: http://foo:bar@proxy.example.com/
28
+ open_timeout: 120
29
+ read_timeout: 300
30
+
31
+ test:
32
+ db:
33
+ adapter: sqlite3
34
+ database: ':memory:'
35
+ pool: 5
36
+ timeout: 5000
37
+ source:
38
+ protocol: Resync
39
+ capability_list_url: http://localhost:8888/capabilitylist.xml
40
+ index:
41
+ adapter: solr
42
+ url: http://localhost:8000/solr/
43
+
44
+ production:
45
+ <<: *defaults
46
+ db:
47
+ adapter: mysql2
48
+ encoding: utf8
49
+ pool: 5
50
+ database: example_pord
51
+ host: mysql.example.org
52
+ port: 3306
@@ -0,0 +1,19 @@
1
+ db:
2
+ adapter: mysql2
3
+ encoding: utf8
4
+ pool: 5
5
+ database: example_pord
6
+ host: mysql-dev.example.org
7
+ port: 3306
8
+ source:
9
+ protocol: OAI
10
+ oai_base_url: http://oai.example.org/oai
11
+ metadata_prefix: some_prefix
12
+ set: some_set
13
+ seconds_granularity: true
14
+ index:
15
+ adapter: solr
16
+ url: http://solr.example.org/
17
+ proxy: http://foo:bar@proxy.example.com/
18
+ open_timeout: 120
19
+ read_timeout: 300
@@ -0,0 +1,29 @@
1
+ # ------------------------------------------------------------
2
+ # SimpleCov setup
3
+
4
+ if ENV['COVERAGE']
5
+ require 'simplecov'
6
+ require 'simplecov-console'
7
+
8
+ SimpleCov.minimum_coverage 100
9
+ SimpleCov.start do
10
+ add_filter '/spec/'
11
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
12
+ SimpleCov::Formatter::HTMLFormatter,
13
+ SimpleCov::Formatter::Console,
14
+ ]
15
+ end
16
+ end
17
+
18
+ # ------------------------------------------------------------
19
+ # Rspec configuration
20
+
21
+ RSpec.configure do |config|
22
+ config.raise_errors_for_deprecations!
23
+ config.mock_with :rspec
24
+ end
25
+
26
+ # ------------------------------------------------------------
27
+ # Config::Factory
28
+
29
+ require 'config/factory'
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+ require_relative 'fixtures'
3
+
4
+ module Config
5
+ module Factory
6
+ describe AbstractFactory do
7
+ describe '#build_from' do
8
+ it 'builds the correct class with the correct config' do
9
+ config_hash = { protocol: 'OAI', oai_base_url: 'http://oai.example.org/oai', metadata_prefix: 'some_prefix', set: 'some_set', seconds_granularity: true }
10
+ product = SourceConfig.build_from(config_hash)
11
+ expect(product).to be_an(OAISourceConfig)
12
+ args = { oai_base_url: URI('http://oai.example.org/oai'), metadata_prefix: 'some_prefix', set: 'some_set', seconds_granularity: true }
13
+ args.each do |k, v|
14
+ expect(product.send(k)).to eq(v)
15
+ end
16
+ end
17
+
18
+ it 'raises a sensible exception if no product found for the key' do
19
+ config_hash = { protocol: 'Elvis' }
20
+ expect { SourceConfig.build_from(config_hash) }.to raise_error(ArgumentError, /SourceConfig.*protocol.*Elvis/)
21
+ end
22
+ end
23
+
24
+ describe '#for_environment' do
25
+ it 'builds the correct class with the correct config' do
26
+ config_hash = { protocol: 'OAI', oai_base_url: 'http://oai.example.org/oai', metadata_prefix: 'some_prefix', set: 'some_set', seconds_granularity: true }
27
+ env = instance_double(Environment)
28
+ expect(env).to receive(:args_for).with(:source) { config_hash }
29
+
30
+ product = SourceConfig.for_environment(env, :source)
31
+ expect(product).to be_an(OAISourceConfig)
32
+ args = { oai_base_url: URI('http://oai.example.org/oai'), metadata_prefix: 'some_prefix', set: 'some_set', seconds_granularity: true }
33
+ args.each do |k, v|
34
+ expect(product.send(k)).to eq(v)
35
+ end
36
+ end
37
+
38
+ it 'raises a sensible exception if no product found for the key' do
39
+ config_hash = { protocol: 'Elvis' }
40
+ env = instance_double(Environment)
41
+ expect(env).to receive(:args_for).with(:source) { config_hash }
42
+ expect { SourceConfig.for_environment(env, :source) }.to raise_error(ArgumentError, /SourceConfig.*protocol.*Elvis/)
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+ require_relative 'fixtures'
3
+
4
+ module Config
5
+ module Factory
6
+ describe Environment do
7
+ describe '#new' do
8
+ it 'sets the name' do
9
+ env = Environment.new(name: :name, configs: {})
10
+ expect(env.name).to eq(:name)
11
+ end
12
+ it 'requires a name' do
13
+ expect { Environment.new(name: nil, configs: {}) }.to raise_error(ArgumentError)
14
+ end
15
+ it 'requires a symbol name' do
16
+ expect { Environment.new(name: 'name', configs: {}) }.to raise_error(ArgumentError)
17
+ end
18
+ it 'registers the configurations' do
19
+ yaml_hash = YAML.load_file('spec/data/single-environment.yml')
20
+ env = Environment.new(name: :test, configs: yaml_hash)
21
+ %w(db source index).each do |key|
22
+ expect(env.args_for(key)).to eq(yaml_hash[key])
23
+ end
24
+ end
25
+ end
26
+
27
+ describe '#load_file' do
28
+ it 'loads a single-environment config file' do
29
+ env = Environment.load_file('spec/data/single-environment.yml')
30
+ expect(env).to be_an(Environment)
31
+ expect(env.name).to eq(Environments::DEFAULT_ENVIRONMENT)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ module Config
4
+ module Factory
5
+ module Environments
6
+ describe '#load_file' do
7
+ it 'loads a multi-environment config file' do
8
+ envs = Environments.load_file('spec/data/multiple-environments.yml')
9
+ expect(envs).to be_a(Hash)
10
+ expect(envs.size).to eq(4)
11
+ [:defaults, :development, :test, :production].each do |env_name|
12
+ env = envs[env_name]
13
+ expect(env).to be_an(Environment)
14
+ expect(env.name).to eq(env_name)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,73 @@
1
+ require 'config/factory'
2
+ require 'uri'
3
+
4
+ class SourceConfig
5
+ include Config::Factory
6
+
7
+ key :protocol
8
+
9
+ attr_reader :source_uri
10
+
11
+ def initialize(source_url:)
12
+ @source_uri = URI(source_url)
13
+ end
14
+ end
15
+
16
+ class OAISourceConfig < SourceConfig
17
+ protocol 'OAI'
18
+
19
+ attr_reader :oai_base_url
20
+ attr_reader :metadata_prefix
21
+ attr_reader :set
22
+ attr_reader :seconds_granularity
23
+
24
+ def initialize(oai_base_url:, metadata_prefix:, set: nil, seconds_granularity: false)
25
+ super(source_url: oai_base_url)
26
+ @oai_base_url = source_uri
27
+ @metadata_prefix = metadata_prefix
28
+ @set = set
29
+ @seconds_granularity = seconds_granularity
30
+ end
31
+ end
32
+
33
+ class ResyncSourceConfig < SourceConfig
34
+ protocol 'Resync'
35
+
36
+ attr_reader :capability_list_url
37
+
38
+ def initialize(capability_list_url:)
39
+ super(url: capability_list_url)
40
+ @capability_list_url = source_uri
41
+ end
42
+ end
43
+
44
+ # IndexConfig
45
+
46
+ class IndexConfig
47
+ include Config::Factory
48
+
49
+ key :adapter
50
+
51
+ attr_reader :uri
52
+
53
+ def initialize(url:)
54
+ @uri = URI(url)
55
+ end
56
+ end
57
+
58
+ class SolrConfig < IndexConfig
59
+ adapter 'Solr'
60
+
61
+ attr_reader :url
62
+ attr_reader :proxy
63
+ attr_reader :open_timeout
64
+ attr_reader :read_timeout
65
+
66
+ def initialize(url:, proxy: nil, open_timeout: 60, read_timeout: 120)
67
+ super(url: url)
68
+ @url = uri
69
+ @proxy = proxy
70
+ @open_timeout = open_timeout
71
+ @read_timeout = read_timeout
72
+ end
73
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ module Config
4
+ module Factory
5
+ describe 'log' do
6
+ it 'logs to stdout in a timestamp-first format' do
7
+ out = StringIO.new
8
+ Factory.log_device = out
9
+ begin
10
+ msg = 'I am a log message'
11
+ Factory.log.warn(msg)
12
+ logged = out.string
13
+ expect(logged).to include(msg)
14
+ timestamp_str = logged.split[0]
15
+ timestamp = DateTime.parse(timestamp_str)
16
+ expect(timestamp.to_date).to eq(Time.now.utc.to_date)
17
+ ensure
18
+ Factory.log_device = $stdout
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
metadata ADDED
@@ -0,0 +1,164 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: config-factory
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - David Moles
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-01-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.4'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.2'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.2'
55
+ - !ruby/object:Gem::Dependency
56
+ name: simplecov
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.9.2
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.9.2
69
+ - !ruby/object:Gem::Dependency
70
+ name: simplecov-console
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.2.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.2.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.35.1
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.35.1
97
+ description: A gem for creating configuration classes using the Abstract Factory pattern,
98
+ with run-time configuration provided by hashes or YAML files.
99
+ email:
100
+ - david.moles@ucop.edu
101
+ executables: []
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - ".gitignore"
106
+ - ".rubocop.yml"
107
+ - ".ruby-version"
108
+ - ".travis.yml"
109
+ - Gemfile
110
+ - LICENSE.md
111
+ - README.md
112
+ - Rakefile
113
+ - config-factory.gemspec
114
+ - example.rb
115
+ - lib/config/factory.rb
116
+ - lib/config/factory/abstract_factory.rb
117
+ - lib/config/factory/environment.rb
118
+ - lib/config/factory/environments.rb
119
+ - lib/config/factory/log.rb
120
+ - lib/config/factory/module_info.rb
121
+ - spec/.rubocop.yml
122
+ - spec/data/multiple-environments.yml
123
+ - spec/data/single-environment.yml
124
+ - spec/spec_helper.rb
125
+ - spec/unit/config/factory/abstract_factory_spec.rb
126
+ - spec/unit/config/factory/environment_spec.rb
127
+ - spec/unit/config/factory/environments_spec.rb
128
+ - spec/unit/config/factory/fixtures.rb
129
+ - spec/unit/config/factory/log_spec.rb
130
+ homepage: http://github.com/dmolesUC3/config-factory
131
+ licenses:
132
+ - MIT
133
+ metadata: {}
134
+ post_install_message:
135
+ rdoc_options: []
136
+ require_paths:
137
+ - lib
138
+ required_ruby_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ required_rubygems_version: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: '0'
148
+ requirements: []
149
+ rubyforge_project:
150
+ rubygems_version: 2.4.5.1
151
+ signing_key:
152
+ specification_version: 4
153
+ summary: A gem for creating configuration classes using the Abstract Factory pattern.
154
+ test_files:
155
+ - spec/.rubocop.yml
156
+ - spec/data/multiple-environments.yml
157
+ - spec/data/single-environment.yml
158
+ - spec/spec_helper.rb
159
+ - spec/unit/config/factory/abstract_factory_spec.rb
160
+ - spec/unit/config/factory/environment_spec.rb
161
+ - spec/unit/config/factory/environments_spec.rb
162
+ - spec/unit/config/factory/fixtures.rb
163
+ - spec/unit/config/factory/log_spec.rb
164
+ has_rdoc: