a9n 0.4.10 → 0.4.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +1 -1
- data/Gemfile +0 -3
- data/a9n.gemspec +5 -2
- data/lib/a9n.rb +24 -21
- data/lib/a9n/exceptions.rb +7 -0
- data/lib/a9n/ext/hash.rb +1 -1
- data/lib/a9n/loader.rb +3 -5
- data/lib/a9n/scope.rb +4 -4
- data/lib/a9n/struct.rb +1 -1
- data/lib/a9n/version.rb +1 -1
- data/spec/spec_helper.rb +72 -4
- data/spec/unit/a9n_spec.rb +14 -14
- data/spec/unit/scope_spec.rb +2 -2
- metadata +47 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c71a89a1074cdf639fc076b8270d1492bda0fb92
|
4
|
+
data.tar.gz: 982f8eb998d9bd89f2942bc6fa1ee77b6e0f16a3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1122f4218143bfb287cf5d3203eebfa5a935bcd19d8cec8acbb4944d7af4f8eedf2578022f1f2d97f00bcb1f032ed7a27a45bb992b74e831a51cdcf07c533b9d
|
7
|
+
data.tar.gz: 2384c6aafc3e68c25acf4f8f0f51d59b61cd5094a3693e4412d98de7ce14bcd423587f81ccbaa274ad982fe9ce376b52b847cb9d826aeabb97d1d2c55ed24a10
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/a9n.gemspec
CHANGED
@@ -1,9 +1,8 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
require File.expand_path('../lib/a9n/version', __FILE__)
|
3
2
|
|
4
3
|
Gem::Specification.new do |gem|
|
5
4
|
gem.authors = ["Krzysztof Knapik"]
|
6
|
-
gem.email = ["
|
5
|
+
gem.email = ["knapo@knapo.net"]
|
7
6
|
gem.description = %q{a9n - ruby/rails apps configuration manager}
|
8
7
|
gem.summary = %q{a9n is a tool to keep ruby/rails apps extra configuration easily maintainable and verifiable}
|
9
8
|
gem.homepage = "https://github.com/knapo/a9n"
|
@@ -16,4 +15,8 @@ Gem::Specification.new do |gem|
|
|
16
15
|
gem.version = A9n::VERSION
|
17
16
|
|
18
17
|
gem.required_ruby_version = ">= 2.0"
|
18
|
+
|
19
|
+
gem.add_development_dependency 'rake', '~> 11.3'
|
20
|
+
gem.add_development_dependency 'rspec', '~> 3.5'
|
21
|
+
gem.add_development_dependency 'codeclimate-test-reporter', '~> 0.6'
|
19
22
|
end
|
data/lib/a9n.rb
CHANGED
@@ -1,25 +1,21 @@
|
|
1
|
+
require "ostruct"
|
2
|
+
require "yaml"
|
3
|
+
require "erb"
|
1
4
|
require "a9n/version"
|
5
|
+
require "a9n/exceptions"
|
2
6
|
require "a9n/struct"
|
3
7
|
require "a9n/scope"
|
4
8
|
require "a9n/ext/hash"
|
5
9
|
require "a9n/loader"
|
6
|
-
require "yaml"
|
7
|
-
require "erb"
|
8
10
|
|
9
11
|
module A9n
|
10
12
|
extend SingleForwardable
|
11
13
|
|
12
|
-
class ConfigurationNotLoadedError < StandardError; end
|
13
|
-
class MissingConfigurationDataError < StandardError; end
|
14
|
-
class MissingConfigurationVariablesError < StandardError; end
|
15
|
-
class NoSuchConfigurationVariableError < StandardError; end
|
16
|
-
class MissingEnvVariableError < StandardError; end
|
17
|
-
|
18
14
|
EXTENSION_LIST = "{yml,yml.erb,yml.example,yml.erb.example}"
|
19
15
|
|
20
16
|
class << self
|
21
17
|
def env
|
22
|
-
@env ||= app_env ||
|
18
|
+
@env ||= app_env || env_var("RAILS_ENV") || env_var("RACK_ENV") || env_var("APP_ENV")
|
23
19
|
end
|
24
20
|
|
25
21
|
def app_env
|
@@ -27,7 +23,7 @@ module A9n
|
|
27
23
|
end
|
28
24
|
|
29
25
|
def app
|
30
|
-
@app ||=
|
26
|
+
@app ||= rails_app
|
31
27
|
end
|
32
28
|
|
33
29
|
def app=(app_instance)
|
@@ -46,24 +42,24 @@ module A9n
|
|
46
42
|
@root = path.to_s.empty? ? nil : Pathname.new(path.to_s)
|
47
43
|
end
|
48
44
|
|
49
|
-
def
|
45
|
+
def rails_app
|
50
46
|
defined?(Rails) ? Rails : nil
|
51
47
|
end
|
52
48
|
|
53
|
-
def
|
54
|
-
|
49
|
+
def env_var(name, strict: false)
|
50
|
+
fail A9n::MissingEnvVariableError.new(name) if strict && !ENV.key?(name)
|
55
51
|
ENV[name]
|
56
52
|
end
|
57
53
|
|
58
54
|
def default_files
|
59
|
-
files = Dir[root.join("config/#{A9n::Scope::
|
55
|
+
files = Dir[root.join("config/#{A9n::Scope::ROOT_NAME}.#{EXTENSION_LIST}").to_s]
|
60
56
|
files += Dir[root.join("config/a9n/*.#{EXTENSION_LIST}")]
|
61
57
|
files.map{ |f| f.sub(/.example$/,'') }.uniq
|
62
58
|
end
|
63
59
|
|
64
60
|
def load(*files)
|
65
61
|
require_local_extension
|
66
|
-
files = files.empty? ? default_files :
|
62
|
+
files = files.empty? ? default_files : absolute_paths_for(files)
|
67
63
|
files.map { |file| load_file(file) }
|
68
64
|
end
|
69
65
|
|
@@ -85,26 +81,33 @@ module A9n
|
|
85
81
|
end
|
86
82
|
|
87
83
|
def setup_scope(scope, data)
|
88
|
-
if scope.
|
84
|
+
if scope.root?
|
89
85
|
storage.merge(data)
|
90
|
-
|
91
|
-
|
86
|
+
safe_def_delegator :storage, :fetch
|
87
|
+
safe_def_delegator :storage, *data.keys
|
92
88
|
else
|
93
89
|
storage[scope.name] = data
|
94
|
-
|
90
|
+
safe_def_delegator :storage, scope.name
|
95
91
|
end
|
96
92
|
return data
|
97
93
|
end
|
98
94
|
|
99
|
-
def
|
95
|
+
def absolute_paths_for(files)
|
100
96
|
files.map { |file| Pathname.new(file).absolute? ? file : self.root.join('config', file).to_s }
|
101
97
|
end
|
102
98
|
|
103
99
|
def require_local_extension
|
104
100
|
return if app.nil? || root.nil?
|
105
101
|
local_extension_file = File.join(root, "config/a9n.rb")
|
106
|
-
return unless File.
|
102
|
+
return unless File.exist?(local_extension_file)
|
107
103
|
require local_extension_file
|
108
104
|
end
|
105
|
+
|
106
|
+
def safe_def_delegator(target, *names)
|
107
|
+
names.each do |name|
|
108
|
+
next if respond_to?(name)
|
109
|
+
def_delegator :storage, name
|
110
|
+
end
|
111
|
+
end
|
109
112
|
end
|
110
113
|
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
module A9n
|
2
|
+
class ConfigurationNotLoadedError < StandardError; end
|
3
|
+
class MissingConfigurationDataError < StandardError; end
|
4
|
+
class MissingConfigurationVariablesError < StandardError; end
|
5
|
+
class NoSuchConfigurationVariableError < StandardError; end
|
6
|
+
class MissingEnvVariableError < StandardError; end
|
7
|
+
end
|
data/lib/a9n/ext/hash.rb
CHANGED
data/lib/a9n/loader.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'ostruct'
|
2
|
-
|
3
1
|
module A9n
|
4
2
|
class Loader
|
5
3
|
attr_reader :scope, :env, :local_file, :example_file
|
@@ -22,7 +20,7 @@ module A9n
|
|
22
20
|
example_config = self.class.load_yml(example_file, scope, env)
|
23
21
|
|
24
22
|
if local_config.nil? && example_config.nil?
|
25
|
-
|
23
|
+
fail A9n::MissingConfigurationDataError.new("Configuration data for *#{env}* env was not found in neither *#{example_file}* nor *#{local_file}*")
|
26
24
|
end
|
27
25
|
|
28
26
|
if !local_config.nil? && !example_config.nil?
|
@@ -34,7 +32,7 @@ module A9n
|
|
34
32
|
|
35
33
|
class << self
|
36
34
|
def load_yml(file_path, scope, env)
|
37
|
-
return nil unless File.
|
35
|
+
return nil unless File.exist?(file_path)
|
38
36
|
yml = YAML.load(ERB.new(File.read(file_path)).result)
|
39
37
|
|
40
38
|
common_scope = prepare_yml_scope(yml, scope, COMMON_SCOPE)
|
@@ -57,7 +55,7 @@ module A9n
|
|
57
55
|
def verify!(local, example)
|
58
56
|
missing_keys = example.keys - local.keys
|
59
57
|
if missing_keys.any?
|
60
|
-
|
58
|
+
fail A9n::MissingConfigurationVariablesError.new("Following variables are missing in #{local_file} file: #{missing_keys.join(',')}")
|
61
59
|
end
|
62
60
|
end
|
63
61
|
end
|
data/lib/a9n/scope.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module A9n
|
2
2
|
class Scope
|
3
|
-
|
3
|
+
ROOT_NAME = :configuration
|
4
4
|
|
5
5
|
attr_reader :name
|
6
6
|
|
@@ -8,12 +8,12 @@ module A9n
|
|
8
8
|
@name = name.to_sym
|
9
9
|
end
|
10
10
|
|
11
|
-
def
|
12
|
-
name ==
|
11
|
+
def root?
|
12
|
+
name == ROOT_NAME
|
13
13
|
end
|
14
14
|
|
15
15
|
def env_key_name(key)
|
16
|
-
(
|
16
|
+
(root? ? key : "#{name}_#{key}").upcase
|
17
17
|
end
|
18
18
|
|
19
19
|
def self.form_file_path(path)
|
data/lib/a9n/struct.rb
CHANGED
data/lib/a9n/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -9,18 +9,85 @@ require "bundler/setup"
|
|
9
9
|
require "a9n"
|
10
10
|
|
11
11
|
RSpec.configure do |config|
|
12
|
-
config.
|
13
|
-
|
12
|
+
# rspec-expectations config goes here. You can use an alternate
|
13
|
+
# assertion/expectation library such as wrong or the stdlib/minitest
|
14
|
+
# assertions if you prefer.
|
14
15
|
config.expect_with :rspec do |expectations|
|
16
|
+
# This option will default to `true` in RSpec 4. It makes the `description`
|
17
|
+
# and `failure_message` of custom matchers include text for helper methods
|
18
|
+
# defined using `chain`, e.g.:
|
19
|
+
# be_bigger_than(2).and_smaller_than(4).description
|
20
|
+
# # => "be bigger than 2 and smaller than 4"
|
21
|
+
# ...rather than:
|
22
|
+
# # => "be bigger than 2"
|
15
23
|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
16
24
|
end
|
17
25
|
|
26
|
+
# rspec-mocks config goes here. You can use an alternate test double
|
27
|
+
# library (such as bogus or mocha) by changing the `mock_with` option here.
|
18
28
|
config.mock_with :rspec do |mocks|
|
29
|
+
# Prevents you from mocking or stubbing a method that does not exist on
|
30
|
+
# a real object. This is generally recommended, and will default to
|
31
|
+
# `true` in RSpec 4.
|
19
32
|
mocks.verify_partial_doubles = true
|
20
33
|
end
|
21
34
|
|
22
|
-
|
23
|
-
|
35
|
+
# This option will default to `:apply_to_host_groups` in RSpec 4 (and will
|
36
|
+
# have no way to turn it off -- the option exists only for backwards
|
37
|
+
# compatibility in RSpec 3). It causes shared context metadata to be
|
38
|
+
# inherited by the metadata hash of host groups and examples, rather than
|
39
|
+
# triggering implicit auto-inclusion in groups with matching metadata.
|
40
|
+
config.shared_context_metadata_behavior = :apply_to_host_groups
|
41
|
+
|
42
|
+
# This allows you to limit a spec run to individual examples or groups
|
43
|
+
# you care about by tagging them with `:focus` metadata. When nothing
|
44
|
+
# is tagged with `:focus`, all examples get run. RSpec also provides
|
45
|
+
# aliases for `it`, `describe`, and `context` that include `:focus`
|
46
|
+
# metadata: `fit`, `fdescribe` and `fcontext`, respectively.
|
47
|
+
config.filter_run_when_matching :focus
|
48
|
+
|
49
|
+
# Allows RSpec to persist some state between runs in order to support
|
50
|
+
# the `--only-failures` and `--next-failure` CLI options. We recommend
|
51
|
+
# you configure your source control system to ignore this file.
|
52
|
+
config.example_status_persistence_file_path = "spec/examples.txt"
|
53
|
+
|
54
|
+
# Limits the available syntax to the non-monkey patched syntax that is
|
55
|
+
# recommended. For more details, see:
|
56
|
+
# - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
|
57
|
+
# - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
58
|
+
# - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
|
59
|
+
config.disable_monkey_patching!
|
60
|
+
|
61
|
+
# This setting enables warnings. It's recommended, but in some cases may
|
62
|
+
# be too noisy due to issues in dependencies.
|
63
|
+
config.warnings = true
|
64
|
+
|
65
|
+
# Many RSpec users commonly either run the entire suite or an individual
|
66
|
+
# file, and it's useful to allow more verbose output when running an
|
67
|
+
# individual spec file.
|
68
|
+
# if config.files_to_run.one?
|
69
|
+
# # Use the documentation formatter for detailed output,
|
70
|
+
# # unless a formatter has already been configured
|
71
|
+
# # (e.g. via a command-line flag).
|
72
|
+
# config.default_formatter = 'doc'
|
73
|
+
# end
|
74
|
+
|
75
|
+
# Print the 10 slowest examples and example groups at the
|
76
|
+
# end of the spec run, to help surface which specs are running
|
77
|
+
# particularly slow.
|
78
|
+
config.profile_examples = 10
|
79
|
+
|
80
|
+
# Run specs in random order to surface order dependencies. If you find an
|
81
|
+
# order dependency and want to debug it, you can fix the order by providing
|
82
|
+
# the seed, which is printed after each run.
|
83
|
+
# --seed 1234
|
84
|
+
config.order = :random
|
85
|
+
|
86
|
+
# Seed global randomization in this process using the `--seed` CLI option.
|
87
|
+
# Setting this allows you to use `--seed` to deterministically reproduce
|
88
|
+
# test failures related to randomization by passing the same `--seed` value
|
89
|
+
# as the one that triggered the failure.
|
90
|
+
Kernel.srand config.seed
|
24
91
|
end
|
25
92
|
|
26
93
|
def clean_singleton(klass)
|
@@ -30,3 +97,4 @@ def clean_singleton(klass)
|
|
30
97
|
end
|
31
98
|
end
|
32
99
|
end
|
100
|
+
|
data/spec/unit/a9n_spec.rb
CHANGED
@@ -11,7 +11,7 @@ RSpec.describe A9n do
|
|
11
11
|
context "app_env is set" do
|
12
12
|
before do
|
13
13
|
expect(subject).to receive(:app).and_return(double(env: "dwarf_env")).exactly(3).times
|
14
|
-
expect(subject).to receive(:
|
14
|
+
expect(subject).to receive(:env_var).never
|
15
15
|
end
|
16
16
|
|
17
17
|
it do
|
@@ -22,9 +22,9 @@ RSpec.describe A9n do
|
|
22
22
|
context "when APP_ENV is set" do
|
23
23
|
before do
|
24
24
|
expect(subject).to receive(:app_env).and_return(nil)
|
25
|
-
expect(subject).to receive(:
|
26
|
-
expect(subject).to receive(:
|
27
|
-
expect(subject).to receive(:
|
25
|
+
expect(subject).to receive(:env_var).with("RAILS_ENV").and_return(nil)
|
26
|
+
expect(subject).to receive(:env_var).with("RACK_ENV").and_return(nil)
|
27
|
+
expect(subject).to receive(:env_var).with("APP_ENV").and_return("dwarf_env")
|
28
28
|
end
|
29
29
|
|
30
30
|
it do
|
@@ -36,7 +36,7 @@ RSpec.describe A9n do
|
|
36
36
|
describe ".app" do
|
37
37
|
context "when rails not found" do
|
38
38
|
before do
|
39
|
-
expect(subject).to receive(:
|
39
|
+
expect(subject).to receive(:rails_app).and_return(nil)
|
40
40
|
end
|
41
41
|
|
42
42
|
it do
|
@@ -48,7 +48,7 @@ RSpec.describe A9n do
|
|
48
48
|
let(:app) { double(env: "test", root: "/apps/a9n") }
|
49
49
|
|
50
50
|
before do
|
51
|
-
expect(subject).to receive(:
|
51
|
+
expect(subject).to receive(:rails_app).and_return(app)
|
52
52
|
end
|
53
53
|
|
54
54
|
it do
|
@@ -121,7 +121,7 @@ RSpec.describe A9n do
|
|
121
121
|
end
|
122
122
|
end
|
123
123
|
|
124
|
-
describe ".
|
124
|
+
describe ".rails_app" do
|
125
125
|
context "when defined" do
|
126
126
|
before do
|
127
127
|
Object.const_set(:Rails, Module.new)
|
@@ -132,28 +132,28 @@ RSpec.describe A9n do
|
|
132
132
|
end
|
133
133
|
|
134
134
|
it do
|
135
|
-
expect(subject.
|
135
|
+
expect(subject.rails_app).to be_kind_of(Module)
|
136
136
|
end
|
137
137
|
end
|
138
138
|
|
139
139
|
context "when not defined" do
|
140
140
|
it do
|
141
|
-
expect(subject.
|
141
|
+
expect(subject.rails_app).to be_nil
|
142
142
|
end
|
143
143
|
end
|
144
144
|
end
|
145
145
|
|
146
|
-
describe ".
|
146
|
+
describe ".env_var" do
|
147
147
|
before do
|
148
148
|
ENV["DWARF"] = "little dwarf"
|
149
149
|
end
|
150
150
|
|
151
151
|
it do
|
152
|
-
expect(subject.
|
152
|
+
expect(subject.env_var("DWARF")).to eq("little dwarf")
|
153
153
|
end
|
154
154
|
|
155
155
|
it do
|
156
|
-
expect(subject.
|
156
|
+
expect(subject.env_var("IS_DWARF")).to be_nil
|
157
157
|
end
|
158
158
|
end
|
159
159
|
|
@@ -189,7 +189,7 @@ RSpec.describe A9n do
|
|
189
189
|
|
190
190
|
before do
|
191
191
|
expect(subject).to receive(:default_files).and_return(files.keys)
|
192
|
-
expect(subject).to receive(:
|
192
|
+
expect(subject).to receive(:absolute_paths_for).never
|
193
193
|
end
|
194
194
|
|
195
195
|
it do
|
@@ -211,7 +211,7 @@ RSpec.describe A9n do
|
|
211
211
|
|
212
212
|
before do
|
213
213
|
expect(subject).to receive(:default_files).never
|
214
|
-
expect(subject).to receive(:
|
214
|
+
expect(subject).to receive(:absolute_paths_for).with(given_files).and_call_original
|
215
215
|
end
|
216
216
|
|
217
217
|
it do
|
data/spec/unit/scope_spec.rb
CHANGED
@@ -9,12 +9,12 @@ RSpec.describe A9n::Scope do
|
|
9
9
|
describe "#main?" do
|
10
10
|
context "when name is configuration" do
|
11
11
|
let(:name) { "configuration" }
|
12
|
-
it { expect(subject).to
|
12
|
+
it { expect(subject).to be_root }
|
13
13
|
end
|
14
14
|
|
15
15
|
context "when name is other than configuration" do
|
16
16
|
let(:name) { "mandrill" }
|
17
|
-
it { expect(subject).not_to
|
17
|
+
it { expect(subject).not_to be_root }
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
metadata
CHANGED
@@ -1,18 +1,60 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: a9n
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Krzysztof Knapik
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
12
|
-
dependencies:
|
11
|
+
date: 2016-09-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '11.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '11.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.5'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.5'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: codeclimate-test-reporter
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.6'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.6'
|
13
55
|
description: a9n - ruby/rails apps configuration manager
|
14
56
|
email:
|
15
|
-
-
|
57
|
+
- knapo@knapo.net
|
16
58
|
executables: []
|
17
59
|
extensions: []
|
18
60
|
extra_rdoc_files: []
|
@@ -31,6 +73,7 @@ files:
|
|
31
73
|
- lib/a9n/capistrano.rb
|
32
74
|
- lib/a9n/capistrano/tasks.cap
|
33
75
|
- lib/a9n/capistrano/ver2x.rb
|
76
|
+
- lib/a9n/exceptions.rb
|
34
77
|
- lib/a9n/ext/hash.rb
|
35
78
|
- lib/a9n/loader.rb
|
36
79
|
- lib/a9n/scope.rb
|