nvar 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.devcontainer/Dockerfile +14 -0
- data/.devcontainer/create-db-user.sql +2 -0
- data/.devcontainer/devcontainer.json +53 -0
- data/.devcontainer/docker-compose.yml +44 -0
- data/.github/workflows/release.yml +31 -0
- data/.github/workflows/rubyonrails-lint.yml +32 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.rubocop.yml +9 -0
- data/.rubocop_todo.yml +11 -0
- data/.tool-versions +1 -0
- data/CHANGELOG.md +0 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/CONTRIBUTING.md +41 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +209 -0
- data/LICENSE.txt +21 -0
- data/README.md +84 -0
- data/Rakefile +8 -0
- data/bin/brakeman +29 -0
- data/bin/bundle-audit +29 -0
- data/bin/bundler-audit +29 -0
- data/bin/console +15 -0
- data/bin/rspec +29 -0
- data/bin/rubocop +29 -0
- data/bin/setup +8 -0
- data/lib/nvar/engine.rb +27 -0
- data/lib/nvar/environment_variable.rb +84 -0
- data/lib/nvar/rails/tasks/verify_environment_file.rake +8 -0
- data/lib/nvar/version.rb +5 -0
- data/lib/nvar.rb +98 -0
- data/nvar.gemspec +45 -0
- data/script/create-sample-app +19 -0
- metadata +237 -0
data/README.md
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
# `Nvar`
|
2
|
+
|
3
|
+
If your app relies on lots of environment secrets, onboarding's tough. New team members need to add credentials for fifty different services and configure no end of app settings through their environment. Worse still, if a merged PR introduces something new, it can lead to inconvenient and unpredictable errors. **`Nvar` helps keep your team in step** by making sure all necessary environment variables are set.
|
4
|
+
|
5
|
+
You can use `Nvar` in Ruby apps, with out-of-the-box support provided for Rails.
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add the gem to your Gemfile and install it with `bundle add nvar`. If you're not on Rails, you'll need to make sure that `Nvar` is required with `require 'nvar'`, and then manually call `Nvar::EnvironmentVariable.load_all` as early as is appropriate.
|
9
|
+
## Configuration
|
10
|
+
|
11
|
+
`Nvar` is configured by way of `config/environment_variables.yml`. If you're on Rails, this file will be created for you automatically. Each key corresponds to the name of a required environment variable, and houses its configuration, all of which is optional.
|
12
|
+
|
13
|
+
```yml
|
14
|
+
REQUIRED_ENV_VAR:
|
15
|
+
required: false # defaults to true
|
16
|
+
type: Integer # defaults to String
|
17
|
+
default_value: 8
|
18
|
+
filter_from_requests: true # defaults to false
|
19
|
+
passthrough: true # defaults to false
|
20
|
+
```
|
21
|
+
|
22
|
+
- **required** determines whether an error will be raised if the environment variable is unset during initialization.
|
23
|
+
- **type** determines which type the variable will be cast to on load.
|
24
|
+
- **default_value** decides the value of the environment variable if it's absent.
|
25
|
+
- **filter_from_requests** is potentially the most exciting of the bunch - it integrates with the `vcr` gem. If your environment variable is a secret that's used directly (e.g. in bearer token authentication), use `true`. If it's used on its own as the password for basic auth, use `alone_with_basic_auth_password`. To activate the filtering, configure `VCR` as follows:
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
VCR.configure do |config|
|
29
|
+
Nvar::EnvironmentVariable.filter_from_vcr_cassettes(config)
|
30
|
+
end
|
31
|
+
```
|
32
|
+
|
33
|
+
Now, if you use `VCR` to record a request, that credential will be hidden using `vcr`'s `#filter_sensitive_data` hooks.
|
34
|
+
|
35
|
+
This is just a glimpse of `Nvar`'s greater aim - centralizing configuration for your environment variables as much as possible. Doing so enables you to onboard developers easily, and makes it easier to hide environment variables from logs and files.
|
36
|
+
|
37
|
+
### Passthrough
|
38
|
+
|
39
|
+
The final config option, `passthrough`, deserves some extra detail. By default, `Nvar` sets your environment constants to their actual values in development and production environments, and to their names in test environments.
|
40
|
+
|
41
|
+
In production/development, or in test with passthrough active:
|
42
|
+
|
43
|
+
```
|
44
|
+
irb(main):001:0> REQUIRED_ENV_VAR
|
45
|
+
=> "set"
|
46
|
+
```
|
47
|
+
|
48
|
+
In test:
|
49
|
+
|
50
|
+
```
|
51
|
+
irb(main):001:0> REQUIRED_ENV_VAR
|
52
|
+
=> "REQUIRED_ENV_VAR"
|
53
|
+
```
|
54
|
+
|
55
|
+
Your tests shouldn't be reliant on your environment, so generally, you want to have `passthrough` set to `true` as little as possible. What it *is* useful for, however, is recording VCR cassettes. Set `passthrough: true` on necessary environment variables before recording VCR cassettes, then remove it and run your tests again to make sure they're not reliant on your environment.
|
56
|
+
|
57
|
+
|
58
|
+
## Usage
|
59
|
+
|
60
|
+
Now that you've been through and configured the environment variables that are necessary for your app, `Nvar` will write your environment variables to top-level constants, cast to any types you've specified, and raise an informative error if any are absent.
|
61
|
+
### .env files
|
62
|
+
|
63
|
+
`Nvar` works well with gems like `dotenv` that source their config from a `.env` file. If an environment variable is unset when the app initializes and isn't present in `.env`, it will be added to that file. If a default value is specified in your `Nvar` config, that will be passed to `.env` too.
|
64
|
+
|
65
|
+
When using gems such as `dotenv`, make sure you load those first so that the environment is ready for `Nvar` to check.
|
66
|
+
|
67
|
+
## Development
|
68
|
+
|
69
|
+
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.
|
70
|
+
|
71
|
+
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).
|
72
|
+
|
73
|
+
## Contributing
|
74
|
+
|
75
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/boardfish/nvar. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/boardfish/nvar/blob/master/CODE_OF_CONDUCT.md).
|
76
|
+
|
77
|
+
|
78
|
+
## License
|
79
|
+
|
80
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
81
|
+
|
82
|
+
## Code of Conduct
|
83
|
+
|
84
|
+
Everyone interacting in the Nvar project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/boardfish/nvar/blob/master/CODE_OF_CONDUCT.md).
|
data/Rakefile
ADDED
data/bin/brakeman
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'brakeman' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
require "pathname"
|
12
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
13
|
+
Pathname.new(__FILE__).realpath)
|
14
|
+
|
15
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
+
|
17
|
+
if File.file?(bundle_binstub)
|
18
|
+
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
19
|
+
load(bundle_binstub)
|
20
|
+
else
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
require "rubygems"
|
27
|
+
require "bundler/setup"
|
28
|
+
|
29
|
+
load Gem.bin_path("brakeman", "brakeman")
|
data/bin/bundle-audit
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'bundle-audit' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
require "pathname"
|
12
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
13
|
+
Pathname.new(__FILE__).realpath)
|
14
|
+
|
15
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
+
|
17
|
+
if File.file?(bundle_binstub)
|
18
|
+
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
19
|
+
load(bundle_binstub)
|
20
|
+
else
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
require "rubygems"
|
27
|
+
require "bundler/setup"
|
28
|
+
|
29
|
+
load Gem.bin_path("bundler-audit", "bundle-audit")
|
data/bin/bundler-audit
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'bundler-audit' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
require "pathname"
|
12
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
13
|
+
Pathname.new(__FILE__).realpath)
|
14
|
+
|
15
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
+
|
17
|
+
if File.file?(bundle_binstub)
|
18
|
+
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
19
|
+
load(bundle_binstub)
|
20
|
+
else
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
require "rubygems"
|
27
|
+
require "bundler/setup"
|
28
|
+
|
29
|
+
load Gem.bin_path("bundler-audit", "bundler-audit")
|
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 'nvar'
|
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/rspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'rspec' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
require "pathname"
|
12
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
13
|
+
Pathname.new(__FILE__).realpath)
|
14
|
+
|
15
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
+
|
17
|
+
if File.file?(bundle_binstub)
|
18
|
+
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
19
|
+
load(bundle_binstub)
|
20
|
+
else
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
require "rubygems"
|
27
|
+
require "bundler/setup"
|
28
|
+
|
29
|
+
load Gem.bin_path("rspec-core", "rspec")
|
data/bin/rubocop
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'rubocop' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
require "pathname"
|
12
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
13
|
+
Pathname.new(__FILE__).realpath)
|
14
|
+
|
15
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
+
|
17
|
+
if File.file?(bundle_binstub)
|
18
|
+
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
19
|
+
load(bundle_binstub)
|
20
|
+
else
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
require "rubygems"
|
27
|
+
require "bundler/setup"
|
28
|
+
|
29
|
+
load Gem.bin_path("rubocop", "rubocop")
|
data/bin/setup
ADDED
data/lib/nvar/engine.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails'
|
4
|
+
require_relative './environment_variable'
|
5
|
+
|
6
|
+
module Nvar
|
7
|
+
class Engine < Rails::Engine # :nodoc:
|
8
|
+
# Load environment variables from `config/environment_variables.yml`, and assign
|
9
|
+
# them to constants in the app. The EnvironmentVariable class will raise an
|
10
|
+
# error if it can't source a required env var from the environment, and set
|
11
|
+
# values for use during tests.
|
12
|
+
config.after_initialize do |app|
|
13
|
+
Nvar::EnvironmentVariable.configure_for_rails(app)
|
14
|
+
Nvar::EnvironmentVariable.load_all
|
15
|
+
rescue Nvar::EnvironmentVariableNotPresentError => e
|
16
|
+
raise e unless Rails.env.test?
|
17
|
+
|
18
|
+
e.vars.each do |var|
|
19
|
+
Object.const_set(var.name, var.name)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
rake_tasks do
|
24
|
+
load 'nvar/rails/tasks/verify_environment_file.rake'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Wrapper for retrieval of environment variables. See
|
4
|
+
# config/initializers/environment_variable_loader.rb to check out how it's used.
|
5
|
+
require 'active_support/core_ext/hash/keys'
|
6
|
+
require 'active_support/core_ext/object/blank'
|
7
|
+
require 'yaml'
|
8
|
+
|
9
|
+
module Nvar
|
10
|
+
# Wrapper for loading environment variables, used across relevant Rake tasks
|
11
|
+
class EnvironmentVariable
|
12
|
+
attr_reader :name, :type, :value, :required, :defined
|
13
|
+
|
14
|
+
def initialize(name:, type: 'String', filter_from_requests: nil, **args)
|
15
|
+
@name = name
|
16
|
+
@type = type
|
17
|
+
@required = args[:required].nil? ? true : args[:required]
|
18
|
+
@filter_from_requests = filter_from_requests.yield_self { |f| [true, false].include?(f) ? f : f&.to_sym }
|
19
|
+
@value = fetch_value(args.slice(:passthrough, :default_value))
|
20
|
+
@defined = true
|
21
|
+
rescue KeyError
|
22
|
+
@value = args[:default_value]
|
23
|
+
@defined = false
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_const
|
27
|
+
raise Nvar::EnvironmentVariableNotPresentError, self unless defined
|
28
|
+
|
29
|
+
Object.const_set(name, typecast_value)
|
30
|
+
end
|
31
|
+
|
32
|
+
def set?
|
33
|
+
return false unless defined
|
34
|
+
|
35
|
+
return value.present? if required
|
36
|
+
|
37
|
+
true
|
38
|
+
end
|
39
|
+
|
40
|
+
def add_to_env_file
|
41
|
+
return if present_in_env_file?
|
42
|
+
|
43
|
+
File.write(Nvar.env_file_path, to_env_assign, mode: 'a')
|
44
|
+
end
|
45
|
+
|
46
|
+
def filter_from_vcr_cassettes(config)
|
47
|
+
return if @filter_from_requests.nil? || !@filter_from_requests
|
48
|
+
|
49
|
+
config.filter_sensitive_data("<#{name}>") do
|
50
|
+
# :nocov:
|
51
|
+
case @filter_from_requests
|
52
|
+
when :alone_as_basic_auth_password
|
53
|
+
Base64.encode64(['', @value].join(':')).delete("\n")
|
54
|
+
when true
|
55
|
+
@value
|
56
|
+
end
|
57
|
+
# :nocov:
|
58
|
+
end
|
59
|
+
config
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def present_in_env_file?
|
65
|
+
File.open(Nvar.env_file_path) { |f| f.each_line.find { |line| line.start_with?("#{name}=") } }
|
66
|
+
end
|
67
|
+
|
68
|
+
def to_env_assign
|
69
|
+
"#{name}=#{value}\n"
|
70
|
+
end
|
71
|
+
|
72
|
+
def typecast_value
|
73
|
+
return value if value.nil?
|
74
|
+
|
75
|
+
Kernel.public_send(type.to_sym, value)
|
76
|
+
end
|
77
|
+
|
78
|
+
def fetch_value(passthrough: false, default_value: nil)
|
79
|
+
return (default_value || name) if ENV['RAILS_ENV'] == 'test' && !passthrough
|
80
|
+
|
81
|
+
required ? ENV.fetch(name.to_s) : ENV[name.to_s]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
data/lib/nvar/version.rb
ADDED
data/lib/nvar.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'nvar/version'
|
4
|
+
require 'nvar/environment_variable'
|
5
|
+
require 'nvar/engine' if defined?(Rails)
|
6
|
+
require 'active_support/core_ext/module/attribute_accessors'
|
7
|
+
|
8
|
+
# Centralized configuration for required environment variables in your Ruby app.
|
9
|
+
module Nvar
|
10
|
+
mattr_accessor :config_file_path, default: File.expand_path('config/environment_variables.yml')
|
11
|
+
mattr_accessor :env_file_path, default: File.expand_path('.env')
|
12
|
+
|
13
|
+
# Comments in .env files must have a leading '#' symbol. This cannot be
|
14
|
+
# followed by a space.
|
15
|
+
ENV_COMMENT = <<~'COMMENT'
|
16
|
+
#Environment variables are managed through this file (.env). The Scripts to
|
17
|
+
#Rule Them All (in script/) load the environment from here, and the app warns
|
18
|
+
#on startup if any required environment variables are missing. You can see the
|
19
|
+
#list of environment variables that can be set for the app in
|
20
|
+
#config/environment_variables.yml.
|
21
|
+
COMMENT
|
22
|
+
|
23
|
+
class Error < StandardError; end
|
24
|
+
|
25
|
+
# Error that is raised when an environment variable is blank or unset when it is
|
26
|
+
# required
|
27
|
+
class EnvironmentVariableNotPresentError < Error
|
28
|
+
attr_reader :vars
|
29
|
+
|
30
|
+
def initialize(*vars)
|
31
|
+
@vars = vars
|
32
|
+
super()
|
33
|
+
end
|
34
|
+
|
35
|
+
def message
|
36
|
+
"The following variables are unset or blank: #{vars.map(&:name).join(', ')}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class << self
|
41
|
+
def configure_for_rails(app)
|
42
|
+
self.config_file_path = app.root.join('config/environment_variables.yml')
|
43
|
+
self.env_file_path = app.root.join('.env')
|
44
|
+
[config_file_path, env_file_path].each do |path|
|
45
|
+
File.open(path, 'w') {} unless path.exist? # rubocop:disable Lint/EmptyBlock
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def load_all
|
50
|
+
all.tap do |set, unset|
|
51
|
+
set.map(&:to_const)
|
52
|
+
raise EnvironmentVariableNotPresentError.new(*unset) if unset.any?
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def filter_from_vcr_cassettes(config)
|
57
|
+
set, = all
|
58
|
+
set.reduce(config) do |c, env_var|
|
59
|
+
c.tap { env_var.filter_from_vcr_cassettes(c) }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def all
|
64
|
+
variables.map do |variable_name, config|
|
65
|
+
EnvironmentVariable.new(**(config || {}).merge(name: variable_name))
|
66
|
+
end.partition(&:set?)
|
67
|
+
end
|
68
|
+
|
69
|
+
def touch_env
|
70
|
+
File.write(env_file_path, ENV_COMMENT, mode: 'w') unless File.exist?(env_file_path)
|
71
|
+
end
|
72
|
+
|
73
|
+
def verify_env(write_to_file: true)
|
74
|
+
_set, unset = all
|
75
|
+
return true if all_required_env_variables_set?
|
76
|
+
|
77
|
+
puts 'Please update .env with values for each environment variable:'
|
78
|
+
touch_env if write_to_file
|
79
|
+
unset.each do |variable|
|
80
|
+
variable.add_to_env_file if write_to_file
|
81
|
+
puts "- #{variable.name}"
|
82
|
+
end
|
83
|
+
puts "#{config_file_path} contains information on required environment variables across the app."
|
84
|
+
# Don't exit if all unset variables had defaults that were written to .env
|
85
|
+
write_to_file && unset.all? { |variable| variable.value.present? }
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def all_required_env_variables_set?
|
91
|
+
all[1].none? || ENV['RAILS_ENV'] == 'test'
|
92
|
+
end
|
93
|
+
|
94
|
+
def variables
|
95
|
+
(YAML.safe_load(File.read(config_file_path)) || {}).deep_symbolize_keys
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
data/nvar.gemspec
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lib/nvar/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'nvar'
|
7
|
+
spec.version = Nvar::VERSION
|
8
|
+
spec.authors = ['Simon Fish']
|
9
|
+
spec.email = ['si@mon.fish']
|
10
|
+
|
11
|
+
spec.summary = 'Manage environment variables in Ruby'
|
12
|
+
spec.description = 'Manage environment variables in Ruby'
|
13
|
+
spec.homepage = 'https://github.com/boardfish/nvar'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.7.0')
|
16
|
+
|
17
|
+
spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
|
18
|
+
|
19
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
20
|
+
spec.metadata['source_code_uri'] = spec.homepage
|
21
|
+
spec.metadata['changelog_uri'] = spec.homepage
|
22
|
+
|
23
|
+
# Specify which files should be added to the gem when it is released.
|
24
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
25
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
26
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
27
|
+
end
|
28
|
+
spec.bindir = 'exe'
|
29
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
30
|
+
spec.require_paths = ['lib']
|
31
|
+
spec.add_runtime_dependency 'activesupport', ['>= 5.0.0', '< 8.0']
|
32
|
+
spec.add_development_dependency 'bundler-audit'
|
33
|
+
spec.add_development_dependency 'byebug'
|
34
|
+
spec.add_development_dependency 'climate_control'
|
35
|
+
spec.add_development_dependency 'rails'
|
36
|
+
spec.add_development_dependency 'rubocop', '~> 1.12.0'
|
37
|
+
spec.add_development_dependency 'rubocop-rake'
|
38
|
+
spec.add_development_dependency 'rubocop-rspec'
|
39
|
+
spec.add_development_dependency 'simplecov'
|
40
|
+
spec.add_development_dependency 'tempfile'
|
41
|
+
spec.add_development_dependency 'vcr'
|
42
|
+
spec.metadata = {
|
43
|
+
'rubygems_mfa_required' => 'true'
|
44
|
+
}
|
45
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
# Exit if repo already exists
|
3
|
+
[ -d "replicate-bug" ] && echo "Sample repo exists. Rename or remove it to begin." && exit
|
4
|
+
branch_name=$(git rev-parse --abbrev-ref HEAD)
|
5
|
+
# Ensure that when we install nvar in the repo, we install this copy.
|
6
|
+
bundle config local.nvar $(pwd)
|
7
|
+
# Create and enter a minimal example repo
|
8
|
+
rails new --minimal replicate-bug
|
9
|
+
cd replicate-bug
|
10
|
+
# Add our local copy of ViewComponent
|
11
|
+
bundle add nvar --git https://github.com/boardfish/nvar --branch $branch_name
|
12
|
+
# Generate a controller
|
13
|
+
rails g controller Home index
|
14
|
+
# Root to the index action on HomeController
|
15
|
+
cat << 'ROUTES' > 'config/routes.rb'
|
16
|
+
Rails.application.routes.draw do
|
17
|
+
root to: 'home#index'
|
18
|
+
end
|
19
|
+
ROUTES
|