confswap 0.0.5 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/README.md +25 -5
- data/confswap.gemspec +3 -3
- data/features/env_variable_should_overwrite_properties.feature +31 -0
- data/features/save_conf_yaml.feature +23 -0
- data/features/version.feature +1 -1
- data/lib/confswap.rb +1 -0
- data/lib/confswap/bash_parser.rb +37 -0
- data/lib/confswap/command.rb +38 -10
- data/lib/confswap/version.rb +1 -1
- data/spec/bash_parser_spec.rb +54 -0
- data/spec/conf_reader_spec.rb +3 -3
- data/spec/property_reader_spec.rb +8 -8
- data/spec/spec_helper.rb +4 -0
- metadata +14 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f792ae191b624dc16a9c682d7076b4b4dd36991
|
4
|
+
data.tar.gz: a891d0741a8e1e6a3d0b27fa0cc624f063aa7b1e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2236b56d692b3eb394c54619112dc9c35a244fb1410595521d2d116b74c5e9a815d9ac109f89f4442fc65fca858ca0867338894c8bc4ff0e248dd4fb0a08149e
|
7
|
+
data.tar.gz: f5e6573966e0135f9028c135a18defea9e61ff3de3b2ea49955a111d5f0317e157911fb4de2c6d3076126aaea921e802f4688f4d1a07b84687108668b3fef832
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -22,7 +22,7 @@ lang=%{LANG}
|
|
22
22
|
|
23
23
|
### Environment Variables
|
24
24
|
|
25
|
-
```confswap
|
25
|
+
```confswap -t sample1.template sample.conf
|
26
26
|
|
27
27
|
will use the USER and LANG variables in your shell to populate the template. You can use ``env`` to see your current environment variables.
|
28
28
|
|
@@ -30,11 +30,11 @@ additionally you can add additional variables to use, or overwrite extisting env
|
|
30
30
|
|
31
31
|
1. The envvar flag (which takes multiple variables which must be separated by an = sign
|
32
32
|
|
33
|
-
```confswap --
|
33
|
+
```confswap --envvar USER=something --envvar LANG=en_US.UTF-8 -t sample1.template sample2.conf
|
34
34
|
|
35
35
|
2. explicit setting:
|
36
36
|
|
37
|
-
```USER=someoneelse LANG=en_IE.UTF-8 confswap
|
37
|
+
```USER=someoneelse LANG=en_IE.UTF-8 confswap -t sample1.template sample3.conf```
|
38
38
|
|
39
39
|
### Properties File
|
40
40
|
|
@@ -47,8 +47,21 @@ USER: anotherone
|
|
47
47
|
|
48
48
|
Then read it using
|
49
49
|
|
50
|
-
```confswap
|
50
|
+
```confswap -p sample.properties -t sample1.template sample3.conf```
|
51
51
|
|
52
|
+
You can also save templates as yaml files!
|
53
|
+
|
54
|
+
Pass in variables as you would normally then choose to make a yaml file config
|
55
|
+
|
56
|
+
```confswap -e test=giblets -e user=alsogiblets -e array='["1","3","4"]' --yaml your_conf.yaml```
|
57
|
+
|
58
|
+
1. Note array must be passed as a json string)
|
59
|
+
2. Also note that by default this will also save the environment variables currently saved in the shell, to ignore these, please use the ignore shell vars (-i) flag, i.e.
|
60
|
+
|
61
|
+
```confswap -e test=giblets -e user=alsogiblets -e array='["1","3","4"]' --ignore-shell-vars --force --yaml your_conf.yaml```
|
62
|
+
|
63
|
+
|
64
|
+
should create a conf.yaml file with the environments
|
52
65
|
|
53
66
|
## Requirements
|
54
67
|
|
@@ -78,7 +91,14 @@ I originally used this approach but the script grew unwieldy, maybe I don't do g
|
|
78
91
|
|
79
92
|
- ~~error message when config contains env variable that doesnt exist~~ Version 0.0.2
|
80
93
|
- ~~Read config from properties file~~ Version 0.0.4
|
81
|
-
- verbose command
|
94
|
+
- ~~verbose command~~ Version 0.0.5
|
95
|
+
- ~~YAML~~ Version 0.1.0
|
96
|
+
|
97
|
+
### Roadmap
|
98
|
+
- JSON Version 0.1.1
|
99
|
+
- improved logging 0.1.2
|
100
|
+
|
101
|
+
- improve verbose messages
|
82
102
|
- summary of what will change? dry-run maybe?
|
83
103
|
- diff on what has changed in a config if overwriting?
|
84
104
|
- test command.rb
|
data/confswap.gemspec
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'confswap'
|
3
|
-
s.version = '0.0
|
3
|
+
s.version = '0.1.0'
|
4
4
|
s.licenses = ['APACHE2']
|
5
|
-
s.summary = "
|
6
|
-
s.description = "Create
|
5
|
+
s.summary = "Programmatic configuration file maker"
|
6
|
+
s.description = "Create configuration files from templates using environment variables or property lists. Save as text, yaml and json"
|
7
7
|
s.authors = ["Tom Cowling"]
|
8
8
|
s.email = 'tom.cowling@gmail.com'
|
9
9
|
s.homepage = 'https://www.tlcowling.com/gems/confswap'
|
@@ -0,0 +1,31 @@
|
|
1
|
+
Feature: Add environment variables with command line
|
2
|
+
Background:
|
3
|
+
Given a file named "test.conf" with:
|
4
|
+
"""
|
5
|
+
# This is a test config
|
6
|
+
# that has some variables in it
|
7
|
+
%{TEST}
|
8
|
+
%{USER}
|
9
|
+
"""
|
10
|
+
And a file named "test.properties" with:
|
11
|
+
"""
|
12
|
+
TEST: not giblets
|
13
|
+
USER: not alsogiblets
|
14
|
+
"""
|
15
|
+
Scenario: Single environment variable
|
16
|
+
When I run `confswap -p test.properties -e TEST=giblets -t test.conf test.conf.out`
|
17
|
+
Then a file named "test.conf.out" should exist
|
18
|
+
And the file "test.conf.out" should contain:
|
19
|
+
"""
|
20
|
+
giblets
|
21
|
+
"""
|
22
|
+
|
23
|
+
Scenario: Multiple environment variable
|
24
|
+
When I run `confswap -p test.properties -e TEST=giblets -e USER=alsogiblets -t test.conf test.conf.out`
|
25
|
+
Then a file named "test.conf.out" should exist
|
26
|
+
And the file "test.conf.out" should contain:
|
27
|
+
"""
|
28
|
+
giblets
|
29
|
+
alsogiblets
|
30
|
+
"""
|
31
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
Feature: Create a yaml file from the variables passed to confswap
|
2
|
+
Scenario: Use default name for yaml
|
3
|
+
When I run `confswap -e TEST=giblets -e array=[1,2,3] --yaml --ignore-shell-vars`
|
4
|
+
Then a file named "your.conf" should exist
|
5
|
+
And the file "your.conf" should contain:
|
6
|
+
"""
|
7
|
+
---
|
8
|
+
TEST: giblets
|
9
|
+
array:
|
10
|
+
- 1
|
11
|
+
- 2
|
12
|
+
- 3
|
13
|
+
"""
|
14
|
+
|
15
|
+
Scenario: Specify yaml file name and ignore persisted shell variables
|
16
|
+
When I run `confswap -e TEST=giblets -e USER=alsogiblets --ignore-shell-vars --yaml test.yaml`
|
17
|
+
Then a file named "test.yaml" should exist
|
18
|
+
And the file "test.yaml" should contain:
|
19
|
+
"""
|
20
|
+
TEST: giblets
|
21
|
+
USER: alsogiblets
|
22
|
+
"""
|
23
|
+
|
data/features/version.feature
CHANGED
data/lib/confswap.rb
CHANGED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Confswap
|
4
|
+
class BashParser
|
5
|
+
def self.parse_user_input user_input
|
6
|
+
parsed_input = {}
|
7
|
+
user_input.each { |k,v|
|
8
|
+
parsed_input[k.to_s] = self.parse v
|
9
|
+
}
|
10
|
+
parsed_input
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.parse text
|
14
|
+
parsed_text = text
|
15
|
+
parsed_text = parse_as_array text if text.start_with? "["
|
16
|
+
parsed_text = parse_as_object text if text.start_with? "{"
|
17
|
+
parsed_text
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
def self.parse_as_array text
|
22
|
+
parse_as_json_string text
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.parse_as_object text
|
26
|
+
parse_as_json_string text
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.parse_as_json_string text
|
30
|
+
begin
|
31
|
+
return JSON.parse text
|
32
|
+
rescue JSON::ParserError
|
33
|
+
return text
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/confswap/command.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'clamp'
|
2
2
|
require 'confswap'
|
3
|
+
require 'yaml'
|
3
4
|
|
4
5
|
module Confswap
|
5
6
|
class Command < Clamp::Command
|
6
7
|
|
7
|
-
@env_variables
|
8
|
-
|
9
8
|
def initialize *args
|
9
|
+
@env_variables = {}
|
10
10
|
super *args
|
11
11
|
end
|
12
12
|
|
@@ -27,6 +27,11 @@ module Confswap
|
|
27
27
|
return 0
|
28
28
|
end
|
29
29
|
|
30
|
+
if yaml?
|
31
|
+
save_as_yaml()
|
32
|
+
return 0
|
33
|
+
end
|
34
|
+
|
30
35
|
if configuration_filename.nil?
|
31
36
|
puts 'Specify a template file or use --help for usage information'
|
32
37
|
return 0
|
@@ -41,19 +46,22 @@ module Confswap
|
|
41
46
|
end
|
42
47
|
end
|
43
48
|
|
44
|
-
def
|
45
|
-
|
46
|
-
|
47
|
-
configuration_template = Confswap::ConfigurationFileReader.read configuration_filename
|
48
|
-
@env_variables = Confswap::EnvironmentVariableReader.read_variables
|
49
|
-
|
50
|
-
process_envvars() if envvars
|
49
|
+
def gather_variables
|
50
|
+
@env_variables = Confswap::EnvironmentVariableReader.read_variables unless ignore_persisted_shell_variables?
|
51
51
|
|
52
52
|
if !property_file.nil? and File.exists? property_file
|
53
|
-
puts 'pfile specified'
|
54
53
|
@env_variables = Confswap::PropertyFileVariableReader.read_variables_from_file property_file
|
55
54
|
puts @env_variables
|
56
55
|
end
|
56
|
+
|
57
|
+
process_envvars() if envvars
|
58
|
+
end
|
59
|
+
|
60
|
+
def swap_config configuration_filename
|
61
|
+
output_filename_default = configuration_filename + '.out' if output_filename.nil?
|
62
|
+
|
63
|
+
configuration_template = Confswap::ConfigurationFileReader.read configuration_filename
|
64
|
+
gather_variables()
|
57
65
|
|
58
66
|
begin
|
59
67
|
output = configuration_template % @env_variables
|
@@ -86,6 +94,24 @@ module Confswap
|
|
86
94
|
end
|
87
95
|
end
|
88
96
|
|
97
|
+
def save_as_yaml
|
98
|
+
gather_variables()
|
99
|
+
|
100
|
+
@env_variables = parse_envvars()
|
101
|
+
|
102
|
+
output_filename_yaml = output_filename || 'conf.yaml'
|
103
|
+
puts "Writing #{output_filename_yaml}"
|
104
|
+
env_variables_yaml = @env_variables.to_yaml
|
105
|
+
|
106
|
+
write_file env_variables_yaml, output_filename_yaml
|
107
|
+
end
|
108
|
+
|
109
|
+
def parse_envvars
|
110
|
+
parsed_variables = Confswap::BashParser.parse_user_input @env_variables
|
111
|
+
puts "Interpreted user variables: #{parsed_variables}" if verbose?
|
112
|
+
parsed_variables
|
113
|
+
end
|
114
|
+
|
89
115
|
def write_file output_file_contents, output_filename
|
90
116
|
return File.write output_filename, output_file_contents unless File.exists? output_filename
|
91
117
|
|
@@ -103,6 +129,8 @@ module Confswap
|
|
103
129
|
option ['-f','--force'], :flag, "Overwrite file if it already exists", :attribute_name => :force
|
104
130
|
option ['-v', '--version'], :flag, "The version of confswap you are running", :attribute_name => :version
|
105
131
|
option ['--verbose'], :flag, "Be more verbose"
|
132
|
+
option ['-i', '--ignore-shell-vars'], :flag, "Ignore persisted shell variables", :attribute_name => :ignore_persisted_shell_variables
|
133
|
+
option ['-y', '--yaml'], :flag, "Create yaml config from variables", :attribute_name => :yaml
|
106
134
|
parameter "[OUTPUT FILE]", "Path to the configuration file", :attribute_name => :output_filename, :default => "your.conf"
|
107
135
|
end
|
108
136
|
end
|
data/lib/confswap/version.rb
CHANGED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'confswap/bash_parser'
|
2
|
+
|
3
|
+
describe 'Confswap::BashParser' do
|
4
|
+
describe 'normal string' do
|
5
|
+
it 'should not try to parse a normal string' do
|
6
|
+
normal_string = Confswap::BashParser.parse 'normal_string'
|
7
|
+
expect(normal_string).to be_kind_of String
|
8
|
+
expect(normal_string).to_not be_nil
|
9
|
+
end
|
10
|
+
end
|
11
|
+
describe 'Parsing arrays' do
|
12
|
+
it 'should attempt to convert a string starting with a [ to a ruby array object' do
|
13
|
+
parsed_array = Confswap::BashParser.parse '[1,2,3,4]'
|
14
|
+
expect(parsed_array).to be_kind_of Array
|
15
|
+
expect(parsed_array).to eq([1,2,3,4])
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should leave unparseable array as a string' do
|
19
|
+
invalid_array_string = Confswap::BashParser.parse '[1,2'
|
20
|
+
expect(invalid_array_string).to be_kind_of String
|
21
|
+
expect(invalid_array_string).to eq("[1,2")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe 'Ruby hash' do
|
26
|
+
it 'should attempt to convert a string starting with a { to a ruby hash, but leave as a string if not possible' do
|
27
|
+
parsed_array = Confswap::BashParser.parse '{"a": "1", "b": "2", "c": "3", "d": "4"}'
|
28
|
+
expect(parsed_array).to be_kind_of Hash
|
29
|
+
expect(parsed_array).to eq({"a" => "1", "b" => "2", "c" => "3", "d" => "4"})
|
30
|
+
end
|
31
|
+
it 'should leave unparseable object as string' do
|
32
|
+
parsed_array = Confswap::BashParser.parse '{a: 1, b: 2, c: 3, d:'
|
33
|
+
expect(parsed_array).to be_kind_of String
|
34
|
+
expect(parsed_array).to eq('{a: 1, b: 2, c: 3, d:')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe 'Whole User Input' do
|
39
|
+
it 'should parse envvars and convert array strings and hash strings to ruby object' do
|
40
|
+
user_input = {
|
41
|
+
:ARRAY => "[1,2,3,4]",
|
42
|
+
:TEST => "test",
|
43
|
+
:OBJECT => "{}",
|
44
|
+
}
|
45
|
+
parsed_input = Confswap::BashParser.parse_user_input user_input
|
46
|
+
expect(parsed_input).to be_kind_of Hash
|
47
|
+
expect(parsed_input).to eq({
|
48
|
+
"ARRAY" => [1,2,3,4],
|
49
|
+
"TEST" => "test",
|
50
|
+
"OBJECT" => {},
|
51
|
+
})
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/spec/conf_reader_spec.rb
CHANGED
@@ -3,11 +3,11 @@ require_relative './spec_helper.rb'
|
|
3
3
|
|
4
4
|
describe 'Confswap::ConfigFileReader' do
|
5
5
|
before(:each) do
|
6
|
-
File.write('/
|
6
|
+
File.write(tmp_dir + '/test.txt', sample_config)
|
7
7
|
end
|
8
8
|
|
9
9
|
it 'should read the contents of a file specified' do
|
10
|
-
expect(Confswap::ConfigurationFileReader.read '/
|
10
|
+
expect(Confswap::ConfigurationFileReader.read tmp_dir + '/test.txt').to eql(sample_config)
|
11
11
|
end
|
12
12
|
|
13
13
|
it 'should return nil if the file does not exist' do
|
@@ -15,6 +15,6 @@ describe 'Confswap::ConfigFileReader' do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
after(:each) do
|
18
|
-
File.delete('/
|
18
|
+
File.delete(tmp_dir + '/test.txt') if File.exists?(tmp_dir + '/test.txt')
|
19
19
|
end
|
20
20
|
end
|
@@ -3,8 +3,8 @@ require 'confswap/property_reader'
|
|
3
3
|
describe 'Confswap::PropertyFileVariableReader' do
|
4
4
|
it 'should split only on first colon and extra newlines' do
|
5
5
|
variables = "VAR1: 192.168.0.1\n\n\nVAR2: giblets\nVAR3: this should : : have: colons"
|
6
|
-
File.write '
|
7
|
-
vars = Confswap::PropertyFileVariableReader.read_variables_from_file '
|
6
|
+
File.write tmp_dir + '/property_vars', variables
|
7
|
+
vars = Confswap::PropertyFileVariableReader.read_variables_from_file tmp_dir + '/property_vars'
|
8
8
|
|
9
9
|
expect(vars).to be_instance_of Hash
|
10
10
|
expect(vars.length).to equal(3)
|
@@ -18,8 +18,8 @@ describe 'Confswap::PropertyFileVariableReader' do
|
|
18
18
|
|
19
19
|
it 'should ignore comments in a property file' do
|
20
20
|
file_contents = "# this is a comment \nVAR1: 192.168.0.1\n\n\nVAR2: giblets\nVAR3: this should : : have: colons"
|
21
|
-
File.write '
|
22
|
-
vars = Confswap::PropertyFileVariableReader.read_variables_from_file '
|
21
|
+
File.write tmp_dir + '/property_file_with_comments', file_contents
|
22
|
+
vars = Confswap::PropertyFileVariableReader.read_variables_from_file tmp_dir + '/property_file_with_comments'
|
23
23
|
expect(vars.length).to eq(3)
|
24
24
|
expect(vars).to eq({
|
25
25
|
:VAR1 => '192.168.0.1',
|
@@ -30,17 +30,17 @@ describe 'Confswap::PropertyFileVariableReader' do
|
|
30
30
|
|
31
31
|
it 'should warn for invalid property file when property file is empty' do
|
32
32
|
file_contents = ""
|
33
|
-
File.write '
|
33
|
+
File.write tmp_dir + '/invalid_property_file', file_contents
|
34
34
|
expect {
|
35
|
-
Confswap::PropertyFileVariableReader.read_variables_from_file '
|
35
|
+
Confswap::PropertyFileVariableReader.read_variables_from_file tmp_dir + '/invalid_property_file'
|
36
36
|
}.to raise_exception Confswap::PropertyFileVariableReader::InvalidPropertyFileException
|
37
37
|
end
|
38
38
|
|
39
39
|
pending 'should warn for invalid property file when property file is invalid' do
|
40
40
|
file_contents = "# this is a comment \nVAR1: "
|
41
|
-
File.write '
|
41
|
+
File.write tmp_dir + '/invalid_property_file', file_contents
|
42
42
|
expect {
|
43
|
-
Confswap::PropertyFileVariableReader.read_variables_from_file '
|
43
|
+
Confswap::PropertyFileVariableReader.read_variables_from_file tmp_dir + '/invalid_property_file'
|
44
44
|
}.to raise_exception Confswap::PropertyFileVariableReader::InvalidPropertyFileException
|
45
45
|
end
|
46
46
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: confswap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Cowling
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01-
|
11
|
+
date: 2015-01-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: clamp
|
@@ -38,7 +38,8 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
-
description: Create
|
41
|
+
description: Create configuration files from templates using environment variables
|
42
|
+
or property lists. Save as text, yaml and json
|
42
43
|
email: tom.cowling@gmail.com
|
43
44
|
executables:
|
44
45
|
- confswap
|
@@ -54,22 +55,27 @@ files:
|
|
54
55
|
- Rakefile
|
55
56
|
- bin/confswap
|
56
57
|
- confswap.gemspec
|
58
|
+
- features/env_variable_should_overwrite_properties.feature
|
57
59
|
- features/pass_environment_variables_with_command_line.feature
|
58
60
|
- features/property_file.feature
|
61
|
+
- features/save_conf_yaml.feature
|
59
62
|
- features/support/env.rb
|
60
63
|
- features/support/hooks.rb
|
61
64
|
- features/variable_replace.feature
|
62
65
|
- features/version.feature
|
63
66
|
- lib/confswap.rb
|
67
|
+
- lib/confswap/bash_parser.rb
|
64
68
|
- lib/confswap/command.rb
|
65
69
|
- lib/confswap/conf_reader.rb
|
66
70
|
- lib/confswap/env_reader.rb
|
67
71
|
- lib/confswap/property_reader.rb
|
68
72
|
- lib/confswap/version.rb
|
73
|
+
- spec/bash_parser_spec.rb
|
69
74
|
- spec/conf_reader_spec.rb
|
70
75
|
- spec/env_reader_spec.rb
|
71
76
|
- spec/property_reader_spec.rb
|
72
77
|
- spec/spec_helper.rb
|
78
|
+
- spec/tmp/.gitkeep
|
73
79
|
homepage: https://www.tlcowling.com/gems/confswap
|
74
80
|
licenses:
|
75
81
|
- APACHE2
|
@@ -93,15 +99,19 @@ rubyforge_project:
|
|
93
99
|
rubygems_version: 2.4.5
|
94
100
|
signing_key:
|
95
101
|
specification_version: 4
|
96
|
-
summary:
|
102
|
+
summary: Programmatic configuration file maker
|
97
103
|
test_files:
|
104
|
+
- features/env_variable_should_overwrite_properties.feature
|
98
105
|
- features/pass_environment_variables_with_command_line.feature
|
99
106
|
- features/property_file.feature
|
107
|
+
- features/save_conf_yaml.feature
|
100
108
|
- features/support/env.rb
|
101
109
|
- features/support/hooks.rb
|
102
110
|
- features/variable_replace.feature
|
103
111
|
- features/version.feature
|
112
|
+
- spec/bash_parser_spec.rb
|
104
113
|
- spec/conf_reader_spec.rb
|
105
114
|
- spec/env_reader_spec.rb
|
106
115
|
- spec/property_reader_spec.rb
|
107
116
|
- spec/spec_helper.rb
|
117
|
+
- spec/tmp/.gitkeep
|