dotenvious 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +20 -5
- data/dotenvious.gemspec +2 -2
- data/lib/dotenvious/cli/env_file_consolidator.rb +6 -5
- data/lib/dotenvious/cli/env_file_sorter.rb +8 -2
- data/lib/dotenvious/cli/main.rb +17 -5
- data/lib/dotenvious/env_appender.rb +7 -2
- data/lib/dotenvious/loaders/environments.rb +3 -2
- data/lib/dotenvious/prompter.rb +16 -10
- data/lib/dotenvious/value_replacer.rb +9 -4
- data/spec/dotenvious/cli/env_file_consolidator_spec.rb +5 -3
- data/spec/dotenvious/cli/main_spec.rb +18 -2
- data/spec/dotenvious/env_appender_spec.rb +3 -2
- data/spec/dotenvious/prompter_spec.rb +11 -4
- data/spec/dotenvious/value_replacer_spec.rb +15 -11
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ab78cc6851361858979e2f864f6f7c50bc5265b3
|
4
|
+
data.tar.gz: 4ba12610eb2d596bd875b200d19e755ac21c9154
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aa8135e30a38c0d91180866fa659f509cc56829e7e54302648de7d4438a2e7d32ceb1164892ad784590cc48957a9ce944e8ae09a85a249aa9714935906303856
|
7
|
+
data.tar.gz: 3a57368c0557b87a84fa983b39650233ecde8370c0e65457eb7290d4f22697a2cf2093d8f7da8c709649bd38d460130fa92bb92252eda33987607ad89db099a6
|
data/README.md
CHANGED
@@ -39,25 +39,40 @@ First, add a `.envious` file to the root of your project. In the file, you can s
|
|
39
39
|
Dotenvious::Configuration.new do |config|
|
40
40
|
|
41
41
|
config.custom_variables = %w(VARIABLES WITH DIFFERENT VALUES)
|
42
|
-
|
42
|
+
|
43
43
|
config.optional_variables = %w(VARIABLES YOU DONT NEED)
|
44
44
|
|
45
45
|
end
|
46
46
|
|
47
|
-
```
|
47
|
+
```
|
48
48
|
|
49
49
|
These both need to be arrays.
|
50
50
|
|
51
51
|
`dotenvious` will ignore the variables specified.
|
52
52
|
|
53
|
-
###
|
53
|
+
### Additional Options
|
54
|
+
|
55
|
+
#### --sort
|
54
56
|
|
55
57
|
Running `dotenvious --sort` will sort your `.env` file alphabetically.
|
56
58
|
|
57
|
-
|
59
|
+
#### --file
|
60
|
+
|
61
|
+
To select another example enironment file to use, add the optional flag `--file .env-example` or whatever your filename is.
|
58
62
|
|
63
|
+
This gem also works with `.yml` or `.yaml` files designed for CircleCI. To use a `.yaml` file of this style, it must have the format:
|
59
64
|
|
60
|
-
|
65
|
+
```
|
66
|
+
machine:
|
67
|
+
environment:
|
68
|
+
MY_ENV_VAR_1: "asdfghjk"
|
69
|
+
MY_ENV_VAR_2: "qwertyu"
|
70
|
+
...
|
71
|
+
```
|
72
|
+
|
73
|
+
Other configuration formats can be added in the future.
|
74
|
+
|
75
|
+
## Future Work
|
61
76
|
|
62
77
|
- [ ] Persist user's individual choices in a `.envious` file in directory after run
|
63
78
|
|
data/dotenvious.gemspec
CHANGED
@@ -6,23 +6,24 @@ require_relative '../loaders/configuration'
|
|
6
6
|
module Dotenvious
|
7
7
|
module CLI
|
8
8
|
class EnvFileConsolidator
|
9
|
-
def initialize(
|
10
|
-
@example_file =
|
9
|
+
def initialize(example_file: DEFAULT_EXAMPLE_ENV_FILE, env_file: DEFAULT_ENV_FILE)
|
10
|
+
@example_file = example_file
|
11
|
+
@env_file = env_file
|
11
12
|
end
|
12
13
|
|
13
14
|
def run
|
14
15
|
Loaders::Configuration.new.load
|
15
|
-
Loaders::Environments.new({example_file: example_file}).load_environments
|
16
|
+
Loaders::Environments.new({example_file: example_file, env_file: env_file}).load_environments
|
16
17
|
unless all_vars_present? && all_vars_match?
|
17
18
|
alert_user
|
18
19
|
decision = STDIN.gets.strip
|
19
|
-
Prompter.run if decision.downcase == 'y'
|
20
|
+
Prompter.new(env_file).run if decision.downcase == 'y'
|
20
21
|
end
|
21
22
|
end
|
22
23
|
|
23
24
|
private
|
24
25
|
|
25
|
-
attr_reader :example_file, :filename
|
26
|
+
attr_reader :example_file, :env_file, :filename
|
26
27
|
|
27
28
|
def alert_user
|
28
29
|
puts "You have missing ENV variables. Examime them? [y/n]"
|
@@ -1,15 +1,21 @@
|
|
1
1
|
module Dotenvious
|
2
2
|
module CLI
|
3
3
|
class EnvFileSorter
|
4
|
+
def initialize(filename = DEFAULT_ENV_FILE)
|
5
|
+
@filename = filename
|
6
|
+
end
|
7
|
+
|
4
8
|
def run
|
5
|
-
File.open(
|
9
|
+
File.open(filename, 'w') do |file|
|
6
10
|
file.write(sorted_env_text)
|
7
11
|
end
|
8
|
-
puts
|
12
|
+
puts "Your #{filename} file is now neat and orderly. Enjoy!"
|
9
13
|
end
|
10
14
|
|
11
15
|
private
|
12
16
|
|
17
|
+
attr_reader :filename
|
18
|
+
|
13
19
|
def sorted_env_text
|
14
20
|
ENV.sort.map do |(key, value)|
|
15
21
|
"#{key}=#{value}"
|
data/lib/dotenvious/cli/main.rb
CHANGED
@@ -11,23 +11,35 @@ module Dotenvious
|
|
11
11
|
|
12
12
|
def run
|
13
13
|
parse_options
|
14
|
-
EnvFileConsolidator.new(
|
15
|
-
EnvFileSorter.new.run if options[:sort]
|
14
|
+
EnvFileConsolidator.new(file_options).run
|
15
|
+
EnvFileSorter.new(options[:env_file]).run if options[:sort]
|
16
16
|
end
|
17
17
|
|
18
18
|
private
|
19
19
|
|
20
20
|
attr_accessor :options
|
21
|
+
attr_reader :file_options
|
22
|
+
|
23
|
+
def file_options
|
24
|
+
@file_options ||= Hash.new.tap do |hash|
|
25
|
+
hash[:example_file] = options[:example_file] if options.key?(:example_file)
|
26
|
+
hash[:env_file] = options[:env_file] if options.key?(:env_file)
|
27
|
+
end
|
28
|
+
end
|
21
29
|
|
22
30
|
def parse_options
|
23
31
|
parser = OptionParser.new do |opts|
|
24
32
|
opts.banner = "How to use Dotenvious:"
|
25
33
|
|
26
|
-
opts.on('-
|
27
|
-
options[:
|
34
|
+
opts.on('-x .example-env-file', '--example .example-env-file', 'Specify which example file to use') do |file|
|
35
|
+
options[:example_file] = file
|
36
|
+
end
|
37
|
+
|
38
|
+
opts.on('-f .env-file', '--file .env-file', 'Specify which file to write to') do |file|
|
39
|
+
options[:env_file] = file
|
28
40
|
end
|
29
41
|
|
30
|
-
opts.on('-s', '--sort', 'Sort
|
42
|
+
opts.on('-s', '--sort', 'Sort env file by key names alphabetically') do
|
31
43
|
options[:sort] = true
|
32
44
|
end
|
33
45
|
|
@@ -1,15 +1,20 @@
|
|
1
1
|
module Dotenvious
|
2
2
|
class EnvAppender
|
3
|
+
def initialize(filename)
|
4
|
+
@filename = filename
|
5
|
+
end
|
6
|
+
|
3
7
|
def append(key)
|
4
8
|
env.write("#{key}=#{ENV_EXAMPLE[key]}\n")
|
9
|
+
env.close
|
5
10
|
end
|
6
11
|
|
7
12
|
private
|
8
13
|
|
9
|
-
attr_reader :env
|
14
|
+
attr_reader :env, :filename
|
10
15
|
|
11
16
|
def env
|
12
|
-
@env ||= File.open(
|
17
|
+
@env ||= File.open(filename, 'a+')
|
13
18
|
end
|
14
19
|
end
|
15
20
|
end
|
@@ -6,17 +6,18 @@ module Dotenvious
|
|
6
6
|
class Environments
|
7
7
|
def initialize(options = {})
|
8
8
|
@example_file = options[:example_file] || DEFAULT_EXAMPLE_ENV_FILE
|
9
|
+
@env_file = options[:env_file] || DEFAULT_ENV_FILE
|
9
10
|
end
|
10
11
|
|
11
12
|
def load_environments
|
12
|
-
ENV.merge!(DotenvFile.load_from(
|
13
|
+
ENV.merge!(DotenvFile.load_from(env_file))
|
13
14
|
environment_loader = example_file.match(/\.ya?ml/) ? YamlFile : DotenvFile
|
14
15
|
ENV_EXAMPLE.merge!(environment_loader.load_from(example_file))
|
15
16
|
end
|
16
17
|
|
17
18
|
private
|
18
19
|
|
19
|
-
attr_reader :example_file
|
20
|
+
attr_reader :example_file, :env_file
|
20
21
|
end
|
21
22
|
end
|
22
23
|
end
|
data/lib/dotenvious/prompter.rb
CHANGED
@@ -5,47 +5,53 @@ require_relative 'env_appender'
|
|
5
5
|
|
6
6
|
module Dotenvious
|
7
7
|
class Prompter
|
8
|
-
def
|
8
|
+
def initialize(filename = DEFAULT_ENV_FILE)
|
9
|
+
@filename = filename
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
9
13
|
keys_in_question.each do |key, status|
|
10
14
|
decision = prompt(key, status)
|
11
15
|
return if decision == 'q'
|
12
16
|
next unless decision.downcase == 'y'
|
13
17
|
|
14
18
|
if status == 'missing'
|
15
|
-
EnvAppender.new.append(key)
|
19
|
+
EnvAppender.new(filename).append(key)
|
16
20
|
elsif status == 'mismatched'
|
17
|
-
ValueReplacer.new.replace(key)
|
21
|
+
ValueReplacer.new(filename).replace(key)
|
18
22
|
end
|
19
23
|
end
|
20
24
|
end
|
21
25
|
|
22
26
|
private
|
23
27
|
|
24
|
-
|
28
|
+
attr_reader :filename
|
29
|
+
|
30
|
+
def keys_in_question
|
25
31
|
missing_keys = missing_vars.zip(['missing'] * missing_vars.length)
|
26
32
|
mismatched_keys = mismatched_vars.zip(['mismatched'] * mismatched_vars.length)
|
27
33
|
missing_keys + mismatched_keys
|
28
34
|
end
|
29
35
|
|
30
|
-
def
|
36
|
+
def missing_vars
|
31
37
|
MissingVariableFinder.missing_required_vars
|
32
38
|
end
|
33
39
|
|
34
|
-
def
|
40
|
+
def mismatched_vars
|
35
41
|
MismatchedVariableFinder.mismatched_vars
|
36
42
|
end
|
37
43
|
|
38
|
-
def
|
44
|
+
def prompt(var, status)
|
39
45
|
send(:"display_#{status}_output", var)
|
40
46
|
STDIN.gets.strip
|
41
47
|
end
|
42
48
|
|
43
|
-
def
|
49
|
+
def display_missing_output(var)
|
44
50
|
puts "#{var}=#{ENV_EXAMPLE[var]}"
|
45
|
-
puts "Add to
|
51
|
+
puts "Add to #{filename}? [y/n/q]"
|
46
52
|
end
|
47
53
|
|
48
|
-
def
|
54
|
+
def display_mismatched_output(var)
|
49
55
|
puts "ENV[#{var}] is set to: #{ENV[var]}"
|
50
56
|
puts "Example [#{var}] is set to: #{ENV_EXAMPLE[var]}"
|
51
57
|
puts "Replace with the example value? [y/n/q]"
|
@@ -1,24 +1,29 @@
|
|
1
1
|
module Dotenvious
|
2
2
|
class ValueReplacer
|
3
|
+
def initialize(filename)
|
4
|
+
@filename = filename
|
5
|
+
end
|
6
|
+
|
3
7
|
def replace(key)
|
4
8
|
line_number = base_env.find_index do |line|
|
5
9
|
line.match(/^#{key}=/)
|
6
10
|
end
|
7
11
|
updated_env = base_env.dup
|
8
12
|
updated_env[line_number] = "#{key}=#{ENV_EXAMPLE[key]}"
|
9
|
-
env_writer.write(updated_env.join("\n"))
|
13
|
+
env_writer.write(updated_env.join("\n") + "\n")
|
14
|
+
env_writer.close
|
10
15
|
end
|
11
16
|
|
12
17
|
private
|
13
18
|
|
14
|
-
attr_reader :base_env
|
19
|
+
attr_reader :base_env, :filename
|
15
20
|
|
16
21
|
def base_env
|
17
|
-
@base_env ||= File.read(
|
22
|
+
@base_env ||= File.read(filename).split("\n")
|
18
23
|
end
|
19
24
|
|
20
25
|
def env_writer
|
21
|
-
File.open(
|
26
|
+
@env_writer ||= File.open(filename, 'w')
|
22
27
|
end
|
23
28
|
end
|
24
29
|
end
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Dotenvious::CLI::EnvFileConsolidator do
|
4
4
|
describe '.new' do
|
5
5
|
it 'takes option hash' do
|
6
|
-
expect { described_class.new({example_file: '.envenvenv'}) }.to_not raise_error
|
6
|
+
expect { described_class.new({example_file: '.envenvenv', env_file: '.env'}) }.to_not raise_error
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
@@ -23,9 +23,11 @@ describe Dotenvious::CLI::EnvFileConsolidator do
|
|
23
23
|
context 'and the user wants to append them' do
|
24
24
|
it 'begins the Prompter' do
|
25
25
|
io_object = double
|
26
|
+
prompter = double
|
26
27
|
expect(STDIN).to receive(:gets).and_return('y')
|
27
28
|
expect_any_instance_of(described_class).to receive(:all_vars_present?).and_return false
|
28
|
-
expect(Dotenvious::Prompter).to receive(:
|
29
|
+
expect(Dotenvious::Prompter).to receive(:new).and_return prompter
|
30
|
+
expect(prompter).to receive(:run)
|
29
31
|
described_class.new.run
|
30
32
|
end
|
31
33
|
end
|
@@ -56,7 +58,7 @@ describe Dotenvious::CLI::EnvFileConsolidator do
|
|
56
58
|
it 'loads environments with that example_file' do
|
57
59
|
environments_double = double
|
58
60
|
expect(Dotenvious::Loaders::Environments).to receive(:new)
|
59
|
-
.with({example_file: '.test.env.test'}).and_return(environments_double)
|
61
|
+
.with({example_file: '.test.env.test', env_file: '.env'}).and_return(environments_double)
|
60
62
|
expect(environments_double).to receive(:load_environments)
|
61
63
|
|
62
64
|
described_class.new({example_file: '.test.env.test'}).run
|
@@ -41,9 +41,9 @@ describe Dotenvious::CLI::Main do
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
-
context '--
|
44
|
+
context '--example' do
|
45
45
|
before do
|
46
|
-
stub_const('ARGV', ['--
|
46
|
+
stub_const('ARGV', ['--example', '.my-test-file-env'])
|
47
47
|
end
|
48
48
|
|
49
49
|
it 'uses the user-specified filename to read example environment' do
|
@@ -56,6 +56,22 @@ describe Dotenvious::CLI::Main do
|
|
56
56
|
described_class.new.run
|
57
57
|
end
|
58
58
|
end
|
59
|
+
|
60
|
+
context '--file' do
|
61
|
+
before do
|
62
|
+
stub_const('ARGV', ['--file', '.my-env'])
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'uses the user-specified filename to read example environment' do
|
66
|
+
fake_consolidator = double
|
67
|
+
expect(fake_consolidator).to receive(:run)
|
68
|
+
expect(Dotenvious::CLI::EnvFileConsolidator).to receive(:new)
|
69
|
+
.with({env_file: '.my-env'})
|
70
|
+
.and_return(fake_consolidator)
|
71
|
+
|
72
|
+
described_class.new.run
|
73
|
+
end
|
74
|
+
end
|
59
75
|
end
|
60
76
|
end
|
61
77
|
end
|
@@ -9,11 +9,12 @@ describe Dotenvious::EnvAppender do
|
|
9
9
|
it 'appends the value to the end of the .env file' do
|
10
10
|
env_double = double('File', write: nil)
|
11
11
|
expect(env_double).to receive(:write).with("test2=example2\n")
|
12
|
+
expect(env_double).to receive(:close)
|
12
13
|
expect(File).to receive(:open).
|
13
|
-
with('.env', 'a+').once.
|
14
|
+
with('.big-ol-env', 'a+').once.
|
14
15
|
and_return(env_double)
|
15
16
|
|
16
|
-
described_class.new.append('test2')
|
17
|
+
described_class.new('.big-ol-env').append('test2')
|
17
18
|
end
|
18
19
|
end
|
19
20
|
end
|
@@ -11,22 +11,29 @@ describe Dotenvious::Prompter do
|
|
11
11
|
it 'prompts the user to add every missing or mismatched variable do' do
|
12
12
|
expect(STDIN).to receive(:gets).twice.and_return('n')
|
13
13
|
|
14
|
-
described_class.run
|
14
|
+
described_class.new.run
|
15
15
|
end
|
16
16
|
|
17
17
|
it 'appends the vars to .env' do
|
18
18
|
expect(STDIN).to receive(:gets).twice.and_return('y','n')
|
19
|
+
file_double = double
|
20
|
+
expect(file_double).to receive(:write).with("test2=\n")
|
21
|
+
expect(file_double).to receive(:close)
|
22
|
+
|
19
23
|
expect(File).to receive(:open).
|
20
24
|
with('.env', 'a+').once.
|
21
|
-
and_return(
|
25
|
+
and_return(file_double)
|
22
26
|
|
23
|
-
described_class.run
|
27
|
+
described_class.new.run
|
24
28
|
end
|
25
29
|
|
26
30
|
it 'quits out if the user presses q' do
|
27
31
|
expect(STDIN).to receive(:gets).once.and_return('q')
|
28
32
|
|
29
|
-
described_class.run
|
33
|
+
described_class.new.run
|
34
|
+
end
|
35
|
+
|
36
|
+
xit 'given missing and different args, appends/rewrites correctly into env' do
|
30
37
|
end
|
31
38
|
end
|
32
39
|
end
|
@@ -3,21 +3,25 @@ require 'spec_helper'
|
|
3
3
|
describe Dotenvious::ValueReplacer do
|
4
4
|
describe '#replace' do
|
5
5
|
before do
|
6
|
-
stub_const('Dotenvious::ENV_EXAMPLE',
|
6
|
+
stub_const('Dotenvious::ENV_EXAMPLE', example_const )
|
7
7
|
end
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
context 'given a key with a different value' do
|
9
|
+
let(:example_const) { {'fake' => 'correct'} }
|
10
|
+
it "replaces the key's value in .env if user presses yes" do
|
11
|
+
expect(File).to receive(:read).
|
12
|
+
with('.big-ol-env').
|
13
|
+
and_return("test=1234\nfake=missing")
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
+
env_double = double('File', write: nil)
|
16
|
+
expect(env_double).to receive(:write).with("test=1234\nfake=correct\n")
|
17
|
+
expect(env_double).to receive(:close)
|
15
18
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
+
expect(File).to receive(:open).
|
20
|
+
with('.big-ol-env', 'w').
|
21
|
+
and_return(env_double)
|
19
22
|
|
20
|
-
|
23
|
+
described_class.new('.big-ol-env').replace('fake')
|
24
|
+
end
|
21
25
|
end
|
22
26
|
end
|
23
27
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dotenvious
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jake Faris
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-10-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|