remote_config 1.0.0.pre.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. checksums.yaml +7 -0
  2. data/.github/PULL_REQUEST_TEMPLATE.md +13 -0
  3. data/.github/workflows/continuous-deployment.yml +34 -0
  4. data/.github/workflows/continuous-integration.yml +45 -0
  5. data/.gitignore +58 -0
  6. data/.rubocop.yml +9 -0
  7. data/Gemfile +23 -0
  8. data/README.md +122 -0
  9. data/Rakefile +24 -0
  10. data/app/controllers/remote_config/application_controller.rb +5 -0
  11. data/app/models/remote_config/application_record.rb +8 -0
  12. data/bin/rails +14 -0
  13. data/config/routes.rb +3 -0
  14. data/lib/remote_config/adapters/base.rb +23 -0
  15. data/lib/remote_config/adapters/ruby_config_adapter.rb +32 -0
  16. data/lib/remote_config/engine.rb +7 -0
  17. data/lib/remote_config/exceptions.rb +47 -0
  18. data/lib/remote_config/flagging.rb +33 -0
  19. data/lib/remote_config/rails/routes.rb +11 -0
  20. data/lib/remote_config/version.rb +5 -0
  21. data/lib/remote_config.rb +50 -0
  22. data/remote-config.gemspec +21 -0
  23. data/spec/rails_app/.rspec +1 -0
  24. data/spec/rails_app/Rakefile +6 -0
  25. data/spec/rails_app/app/assets/config/manifest.js +3 -0
  26. data/spec/rails_app/app/assets/images/.keep +0 -0
  27. data/spec/rails_app/app/assets/stylesheets/application.css +15 -0
  28. data/spec/rails_app/app/channels/application_cable/channel.rb +4 -0
  29. data/spec/rails_app/app/channels/application_cable/connection.rb +4 -0
  30. data/spec/rails_app/app/controllers/application_controller.rb +2 -0
  31. data/spec/rails_app/app/controllers/concerns/.keep +0 -0
  32. data/spec/rails_app/app/helpers/application_helper.rb +2 -0
  33. data/spec/rails_app/app/jobs/application_job.rb +7 -0
  34. data/spec/rails_app/app/mailers/application_mailer.rb +4 -0
  35. data/spec/rails_app/app/models/application_record.rb +3 -0
  36. data/spec/rails_app/app/models/concerns/.keep +0 -0
  37. data/spec/rails_app/app/views/layouts/application.html.erb +15 -0
  38. data/spec/rails_app/app/views/layouts/mailer.html.erb +13 -0
  39. data/spec/rails_app/app/views/layouts/mailer.text.erb +1 -0
  40. data/spec/rails_app/bin/rails +4 -0
  41. data/spec/rails_app/bin/rake +4 -0
  42. data/spec/rails_app/bin/setup +33 -0
  43. data/spec/rails_app/config/application.rb +25 -0
  44. data/spec/rails_app/config/boot.rb +5 -0
  45. data/spec/rails_app/config/cable.yml +10 -0
  46. data/spec/rails_app/config/database.yml +25 -0
  47. data/spec/rails_app/config/environment.rb +5 -0
  48. data/spec/rails_app/config/environments/development.rb +70 -0
  49. data/spec/rails_app/config/environments/production.rb +93 -0
  50. data/spec/rails_app/config/environments/test.rb +60 -0
  51. data/spec/rails_app/config/initializers/assets.rb +12 -0
  52. data/spec/rails_app/config/initializers/content_security_policy.rb +26 -0
  53. data/spec/rails_app/config/initializers/filter_parameter_logging.rb +8 -0
  54. data/spec/rails_app/config/initializers/inflections.rb +16 -0
  55. data/spec/rails_app/config/initializers/permissions_policy.rb +11 -0
  56. data/spec/rails_app/config/locales/en.yml +33 -0
  57. data/spec/rails_app/config/puma.rb +43 -0
  58. data/spec/rails_app/config/routes.rb +3 -0
  59. data/spec/rails_app/config/storage.yml +34 -0
  60. data/spec/rails_app/config.ru +6 -0
  61. data/spec/rails_app/db/schema.rb +15 -0
  62. data/spec/rails_app/lib/assets/.keep +0 -0
  63. data/spec/rails_app/log/.keep +0 -0
  64. data/spec/rails_app/public/404.html +67 -0
  65. data/spec/rails_app/public/422.html +67 -0
  66. data/spec/rails_app/public/500.html +66 -0
  67. data/spec/rails_app/public/apple-touch-icon-precomposed.png +0 -0
  68. data/spec/rails_app/public/apple-touch-icon.png +0 -0
  69. data/spec/rails_app/public/favicon.ico +0 -0
  70. data/spec/rails_app/storage/.keep +0 -0
  71. data/spec/rails_app/tmp/.keep +0 -0
  72. data/spec/rails_app/tmp/development_secret.txt +1 -0
  73. data/spec/rails_app/tmp/pids/.keep +0 -0
  74. data/spec/rails_app/tmp/storage/.keep +0 -0
  75. data/spec/rails_helper.rb +66 -0
  76. data/spec/remote_config/adapters/ruby_config_adapter_spec.rb +83 -0
  77. data/spec/remote_config/flagging_spec.rb +171 -0
  78. data/spec/spec_helper.rb +97 -0
  79. metadata +118 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 31d21488e0ffa05436025e157209cc9d44dc1e3fabb307a2e9d71c220bdb7069
4
+ data.tar.gz: 0bd6482ddcbdb2ab5abe5286997ea029134f46b42bd5a1f695206904634c3bc1
5
+ SHA512:
6
+ metadata.gz: 164e299f5dcd5585d136d3aafecb8d49d98a8555ec0330de972803fe798c2e763c76c6af188c8f24468890f36407aa04fc3a7c241129738315eee2b49f0dda80
7
+ data.tar.gz: 51a8988537d414973c5a3473a0aaaba25c0458ccc39352f565d2b0edd075866437409f3add830a3e2377a95f7819db8dbddd5826810979e6ec9ed5e482f5d304
@@ -0,0 +1,13 @@
1
+ <!--
2
+ List of related JIRAs:
3
+ e.g. [[MISC-123]](https://paperkite.atlassian.net/browse/MISC-123)
4
+ -->
5
+
6
+ ### Description
7
+ <!-- explanation of the change and your thinking behind the implementation -->
8
+
9
+ ### How to test
10
+ <!-- explanation of how to test / perform acceptance over the changes -->
11
+
12
+ ### Resources
13
+ <!-- attach screenshots of change or links to relevant resources when applicable -->
@@ -0,0 +1,34 @@
1
+ name: Continuous Deployment
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - v[0-9]+.[0-9]+.[0-9]+ # e.g. 2.7.1
7
+ - v[0-9]+.[0-9]+.[0-9]+-[a-z]+ # e.g. v2.7.1-beta
8
+ - v[0-9]+.[0-9]+.[0-9]+-[a-z]+.[0-9]+ # e.g. v2.7.1-beta.1
9
+
10
+ jobs:
11
+
12
+ publish_to_rubygems:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v2
16
+ - uses: ruby/setup-ruby@v1
17
+ with:
18
+ ruby-version: 3.1.1
19
+ - name: Install bundler and bundle
20
+ run: |
21
+ gem install bundler
22
+ bundle
23
+ - name: Set up Rubygems credentials
24
+ run: |
25
+ mkdir -p ~/.gem
26
+ cat > ~/.gem/credentials << ENDOFFILE
27
+ ---
28
+ :github: Bearer ${{ github.token }}
29
+ :rubygems_api_key: ${{ secrets.RUBYGEMS_API_KEY }}
30
+ ENDOFFILE
31
+
32
+ chmod 0600 ~/.gem/credentials
33
+ - name: Publish to Rubygems
34
+ run: rake publish
@@ -0,0 +1,45 @@
1
+ name: Continuous Integration
2
+
3
+ on:
4
+ pull_request:
5
+ branches:
6
+ - main
7
+ - develop
8
+ - epic/*
9
+
10
+ jobs:
11
+
12
+ rubocop:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v2
16
+ - uses: ruby/setup-ruby@v1
17
+ with:
18
+ ruby-version: 3.0.1
19
+ - name: Install PK Rubocop gem
20
+ run: |
21
+ gem install paperkite-rubocop --pre
22
+ - name: Run Rubocop
23
+ run: |
24
+ rubocop
25
+
26
+ rspec:
27
+ runs-on: ubuntu-latest
28
+ strategy:
29
+ matrix:
30
+ ruby-version: [2.7.4, 3.0.1, 3.1.1]
31
+ steps:
32
+ - uses: actions/checkout@v2
33
+ - uses: ruby/setup-ruby@v1
34
+ with:
35
+ ruby-version: ${{ matrix.ruby-version }}
36
+ - name: Install bundler and bundle
37
+ run: |
38
+ gem install bundler
39
+ bundle
40
+ - name: Run RSpec
41
+ env:
42
+ RAILS_ENV: test
43
+ run: |
44
+ bundle exec rails db:test:prepare
45
+ bundle exec rspec
data/.gitignore ADDED
@@ -0,0 +1,58 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /spec/rails_app/db/*.sqlite3
10
+ /spec/rails_app/log
11
+ /test/tmp/
12
+ /test/version_tmp/
13
+ /tmp/
14
+
15
+ # Used by dotenv library to load environment variables.
16
+ # .env
17
+
18
+ # Ignore Byebug command history file.
19
+ .byebug_history
20
+
21
+ ## Specific to RubyMotion:
22
+ .dat*
23
+ .repl_history
24
+ build/
25
+ *.bridgesupport
26
+ build-iPhoneOS/
27
+ build-iPhoneSimulator/
28
+
29
+ ## Specific to RubyMotion (use of CocoaPods):
30
+ #
31
+ # We recommend against adding the Pods directory to your .gitignore. However
32
+ # you should judge for yourself, the pros and cons are mentioned at:
33
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
34
+ #
35
+ # vendor/Pods/
36
+
37
+ ## Documentation cache and generated files:
38
+ /.yardoc/
39
+ /_yardoc/
40
+ /doc/
41
+ /rdoc/
42
+
43
+ ## Environment normalization:
44
+ /.bundle/
45
+ /vendor/bundle
46
+ /lib/bundler/man/
47
+
48
+ # for a library or gem, you might want to ignore these files since the code is
49
+ # intended to run in multiple environments; otherwise, check them in:
50
+ Gemfile.lock
51
+ .ruby-version
52
+ .ruby-gemset
53
+
54
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
55
+ .rvmrc
56
+
57
+ # Used by RuboCop. Remote config files pulled in from inherit_from directive.
58
+ # .rubocop-https?--*
data/.rubocop.yml ADDED
@@ -0,0 +1,9 @@
1
+ inherit_gem:
2
+ paperkite-rubocop: config/base.yml
3
+
4
+ AllCops:
5
+ TargetRubyVersion: 2.5
6
+ Exclude:
7
+ - spec/rails_app/**/*
8
+ - bin/*
9
+ - Rakefile
data/Gemfile ADDED
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ ruby RUBY_VERSION
6
+
7
+ gemspec
8
+
9
+ gem "config"
10
+ gem "rails"
11
+
12
+ group :test do
13
+ gem "rspec-rails"
14
+ gem "sqlite3"
15
+ end
16
+
17
+ group :test, :development do
18
+ gem "pry"
19
+ end
20
+
21
+ group :development do
22
+ gem "paperkite-rubocop", tag: "v1.0.0-beta.6"
23
+ end
data/README.md ADDED
@@ -0,0 +1,122 @@
1
+ # Remote config
2
+
3
+ A gem for managing feature and release flags in the backend and providing them remotely to a front-end.
4
+
5
+ ## Usage
6
+
7
+ ### Feature Flagging
8
+
9
+ Flagging allows checking of config values and doing different things based on their boolean value.
10
+
11
+ By including the flagging module you'll have access to the following methods:
12
+
13
+ ```rb
14
+ include RemoteConfig::Flagging
15
+ ```
16
+
17
+ ```rb
18
+ caffeinate if feature_enabled? "coffee.caffeinated"
19
+ ```
20
+
21
+ ```rb
22
+ feature_enabled? "coffee.caffeinated" do
23
+ caffeinate
24
+ end
25
+ ```
26
+
27
+ The `RemoteConfig::Flagging` module is included into the rails route mapper so you can use flagging at route setup. This allows the deployment of unreleased endpoints that aren't routable until they are released.
28
+
29
+ ```rb
30
+ routes do
31
+ feature_enabled? "coffee_ordering" do
32
+ resource :coffee
33
+ end
34
+ end
35
+ ```
36
+
37
+ ### Release flags
38
+
39
+ Release flags work with the same syntax (replace `feature?` with `released?`), however instead of checking for boolean truthfulness, the value of the falg corresponds to a stage that it is released to. The `released?` method will then be checking if the current environment is in that release stage and returning true if so.
40
+
41
+ For example, if your configured release stages are:
42
+ ```rb
43
+ RemoteConfig.configure do |config|
44
+ config.release_stages = {
45
+ production: %s[production qa dev development],
46
+ qa: %s[qa dev development],
47
+ development: %s[dev development]
48
+ }
49
+ ```
50
+
51
+ Then the following values are returned:
52
+
53
+ | | development | uat | production |
54
+ | ----------- | ----------- | ----- | ---------- |
55
+ | dev | true | true | true |
56
+ | development | true | true | true |
57
+ | qa | false | true | true |
58
+ | production | false | false | true |
59
+
60
+ *Current environments down the left VS the release stages along the top.*
61
+
62
+ Alternatively, if you wanted to release to specific environments instead of progressing through them, you can return an array of the exact environment(s) that you want it released on.
63
+
64
+ e.g. if the value is `[:qa]`, them it'll be `false` on development, dev and production, while true on qa.
65
+
66
+ By including the flagging module you'll have access to the following methods:
67
+
68
+ ```rb
69
+ include RemoteConfig::Flagging
70
+ ```
71
+
72
+ ```rb
73
+ prompt_for_coffee_ordering if released? "coffee_ordering.cta"
74
+ ```
75
+
76
+ ```rb
77
+ released? "coffee_ordering.cta" do
78
+ prompt_for_coffee_ordering
79
+ end
80
+ ```
81
+
82
+ ### Adapters
83
+
84
+ Where the feature and release flags are sorted from depends on what adapter is used. Currently, the only adapater is the `RemoteConfig::Adapters::RubyConfigAdapter`, which sources from a local YML file using the [Config](https://github.com/rubyconfig/config) gem.
85
+
86
+ By default the feature flagging looks for values under under `features` and release flagging looks for values under `releases`.
87
+
88
+ If you want to nest a flag under another, for example, you have a `coffee_ordering` release flag and you want to add a `coffee_ordernig.pre_pay` release flag. Then you can nest the new flag under the old one and add a `_` key underneath it for it's own value, e.g:
89
+
90
+ ```yml
91
+ releases:
92
+ coffee_ordering:
93
+ _: uat
94
+ pre_pay: development
95
+
96
+ ```
97
+
98
+ An example `app/config/settings.yml` might look like:
99
+
100
+ ```yml
101
+ releases:
102
+ loyalty: uat
103
+ coffee_ordering:
104
+ _: production
105
+ pre_pay: production
106
+ v2:
107
+ _: uat
108
+ pre_pay: development
109
+ v3:
110
+ _: development
111
+
112
+ features:
113
+ pay_in_car: true
114
+ ```
115
+
116
+ NOTE: it may be useful to split out your releases and features YML into different files and load them in.
117
+
118
+ `app/config/releases.yml`
119
+ `app/config/features.yml`
120
+
121
+ TODO: provide ruby snippet of how to set this up in the initializers
122
+
data/Rakefile ADDED
@@ -0,0 +1,24 @@
1
+ require "bundler/setup"
2
+
3
+ APP_RAKEFILE = File.expand_path("spec/rails_app/Rakefile", __dir__)
4
+ load "rails/tasks/engine.rake"
5
+
6
+ load "rails/tasks/statistics.rake"
7
+
8
+ require "bundler/gem_tasks"
9
+ require_relative "./lib/remote_config/version"
10
+
11
+ task :publish do
12
+ if ENV["GITHUB_REF"] == "refs/tags/v#{RemoteConfig::VERSION}"
13
+ puts "Release ref \"#{ENV["GITHUB_REF"]}\" matches gem version \"#{RemoteConfig::VERSION}\""
14
+
15
+ sh "gem build"
16
+ sh "ls *.gem | xargs gem push"
17
+
18
+ puts "Bult and pushed version #{RemoteConfig::VERSION} to rubygems"
19
+ exit 0
20
+ else
21
+ puts "Release ref \"#{ENV["GITHUB_REF"]}\" does not match gem version \"#{RemoteConfig::VERSION}\""
22
+ exit 1
23
+ end
24
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RemoteConfig
4
+ class ApplicationController < ActionController::Base; end
5
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RemoteConfig
4
+ # Base class for all RemoteConfig models
5
+ class ApplicationRecord < ActiveRecord::Base
6
+ self.abstract_class = true
7
+ end
8
+ end
data/bin/rails ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails gems
3
+ # installed from the root of your application.
4
+
5
+ ENGINE_ROOT = File.expand_path("..", __dir__)
6
+ ENGINE_PATH = File.expand_path("../lib/remote-config/engine", __dir__)
7
+ APP_PATH = File.expand_path("../spec/rails_app/config/application", __dir__)
8
+
9
+ # Set up gems listed in the Gemfile.
10
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
11
+ require "bundler/setup" if File.exist?(ENV["BUNDLE_GEMFILE"])
12
+
13
+ require "rails/all"
14
+ require "rails/engine/commands"
data/config/routes.rb ADDED
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ RemoteConfig::Engine.routes.draw {} # rubocop:disable Lint/EmptyBlock
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RemoteConfig
4
+ module Adapters
5
+ # Adapters are the interface for fetching the feature and release flags from
6
+ # varying sources.
7
+ class Base
8
+ attr_reader :options
9
+
10
+ def initialize(options)
11
+ @options = options
12
+ end
13
+
14
+ def fetch_feature_flag(key)
15
+ raise NotImplementedError
16
+ end
17
+
18
+ def fetch_release_flag(key)
19
+ raise NotImplementedError
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RemoteConfig
4
+ module Adapters
5
+ # Adapter for fetching feature and release flags from a set up config using
6
+ # the Config gem (see https://github.com/rubyconfig/config).
7
+ class RubyConfigAdapter < Base
8
+ def fetch_feature_flag(key)
9
+ fetch_flag(options[:feature_flags_key], key)
10
+ end
11
+
12
+ def fetch_release_flag(key)
13
+ fetch_flag(options[:release_flags_key], key)
14
+ end
15
+
16
+ private
17
+
18
+ def fetch_flag(root_key, key)
19
+ value = config_class.dig(root_key, *key.split("."))
20
+ return value._ if value.is_a? Config::Options
21
+
22
+ value
23
+ rescue TypeError
24
+ nil
25
+ end
26
+
27
+ def config_class
28
+ options[:const_name].constantize
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RemoteConfig
4
+ class Engine < ::Rails::Engine
5
+ isolate_namespace RemoteConfig
6
+ end
7
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Style/Documentation
4
+ module RemoteConfig
5
+ class FlagError < StandardError
6
+ attr_reader :key
7
+
8
+ def initialize(key)
9
+ @key = key
10
+
11
+ super
12
+ end
13
+ end
14
+
15
+ class UnknownFeatureFlagError < FlagError
16
+ def message
17
+ "Unknown feature flag: #{key}"
18
+ end
19
+ end
20
+
21
+ class NonBooleanFeatureFlagError < FlagError
22
+ def message
23
+ "Non-boolean feature flag: #{key}"
24
+ end
25
+ end
26
+
27
+ class UnknownReleaseFlagError < FlagError
28
+ def message
29
+ "Unknown release flag: #{key}"
30
+ end
31
+ end
32
+
33
+ class UnknownReleaseStageError < FlagError
34
+ attr_reader :value
35
+
36
+ def initialize(key, value)
37
+ @value = value
38
+
39
+ super(key)
40
+ end
41
+
42
+ def message
43
+ "Unknown release stage \"#{value}\" for release flag: #{key}"
44
+ end
45
+ end
46
+ end
47
+ # rubocop:enable Style/Documentation
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RemoteConfig
4
+ # Module to be included into the using application to allow for checking
5
+ # for feature and release flags.
6
+ module Flagging
7
+ def feature_enabled?(key)
8
+ enabled = RemoteConfig.adapter.fetch_feature_flag(key)
9
+ raise RemoteConfig::UnknownFeatureFlagError, key if enabled.nil?
10
+ raise RemoteConfig::NonBooleanFeatureFlagError, key unless enabled.in? [true, false]
11
+
12
+ yield if block_given? && enabled
13
+
14
+ enabled
15
+ end
16
+
17
+ # rubocop:disable Metrics/AbcSize
18
+ def released?(key)
19
+ release_stage = RemoteConfig.adapter.fetch_release_flag(key)
20
+ raise RemoteConfig::UnknownReleaseFlagError, key if release_stage.nil?
21
+
22
+ release_stages_envs = RemoteConfig.configuration.release_stages[release_stage.to_sym]
23
+ raise RemoteConfig::UnknownReleaseStageError.new(key, release_stage) if release_stages_envs.nil?
24
+
25
+ is_released = release_stages_envs.map(&:to_s).include? Rails.env
26
+
27
+ yield if block_given? && is_released
28
+
29
+ is_released
30
+ end
31
+ # rubocop:enable Metrics/AbcSize
32
+ end
33
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionDispatch
4
+ module Routing
5
+ # Re-open the ActionDispatch::Routing::Mapping class and include the methods
6
+ # for flagging.
7
+ class Mapper
8
+ include RemoteConfig::Flagging
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RemoteConfig
4
+ VERSION = "1.0.0-beta.1"
5
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "remote_config/version"
4
+ require "remote_config/engine"
5
+ require "remote_config/flagging"
6
+ require "remote_config/exceptions"
7
+ require "remote_config/adapters/base"
8
+ require "remote_config/adapters/ruby_config_adapter"
9
+
10
+ # Root gem module containing config and adapter setup.
11
+ module RemoteConfig
12
+ Configuration = Struct.new(
13
+ # The adapter to be used for fetching the flags.
14
+ :adapter,
15
+ # The options hash to be passed to the adapter at initialization.
16
+ :adapter_options,
17
+ # An hash of release stages to an array of rails environments that will have
18
+ # the it will release to.
19
+ :release_stages,
20
+ keyword_init: true
21
+ )
22
+
23
+ class << self
24
+ def configure
25
+ yield configuration
26
+ end
27
+
28
+ def configuration
29
+ @configuration ||= Configuration.new(
30
+ adapter: Adapters::RubyConfigAdapter,
31
+ adapter_options: {
32
+ const_name: "Settings",
33
+ feature_flags_key: "feature_flags",
34
+ release_flags_key: "release_flags"
35
+ },
36
+
37
+ release_stages: {
38
+ production: %i[production development],
39
+ development: %i[development]
40
+ }
41
+ )
42
+ end
43
+
44
+ def adapter
45
+ @adapter ||= configuration.adapter.new(configuration.adapter_options)
46
+ end
47
+ end
48
+ end
49
+
50
+ require "remote_config/rails/routes" if defined? ::Rails
@@ -0,0 +1,21 @@
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 "remote_config/version"
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "remote_config"
9
+ spec.version = RemoteConfig::VERSION
10
+ spec.authors = ["Montgomery Anderson"]
11
+ spec.email = "montgomery.c.anderson@gmail.com"
12
+
13
+ spec.summary = "Remote Config for Ruby on Rails"
14
+ spec.description = "Remote Config for Ruby on Rails"
15
+ spec.homepage = "https://github.com/paperkite/rails-remote-config"
16
+
17
+ spec.require_paths = ["lib"]
18
+ spec.required_ruby_version = ">= 2.5.0"
19
+
20
+ spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
21
+ end
@@ -0,0 +1 @@
1
+ --require spec_helper
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require_relative "config/application"
5
+
6
+ Rails.application.load_tasks
@@ -0,0 +1,3 @@
1
+ //= link_tree ../images
2
+ //= link_directory ../stylesheets .css
3
+ //= link rails_remote_config_manifest.js
File without changes
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,4 @@
1
+ module ApplicationCable
2
+ class Channel < ActionCable::Channel::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module ApplicationCable
2
+ class Connection < ActionCable::Connection::Base
3
+ end
4
+ end
@@ -0,0 +1,2 @@
1
+ class ApplicationController < ActionController::Base
2
+ end
File without changes
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end