knowledge 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,107 @@
1
+ # Knowledge
2
+
3
+ Configuration variables are a project's knowledge. This gem is here to help your projects learn what they need to work properly.
4
+
5
+ ## Disclaimer
6
+
7
+ The full documentation is currently being written. You should be able to find a better documentation in a few hours.
8
+
9
+ Waiting for the full documentation, you can have a look at the code which is already well-documented.
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ ```ruby
16
+ gem 'knowledge'
17
+ ```
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ Or install it yourself as:
24
+
25
+ $ gem install knowledge
26
+
27
+ ## Usage
28
+
29
+ Documentation is in progress. Please have a look to the [wiki](https://github.com/knowledge-ruby/knowledge/wiki/).
30
+
31
+ **Using default stuff**:
32
+
33
+ ```ruby
34
+ knowledge = Knowledge::Learner.new
35
+
36
+ knowledge.use(name: :default)
37
+ knowledge.variables = { key: :value }
38
+ knowledge.gather!
39
+
40
+ Knowledge::Configuration.key # => "value"
41
+ ```
42
+
43
+ **Using your own setter**:
44
+
45
+ ```ruby
46
+ #
47
+ # === Description ===
48
+ #
49
+ # Sets config variables in Rails.application.config
50
+ #
51
+ # === Usage ===
52
+ #
53
+ # @example:
54
+ # setter = MyCustomRailsSetter.new
55
+ # setter.set(name: :foo, value: :bar)
56
+ #
57
+ # Rails.application.config.foo # => "bar"
58
+ #
59
+ class MyCustomRailsSetter
60
+ #
61
+ # === Description ===
62
+ #
63
+ # Sets config variables in the right place.
64
+ #
65
+ # === Usage ===
66
+ #
67
+ # See the same section in the class description.
68
+ #
69
+ # === Attributes ===
70
+ #
71
+ # @option [String | Symbol] :name
72
+ # @option [Any] :value
73
+ #
74
+ def set(name:, value:)
75
+ Rails.application.config.public_send("#{name}=", value)
76
+ end
77
+ end
78
+
79
+ knowledge = Knowledge::Learner.new
80
+
81
+ knowledge.setter = MyCustomRailsSetter.new
82
+ knowledge.use(name: :default)
83
+ knowledge.variables = { key: :value }
84
+ knowledge.gather!
85
+
86
+ Rails.application.config.key # => "value"
87
+ ```
88
+
89
+ ## Development
90
+
91
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
92
+
93
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
94
+
95
+ ## Contributing
96
+
97
+ Bug reports and pull requests are welcome on GitHub at https://github.com/knowledge-ruby/knowledge. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
98
+
99
+ ## Code of Conduct
100
+
101
+ Everyone interacting in the Knowledge project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/knowledge-ruby/knowledge/blob/master/CODE_OF_CONDUCT.md).
102
+
103
+ ## Licensing
104
+
105
+ This project is licensed under [GPLv3+](https://www.gnu.org/licenses/gpl-3.0.en.html).
106
+
107
+ You can find it in LICENSE.md file.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'knowledge'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require 'irb'
15
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/knowledge.gemspec ADDED
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'knowledge/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'knowledge'
9
+ spec.version = Knowledge::VERSION
10
+ spec.authors = ['Johann Wilfrid-Calixte']
11
+ spec.email = ['johann.open-source@protonmail.ch']
12
+
13
+ spec.licenses = ['GPL-3.0']
14
+
15
+ spec.summary = "Because configuration is your app's knowledge."
16
+ spec.description = 'Easy knowledge for yout project.'
17
+ spec.homepage = 'https://github.com/knowledge-ruby/knowledge'
18
+
19
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
20
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
21
+ if spec.respond_to?(:metadata)
22
+ # spec.metadata['allowed_push_host'] = 'https://johann.wilfrid-calixte.fr'
23
+
24
+ spec.metadata['homepage_uri'] = spec.homepage
25
+ spec.metadata['source_code_uri'] = 'https://github.com/knowledge-ruby/knowledge'
26
+ spec.metadata['changelog_uri'] = 'https://github.com/knowledge-ruby/knowledge/blob/master/CHANGELOG.md'
27
+ else
28
+ raise 'RubyGems 2.0 or newer is required to protect against ' \
29
+ 'public gem pushes.'
30
+ end
31
+
32
+ # Specify which files should be added to the gem when it is released.
33
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
34
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
35
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
36
+ end
37
+ spec.bindir = 'exe'
38
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
39
+ spec.require_paths = ['lib']
40
+
41
+ spec.add_dependency 'dry-configurable', '~> 0.7'
42
+
43
+ spec.add_development_dependency 'bundler', '~> 1.16'
44
+ spec.add_development_dependency 'pry', '>= 0.12'
45
+ spec.add_development_dependency 'rake', '~> 10.0'
46
+ spec.add_development_dependency 'rspec', '~> 3.0'
47
+ spec.add_development_dependency 'rubocop', '>= 0.60'
48
+ spec.add_development_dependency 'simplecov'
49
+ end
data/lib/knowledge.rb ADDED
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dry-configurable'
4
+
5
+ require 'knowledge/version'
6
+ require 'knowledge/exceptions'
7
+ require 'knowledge/learner'
8
+
9
+ #
10
+ # === Description ===
11
+ #
12
+ # Configuration is your project's knowledge, let's make it very simple!
13
+ #
14
+ # === Configuration ===
15
+ #
16
+ # Funny but quite normal, this gem needs some config.
17
+ # If you're familiar with dry-configurable, it should be very understandable for you.
18
+ # If not, it's still simple.
19
+ #
20
+ # You can configure it one by one or all at once:
21
+ #
22
+ # @example:
23
+ #
24
+ # Knowledge.config.environment = ENV['RACK_ENV'] || Rails.env || ENV['APP_ENV'] # Or whatever you want
25
+ #
26
+ # Knowledge.configure do |config|
27
+ # config.environment = ENV['RACK_ENV'] || Rails.env || ENV['APP_ENV'] # Or whatever you want
28
+ # end
29
+ #
30
+ # === Usage ===
31
+ #
32
+ # @example:
33
+ # Knowledge.configure do |config|
34
+ # config.environment = :production
35
+ # end
36
+ #
37
+ # # or
38
+ #
39
+ # Knowledge.config.environment = :production
40
+ # learner = Knowledge::Learner.new
41
+ # learner.setter = MyCustomProjectVariableSetter
42
+ # learner.variables = 'path/to/config/file'
43
+ # # or
44
+ # learner.variables = { name: 'value_key' }
45
+ # learner.register_adapter(:custom, MyCustomProjectVariableAdapter, enable: true)
46
+ #
47
+ # learner.gather!
48
+ #
49
+ module Knowledge
50
+ # == Behaviors ===================================================================================================
51
+ extend Dry::Configurable
52
+
53
+ # == Settings ====================================================================================================
54
+ setting :environment, :development
55
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Knowledge
4
+ #
5
+ # === Description ===
6
+ #
7
+ # This is the namespace used to put the lib's adapters.
8
+ # You can find the adapters by looking to the inclusions below or to the adapters folder.
9
+ #
10
+ module Adapters
11
+ end
12
+ end
13
+
14
+ require 'knowledge/adapters/base'
15
+ require 'knowledge/adapters/environment'
16
+ require 'knowledge/adapters/key_value'
17
+ require 'knowledge/adapters/file'
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Knowledge
4
+ module Adapters
5
+ #
6
+ # === Description ===
7
+ #
8
+ # This adapter is the base adapter.
9
+ # It does nothing specific but is meant to manage all generic stuff.
10
+ #
11
+ # === Usage ===
12
+ #
13
+ # Just inherit from it
14
+ #
15
+ # === Attributes ===
16
+ #
17
+ # @attr_reader [Class] setter
18
+ # @attr_reader [Hash] variables
19
+ #
20
+ class Base
21
+ # == Attributes ==================================================================================================
22
+ attr_reader :setter, :variables
23
+
24
+ # == Constructor =================================================================================================
25
+ #
26
+ # @option [Hash] :variables
27
+ # @option [Class] :setter
28
+ # @option [Hash] :params
29
+ #
30
+ def initialize(variables:, setter:, params: nil) # rubocop:disable Lint/UnusedMethodArgument
31
+ @variables = variables
32
+ @setter = setter
33
+ end
34
+
35
+ # == Instance Methods ============================================================================================
36
+ #
37
+ # === Description ===
38
+ #
39
+ # Should run the actual adapter.
40
+ # This method is meant to be overriden
41
+ #
42
+ # === Errors ===
43
+ #
44
+ # @raise [Knowledge::AdapterRunMethodNotImplemented] if not overridden by subclasses
45
+ #
46
+ def run
47
+ raise ::Knowledge::AdapterRunMethodNotImplemented, "Please override the #run method for #{self.class}"
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Knowledge
4
+ module Adapters
5
+ #
6
+ # === Description ===
7
+ #
8
+ # This adapter takes some vars in ENV vars and put it in your project's config.
9
+ #
10
+ # === Usage ===
11
+ #
12
+ # @example:
13
+ # adapter = Knowledge::Adapters::Environment.new(setter: MySetter, variables: my_vars)
14
+ #
15
+ # adapter.run
16
+ #
17
+ # === Attributes ===
18
+ #
19
+ # @attr_reader [Class] setter
20
+ # @attr_reader [Hash] variables
21
+ #
22
+ class Environment < Base
23
+ # == Instance Methods ============================================================================================
24
+ #
25
+ # === Description ===
26
+ #
27
+ # Runs the actual adapter.
28
+ #
29
+ def run
30
+ variables.each do |name_in_project, name_in_env|
31
+ setter.set(name: name_in_project, value: ENV[name_in_env.to_s])
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Knowledge
4
+ module Adapters
5
+ #
6
+ # === Description ===
7
+ #
8
+ # This adapter takes some vars in a config file and put it in your project's config.
9
+ # The config file should provide some YAML with key=value format.
10
+ #
11
+ # === Usage ===
12
+ #
13
+ # @example:
14
+ # adapter = Knowledge::Adapters::File.new(setter: MySetter, variables: my_vars)
15
+ #
16
+ # adapter.run
17
+ #
18
+ # === Attributes ===
19
+ #
20
+ # @attr_reader [Class] setter
21
+ # @attr_reader [Hash] variables
22
+ #
23
+ class File < KeyValue; end
24
+ end
25
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Knowledge
4
+ module Adapters
5
+ #
6
+ # === Description ===
7
+ #
8
+ # This adapter takes some vars in a config object and put it in your project's config.
9
+ # The config object should provide a hash with key=value format.
10
+ #
11
+ # === Usage ===
12
+ #
13
+ # @example:
14
+ # adapter = Knowledge::Adapters::KeyValue.new(setter: MySetter, variables: my_vars)
15
+ #
16
+ # adapter.run
17
+ #
18
+ # === Attributes ===
19
+ #
20
+ # @attr_reader [Class] setter
21
+ # @attr_reader [Hash] variables
22
+ #
23
+ class KeyValue < Base
24
+ # == Instance Methods ============================================================================================
25
+ #
26
+ # === Description ===
27
+ #
28
+ # Runs the actual adapter.
29
+ #
30
+ def run
31
+ variables.each { |name, value| setter.set(name: name, value: value) }
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Knowledge
4
+ #
5
+ # === Description ===
6
+ #
7
+ # If the project has no defined way to manage its config, why not providing it our way?
8
+ #
9
+ class Configuration
10
+ class << self
11
+ #
12
+ # === Description ===
13
+ #
14
+ # We're doing black magic (a.k.a metaprogramming) to set variables directly on this class.
15
+ # When programmers do black magic, they should redefine some basic things that are broken as a side effect.
16
+ # That's what happens here. To have a proper inspect, we've got to re-write it manually.
17
+ # It's not something I find very clear but anyway, the API is cool so it's ok for me.
18
+ #
19
+ # It allows us to see every variable that has been defined on the class by metaprogramming.
20
+ #
21
+ # === Usage ===
22
+ #
23
+ # @example:
24
+ # # Do some magic before
25
+ # Knowledge.config.environment = :development
26
+ # learner = Knowledge::Learner.new
27
+ # learner.use name: :default
28
+ # learner.variables = { foo: :bar }
29
+ # learner.gather!
30
+ # # And then inspect it
31
+ # puts Knowledge::Configuration.inspect
32
+ # # => #<Knowledge::Configuration:0x000047116740290980 @foo="bar">
33
+ # # Wonderful, isn't it?
34
+ #
35
+ # === Parameters ===
36
+ #
37
+ # @return [String] as expected
38
+ #
39
+ def inspect
40
+ base = "#<Knowledge::Configuration:0x0000#{object_id}"
41
+
42
+ instance_variables.each do |var_name|
43
+ base = "#{base} #{var_name}=\"#{instance_variable_get(var_name)}\""
44
+ end
45
+
46
+ "#{base}>"
47
+ end
48
+ end
49
+ end
50
+ end