dotenvious 0.0.6 → 0.0.7
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 +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
|