dotenvious 0.0.1
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/.gitignore +5 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +41 -0
- data/README.md +41 -0
- data/bin/dotenvious +4 -0
- data/dotenvious.gemspec +19 -0
- data/lib/dotenvious/cli.rb +44 -0
- data/lib/dotenvious/configuration.rb +39 -0
- data/lib/dotenvious/env_appender.rb +15 -0
- data/lib/dotenvious/loaders/configuration.rb +27 -0
- data/lib/dotenvious/loaders/env.rb +11 -0
- data/lib/dotenvious/loaders/environment.rb +28 -0
- data/lib/dotenvious/loaders/environments.rb +22 -0
- data/lib/dotenvious/loaders/example.rb +13 -0
- data/lib/dotenvious/mismatched_variable_finder.rb +22 -0
- data/lib/dotenvious/missing_variable_finder.rb +23 -0
- data/lib/dotenvious/prompter.rb +54 -0
- data/lib/dotenvious/value_replacer.rb +24 -0
- data/lib/dotenvious.rb +7 -0
- data/spec/dotenvious/cli_spec.rb +47 -0
- data/spec/dotenvious/configuration_spec.rb +84 -0
- data/spec/dotenvious/env_appender_spec.rb +19 -0
- data/spec/dotenvious/loaders/configuration_spec.rb +28 -0
- data/spec/dotenvious/loaders/env_spec.rb +26 -0
- data/spec/dotenvious/loaders/environments_spec.rb +18 -0
- data/spec/dotenvious/loaders/example_spec.rb +26 -0
- data/spec/dotenvious/mismatched_variable_finder_spec.rb +41 -0
- data/spec/dotenvious/missing_variable_finder_spec.rb +46 -0
- data/spec/dotenvious/prompter_spec.rb +32 -0
- data/spec/dotenvious/value_replacer_spec.rb +23 -0
- data/spec/spec_helper.rb +20 -0
- metadata +118 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7f3d8233b6bd8144495af0638e41cf3b14fa65db
|
4
|
+
data.tar.gz: 18506bfd293ac3125816db78052fed52dd85660a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 26a1170e357207a78f1ecfb5a8881e0ca1a462b0db643ba7e1dff023eec89b38d3cad3b60f26297d76439aa44c578e0843a260cf5cbf2719b63a38f80e3fe479
|
7
|
+
data.tar.gz: cc93d31e8d2ac1cec5e6b47e9bb033d0b993b5f99647b284488dfa4ccb3320be2366fd524a16f042cb623603d75246c778b05eac8a8d2fd6e5d8659366ca72b5
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
dotenvious (0.0.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://www.rubygems.org/
|
8
|
+
specs:
|
9
|
+
coderay (1.1.1)
|
10
|
+
diff-lcs (1.2.5)
|
11
|
+
method_source (0.8.2)
|
12
|
+
pry (0.10.3)
|
13
|
+
coderay (~> 1.1.0)
|
14
|
+
method_source (~> 0.8.1)
|
15
|
+
slop (~> 3.4)
|
16
|
+
rspec (3.3.0)
|
17
|
+
rspec-core (~> 3.3.0)
|
18
|
+
rspec-expectations (~> 3.3.0)
|
19
|
+
rspec-mocks (~> 3.3.0)
|
20
|
+
rspec-core (3.3.2)
|
21
|
+
rspec-support (~> 3.3.0)
|
22
|
+
rspec-expectations (3.3.1)
|
23
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
24
|
+
rspec-support (~> 3.3.0)
|
25
|
+
rspec-mocks (3.3.2)
|
26
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
27
|
+
rspec-support (~> 3.3.0)
|
28
|
+
rspec-support (3.3.0)
|
29
|
+
slop (3.6.0)
|
30
|
+
|
31
|
+
PLATFORMS
|
32
|
+
ruby
|
33
|
+
|
34
|
+
DEPENDENCIES
|
35
|
+
bundler (~> 1.3)
|
36
|
+
dotenvious!
|
37
|
+
pry
|
38
|
+
rspec (>= 3.0)
|
39
|
+
|
40
|
+
BUNDLED WITH
|
41
|
+
1.12.5
|
data/README.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# Dotenvious
|
2
|
+
|
3
|
+
A gem to manage .env dependencies.
|
4
|
+
|
5
|
+
Your `.env` file gets jealous when `.example-env` has keys that it does not. Dotenvious helps `.env` get back on the right track.
|
6
|
+
|
7
|
+
This gem exists to solve the following workflow:
|
8
|
+
|
9
|
+
Imagine you're working at a small to mid-size team in a startup whose architecture is constantly evolving. In a fast-moving startup, environment variable may change rapidly.
|
10
|
+
|
11
|
+
If you're working on one team within a larger application, environment variables may be added to your codebase that you might know were added, some of which may break the application's code after pulling from your updated repository.
|
12
|
+
|
13
|
+
Dotenvious solves this problem. See that your most recent pull breaks Rails on startup? Run dotenvious and it will present to you the new variables that were added - and give you the option to immediately add them to your `.env` file.
|
14
|
+
|
15
|
+
Dotenvious eliminates the pain of manually parsing through a newly changed `.example-env` file to see which new breaking variables have been added.
|
16
|
+
|
17
|
+
## Getting Started
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
## What You Need
|
22
|
+
|
23
|
+
This gem compares the variables set in your `.env` file with what exists in `.example-env`. The gem includes a CLI which walks you through the variables missing in `.env` but present in `.example-env`.
|
24
|
+
|
25
|
+
Currently, this gem relies on [Dotenv](https://github.com/bkeepers/dotenv) to load dependencies from ENV.
|
26
|
+
|
27
|
+
## Future Work
|
28
|
+
|
29
|
+
- [ ] Figure out how to incorporate in rakefile
|
30
|
+
|
31
|
+
- [x] Compare keys already present in both files but with different values
|
32
|
+
|
33
|
+
- [ ] Ability to choose which development `.env-*` file to load from
|
34
|
+
|
35
|
+
- [ ] Persist user's individual choices in a `.dotenvious` file in directory
|
36
|
+
|
37
|
+
- [ ] Option to always run on boot after recent pull from master
|
38
|
+
|
39
|
+
- [ ] Auto create `.envious` with user specified options if not exists
|
40
|
+
|
41
|
+
- [ ] More things are always on the horizon!
|
data/bin/dotenvious
ADDED
data/dotenvious.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'dotenvious'
|
3
|
+
s.version = '0.0.1'
|
4
|
+
s.date = '2016-09-10'
|
5
|
+
s.summary = "Dotenvious"
|
6
|
+
s.description = "A dotenv wrapper to manage variables"
|
7
|
+
s.authors = ["Jake Faris"]
|
8
|
+
s.email = 'jakefaris@outlook.com'
|
9
|
+
s.files = `git ls-files`.split($/)
|
10
|
+
s.executables = ['dotenvious']
|
11
|
+
s.homepage =
|
12
|
+
'http://rubygems.org/gems/dotenvious'
|
13
|
+
s.license = 'MIT'
|
14
|
+
|
15
|
+
s.add_development_dependency 'bundler', '~> 1.3'
|
16
|
+
s.add_development_dependency 'rspec', '~> 3.0'
|
17
|
+
s.add_development_dependency 'pry', '~> 0.10'
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require_relative 'loaders/environments'
|
2
|
+
require_relative 'missing_variable_finder'
|
3
|
+
require_relative 'prompter'
|
4
|
+
require_relative 'loaders/configuration'
|
5
|
+
require 'pry'
|
6
|
+
module Dotenvious
|
7
|
+
class CLI
|
8
|
+
def initialize
|
9
|
+
#figure out which file - for now can just look .env.example or .example-env
|
10
|
+
@filename = '.example-env' # or .env-example
|
11
|
+
end
|
12
|
+
|
13
|
+
def run
|
14
|
+
Loaders::Configuration.new.load
|
15
|
+
Loaders::Environments.new(filename).load_envs
|
16
|
+
unless all_vars_present? && all_vars_match?
|
17
|
+
alert_user
|
18
|
+
decision = STDIN.gets.strip
|
19
|
+
Prompter.run if decision.downcase == 'y'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
attr_reader :filename
|
26
|
+
|
27
|
+
def alert_user
|
28
|
+
puts "You have missing ENV variables. Examime them? [y/n]"
|
29
|
+
end
|
30
|
+
|
31
|
+
def all_vars_present?
|
32
|
+
!MissingVariableFinder.required_vars_missing?
|
33
|
+
end
|
34
|
+
|
35
|
+
def all_vars_match?
|
36
|
+
!MismatchedVariableFinder.mismatched_vars?
|
37
|
+
end
|
38
|
+
|
39
|
+
def abort
|
40
|
+
abort_message = 'Hold up! Your .env file is green with envy towards .example-env. You should update it.'
|
41
|
+
super abort_message
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'pry'
|
2
|
+
module Dotenvious
|
3
|
+
class Configuration
|
4
|
+
|
5
|
+
class ConfigurationError < StandardError; end
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
yield self if block_given?
|
9
|
+
end
|
10
|
+
|
11
|
+
def example_file=(filename)
|
12
|
+
raise ConfigurationError if not_string?(filename)
|
13
|
+
CONFIG[:example_file] = filename
|
14
|
+
end
|
15
|
+
|
16
|
+
def custom_variables=(vars)
|
17
|
+
raise ConfigurationError unless all_caps_array?(vars)
|
18
|
+
CONFIG[:custom_variables] = vars
|
19
|
+
end
|
20
|
+
|
21
|
+
def optional_variables=(vars)
|
22
|
+
raise ConfigurationError unless all_caps_array?(vars)
|
23
|
+
CONFIG[:optional_variables] = vars
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def not_string?(filename)
|
29
|
+
filename.class != String
|
30
|
+
end
|
31
|
+
|
32
|
+
def all_caps_array?(vars)
|
33
|
+
vars.class == Array &&
|
34
|
+
vars.all? do |var|
|
35
|
+
var.class == String && var.upcase == var
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'pry'
|
2
|
+
require_relative '../configuration'
|
3
|
+
module Dotenvious
|
4
|
+
module Loaders
|
5
|
+
class Configuration
|
6
|
+
def load
|
7
|
+
load_config if config_file_present?
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
attr_reader :file
|
13
|
+
|
14
|
+
def load_config
|
15
|
+
Kernel.load dotenvious
|
16
|
+
end
|
17
|
+
|
18
|
+
def dotenvious
|
19
|
+
Dir.pwd + '/.envious'
|
20
|
+
end
|
21
|
+
|
22
|
+
def config_file_present?
|
23
|
+
File.file?(dotenvious)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Dotenvious
|
2
|
+
module Loaders
|
3
|
+
class Environment
|
4
|
+
def initialize(filename)
|
5
|
+
@filename = filename
|
6
|
+
end
|
7
|
+
|
8
|
+
def load
|
9
|
+
#took from Dotenv source code whoops
|
10
|
+
file.each do |line|
|
11
|
+
environment[$1] = $2 if line =~ /\A([\w_]+)=(.*)\z/
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def environment
|
18
|
+
raise "environment must be defined in child class"
|
19
|
+
end
|
20
|
+
|
21
|
+
def file
|
22
|
+
File.read(@filename).split("\n")
|
23
|
+
end
|
24
|
+
|
25
|
+
attr_reader :filename
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require_relative 'example'
|
2
|
+
require_relative 'env'
|
3
|
+
|
4
|
+
module Dotenvious
|
5
|
+
module Loaders
|
6
|
+
class Environments
|
7
|
+
|
8
|
+
def initialize(filename)
|
9
|
+
@filename = filename
|
10
|
+
end
|
11
|
+
|
12
|
+
def load_envs
|
13
|
+
Env.new('.env').load
|
14
|
+
Example.new(filename).load
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
attr_reader :filename
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Dotenvious
|
2
|
+
class MismatchedVariableFinder
|
3
|
+
def self.mismatched_vars?
|
4
|
+
mismatched_vars.any?
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.mismatched_vars
|
8
|
+
keys.select do |key|
|
9
|
+
ENV_EXAMPLE.has_key?(key) && ENV_EXAMPLE[key] != ENV[key]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def self.keys
|
16
|
+
return ENV.keys if CONFIG[:custom_variables].nil?
|
17
|
+
ENV.keys.reject do |key|
|
18
|
+
CONFIG[:custom_variables].include?(key)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Dotenvious
|
2
|
+
class MissingVariableFinder
|
3
|
+
def self.required_vars_missing?
|
4
|
+
missing_required_vars.any?
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.missing_required_vars
|
8
|
+
keys.reject do |key|
|
9
|
+
ENV.has_key?(key)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def self.keys
|
16
|
+
all_keys = Dotenvious::ENV_EXAMPLE.keys
|
17
|
+
return all_keys if CONFIG[:optional_variables].nil?
|
18
|
+
all_keys.reject do |key|
|
19
|
+
CONFIG[:optional_variables].include?(key)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require_relative 'value_replacer'
|
2
|
+
require_relative 'mismatched_variable_finder'
|
3
|
+
require_relative 'prompter'
|
4
|
+
require_relative 'env_appender'
|
5
|
+
|
6
|
+
module Dotenvious
|
7
|
+
class Prompter
|
8
|
+
def self.run
|
9
|
+
keys_in_question.each do |key, status|
|
10
|
+
decision = prompt(key, status)
|
11
|
+
return if decision == 'q'
|
12
|
+
next unless decision.downcase == 'y'
|
13
|
+
|
14
|
+
if status == 'missing'
|
15
|
+
EnvAppender.new.append(key)
|
16
|
+
elsif status == 'mismatched'
|
17
|
+
ValueReplacer.new.replace(key)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def self.keys_in_question
|
25
|
+
missing_keys = missing_vars.zip(['missing'] * missing_vars.length)
|
26
|
+
mismatched_keys = mismatched_vars.zip(['mismatched'] * mismatched_vars.length)
|
27
|
+
missing_keys + mismatched_keys
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.missing_vars
|
31
|
+
MissingVariableFinder.missing_required_vars
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.mismatched_vars
|
35
|
+
MismatchedVariableFinder.mismatched_vars
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.prompt(var, status)
|
39
|
+
send(:"display_#{status}_output", var)
|
40
|
+
STDIN.gets.strip
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.display_missing_output(var)
|
44
|
+
puts "#{var}=#{ENV_EXAMPLE[var]}"
|
45
|
+
puts "Add to .env? [y/n/q]"
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.display_mismatched_output(var)
|
49
|
+
puts "ENV[#{var}] is set to: #{ENV[var]}"
|
50
|
+
puts "Example [#{var}] is set to: #{ENV_EXAMPLE[var]}"
|
51
|
+
puts "Replace with the example value? [y/n/q]"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Dotenvious
|
2
|
+
class ValueReplacer
|
3
|
+
def replace(key)
|
4
|
+
line_number = base_env.find_index do |line|
|
5
|
+
line.match(/^#{key}=/)
|
6
|
+
end
|
7
|
+
updated_env = base_env.dup
|
8
|
+
updated_env[line_number] = "#{key}=#{ENV_EXAMPLE[key]}"
|
9
|
+
env_writer.write(updated_env.join("\n"))
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
attr_reader :base_env
|
15
|
+
|
16
|
+
def base_env
|
17
|
+
@base_env ||= File.read('.env').split("\n")
|
18
|
+
end
|
19
|
+
|
20
|
+
def env_writer
|
21
|
+
File.open('.env', 'w')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/dotenvious.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dotenvious::CLI do
|
4
|
+
describe '.new' do
|
5
|
+
xit 'determines the correct file to use as example' do
|
6
|
+
# future release work
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#run' do
|
11
|
+
it 'loads the environment & example environment variables' do
|
12
|
+
expect_any_instance_of(Dotenvious::Loaders::Environments).to receive(:load_envs)
|
13
|
+
|
14
|
+
described_class.new.run
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'when there are ENV vars missing' do
|
18
|
+
context 'and the user wants to append them' do
|
19
|
+
it 'begins the Prompter' do
|
20
|
+
io_object = double
|
21
|
+
expect(STDIN).to receive(:gets).and_return('y')
|
22
|
+
expect_any_instance_of(described_class).to receive(:all_vars_present?).and_return false
|
23
|
+
expect(Dotenvious::Prompter).to receive(:run)#.and_return false
|
24
|
+
described_class.new.run
|
25
|
+
end
|
26
|
+
end
|
27
|
+
context 'but the user does not care' do
|
28
|
+
it 'quits' do
|
29
|
+
expect(STDIN).to receive(:gets).and_return('n')
|
30
|
+
expect_any_instance_of(described_class).to receive(:all_vars_present?).and_return false
|
31
|
+
expect(Dotenvious::Prompter).not_to receive(:run)#.and_return false
|
32
|
+
|
33
|
+
described_class.new.run
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'when there are no ENV vars missing or mismatched' do
|
39
|
+
it 'does nothing' do
|
40
|
+
expect_any_instance_of(described_class).to receive(:all_vars_present?).and_return true
|
41
|
+
expect_any_instance_of(described_class).to receive(:all_vars_match?).and_return true
|
42
|
+
|
43
|
+
expect { described_class.new.run }.to_not raise_error
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dotenvious::Configuration do
|
4
|
+
before(:each) do
|
5
|
+
stub_const('Dotenvious::CONFIG', {} )
|
6
|
+
end
|
7
|
+
describe '#example_file=' do
|
8
|
+
it 'sets :example_file in CONFIG' do
|
9
|
+
described_class.new do |config|
|
10
|
+
config.example_file = 'test_file.txt'
|
11
|
+
end
|
12
|
+
|
13
|
+
expect(Dotenvious::CONFIG[:example_file]).to eq 'test_file.txt'
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'only accepts a string' do
|
17
|
+
expect do
|
18
|
+
described_class.new do |config|
|
19
|
+
config.example_file = 1
|
20
|
+
end
|
21
|
+
end.to raise_error Dotenvious::Configuration::ConfigurationError
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#custom_variables=' do
|
26
|
+
it 'sets :custom_variables in CONFIG' do
|
27
|
+
described_class.new do |config|
|
28
|
+
config.custom_variables = %w(TEST VARS)
|
29
|
+
end
|
30
|
+
|
31
|
+
expect(Dotenvious::CONFIG[:custom_variables]).to eq ['TEST', 'VARS']
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'only accepts an array of all caps strings' do
|
35
|
+
expect do
|
36
|
+
described_class.new do |config|
|
37
|
+
config.custom_variables = 'idk'
|
38
|
+
end
|
39
|
+
end.to raise_error Dotenvious::Configuration::ConfigurationError
|
40
|
+
|
41
|
+
expect do
|
42
|
+
described_class.new do |config|
|
43
|
+
config.custom_variables = [:symbol]
|
44
|
+
end
|
45
|
+
end.to raise_error Dotenvious::Configuration::ConfigurationError
|
46
|
+
|
47
|
+
expect do
|
48
|
+
described_class.new do |config|
|
49
|
+
config.custom_variables = ['lower', 'case']
|
50
|
+
end
|
51
|
+
end.to raise_error Dotenvious::Configuration::ConfigurationError
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '#optional_variables=' do
|
56
|
+
it 'sets :optional_variables in CONFIG' do
|
57
|
+
described_class.new do |config|
|
58
|
+
config.optional_variables = %w(TEST VARS)
|
59
|
+
end
|
60
|
+
|
61
|
+
expect(Dotenvious::CONFIG[:optional_variables]).to eq ['TEST', 'VARS']
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'only accepts an array of all caps strings' do
|
65
|
+
expect do
|
66
|
+
described_class.new do |config|
|
67
|
+
config.optional_variables = 'idk'
|
68
|
+
end
|
69
|
+
end.to raise_error Dotenvious::Configuration::ConfigurationError
|
70
|
+
|
71
|
+
expect do
|
72
|
+
described_class.new do |config|
|
73
|
+
config.optional_variables = [:symbol]
|
74
|
+
end
|
75
|
+
end.to raise_error Dotenvious::Configuration::ConfigurationError
|
76
|
+
|
77
|
+
expect do
|
78
|
+
described_class.new do |config|
|
79
|
+
config.optional_variables = ['lower', 'case']
|
80
|
+
end
|
81
|
+
end.to raise_error Dotenvious::Configuration::ConfigurationError
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dotenvious::EnvAppender do
|
4
|
+
describe '#append' do
|
5
|
+
before do
|
6
|
+
stub_const('Dotenvious::ENV', { 'test' => 'example' } )
|
7
|
+
stub_const('Dotenvious::ENV_EXAMPLE', { 'test' => 'example', 'test2' => 'example2' } )
|
8
|
+
end
|
9
|
+
it 'appends the value to the end of the .env file' do
|
10
|
+
env_double = double('File', write: nil)
|
11
|
+
expect(env_double).to receive(:write).with("test2=example2\n")
|
12
|
+
expect(File).to receive(:open).
|
13
|
+
with('.env', 'a+').once.
|
14
|
+
and_return(env_double)
|
15
|
+
|
16
|
+
described_class.new.append('test2')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dotenvious::Loaders::Configuration do
|
4
|
+
describe '#load' do
|
5
|
+
let(:filepath) { Dir.pwd + '/.envious' }
|
6
|
+
context 'when ./.envious is present' do
|
7
|
+
before do
|
8
|
+
allow(File).to receive(:file?).with(filepath).and_return true
|
9
|
+
end
|
10
|
+
it 'loads the file' do
|
11
|
+
expect(Kernel).to receive(:load).with(filepath)
|
12
|
+
|
13
|
+
described_class.new.load
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'when ./.envious is not present' do
|
18
|
+
before do
|
19
|
+
allow(File).to receive(:file?).with(filepath).and_return false
|
20
|
+
end
|
21
|
+
it 'does nothing' do
|
22
|
+
expect(Kernel).not_to receive(:require)
|
23
|
+
|
24
|
+
described_class.new.load
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dotenvious::Loaders::Env do
|
4
|
+
describe '.new' do
|
5
|
+
it 'takes one argument' do
|
6
|
+
expect{ described_class.new('test') }.to_not raise_error
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#load' do
|
11
|
+
it 'loads files from its .new argument' do
|
12
|
+
expect(File).to receive(:read).with('test').and_return ""
|
13
|
+
|
14
|
+
described_class.new('test').load
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'passes those arguments to Dotenvious::ENV_EXAMPLE' do
|
18
|
+
expect(File).to receive(:read).and_return "TEST=123\nEXAMPLE=234"
|
19
|
+
|
20
|
+
described_class.new('test').load
|
21
|
+
|
22
|
+
expect(Dotenvious::ENV['TEST']).to eq '123'
|
23
|
+
expect(Dotenvious::ENV['EXAMPLE']).to eq '234'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dotenvious::Loaders::Environments do
|
4
|
+
describe '#initialize' do
|
5
|
+
it 'takes 1 argument' do
|
6
|
+
expect { described_class.new('test') }.to_not raise_error
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#load_envs' do
|
11
|
+
it 'loads from Dotenv as well as Loaders::Example' do
|
12
|
+
expect_any_instance_of(Dotenvious::Loaders::Example).to receive(:load)
|
13
|
+
expect_any_instance_of(Dotenvious::Loaders::Env).to receive(:load)
|
14
|
+
|
15
|
+
described_class.new('test').load_envs
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dotenvious::Loaders::Example do
|
4
|
+
describe '.new' do
|
5
|
+
it 'takes one argument' do
|
6
|
+
expect{ described_class.new('test') }.to_not raise_error
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#load' do
|
11
|
+
it 'loads files from its .new argument' do
|
12
|
+
expect(File).to receive(:read).with('test').and_return ""
|
13
|
+
|
14
|
+
described_class.new('test').load
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'passes those arguments to Dotenvious::ENV_EXAMPLE' do
|
18
|
+
expect(File).to receive(:read).and_return "TEST=123\nEXAMPLE=234"
|
19
|
+
|
20
|
+
described_class.new('test').load
|
21
|
+
|
22
|
+
expect(Dotenvious::ENV_EXAMPLE['TEST']).to eq '123'
|
23
|
+
expect(Dotenvious::ENV_EXAMPLE['EXAMPLE']).to eq '234'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dotenvious::MismatchedVariableFinder do
|
4
|
+
describe '.mismatched_vars' do
|
5
|
+
before do
|
6
|
+
stub_const('Dotenvious::ENV', {'test' => 'test_value', 'test_2' => 'same'} )
|
7
|
+
stub_const('Dotenvious::ENV_EXAMPLE', {'test_2' => 'different', 'test_3' => 'test_value'} )
|
8
|
+
end
|
9
|
+
context 'without custom configuration' do
|
10
|
+
it 'returns array of keys whose values are mismatched ENV & ENV_EXAMPLE' do
|
11
|
+
expect(described_class.mismatched_vars).to match_array(['test_2'])
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'with custom configuration' do
|
16
|
+
before do
|
17
|
+
stub_const('Dotenvious::ENV', {'TEST' => 'same', 'TEST_2' => 'some_value'} )
|
18
|
+
stub_const('Dotenvious::ENV_EXAMPLE', {'TEST' => 'different', 'TEST_2' => 'different_value'} )
|
19
|
+
stub_const('Dotenvious::CONFIG', { custom_variables: ['TEST'] } )
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'ignores vars specified in CONFIG[:custom_variables]' do
|
23
|
+
expect(described_class.mismatched_vars).to match_array(['TEST_2'])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '.mismatched_vars?' do
|
29
|
+
it 'returns true if mismatched_vars are present' do
|
30
|
+
expect(described_class).to receive(:mismatched_vars).and_return(['asdf'])
|
31
|
+
|
32
|
+
expect(described_class.mismatched_vars?).to be true
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'returns false if mismatched_vars are not present' do
|
36
|
+
expect(described_class).to receive(:mismatched_vars).and_return([])
|
37
|
+
|
38
|
+
expect(described_class.mismatched_vars?).to be false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dotenvious::MissingVariableFinder do
|
4
|
+
describe '.missing_required_vars' do
|
5
|
+
before(:each) do
|
6
|
+
stub_const('Dotenvious::ENV', {'TEST' => 'same'} )
|
7
|
+
stub_const('Dotenvious::ENV_EXAMPLE', {'TEST' => 'different', 'TEST_2' => 'value', 'TEST_3' => 'missing_value'} )
|
8
|
+
end
|
9
|
+
context 'with custom configuration' do
|
10
|
+
before do
|
11
|
+
stub_const('Dotenvious::CONFIG', { optional_variables: ['TEST_3'] } )
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'ignores vars specified in CONFIG[:custom_variables]' do
|
15
|
+
expect(described_class.missing_required_vars).to match_array(['TEST_2'])
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'without custom configuration' do
|
20
|
+
it 'specifies any ENV_EXAMPLE vars that are missing from ENV' do
|
21
|
+
expect(described_class.missing_required_vars).to match_array(['TEST_2', 'TEST_3'])
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '.required_vars_missing?' do
|
27
|
+
context 'given a loaded ENV and ENV_EXAMPLE' do
|
28
|
+
before(:each) do
|
29
|
+
stub_const('Dotenvious::ENV_EXAMPLE', {'test' => "123", 'example' => "234"} )
|
30
|
+
end
|
31
|
+
context 'where ENV has all variables' do
|
32
|
+
it 'returns false' do
|
33
|
+
allow(described_class).to receive(:missing_required_vars).and_return([])
|
34
|
+
expect(described_class.required_vars_missing?).to eq false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'where ENV is missing variables' do
|
39
|
+
it 'returns true' do
|
40
|
+
allow(described_class).to receive(:missing_required_vars).and_return(['test'])
|
41
|
+
expect(described_class.required_vars_missing?).to eq true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dotenvious::Prompter do
|
4
|
+
describe '.run' do
|
5
|
+
before(:each) do
|
6
|
+
stub_const('Dotenvious::ENV', { 'test' => nil } )
|
7
|
+
stub_const('Dotenvious::ENV_EXAMPLE', {'test' => nil, 'test2' => nil, 'test3' => nil} )
|
8
|
+
# expect(Dotenvious::ENV).to receive(:keys).and_return(['test'])
|
9
|
+
# expect(Dotenvious::ENV_EXAMPLE).to receive(:keys).and_return(['test', 'test2', 'test3'])
|
10
|
+
end
|
11
|
+
it 'prompts the user to add every missing or mismatched variable do' do
|
12
|
+
expect(STDIN).to receive(:gets).twice.and_return('n')
|
13
|
+
|
14
|
+
described_class.run
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'appends the vars to .env' do
|
18
|
+
expect(STDIN).to receive(:gets).twice.and_return('y','n')
|
19
|
+
expect(File).to receive(:open).
|
20
|
+
with('.env', 'a+').once.
|
21
|
+
and_return(double('File', write: nil))
|
22
|
+
|
23
|
+
described_class.run
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'quits out if the user presses q' do
|
27
|
+
expect(STDIN).to receive(:gets).once.and_return('q')
|
28
|
+
|
29
|
+
described_class.run
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dotenvious::ValueReplacer do
|
4
|
+
describe '#replace' do
|
5
|
+
before do
|
6
|
+
stub_const('Dotenvious::ENV_EXAMPLE', {'fake' => 'correct'} )
|
7
|
+
end
|
8
|
+
it "replaces the key's value in .env if user presses yes" do
|
9
|
+
expect(File).to receive(:read).
|
10
|
+
with('.env').
|
11
|
+
and_return("test=1234\nfake=missing")
|
12
|
+
|
13
|
+
env_double = double('File', write: nil)
|
14
|
+
expect(env_double).to receive(:write).with("test=1234\nfake=correct")
|
15
|
+
|
16
|
+
expect(File).to receive(:open).
|
17
|
+
with('.env', 'w').
|
18
|
+
and_return(env_double)
|
19
|
+
|
20
|
+
described_class.new.replace('fake')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
Bundler.setup
|
3
|
+
|
4
|
+
require 'dotenvious' # and any other gems you need
|
5
|
+
|
6
|
+
RSpec.configure do |config|
|
7
|
+
#copied & pasted from http://stackoverflow.com/questions/15430551
|
8
|
+
#whoops
|
9
|
+
original_stderr = $stderr
|
10
|
+
original_stdout = $stdout
|
11
|
+
config.before(:all) do
|
12
|
+
# Redirect stderr and stdout
|
13
|
+
$stderr = File.open(File::NULL, "w")
|
14
|
+
$stdout = File.open(File::NULL, "w")
|
15
|
+
end
|
16
|
+
config.after(:all) do
|
17
|
+
$stderr = original_stderr
|
18
|
+
$stdout = original_stdout
|
19
|
+
end
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dotenvious
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jake Faris
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-09-10 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.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.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.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.10'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.10'
|
55
|
+
description: A dotenv wrapper to manage variables
|
56
|
+
email: jakefaris@outlook.com
|
57
|
+
executables:
|
58
|
+
- dotenvious
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".gitignore"
|
63
|
+
- Gemfile
|
64
|
+
- Gemfile.lock
|
65
|
+
- README.md
|
66
|
+
- bin/dotenvious
|
67
|
+
- dotenvious.gemspec
|
68
|
+
- lib/dotenvious.rb
|
69
|
+
- lib/dotenvious/cli.rb
|
70
|
+
- lib/dotenvious/configuration.rb
|
71
|
+
- lib/dotenvious/env_appender.rb
|
72
|
+
- lib/dotenvious/loaders/configuration.rb
|
73
|
+
- lib/dotenvious/loaders/env.rb
|
74
|
+
- lib/dotenvious/loaders/environment.rb
|
75
|
+
- lib/dotenvious/loaders/environments.rb
|
76
|
+
- lib/dotenvious/loaders/example.rb
|
77
|
+
- lib/dotenvious/mismatched_variable_finder.rb
|
78
|
+
- lib/dotenvious/missing_variable_finder.rb
|
79
|
+
- lib/dotenvious/prompter.rb
|
80
|
+
- lib/dotenvious/value_replacer.rb
|
81
|
+
- spec/dotenvious/cli_spec.rb
|
82
|
+
- spec/dotenvious/configuration_spec.rb
|
83
|
+
- spec/dotenvious/env_appender_spec.rb
|
84
|
+
- spec/dotenvious/loaders/configuration_spec.rb
|
85
|
+
- spec/dotenvious/loaders/env_spec.rb
|
86
|
+
- spec/dotenvious/loaders/environments_spec.rb
|
87
|
+
- spec/dotenvious/loaders/example_spec.rb
|
88
|
+
- spec/dotenvious/mismatched_variable_finder_spec.rb
|
89
|
+
- spec/dotenvious/missing_variable_finder_spec.rb
|
90
|
+
- spec/dotenvious/prompter_spec.rb
|
91
|
+
- spec/dotenvious/value_replacer_spec.rb
|
92
|
+
- spec/spec_helper.rb
|
93
|
+
homepage: http://rubygems.org/gems/dotenvious
|
94
|
+
licenses:
|
95
|
+
- MIT
|
96
|
+
metadata: {}
|
97
|
+
post_install_message:
|
98
|
+
rdoc_options: []
|
99
|
+
require_paths:
|
100
|
+
- lib
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
requirements: []
|
112
|
+
rubyforge_project:
|
113
|
+
rubygems_version: 2.5.1
|
114
|
+
signing_key:
|
115
|
+
specification_version: 4
|
116
|
+
summary: Dotenvious
|
117
|
+
test_files: []
|
118
|
+
has_rdoc:
|