specimen 0.0.3.alpha → 0.0.4.alpha
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 +53 -49
- data/VERSION +1 -1
- data/lib/specimen/command/exec_command_builder.rb +42 -12
- data/lib/specimen/command/runner/cukes_runner.rb +2 -18
- data/lib/specimen/command/runner/specs_runner.rb +2 -17
- data/lib/specimen/command/test_runner.rb +19 -25
- data/lib/specimen/command.rb +12 -5
- data/lib/specimen/commands/encrypted_configuration/USAGE +37 -0
- data/lib/specimen/commands/encrypted_configuration/encrypted_configuration_command.rb +108 -0
- data/lib/specimen/commands/gem_help/USAGE +3 -3
- data/lib/specimen/config_parser.rb +31 -0
- data/lib/specimen/generator/configs/specimen_project_config.rb +1 -1
- data/lib/specimen/generator/cucumber/cucumber_project_generator.rb +2 -0
- data/lib/specimen/generator/cucumber/templates/config/cucumber.yml.tt +4 -1
- data/lib/specimen/generator/cucumber/templates/config/specimen.cukes.yml.tt +22 -0
- data/lib/specimen/generator/cucumber/templates/features/examples/add_numbers.feature.tt +4 -2
- data/lib/specimen/generator/cucumber/templates/features/step_definitions/examples/example_steps.rb.tt +9 -0
- data/lib/specimen/generator/cucumber/templates/features/support/env.rb.tt +22 -0
- data/lib/specimen/generator/project/project_root_generator.rb +0 -1
- data/lib/specimen/generator/project/specimen_project_generator.rb +37 -0
- data/lib/specimen/generator/project/templates/root/config/specimen.yml.tt +11 -7
- data/lib/specimen/generator/rspec/rspec_project_generator.rb +1 -0
- data/lib/specimen/generator/rspec/templates/config/.rspec.tt +0 -4
- data/lib/specimen/generator/rspec/templates/config/specimen.specs.yml.tt +19 -0
- data/lib/specimen/generator/rspec/templates/spec/examples/example_spec.rb.tt +9 -5
- data/lib/specimen/generator/rspec/templates/spec/spec_helper.rb.tt +7 -5
- data/lib/specimen/runtime.rb +124 -54
- data/lib/specimen/utils/encrypted_config_path.rb +54 -0
- data/lib/specimen/utils/encrypted_configuration.rb +156 -0
- data/lib/specimen/utils.rb +8 -0
- data/lib/specimen/version.rb +1 -1
- data/lib/specimen.rb +13 -5
- metadata +11 -5
- data/lib/specimen/command/runner/exec_runner.rb +0 -37
- data/lib/specimen/commands/exec/exec_command.rb +0 -9
- data/lib/specimen/runtime/yml_parser.rb +0 -47
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib_path = "#{File.expand_path(__dir__)}/lib"
|
4
|
+
$LOAD_PATH.unshift(lib_path) unless $LOAD_PATH.include?(lib_path)
|
5
|
+
|
6
|
+
require 'pry' if ENV.key?('DEBUG')
|
7
|
+
require 'specimen'
|
8
|
+
require 'rspec'
|
9
|
+
|
10
|
+
World RSpec::Expectations, RSpec::Matchers
|
11
|
+
|
12
|
+
BeforeAll do
|
13
|
+
Specimen.run_testrunner_hooks!
|
14
|
+
end
|
15
|
+
|
16
|
+
Before do
|
17
|
+
@enc_config = Specimen.enc_config
|
18
|
+
end
|
19
|
+
|
20
|
+
at_exit do
|
21
|
+
p 'bye bye'
|
22
|
+
end
|
@@ -13,12 +13,49 @@ module Specimen
|
|
13
13
|
CucumberProjectGenerator.start([config]) if config[:cucumber]
|
14
14
|
RSpecProjectGenerator.start([config]) if config[:rspec]
|
15
15
|
|
16
|
+
inside config[:root_path] do
|
17
|
+
run('specimen enc create --name example')
|
18
|
+
|
19
|
+
env_file = '.example.env'
|
20
|
+
enc_key = File.read "#{Dir.pwd}/config/enc/example.key"
|
21
|
+
content = "MASTER_KEY='#{enc_key}'\n"
|
22
|
+
File.write(env_file, content)
|
23
|
+
|
24
|
+
say("Created env-file '#{env_file}' containing the MASTER_KEY to decrypt config/enc/example.yml.enc".bold)
|
25
|
+
end
|
26
|
+
|
27
|
+
say(init_message.green.bold)
|
16
28
|
true
|
17
29
|
end
|
18
30
|
|
19
31
|
def config
|
20
32
|
@config ||= Generator::SpecimenProjectConfig.parse(options)
|
21
33
|
end
|
34
|
+
|
35
|
+
def init_message
|
36
|
+
enc_config = 'config/enc/example.yml.enc'
|
37
|
+
|
38
|
+
<<~STRING
|
39
|
+
|
40
|
+
Created new specimen project in
|
41
|
+
#{config[:root_path]}
|
42
|
+
|
43
|
+
Please cd into the directory and run e.g.
|
44
|
+
|
45
|
+
# check out the help for cukes and specs command
|
46
|
+
$> specimen cukes|specs --help|-h
|
47
|
+
|
48
|
+
# run tests using the encrypted example configuration
|
49
|
+
$> specimen cukes|specs --specimen-profile|--sp examples
|
50
|
+
|
51
|
+
# Check out the 'enc' command help
|
52
|
+
$> specimen enc --help|-h
|
53
|
+
|
54
|
+
# Read and update the encrypted config '#{enc_config}'
|
55
|
+
$> specimen enc update --name|-n example
|
56
|
+
|
57
|
+
STRING
|
58
|
+
end
|
22
59
|
end
|
23
60
|
end
|
24
61
|
end
|
@@ -3,6 +3,7 @@ default: &default
|
|
3
3
|
env:
|
4
4
|
- FOO='123'
|
5
5
|
|
6
|
+
<% if data[:cucumber] -%>
|
6
7
|
cucumber: &cucumber
|
7
8
|
framework: cucumber
|
8
9
|
profiles: []
|
@@ -14,6 +15,15 @@ cucumber: &cucumber
|
|
14
15
|
- FOO='123'
|
15
16
|
- BAZ='something'
|
16
17
|
|
18
|
+
ci_cukes:
|
19
|
+
<<: *cucumber
|
20
|
+
env:
|
21
|
+
- CI='1'
|
22
|
+
profiles:
|
23
|
+
- regression
|
24
|
+
<% end -%>
|
25
|
+
|
26
|
+
<% if data[:rspec] -%>
|
17
27
|
rspec: &rspec
|
18
28
|
framework: rspec
|
19
29
|
options:
|
@@ -29,10 +39,4 @@ ci_specs:
|
|
29
39
|
<<: *rspec
|
30
40
|
env:
|
31
41
|
- CI='1'
|
32
|
-
|
33
|
-
ci_cukes:
|
34
|
-
<<: *cucumber
|
35
|
-
env:
|
36
|
-
- CI='1'
|
37
|
-
profiles:
|
38
|
-
- regression
|
42
|
+
<% end -%>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
default_opts: &default_opts
|
2
|
+
- --options config/.rspec
|
3
|
+
- --format documentation
|
4
|
+
- --format html --out tmp/rspec_result.html
|
5
|
+
|
6
|
+
rspec: &rspec
|
7
|
+
options: *default_opts
|
8
|
+
|
9
|
+
examples:
|
10
|
+
<<: *rspec
|
11
|
+
env_file: .example.env
|
12
|
+
enc_configs:
|
13
|
+
- name: example
|
14
|
+
env_key: MASTER_KEY
|
15
|
+
|
16
|
+
ci_specs:
|
17
|
+
<<: *rspec
|
18
|
+
env:
|
19
|
+
- CI='1'
|
@@ -1,13 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
RSpec.describe '
|
4
|
-
context '
|
3
|
+
RSpec.describe 'Add numbers specs' do
|
4
|
+
context 'add 1 + 1', add_numbers: true do
|
5
5
|
before(:example) do
|
6
|
-
@
|
6
|
+
@result = 1 + 1
|
7
7
|
end
|
8
8
|
|
9
|
-
it 'passes' do
|
10
|
-
expect(@
|
9
|
+
it 'passes', pass: true do
|
10
|
+
expect(@result).to eq 2
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'fails due to not being an integer', fail: true do
|
14
|
+
expect(@result).to eq '2'
|
11
15
|
end
|
12
16
|
end
|
13
17
|
end
|
@@ -1,12 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
require 'pry'
|
3
|
+
require 'specimen'
|
5
4
|
|
6
5
|
RSpec.configure do |config|
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
config.before(:suite) do
|
7
|
+
Specimen.run_testrunner_hooks!
|
8
|
+
end
|
9
|
+
|
10
|
+
config.before(:all) do
|
11
|
+
@enc_config = Specimen.enc_config
|
10
12
|
end
|
11
13
|
end
|
12
14
|
|
data/lib/specimen/runtime.rb
CHANGED
@@ -1,84 +1,154 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require 'dotenv'
|
4
|
+
require 'specimen/config_parser'
|
4
5
|
|
5
6
|
module Specimen
|
6
|
-
|
7
|
-
class
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
class Runtime
|
8
|
+
class ConfigNotFoundError < RuntimeError; end
|
9
|
+
class ProfileNotFoundError < RuntimeError; end
|
10
|
+
|
11
|
+
attr_reader :wd_path, :config_directory,
|
12
|
+
:program_name, :config_data,
|
13
|
+
:profile_data, :framework
|
14
|
+
|
15
|
+
attr_accessor :command, :specimen_config, :specimen_profile
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@wd_path = Pathname.getwd
|
19
|
+
@config_directory = Pathname.new("#{wd_path}/config")
|
20
|
+
@program_name = $PROGRAM_NAME
|
21
|
+
@command = nil
|
22
|
+
@specimen_config = nil
|
23
|
+
@specimen_profile = nil
|
24
|
+
@config_data = nil
|
25
|
+
@profile_data = nil
|
12
26
|
end
|
13
27
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
28
|
+
def set_testrunner!(config, profile, command)
|
29
|
+
@specimen_config = config
|
30
|
+
@specimen_profile = profile
|
31
|
+
@command = command
|
32
|
+
|
33
|
+
define_framework!
|
34
|
+
run_default_profile_checks!
|
35
|
+
|
36
|
+
load_specimen_config!
|
37
|
+
load_specimen_profile!
|
19
38
|
end
|
20
39
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
40
|
+
def run_load_profile_hook!
|
41
|
+
@specimen_config = ENV.fetch('SPECIMEN_CONFIG_NAME')
|
42
|
+
@specimen_profile = ENV.fetch('SPECIMEN_PROFILE_NAME')
|
43
|
+
|
44
|
+
load_specimen_config!
|
45
|
+
load_specimen_profile!
|
26
46
|
end
|
27
47
|
|
28
|
-
|
48
|
+
def run_env_file_hook!
|
49
|
+
return unless profile_with_env_file?
|
29
50
|
|
30
|
-
|
31
|
-
|
51
|
+
file = profile_data['env_file']
|
52
|
+
path = Pathname.new("#{wd_path}/#{file}")
|
32
53
|
|
33
|
-
|
34
|
-
@command = command
|
35
|
-
@config = config
|
54
|
+
return Dotenv.load!(path.to_path) if path.exist?
|
36
55
|
|
37
|
-
|
38
|
-
|
56
|
+
raise "Environment file: '#{path.to_path}' is defined in profile '#{specimen_profile}' but it does not exist!"
|
57
|
+
end
|
39
58
|
|
40
|
-
|
41
|
-
|
59
|
+
def run_decrypt_enc_configs_hook!
|
60
|
+
return unless profile_with_enc_configs?
|
42
61
|
|
43
|
-
|
44
|
-
|
45
|
-
end
|
62
|
+
encrypted_config = {}
|
63
|
+
enc_configs = profile_data['enc_configs']
|
46
64
|
|
47
|
-
|
48
|
-
|
49
|
-
|
65
|
+
enc_configs.each do |enc_config|
|
66
|
+
name = enc_config['name']
|
67
|
+
env_key = enc_config['env_key']
|
50
68
|
|
51
|
-
|
52
|
-
|
53
|
-
end
|
69
|
+
warn "env key '#{env_key}' defined but not set!" if env_key && !ENV.key?(env_key)
|
70
|
+
env_key.nil? ? env_key = '' : env_key
|
54
71
|
|
55
|
-
|
56
|
-
|
72
|
+
config = Specimen::Utils::EncryptedConfiguration.decrypt(name:, env_key:)
|
73
|
+
encrypted_config.merge!(config)
|
57
74
|
end
|
58
75
|
|
59
|
-
|
60
|
-
|
76
|
+
Specimen.enc_config = encrypted_config
|
77
|
+
end
|
61
78
|
|
62
|
-
|
63
|
-
|
79
|
+
def define_framework!
|
80
|
+
raise 'Unrecognized command' unless cukes? || specs?
|
64
81
|
|
65
|
-
|
66
|
-
|
82
|
+
@framework = cukes? ? 'cucumber' : 'rspec'
|
83
|
+
end
|
67
84
|
|
68
|
-
|
69
|
-
|
85
|
+
def run_default_profile_checks!
|
86
|
+
raise 'You can not use the rspec profile with Cucumber!' if cukes? && specimen_profile == 'rspec'
|
87
|
+
raise 'You can not use the cucumber profile with RSpec!' if specs? && specimen_profile == 'cucumber'
|
88
|
+
end
|
70
89
|
|
71
|
-
|
72
|
-
|
73
|
-
end
|
90
|
+
def load_specimen_profile!
|
91
|
+
raise 'Specimen profile is not set!' if specimen_profile.nil? || specimen_profile.empty?
|
74
92
|
|
75
|
-
|
76
|
-
|
93
|
+
unless config_data&.key?(specimen_profile)
|
94
|
+
raise ProfileNotFoundError, "Can not find profile '#{specimen_profile}' in #{specimen_config_path.to_path}"
|
77
95
|
end
|
78
96
|
|
79
|
-
|
80
|
-
|
81
|
-
|
97
|
+
@profile_data = config_data[specimen_profile]
|
98
|
+
end
|
99
|
+
|
100
|
+
def load_specimen_config!
|
101
|
+
raise ConfigNotFoundError, 'Specimen config not found' unless specimen_config_exist?
|
102
|
+
|
103
|
+
@config_data = ConfigParser.read!(specimen_config_path.to_path)
|
104
|
+
end
|
105
|
+
|
106
|
+
def specimen_config_path
|
107
|
+
Pathname.new("#{config_directory}/#{specimen_config}")
|
108
|
+
end
|
109
|
+
|
110
|
+
def custom_config
|
111
|
+
@specimen_config
|
112
|
+
end
|
113
|
+
|
114
|
+
def profile_with_enc_configs?
|
115
|
+
return false unless profile_data.is_a?(Hash)
|
116
|
+
|
117
|
+
profile_data&.key?('enc_configs')
|
118
|
+
end
|
119
|
+
|
120
|
+
def profile_with_env_file?
|
121
|
+
return false unless profile_data.is_a?(Hash)
|
122
|
+
|
123
|
+
profile_data&.key?('env_file')
|
124
|
+
end
|
125
|
+
|
126
|
+
def cukes?
|
127
|
+
return false if command.nil?
|
128
|
+
|
129
|
+
command.is_a?(Command::CukesCommand)
|
130
|
+
end
|
131
|
+
|
132
|
+
def specs?
|
133
|
+
return false if command.nil?
|
134
|
+
|
135
|
+
command.is_a?(Command::SpecsCommand)
|
136
|
+
end
|
137
|
+
|
138
|
+
def specimen_config_exist?
|
139
|
+
specimen_config_path.exist?
|
140
|
+
end
|
141
|
+
|
142
|
+
def specimen_bin?
|
143
|
+
program_name.include?('bin/specimen')
|
144
|
+
end
|
145
|
+
|
146
|
+
def cucumber_bin?
|
147
|
+
program_name.include?('bin/cucumber')
|
148
|
+
end
|
149
|
+
|
150
|
+
def parallel_cucumber_bin?
|
151
|
+
program_name.include?('bin/parallel_cucumber')
|
82
152
|
end
|
83
153
|
end
|
84
154
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Specimen
|
4
|
+
module Utils
|
5
|
+
class EncryptedConfigPath
|
6
|
+
ENC_DIRECTORY = 'config/enc'
|
7
|
+
|
8
|
+
attr_reader :name, :runtime
|
9
|
+
|
10
|
+
def initialize(name:)
|
11
|
+
@name = name
|
12
|
+
@runtime = Specimen.runtime
|
13
|
+
end
|
14
|
+
|
15
|
+
def config_base_dir
|
16
|
+
@config_base_dir ||= Pathname.new("#{runtime.wd_path}/#{ENC_DIRECTORY}")
|
17
|
+
end
|
18
|
+
|
19
|
+
def enc_dir
|
20
|
+
return Pathname.new(config_base_dir.to_path) if config_dir.empty?
|
21
|
+
|
22
|
+
Pathname.new("#{config_base_dir}/#{config_dir}")
|
23
|
+
end
|
24
|
+
|
25
|
+
def config_file_name
|
26
|
+
"#{split_name.last}.yml.enc"
|
27
|
+
end
|
28
|
+
|
29
|
+
def config_dir
|
30
|
+
split_name[0...-1].join('/')
|
31
|
+
end
|
32
|
+
|
33
|
+
def split_name
|
34
|
+
name.split('/')
|
35
|
+
end
|
36
|
+
|
37
|
+
def full_enc_path
|
38
|
+
@full_enc_path ||= Pathname.new("#{enc_dir}/#{config_file_name}")
|
39
|
+
end
|
40
|
+
|
41
|
+
def full_key_path
|
42
|
+
@full_key_path ||= Pathname.new("#{enc_dir}/#{config_file_name.gsub('.yml.enc', '.key')}")
|
43
|
+
end
|
44
|
+
|
45
|
+
def config_exist?
|
46
|
+
full_enc_path.exist?
|
47
|
+
end
|
48
|
+
|
49
|
+
def key_exist?
|
50
|
+
full_key_path.exist?
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/encrypted_configuration'
|
4
|
+
require 'specimen/utils/encrypted_config_path'
|
5
|
+
|
6
|
+
module Specimen
|
7
|
+
module Utils
|
8
|
+
class EncryptedConfiguration
|
9
|
+
class ExistingConfigFilesError < StandardError; end
|
10
|
+
class NoSuchConfigError < StandardError; end
|
11
|
+
class MissingKeyFileError < StandardError; end
|
12
|
+
class MissingKeyFileError < StandardError; end
|
13
|
+
|
14
|
+
attr_accessor :name
|
15
|
+
attr_reader :enc_path, :env_key, :config_path, :key_path
|
16
|
+
|
17
|
+
def self.create(name:)
|
18
|
+
new(name:).create_encrypted_config!
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.update(name:)
|
22
|
+
new(name:).update_encrypted_config!
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.validate(name:)
|
26
|
+
new(name:).validate_encrypted_config!
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.decrypt(name:, env_key: 'MASTER_KEY')
|
30
|
+
new(name:, env_key:).decrypt_config!
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(name:, env_key: '')
|
34
|
+
@name = name
|
35
|
+
@enc_path = EncryptedConfigPath.new(name:)
|
36
|
+
@config_path = @enc_path.full_enc_path
|
37
|
+
@key_path = @enc_path.full_key_path
|
38
|
+
@env_key = env_key
|
39
|
+
end
|
40
|
+
|
41
|
+
def decrypt_config!
|
42
|
+
raise NoSuchConfigError, "No such file: '#{config_path.to_path}'" unless config_exist?
|
43
|
+
raise "Missing decryption key for enc-config '#{enc_path.name}'" unless decryption_key?
|
44
|
+
|
45
|
+
YAML.load(enc_yml_content).deep_symbolize_keys!
|
46
|
+
end
|
47
|
+
|
48
|
+
def validate_encrypted_config!
|
49
|
+
run_enc_files_check!
|
50
|
+
YAML.load(enc_yml_content)
|
51
|
+
enc_path
|
52
|
+
rescue StandardError => e
|
53
|
+
e
|
54
|
+
end
|
55
|
+
|
56
|
+
def enc_yml_content
|
57
|
+
enc_config.read
|
58
|
+
end
|
59
|
+
|
60
|
+
def decryption_key?
|
61
|
+
key_exist? || env_key_set?
|
62
|
+
end
|
63
|
+
|
64
|
+
def env_key_set?
|
65
|
+
return false if env_key.empty?
|
66
|
+
|
67
|
+
ENV.key?(env_key)
|
68
|
+
end
|
69
|
+
|
70
|
+
def run_enc_files_check!
|
71
|
+
raise NoSuchConfigError, "No such file: '#{config_path.to_path}'" unless config_exist?
|
72
|
+
raise MissingKeyFileError, "Missing encryption key file: '#{key_path.to_path}'" unless key_exist?
|
73
|
+
end
|
74
|
+
|
75
|
+
def update_encrypted_config!
|
76
|
+
raise NoSuchConfigError, "No such file: '#{config_path.to_path}'" unless config_exist?
|
77
|
+
raise MissingKeyFileError, "Missing encryption key file: '#{key_path.to_path}'" unless key_exist?
|
78
|
+
raise 'Missing EDITOR variable' unless editor_set?
|
79
|
+
raise "Can not find executable for editor '#{editor}'" unless editor?
|
80
|
+
|
81
|
+
enc_config.change do |tmp_path|
|
82
|
+
system("#{ENV.fetch('EDITOR')} #{tmp_path}")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def create_encrypted_config!
|
87
|
+
raise ExistingConfigFilesError, "Existing config at #{config_path.to_path}" if config_exist?
|
88
|
+
raise ExistingConfigFilesError, "Existing key file at #{key_path.to_path}" if key_exist?
|
89
|
+
|
90
|
+
create_key_file!
|
91
|
+
create_enc_config!
|
92
|
+
|
93
|
+
enc_path
|
94
|
+
end
|
95
|
+
|
96
|
+
def enc_config
|
97
|
+
@enc_config ||= ActiveSupport::EncryptedConfiguration.new(
|
98
|
+
config_path:,
|
99
|
+
key_path:,
|
100
|
+
env_key:,
|
101
|
+
raise_if_missing_key: true
|
102
|
+
)
|
103
|
+
end
|
104
|
+
|
105
|
+
def config_exist?
|
106
|
+
enc_path.config_exist?
|
107
|
+
end
|
108
|
+
|
109
|
+
def key_exist?
|
110
|
+
enc_path.key_exist?
|
111
|
+
end
|
112
|
+
|
113
|
+
def create_key_file!
|
114
|
+
FileUtils.mkdir_p(key_path.dirname) unless key_path.directory?
|
115
|
+
key_path.write(generate_key)
|
116
|
+
end
|
117
|
+
|
118
|
+
def create_enc_config!
|
119
|
+
enc_config.write(example_yml)
|
120
|
+
end
|
121
|
+
|
122
|
+
def generate_key
|
123
|
+
ActiveSupport::EncryptedFile.generate_key
|
124
|
+
end
|
125
|
+
|
126
|
+
def editor
|
127
|
+
ENV.fetch('EDITOR')
|
128
|
+
end
|
129
|
+
|
130
|
+
def editor_set?
|
131
|
+
ENV.fetch('EDITOR', false)
|
132
|
+
end
|
133
|
+
|
134
|
+
def editor?
|
135
|
+
system("command -v #{editor}")
|
136
|
+
end
|
137
|
+
|
138
|
+
def example_yml
|
139
|
+
<<~YML
|
140
|
+
user:
|
141
|
+
email: john.doe@example.com
|
142
|
+
password: johnspassword
|
143
|
+
|
144
|
+
service:
|
145
|
+
host: https://api.my-website.biz
|
146
|
+
client_id: secret-id
|
147
|
+
client_secret: client-secret
|
148
|
+
|
149
|
+
platform:
|
150
|
+
website_url: https://my-website.biz
|
151
|
+
admin_url: https://admin.my-website.biz
|
152
|
+
YML
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
data/lib/specimen/version.rb
CHANGED
data/lib/specimen.rb
CHANGED
@@ -13,13 +13,21 @@ require 'specimen/runtime'
|
|
13
13
|
require 'specimen/version'
|
14
14
|
|
15
15
|
module Specimen
|
16
|
-
extend ActiveSupport::Autoload
|
17
|
-
|
18
16
|
class << self
|
19
|
-
attr_accessor :
|
17
|
+
attr_accessor :enc_config
|
18
|
+
|
19
|
+
def runtime
|
20
|
+
@runtime ||= Specimen::Runtime.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def run_testrunner_hooks!
|
24
|
+
runtime.run_load_profile_hook!
|
25
|
+
runtime.run_env_file_hook!
|
26
|
+
runtime.run_decrypt_enc_configs_hook!
|
27
|
+
end
|
20
28
|
|
21
|
-
def
|
22
|
-
|
29
|
+
def shell
|
30
|
+
runtime&.command.shell
|
23
31
|
end
|
24
32
|
end
|
25
33
|
end
|