dotenvious 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,5 @@
1
+ .dotenvious
2
+ .env
3
+ .example-env
4
+ .envious
5
+ dotenvious-*.gem
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://www.rubygems.org'
2
+
3
+ gemspec
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
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "dotenvious"
4
+ Dotenvious::CLI.new.run
@@ -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,15 @@
1
+ module Dotenvious
2
+ class EnvAppender
3
+ def append(key)
4
+ env.write("#{key}=#{ENV_EXAMPLE[key]}\n")
5
+ end
6
+
7
+ private
8
+
9
+ attr_reader :env
10
+
11
+ def env
12
+ @env ||= File.open('.env', 'a+')
13
+ end
14
+ end
15
+ 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,11 @@
1
+ module Dotenvious
2
+ module Loaders
3
+ class Env < Environment
4
+ private
5
+
6
+ def environment
7
+ Dotenvious::ENV
8
+ end
9
+ end
10
+ end
11
+ 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,13 @@
1
+ require_relative 'environment'
2
+
3
+ module Dotenvious
4
+ module Loaders
5
+ class Example < Environment
6
+ private
7
+
8
+ def environment
9
+ Dotenvious::ENV_EXAMPLE
10
+ end
11
+ end
12
+ end
13
+ 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,7 @@
1
+ module Dotenvious
2
+ ENV = {}
3
+ ENV_EXAMPLE = {}
4
+ CONFIG = {}
5
+ end
6
+
7
+ require_relative 'dotenvious/cli'
@@ -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
@@ -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: