producer-core 0.2.5 → 0.2.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/features/{actions/echo.feature → action_echo.feature} +1 -1
- data/features/{actions/file_append.feature → action_file_append.feature} +1 -1
- data/features/{actions/file_replace_content.feature → action_file_replace_content.feature} +11 -14
- data/features/{actions/file_write.feature → action_file_write.feature} +7 -12
- data/features/{actions/mkdir.feature → action_mkdir.feature} +8 -13
- data/features/{actions/sh.feature → action_sh.feature} +14 -14
- data/features/{cli/dry_run.feature → cli_dry_run.feature} +0 -0
- data/features/{cli/usage.feature → cli_usage.feature} +1 -0
- data/features/{cli/verbose.feature → cli_verbose.feature} +12 -23
- data/features/{recipes/ask.feature → recipe_ask.feature} +1 -0
- data/features/{recipes/macro.feature → recipe_macro.feature} +4 -4
- data/features/{recipes/source.feature → recipe_source.feature} +3 -1
- data/features/{recipes/target.feature → recipe_target.feature} +3 -1
- data/features/recipe_test_macro.feature +52 -0
- data/features/{recipes/registry.feature → registry.feature} +9 -4
- data/features/{ssh/config.feature → ssh_config.feature} +3 -1
- data/features/support/env.rb +32 -0
- data/features/support/env_aruba_timeout.rb +3 -0
- data/features/{tasks/condition.feature → task_condition.feature} +1 -1
- data/features/{tests/dir.feature → test_dir.feature} +1 -1
- data/features/{tests/env.feature → test_env.feature} +24 -34
- data/features/{tests/executable.feature → test_executable.feature} +12 -14
- data/features/{tests/file.feature → test_file.feature} +1 -1
- data/features/{tests/file_contains.feature → test_file_contains.feature} +1 -1
- data/features/{tests/negated_test.feature → test_negated_test.feature} +0 -0
- data/features/test_shell_command_status.feature +48 -0
- data/lib/producer/core/cli.rb +19 -15
- data/lib/producer/core/condition/dsl.rb +17 -8
- data/lib/producer/core/condition.rb +2 -2
- data/lib/producer/core/env.rb +6 -10
- data/lib/producer/core/errors.rb +2 -1
- data/lib/producer/core/recipe/dsl.rb +4 -0
- data/lib/producer/core/remote.rb +1 -1
- data/lib/producer/core/tests/condition_test.rb +23 -0
- data/lib/producer/core/version.rb +1 -1
- data/lib/producer/core.rb +1 -0
- data/spec/producer/core/cli_spec.rb +73 -44
- data/spec/producer/core/condition/dsl_spec.rb +33 -5
- data/spec/producer/core/env_spec.rb +41 -36
- data/spec/producer/core/recipe/dsl_spec.rb +10 -0
- data/spec/producer/core/remote_spec.rb +16 -7
- data/spec/producer/core/tests/condition_test_spec.rb +55 -0
- metadata +56 -55
- data/features/recipes/evaluation.feature +0 -9
- data/features/tasks/evaluation.feature +0 -11
- data/features/tasks/registry.feature +0 -13
- data/features/tests/shell_command_status.feature +0 -58
@@ -1,58 +1,48 @@
|
|
1
1
|
@sshd
|
2
2
|
Feature: `env?' condition keyword
|
3
3
|
|
4
|
-
|
4
|
+
Background:
|
5
5
|
Given a recipe with:
|
6
6
|
"""
|
7
7
|
target 'some_host.test'
|
8
8
|
|
9
|
-
task :
|
9
|
+
task :env_test_definition_ok do
|
10
10
|
condition { env? :shell }
|
11
11
|
|
12
|
-
echo '
|
12
|
+
echo 'definition_ok'
|
13
13
|
end
|
14
|
-
"""
|
15
|
-
When I successfully execute the recipe
|
16
|
-
Then the output must contain "evaluated"
|
17
14
|
|
18
|
-
|
19
|
-
Given a recipe with:
|
20
|
-
"""
|
21
|
-
target 'some_host.test'
|
22
|
-
|
23
|
-
task :testing_env_var_definition do
|
15
|
+
task :env_test_definition_ko do
|
24
16
|
condition { env? :non_existent_var }
|
25
17
|
|
26
|
-
echo '
|
18
|
+
echo 'definition_ko'
|
27
19
|
end
|
28
|
-
"""
|
29
|
-
When I successfully execute the recipe
|
30
|
-
Then the output must not contain "evaluated"
|
31
|
-
|
32
|
-
Scenario: succeeds when remote environment variable value match
|
33
|
-
Given a recipe with:
|
34
|
-
"""
|
35
|
-
target 'some_host.test'
|
36
20
|
|
37
|
-
task :
|
21
|
+
task :env_test_value do
|
38
22
|
condition { env? :shell, '/bin/sh' }
|
39
23
|
|
40
|
-
echo '
|
24
|
+
echo 'value_ok'
|
41
25
|
end
|
42
|
-
"""
|
43
|
-
When I successfully execute the recipe
|
44
|
-
Then the output must contain "evaluated"
|
45
26
|
|
46
|
-
|
47
|
-
Given a recipe with:
|
48
|
-
"""
|
49
|
-
target 'some_host.test'
|
50
|
-
|
51
|
-
task :testing_env_var_value do
|
27
|
+
task :env_test_value do
|
52
28
|
condition { env? :shell, 'non_existent_shell' }
|
53
29
|
|
54
|
-
echo '
|
30
|
+
echo 'value_ko'
|
55
31
|
end
|
56
32
|
"""
|
33
|
+
|
34
|
+
Scenario: succeeds when remote environment variable is defined
|
35
|
+
When I successfully execute the recipe
|
36
|
+
Then the output must contain "definition_ok"
|
37
|
+
|
38
|
+
Scenario: fails when remote environment variable is not defined
|
39
|
+
When I successfully execute the recipe
|
40
|
+
Then the output must not contain "definition_ko"
|
41
|
+
|
42
|
+
Scenario: succeeds when remote environment variable value match
|
43
|
+
When I successfully execute the recipe
|
44
|
+
Then the output must contain "value_ok"
|
45
|
+
|
46
|
+
Scenario: fails when remote environment variable value does not match
|
57
47
|
When I successfully execute the recipe
|
58
|
-
Then the output must not contain "
|
48
|
+
Then the output must not contain "value_ko"
|
@@ -1,30 +1,28 @@
|
|
1
1
|
@sshd
|
2
2
|
Feature: `executable?' condition keyword
|
3
3
|
|
4
|
-
|
4
|
+
Background:
|
5
5
|
Given a recipe with:
|
6
6
|
"""
|
7
7
|
target 'some_host.test'
|
8
8
|
|
9
|
-
task :
|
9
|
+
task :executable_test_ok do
|
10
10
|
condition { executable? 'true' }
|
11
11
|
|
12
|
-
echo '
|
12
|
+
echo 'test_ok'
|
13
13
|
end
|
14
|
-
"""
|
15
|
-
When I successfully execute the recipe
|
16
|
-
Then the output must contain "evaluated"
|
17
|
-
|
18
|
-
Scenario: succeeds when remote executable is available
|
19
|
-
Given a recipe with:
|
20
|
-
"""
|
21
|
-
target 'some_host.test'
|
22
14
|
|
23
|
-
task :
|
15
|
+
task :executable_test_ok do
|
24
16
|
condition { executable? 'some_non_existent_executable' }
|
25
17
|
|
26
|
-
echo '
|
18
|
+
echo 'test_ko'
|
27
19
|
end
|
28
20
|
"""
|
21
|
+
|
22
|
+
Scenario: succeeds when remote executable is available
|
23
|
+
When I successfully execute the recipe
|
24
|
+
Then the output must contain "test_ok"
|
25
|
+
|
26
|
+
Scenario: fails when remote executable is not available
|
29
27
|
When I successfully execute the recipe
|
30
|
-
Then the output must not contain "
|
28
|
+
Then the output must not contain "test_ko"
|
File without changes
|
@@ -0,0 +1,48 @@
|
|
1
|
+
@sshd
|
2
|
+
Feature: `sh' and `` condition keyword
|
3
|
+
|
4
|
+
Background:
|
5
|
+
Given a recipe with:
|
6
|
+
"""
|
7
|
+
target 'some_host.test'
|
8
|
+
|
9
|
+
task :sh_test_ok do
|
10
|
+
condition { sh 'true' }
|
11
|
+
|
12
|
+
echo 'test_ok'
|
13
|
+
end
|
14
|
+
|
15
|
+
task :sh_test_ko do
|
16
|
+
condition { sh 'false' }
|
17
|
+
|
18
|
+
echo 'test_ko'
|
19
|
+
end
|
20
|
+
|
21
|
+
task :sh_test_backtick_ok do
|
22
|
+
condition { `true` }
|
23
|
+
|
24
|
+
echo 'test_backtick_ok'
|
25
|
+
end
|
26
|
+
|
27
|
+
task :sh_test_backtick_ko do
|
28
|
+
condition { `false` }
|
29
|
+
|
30
|
+
echo 'test_backtick_ko'
|
31
|
+
end
|
32
|
+
"""
|
33
|
+
|
34
|
+
Scenario: succeeds when remote command execution is a success
|
35
|
+
When I successfully execute the recipe
|
36
|
+
Then the output must contain "test_ok"
|
37
|
+
|
38
|
+
Scenario: fails when remote executable is not available
|
39
|
+
When I successfully execute the recipe
|
40
|
+
Then the output must not contain "test_ko"
|
41
|
+
|
42
|
+
Scenario: `` alias, succeeds when remote executable is available
|
43
|
+
When I successfully execute the recipe
|
44
|
+
Then the output must contain "test_backtick_ok"
|
45
|
+
|
46
|
+
Scenario: `` alias, fails when remote executable is not available
|
47
|
+
When I successfully execute the recipe
|
48
|
+
Then the output must not contain "test_backtick_ko"
|
data/lib/producer/core/cli.rb
CHANGED
@@ -3,36 +3,41 @@ module Producer
|
|
3
3
|
class CLI
|
4
4
|
ArgumentError = Class.new(::ArgumentError)
|
5
5
|
|
6
|
-
USAGE = "Usage: #{File.basename $0} [-v] [-n] recipe_file"
|
6
|
+
USAGE = "Usage: #{File.basename $0} [-v] [-n] recipe_file".freeze
|
7
7
|
|
8
|
-
EX_USAGE
|
8
|
+
EX_USAGE = 64
|
9
|
+
EX_SOFTWARE = 70
|
9
10
|
|
10
11
|
class << self
|
11
|
-
def run!(arguments,
|
12
|
+
def run!(arguments, stdin: $stdin, stdout: $stdout, stderr: $stderr)
|
13
|
+
cli = new(arguments, stdin: stdin, stdout: stdout, stderr: stderr)
|
12
14
|
begin
|
13
|
-
cli = new(arguments)
|
14
15
|
cli.parse_arguments!
|
16
|
+
cli.run
|
15
17
|
rescue ArgumentError
|
16
|
-
|
18
|
+
stderr.puts USAGE
|
17
19
|
exit EX_USAGE
|
20
|
+
rescue RuntimeError => e
|
21
|
+
stderr.puts "#{e.class.name.split('::').last}: #{e.message}"
|
22
|
+
exit EX_SOFTWARE
|
18
23
|
end
|
19
|
-
cli.run
|
20
24
|
end
|
21
25
|
end
|
22
26
|
|
23
|
-
attr_reader :arguments, :stdout, :
|
27
|
+
attr_reader :arguments, :stdin, :stdout, :stderr, :env
|
24
28
|
|
25
|
-
def initialize(args, stdout: $stdout)
|
29
|
+
def initialize(args, stdin: $stdin, stdout: $stdout, stderr: $stderr)
|
26
30
|
@arguments = args
|
31
|
+
@stdin = stdin
|
27
32
|
@stdout = stdout
|
28
|
-
@env = Env.new(output: stdout)
|
33
|
+
@env = Env.new(input: stdin, output: stdout)
|
29
34
|
end
|
30
35
|
|
31
36
|
def parse_arguments!
|
32
37
|
@arguments = arguments.inject([]) do |m, e|
|
33
38
|
case e
|
34
39
|
when '-v'
|
35
|
-
env.
|
40
|
+
env.verbose = true
|
36
41
|
when '-n'
|
37
42
|
env.dry_run = true
|
38
43
|
else
|
@@ -44,16 +49,15 @@ module Producer
|
|
44
49
|
raise ArgumentError unless arguments.any?
|
45
50
|
end
|
46
51
|
|
47
|
-
def run
|
48
|
-
load_recipe
|
49
|
-
worker.process recipe.tasks
|
52
|
+
def run
|
53
|
+
worker.process load_recipe.tasks
|
50
54
|
end
|
51
55
|
|
52
56
|
def load_recipe
|
53
|
-
|
57
|
+
Recipe.evaluate_from_file(@arguments.first, env)
|
54
58
|
end
|
55
59
|
|
56
|
-
def
|
60
|
+
def worker
|
57
61
|
Worker.new(env)
|
58
62
|
end
|
59
63
|
end
|
@@ -3,12 +3,21 @@ module Producer
|
|
3
3
|
class Condition
|
4
4
|
class DSL
|
5
5
|
class << self
|
6
|
-
def define_test(keyword,
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
def define_test(keyword, test)
|
7
|
+
{
|
8
|
+
keyword => false,
|
9
|
+
"no_#{keyword}" => true
|
10
|
+
}.each do |kw, negated|
|
11
|
+
define_method(kw) do |*args|
|
12
|
+
if test.respond_to? :call
|
13
|
+
args = [test, *args]
|
14
|
+
klass = Tests::ConditionTest
|
15
|
+
else
|
16
|
+
klass = test
|
17
|
+
end
|
18
|
+
t = klass.new(@env, *args, negated: negated)
|
19
|
+
@tests << t
|
20
|
+
end
|
12
21
|
end
|
13
22
|
end
|
14
23
|
end
|
@@ -29,8 +38,8 @@ module Producer
|
|
29
38
|
@tests = []
|
30
39
|
end
|
31
40
|
|
32
|
-
def evaluate
|
33
|
-
|
41
|
+
def evaluate(*args)
|
42
|
+
instance_exec *args, &@block
|
34
43
|
end
|
35
44
|
end
|
36
45
|
end
|
@@ -2,9 +2,9 @@ module Producer
|
|
2
2
|
module Core
|
3
3
|
class Condition
|
4
4
|
class << self
|
5
|
-
def evaluate(env, &block)
|
5
|
+
def evaluate(env, *args, &block)
|
6
6
|
dsl = DSL.new(env, &block)
|
7
|
-
return_value = dsl.evaluate
|
7
|
+
return_value = dsl.evaluate *args
|
8
8
|
Condition.new(dsl.tests, return_value)
|
9
9
|
end
|
10
10
|
end
|
data/lib/producer/core/env.rb
CHANGED
@@ -2,14 +2,14 @@ module Producer
|
|
2
2
|
module Core
|
3
3
|
class Env
|
4
4
|
attr_reader :input, :output, :registry, :logger
|
5
|
-
attr_accessor :target, :dry_run
|
5
|
+
attr_accessor :target, :verbose, :dry_run
|
6
6
|
|
7
7
|
def initialize(input: $stdin, output: $stdout, remote: nil, registry: {})
|
8
|
+
@verbose = @dry_run = false
|
8
9
|
@input = input
|
9
10
|
@output = output
|
10
|
-
@registry = registry
|
11
11
|
@remote = remote
|
12
|
-
@
|
12
|
+
@registry = registry
|
13
13
|
end
|
14
14
|
|
15
15
|
def remote
|
@@ -27,7 +27,7 @@ module Producer
|
|
27
27
|
def logger
|
28
28
|
@logger ||= begin
|
29
29
|
logger = Logger.new(output)
|
30
|
-
logger.level = Logger::ERROR
|
30
|
+
logger.level = verbose? ? Logger::INFO : Logger::ERROR
|
31
31
|
logger.formatter = LoggerFormatter.new
|
32
32
|
logger
|
33
33
|
end
|
@@ -37,12 +37,8 @@ module Producer
|
|
37
37
|
logger.info message
|
38
38
|
end
|
39
39
|
|
40
|
-
def
|
41
|
-
|
42
|
-
end
|
43
|
-
|
44
|
-
def log_level=(level)
|
45
|
-
logger.level = level
|
40
|
+
def verbose?
|
41
|
+
@verbose
|
46
42
|
end
|
47
43
|
|
48
44
|
def dry_run?
|
data/lib/producer/core/errors.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
module Producer
|
2
2
|
module Core
|
3
3
|
Error = Class.new(StandardError)
|
4
|
+
RuntimeError = Class.new(RuntimeError)
|
4
5
|
ConditionNotMetError = Class.new(Error)
|
5
|
-
RemoteCommandExecutionError = Class.new(
|
6
|
+
RemoteCommandExecutionError = Class.new(RuntimeError)
|
6
7
|
end
|
7
8
|
end
|
data/lib/producer/core/remote.rb
CHANGED
@@ -0,0 +1,23 @@
|
|
1
|
+
module Producer
|
2
|
+
module Core
|
3
|
+
module Tests
|
4
|
+
class ConditionTest < Test
|
5
|
+
def verify
|
6
|
+
condition.met?
|
7
|
+
end
|
8
|
+
|
9
|
+
def condition
|
10
|
+
Condition.evaluate(env, *condition_args, &condition_block)
|
11
|
+
end
|
12
|
+
|
13
|
+
def condition_args
|
14
|
+
arguments.drop 1
|
15
|
+
end
|
16
|
+
|
17
|
+
def condition_block
|
18
|
+
arguments.first
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|