producer-core 0.1.10 → 0.1.11
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/features/recipes/ask.feature +22 -0
- data/features/steps/recipe_steps.rb +4 -0
- data/lib/producer/core.rb +1 -0
- data/lib/producer/core/action.rb +2 -2
- data/lib/producer/core/cli.rb +1 -2
- data/lib/producer/core/condition.rb +2 -0
- data/lib/producer/core/condition/dsl.rb +1 -1
- data/lib/producer/core/env.rb +4 -2
- data/lib/producer/core/prompter.rb +21 -0
- data/lib/producer/core/recipe/dsl.rb +1 -3
- data/lib/producer/core/remote.rb +1 -1
- data/lib/producer/core/remote/environment.rb +3 -1
- data/lib/producer/core/remote/fs.rb +2 -0
- data/lib/producer/core/task/dsl.rb +5 -1
- data/lib/producer/core/test.rb +6 -0
- data/lib/producer/core/tests/has_env.rb +1 -1
- data/lib/producer/core/tests/has_file.rb +1 -1
- data/lib/producer/core/version.rb +1 -1
- data/spec/producer/core/action_spec.rb +8 -1
- data/spec/producer/core/cli_spec.rb +3 -9
- data/spec/producer/core/condition/dsl_spec.rb +32 -40
- data/spec/producer/core/condition_spec.rb +15 -31
- data/spec/producer/core/env_spec.rb +16 -11
- data/spec/producer/core/prompter_spec.rb +41 -0
- data/spec/producer/core/recipe/dsl_spec.rb +34 -60
- data/spec/producer/core/remote/environment_spec.rb +20 -17
- data/spec/producer/core/remote/fs_spec.rb +1 -1
- data/spec/producer/core/remote_spec.rb +7 -19
- data/spec/producer/core/task/dsl_spec.rb +48 -54
- data/spec/producer/core/task_spec.rb +23 -51
- data/spec/producer/core/test_spec.rb +14 -14
- data/spec/spec_helper.rb +0 -1
- metadata +6 -3
- data/spec/support/tests_helpers.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e6a27039a047e17f8490bd070f3906b435939441
|
4
|
+
data.tar.gz: 7f1c4c346f1258e97f59454a6bcf3a20c6e02288
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b84f00106289af7baa8f57ab9aa336eaf2f4a9114a5a7553d5431e83ec8a04b8512ed37657c1599367bd75f41f8f99fabb241eada0c3bf4c9c88c2c5a88bc80
|
7
|
+
data.tar.gz: c3ed29fc5633c033e6f35f83d990325d0cdbce10a8a753cbc9f1e7f063795633ad9c465bc322327963ddeb096ec3e0e6c16f6919d2ffef6b753108a52016c7e9
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Feature: `ask' recipe keyword
|
2
|
+
|
3
|
+
Scenario: prompts user with a list of choices on standard output
|
4
|
+
Given a recipe with:
|
5
|
+
"""
|
6
|
+
task :ask_letter do
|
7
|
+
letter = ask 'Which letter?', [[:a, ?A], [:b, ?B]]
|
8
|
+
|
9
|
+
echo letter.inspect
|
10
|
+
end
|
11
|
+
"""
|
12
|
+
When I execute the recipe interactively
|
13
|
+
And I type "1"
|
14
|
+
Then the output must contain:
|
15
|
+
"""
|
16
|
+
Which letter?
|
17
|
+
0: A
|
18
|
+
1: B
|
19
|
+
Choice:
|
20
|
+
:b
|
21
|
+
"""
|
22
|
+
And the exit status must be 0
|
data/lib/producer/core.rb
CHANGED
@@ -14,6 +14,7 @@ require 'producer/core/condition'
|
|
14
14
|
require 'producer/core/condition/dsl'
|
15
15
|
require 'producer/core/env'
|
16
16
|
require 'producer/core/errors'
|
17
|
+
require 'producer/core/prompter'
|
17
18
|
require 'producer/core/recipe'
|
18
19
|
require 'producer/core/recipe/dsl'
|
19
20
|
require 'producer/core/remote'
|
data/lib/producer/core/action.rb
CHANGED
@@ -4,10 +4,10 @@ module Producer
|
|
4
4
|
require 'forwardable'
|
5
5
|
|
6
6
|
extend Forwardable
|
7
|
-
def_delegators :@env, :output, :remote
|
7
|
+
def_delegators :@env, :input, :output, :remote
|
8
8
|
def_delegators :remote, :fs
|
9
9
|
|
10
|
-
|
10
|
+
attr_reader :env, :arguments
|
11
11
|
|
12
12
|
def initialize(env, *args)
|
13
13
|
@env = env
|
data/lib/producer/core/cli.rb
CHANGED
data/lib/producer/core/env.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
module Producer
|
2
2
|
module Core
|
3
3
|
class Env
|
4
|
-
|
4
|
+
attr_reader :input, :output
|
5
|
+
attr_accessor :target
|
5
6
|
|
6
|
-
def initialize(output: $stdout)
|
7
|
+
def initialize(input: $stdin, output: $stdout)
|
8
|
+
@input = input
|
7
9
|
@output = output
|
8
10
|
@target = nil
|
9
11
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Producer
|
2
|
+
module Core
|
3
|
+
class Prompter
|
4
|
+
attr_reader :input, :output
|
5
|
+
|
6
|
+
def initialize(input, output)
|
7
|
+
@input = input
|
8
|
+
@output = output
|
9
|
+
end
|
10
|
+
|
11
|
+
def prompt(question, choices)
|
12
|
+
cs = choices.each_with_index.inject('') do |m, (c, i)|
|
13
|
+
m += "#{i}: #{c.last}\n"
|
14
|
+
end
|
15
|
+
output.puts "#{question}\n#{cs}Choice:"
|
16
|
+
choice = input.gets
|
17
|
+
choices[choice.to_i].first
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -2,7 +2,7 @@ module Producer
|
|
2
2
|
module Core
|
3
3
|
class Recipe
|
4
4
|
class DSL
|
5
|
-
attr_reader :env, :tasks
|
5
|
+
attr_reader :env, :code, :block, :tasks
|
6
6
|
|
7
7
|
def initialize(env, code = nil, &block)
|
8
8
|
@env = env
|
@@ -20,8 +20,6 @@ module Producer
|
|
20
20
|
self
|
21
21
|
end
|
22
22
|
|
23
|
-
private
|
24
|
-
|
25
23
|
def source(filepath)
|
26
24
|
instance_eval File.read("./#{filepath}.rb"), "#{filepath}.rb"
|
27
25
|
end
|
data/lib/producer/core/remote.rb
CHANGED
@@ -15,7 +15,7 @@ module Producer
|
|
15
15
|
|
16
16
|
define_action :file_write, Actions::FileWriter
|
17
17
|
|
18
|
-
|
18
|
+
attr_reader :env, :block, :actions
|
19
19
|
|
20
20
|
def initialize(env, &block)
|
21
21
|
@env = env
|
@@ -32,6 +32,10 @@ module Producer
|
|
32
32
|
@condition = Condition.evaluate(@env, &block) if block
|
33
33
|
@condition
|
34
34
|
end
|
35
|
+
|
36
|
+
def ask(question, choices, prompter: Prompter)
|
37
|
+
prompter.new(env.input, env.output).prompt(question, choices)
|
38
|
+
end
|
35
39
|
end
|
36
40
|
end
|
37
41
|
end
|
data/lib/producer/core/test.rb
CHANGED
@@ -2,8 +2,9 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module Producer::Core
|
4
4
|
describe Action do
|
5
|
+
let(:input) { StringIO.new }
|
5
6
|
let(:output) { StringIO.new }
|
6
|
-
let(:env) { Env.new(output: output) }
|
7
|
+
let(:env) { Env.new(input: input, output: output) }
|
7
8
|
let(:arguments) { [:some, :arguments] }
|
8
9
|
subject(:action) { Action.new(env, *arguments) }
|
9
10
|
|
@@ -19,6 +20,12 @@ module Producer::Core
|
|
19
20
|
end
|
20
21
|
end
|
21
22
|
|
23
|
+
describe '#input' do
|
24
|
+
it 'returns env input' do
|
25
|
+
expect(action.input).to be input
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
22
29
|
describe '#output' do
|
23
30
|
it 'delegates to env output' do
|
24
31
|
action.output.puts 'some content'
|
@@ -53,7 +53,9 @@ module Producer::Core
|
|
53
53
|
context 'without arguments' do
|
54
54
|
let(:arguments) { [] }
|
55
55
|
|
56
|
-
|
56
|
+
it 'raises our ArgumentError exception' do
|
57
|
+
expect { cli }.to raise_error described_class::ArgumentError
|
58
|
+
end
|
57
59
|
end
|
58
60
|
end
|
59
61
|
|
@@ -69,14 +71,6 @@ module Producer::Core
|
|
69
71
|
end
|
70
72
|
end
|
71
73
|
|
72
|
-
describe '#recipe' do
|
73
|
-
it 'returns the assigned recipe' do
|
74
|
-
recipe = double 'recipe'
|
75
|
-
cli.recipe = recipe
|
76
|
-
expect(cli.recipe).to be recipe
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
74
|
describe '#run' do
|
81
75
|
it 'loads the recipe' do
|
82
76
|
cli.run
|
@@ -13,7 +13,7 @@ module Producer::Core
|
|
13
13
|
end
|
14
14
|
|
15
15
|
describe '.define_test' do
|
16
|
-
let(:some_test_class) {
|
16
|
+
let(:some_test_class) { Test }
|
17
17
|
|
18
18
|
before { Condition::DSL.define_test(:some_test, some_test_class) }
|
19
19
|
|
@@ -24,15 +24,38 @@ module Producer::Core
|
|
24
24
|
it 'defines the negated test' do
|
25
25
|
expect(dsl).to respond_to :no_some_test
|
26
26
|
end
|
27
|
+
|
28
|
+
context 'when a test keyword is called' do
|
29
|
+
it 'registers the test' do
|
30
|
+
expect { dsl.some_test }.to change { dsl.tests.count }.by 1
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'registers the test with current env' do
|
34
|
+
dsl.some_test
|
35
|
+
expect(dsl.tests.first.env).to be env
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'registers the test with given arguments' do
|
39
|
+
dsl.some_test :some, :args
|
40
|
+
expect(dsl.tests.first.arguments).to eq [:some, :args]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'when a negated test keyword is called' do
|
45
|
+
it 'registers a negated test' do
|
46
|
+
dsl.no_some_test
|
47
|
+
expect(dsl.tests.first).to be_negated
|
48
|
+
end
|
49
|
+
end
|
27
50
|
end
|
28
51
|
|
29
52
|
describe '#initialize' do
|
30
|
-
it 'assigns the
|
31
|
-
expect(dsl.
|
53
|
+
it 'assigns the env' do
|
54
|
+
expect(dsl.env).to be env
|
32
55
|
end
|
33
56
|
|
34
|
-
it 'assigns the
|
35
|
-
expect(dsl.
|
57
|
+
it 'assigns the code' do
|
58
|
+
expect(dsl.block).to be block
|
36
59
|
end
|
37
60
|
|
38
61
|
it 'assigns no test' do
|
@@ -40,46 +63,15 @@ module Producer::Core
|
|
40
63
|
end
|
41
64
|
end
|
42
65
|
|
43
|
-
describe '#
|
44
|
-
it '
|
45
|
-
dsl.
|
46
|
-
expect
|
66
|
+
describe '#evaluate' do
|
67
|
+
it 'evaluates its code' do
|
68
|
+
dsl = described_class.new(env) { throw :condition_code }
|
69
|
+
expect { dsl.evaluate }.to throw_symbol :condition_code
|
47
70
|
end
|
48
|
-
end
|
49
71
|
|
50
|
-
describe '#evaluate' do
|
51
72
|
it 'returns the value returned by the assigned block' do
|
52
73
|
expect(dsl.evaluate).to eq block.call
|
53
74
|
end
|
54
|
-
|
55
|
-
context 'when a defined test keyword is called' do
|
56
|
-
let(:some_test_class) { double 'SomeTest class' }
|
57
|
-
let(:block) { proc { some_test :some, :args } }
|
58
|
-
|
59
|
-
before { Condition::DSL.define_test(:some_test, some_test_class) }
|
60
|
-
|
61
|
-
it 'builds a new test with the env and given arguments' do
|
62
|
-
expect(some_test_class).to receive(:new).with(env, :some, :args)
|
63
|
-
dsl.evaluate
|
64
|
-
end
|
65
|
-
|
66
|
-
it 'registers the new test' do
|
67
|
-
some_test = double 'SomeTest instance'
|
68
|
-
allow(some_test_class).to receive(:new) { some_test }
|
69
|
-
dsl.evaluate
|
70
|
-
expect(dsl.tests).to include(some_test)
|
71
|
-
end
|
72
|
-
|
73
|
-
context 'when keyword is prefixed with "no_"' do
|
74
|
-
let(:block) { proc { no_some_test :some, :args } }
|
75
|
-
|
76
|
-
it 'builds a negated test' do
|
77
|
-
expect(some_test_class)
|
78
|
-
.to receive(:new).with(env, :some, :args, negated: true)
|
79
|
-
dsl.evaluate
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
75
|
end
|
84
76
|
end
|
85
77
|
end
|
@@ -2,56 +2,40 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module Producer::Core
|
4
4
|
describe Condition do
|
5
|
-
|
6
|
-
|
5
|
+
let(:test_ok) { double 'test', pass?: true }
|
6
|
+
let(:test_ko) { double 'test', pass?: false }
|
7
7
|
let(:tests) { [test_ok, test_ko] }
|
8
8
|
subject(:condition) { Condition.new(tests) }
|
9
9
|
|
10
10
|
describe '.evaluate' do
|
11
|
-
let(:env)
|
12
|
-
let(:block)
|
13
|
-
|
14
|
-
|
15
|
-
expect(Condition::DSL)
|
16
|
-
.to receive(:new).with(env, &block).and_call_original
|
17
|
-
Condition.evaluate(env, &block)
|
18
|
-
end
|
11
|
+
let(:env) { double 'env' }
|
12
|
+
let(:block) { proc { some_test; :some_return_value } }
|
13
|
+
let(:some_test_class) { Class.new(Test) }
|
14
|
+
subject(:condition) { described_class.evaluate(env, &block) }
|
19
15
|
|
20
|
-
|
21
|
-
dsl = double('dsl').as_null_object
|
22
|
-
allow(Condition::DSL).to receive(:new) { dsl }
|
23
|
-
expect(dsl).to receive :evaluate
|
24
|
-
Condition.evaluate(env, &block)
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'builds a condition with its test and block return value' do
|
28
|
-
expect(Condition)
|
29
|
-
.to receive(:new).with([], :some_condition_code)
|
30
|
-
Condition.evaluate(env, &block)
|
31
|
-
end
|
16
|
+
before { Condition::DSL.define_test(:some_test, some_test_class) }
|
32
17
|
|
33
|
-
it 'returns
|
34
|
-
condition
|
35
|
-
|
36
|
-
expect(Condition.evaluate(env, &block)).to be condition
|
18
|
+
it 'returns an evaluated condition' do
|
19
|
+
expect(condition.tests.first).to be_a Test
|
20
|
+
expect(condition.return_value).to eq :some_return_value
|
37
21
|
end
|
38
22
|
end
|
39
23
|
|
40
24
|
describe '#initialize' do
|
41
25
|
it 'assigns the tests' do
|
42
|
-
expect(condition.
|
26
|
+
expect(condition.tests).to eq tests
|
43
27
|
end
|
44
28
|
|
45
29
|
it 'assigns nil as a default return value' do
|
46
|
-
expect(condition.
|
30
|
+
expect(condition.return_value).to be nil
|
47
31
|
end
|
48
32
|
|
49
33
|
context 'when a return value is given as argument' do
|
50
34
|
let(:return_value) { :some_return_value }
|
51
|
-
subject(:condition) {
|
35
|
+
subject(:condition) { described_class.new(tests, return_value) }
|
52
36
|
|
53
37
|
it 'assigns the return value' do
|
54
|
-
expect(condition.
|
38
|
+
expect(condition.return_value).to eq return_value
|
55
39
|
end
|
56
40
|
end
|
57
41
|
end
|
@@ -74,7 +58,7 @@ module Producer::Core
|
|
74
58
|
end
|
75
59
|
|
76
60
|
context 'when there are no test' do
|
77
|
-
subject(:condition) {
|
61
|
+
subject(:condition) { described_class.new([], return_value) }
|
78
62
|
|
79
63
|
context 'and return value is truthy' do
|
80
64
|
let(:return_value) { :some_truthy_value }
|
@@ -2,32 +2,37 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module Producer::Core
|
4
4
|
describe Env do
|
5
|
-
let(:output) { double 'output' }
|
6
5
|
subject(:env) { Env.new }
|
7
6
|
|
8
7
|
describe '#initialize' do
|
8
|
+
it 'assigns $stdin as the default output' do
|
9
|
+
expect(env.input).to be $stdin
|
10
|
+
end
|
11
|
+
|
9
12
|
it 'assigns $stdout as the default output' do
|
10
|
-
expect(env.
|
13
|
+
expect(env.output).to be $stdout
|
11
14
|
end
|
12
15
|
|
13
16
|
it 'assigns no default target' do
|
14
17
|
expect(env.target).not_to be
|
15
18
|
end
|
16
19
|
|
17
|
-
context 'when
|
18
|
-
|
20
|
+
context 'when input is given as argument' do
|
21
|
+
let(:input) { double 'input' }
|
22
|
+
subject(:env) { described_class.new(input: input) }
|
19
23
|
|
20
|
-
it 'assigns the given
|
21
|
-
expect(env.
|
24
|
+
it 'assigns the given input' do
|
25
|
+
expect(env.input).to eq input
|
22
26
|
end
|
23
27
|
end
|
24
|
-
end
|
25
28
|
|
26
|
-
|
27
|
-
|
29
|
+
context 'when output is given as argument' do
|
30
|
+
let(:output) { double 'output' }
|
31
|
+
subject(:env) { described_class.new(output: output) }
|
28
32
|
|
29
|
-
|
30
|
-
|
33
|
+
it 'assigns the given output' do
|
34
|
+
expect(env.output).to eq output
|
35
|
+
end
|
31
36
|
end
|
32
37
|
end
|
33
38
|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Producer::Core
|
4
|
+
describe Prompter do
|
5
|
+
let(:input) { StringIO.new }
|
6
|
+
let(:output) { StringIO.new }
|
7
|
+
let(:env) { Env.new(input: input, output: output) }
|
8
|
+
subject(:prompter) { Prompter.new(input, output) }
|
9
|
+
|
10
|
+
describe '#initialize' do
|
11
|
+
it 'assigns the given input' do
|
12
|
+
expect(prompter.input).to be input
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'assigns the given output' do
|
16
|
+
expect(prompter.output).to be output
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#prompt' do
|
21
|
+
let(:question) { 'Which letter?' }
|
22
|
+
let(:choices) { [[:a, ?A], [:b, ?B]] }
|
23
|
+
|
24
|
+
it 'prompts choices' do
|
25
|
+
prompter.prompt question, choices
|
26
|
+
expect(output.string).to eq <<-eoh.gsub /^\s+\|/, ''
|
27
|
+
|#{question}
|
28
|
+
|0: A
|
29
|
+
|1: B
|
30
|
+
|Choice:
|
31
|
+
eoh
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'returns value for entry chosen by user' do
|
35
|
+
input.puts '1'
|
36
|
+
input.rewind
|
37
|
+
expect(prompter.prompt question, choices).to eq :b
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -5,7 +5,7 @@ module Producer::Core
|
|
5
5
|
include FixturesHelpers
|
6
6
|
|
7
7
|
let(:code) { proc { :some_recipe_code } }
|
8
|
-
let(:env) {
|
8
|
+
let(:env) { Env.new }
|
9
9
|
subject(:dsl) { Recipe::DSL.new(env, &code) }
|
10
10
|
|
11
11
|
describe '#initialize' do
|
@@ -19,16 +19,16 @@ module Producer::Core
|
|
19
19
|
|
20
20
|
context 'when a string of code is given as argument' do
|
21
21
|
let(:code) { 'some_code' }
|
22
|
-
subject(:dsl) {
|
22
|
+
subject(:dsl) { described_class.new(env, code) }
|
23
23
|
|
24
24
|
it 'assigns the string of code' do
|
25
|
-
expect(dsl.
|
25
|
+
expect(dsl.code).to eq code
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
29
|
context 'when a code block is given as argument' do
|
30
30
|
it 'assigns the code block' do
|
31
|
-
expect(dsl.
|
31
|
+
expect(dsl.block).to be code
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
@@ -44,7 +44,7 @@ module Producer::Core
|
|
44
44
|
|
45
45
|
describe '#evaluate' do
|
46
46
|
it 'evaluates its code' do
|
47
|
-
dsl =
|
47
|
+
dsl = described_class.new(env) { throw :recipe_code }
|
48
48
|
expect { dsl.evaluate }.to throw_symbol :recipe_code
|
49
49
|
end
|
50
50
|
|
@@ -53,76 +53,50 @@ module Producer::Core
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
|
57
|
-
|
56
|
+
describe '#source' do
|
57
|
+
let(:filepath) { fixture_path_for 'recipes/throw' }
|
58
58
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
it 'returns the current environment' do
|
63
|
-
expect(env).to receive :some_message
|
64
|
-
dsl.evaluate
|
65
|
-
end
|
59
|
+
it 'sources the recipe given as argument' do
|
60
|
+
expect { dsl.source filepath }.to throw_symbol :recipe_code
|
66
61
|
end
|
62
|
+
end
|
67
63
|
|
68
|
-
|
69
|
-
|
70
|
-
let(:code) { "source '#{filepath}'" }
|
71
|
-
subject(:dsl) { Recipe::DSL.new(env, code) }
|
64
|
+
describe '#target' do
|
65
|
+
let(:host) { 'some_host.example' }
|
72
66
|
|
73
|
-
|
74
|
-
|
75
|
-
|
67
|
+
it 'registers the target host in the env' do
|
68
|
+
dsl.target host
|
69
|
+
expect(env.target).to eq host
|
76
70
|
end
|
71
|
+
end
|
77
72
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
expect(env).to receive(:target=).with('some_host.example')
|
83
|
-
dsl
|
84
|
-
end
|
73
|
+
describe '#task' do
|
74
|
+
it 'registers a new evaluated task' do
|
75
|
+
expect { dsl.task(:some_task) { :some_task_code } }
|
76
|
+
.to change { dsl.tasks.count }.by 1
|
85
77
|
end
|
78
|
+
end
|
86
79
|
|
87
|
-
|
88
|
-
|
80
|
+
describe '#macro' do
|
81
|
+
it 'defines the new recipe keyword' do
|
82
|
+
dsl.macro :hello
|
83
|
+
expect(dsl).to respond_to(:hello)
|
84
|
+
end
|
89
85
|
|
90
|
-
|
91
|
-
|
92
|
-
.to receive(:evaluate).with(:some_task, env, :some, :arg) do |&b|
|
93
|
-
expect(b.call).to eq :some_value
|
94
|
-
end
|
95
|
-
dsl
|
96
|
-
end
|
86
|
+
context 'when a defined macro is called' do
|
87
|
+
before { dsl.macro(:hello) { :some_macro_code } }
|
97
88
|
|
98
89
|
it 'registers the new task' do
|
99
|
-
|
100
|
-
allow(Task).to receive(:new) { task }
|
101
|
-
expect(dsl.tasks).to include(task)
|
90
|
+
expect { dsl.hello }.to change { dsl.tasks.count }.by 1
|
102
91
|
end
|
103
92
|
end
|
104
93
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
it 'defines the new recipe keyword' do
|
109
|
-
expect(dsl).to respond_to(:hello)
|
110
|
-
end
|
111
|
-
|
112
|
-
context 'when the new keyword is called' do
|
113
|
-
let(:code) { proc { macro(:hello) { echo 'hello' }; hello } }
|
114
|
-
|
115
|
-
it 'registers the new task' do
|
116
|
-
expect(dsl.tasks.first.actions.first).to be_an Actions::Echo
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
context 'when macro takes arguments' do
|
121
|
-
let(:code) { proc { macro(:hello) { |e| echo e }; hello :arg } }
|
94
|
+
context 'when a defined macro is called with arguments' do
|
95
|
+
before { dsl.macro(:hello) { |a, b| echo a, b } }
|
122
96
|
|
123
|
-
|
124
|
-
|
125
|
-
|
97
|
+
it 'evaluates task code with arguments' do
|
98
|
+
dsl.hello :some, :args
|
99
|
+
expect(dsl.tasks.first.actions.first.arguments).to eq [:some, :args]
|
126
100
|
end
|
127
101
|
end
|
128
102
|
end
|
@@ -9,37 +9,40 @@ module Producer::Core
|
|
9
9
|
|
10
10
|
describe '.string_to_hash' do
|
11
11
|
it 'converts key=value pairs separated by new lines to a hash' do
|
12
|
-
expect(
|
13
|
-
.to eq variables
|
12
|
+
expect(described_class.string_to_hash(string)).to eq variables
|
14
13
|
end
|
15
14
|
end
|
16
15
|
|
17
16
|
describe '.new_from_string' do
|
18
|
-
it '
|
19
|
-
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'returns the instance' do
|
24
|
-
environment = double 'environment'
|
25
|
-
allow(Remote::Environment).to receive(:new) { environment }
|
26
|
-
expect(Remote::Environment.new_from_string(string)).to be environment
|
17
|
+
it 'returns a new instance with converted keys and values' do
|
18
|
+
environment = described_class.new_from_string string
|
19
|
+
expect(environment.variables).to eq variables
|
27
20
|
end
|
28
21
|
end
|
29
22
|
|
30
23
|
describe '#initialize' do
|
31
24
|
it 'assigns the key/value pairs' do
|
32
|
-
expect(environment.
|
25
|
+
expect(environment.variables).to eq variables
|
33
26
|
end
|
34
27
|
end
|
35
28
|
|
36
29
|
describe '#key?' do
|
37
|
-
|
30
|
+
context 'when key is defined' do
|
31
|
+
it 'returns true' do
|
32
|
+
expect(environment.key? 'FOO').to be true
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'when key is not defined' do
|
37
|
+
it 'returns false' do
|
38
|
+
expect(environment.key? 'INEXISTENT_KEY').to be false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
38
42
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
environment.key? key
|
43
|
+
describe '#[]' do
|
44
|
+
it 'returns the value indexed by given key' do
|
45
|
+
expect(environment['FOO']).to eq 'bar'
|
43
46
|
end
|
44
47
|
end
|
45
48
|
end
|
@@ -5,8 +5,8 @@ module Producer::Core
|
|
5
5
|
let(:hostname) { 'some_host.example' }
|
6
6
|
subject(:remote) { Remote.new(hostname) }
|
7
7
|
|
8
|
-
describe '#
|
9
|
-
it '
|
8
|
+
describe '#initialize' do
|
9
|
+
it 'assigns the given hostname' do
|
10
10
|
expect(remote.hostname).to eq hostname
|
11
11
|
end
|
12
12
|
end
|
@@ -116,26 +116,14 @@ module Producer::Core
|
|
116
116
|
end
|
117
117
|
end
|
118
118
|
|
119
|
-
describe '#environment'
|
119
|
+
describe '#environment' do
|
120
120
|
let(:command) { 'env' }
|
121
|
-
let(:output) {
|
121
|
+
let(:output) { 'FOO=bar' }
|
122
122
|
|
123
|
-
before
|
124
|
-
story_with_new_channel do |ch|
|
125
|
-
ch.sends_exec command
|
126
|
-
ch.gets_data output
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
it 'builds a remote environment with the result of `env` command' do
|
131
|
-
expect(Remote::Environment).to receive(:new_from_string).with(output)
|
132
|
-
remote.environment
|
133
|
-
end
|
123
|
+
before { allow(remote).to receive(:execute) { output } }
|
134
124
|
|
135
|
-
it 'returns
|
136
|
-
environment
|
137
|
-
allow(Remote::Environment).to receive(:new_from_string) { environment }
|
138
|
-
expect(remote.environment).to be environment
|
125
|
+
it 'returns a remote environment' do
|
126
|
+
expect(remote.environment['FOO']).to eq 'bar'
|
139
127
|
end
|
140
128
|
end
|
141
129
|
end
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
module Producer::Core
|
4
4
|
describe Task::DSL do
|
5
5
|
let(:block) { proc {} }
|
6
|
-
let(:env) {
|
6
|
+
let(:env) { Env.new }
|
7
7
|
subject(:dsl) { Task::DSL.new(env, &block) }
|
8
8
|
|
9
9
|
%w[echo sh file_write].each do |action|
|
@@ -13,10 +13,29 @@ module Producer::Core
|
|
13
13
|
end
|
14
14
|
|
15
15
|
describe '.define_action' do
|
16
|
+
let(:some_action_class) { Class.new(Action) }
|
17
|
+
|
18
|
+
before { described_class.define_action(:some_action, some_action_class) }
|
19
|
+
|
16
20
|
it 'defines a new action keyword' do
|
17
|
-
Task::DSL.define_action(:some_action, Object)
|
18
21
|
expect(dsl).to respond_to :some_action
|
19
22
|
end
|
23
|
+
|
24
|
+
context 'when an action keyword is called' do
|
25
|
+
it 'registers the action' do
|
26
|
+
expect { dsl.some_action }.to change { dsl.actions.count }.by 1
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'registers the action with current env' do
|
30
|
+
dsl.some_action
|
31
|
+
expect(dsl.actions.first.env).to be env
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'registers the action with given arguments' do
|
35
|
+
dsl.some_action :some, :args
|
36
|
+
expect(dsl.actions.first.arguments).to eq [:some, :args]
|
37
|
+
end
|
38
|
+
end
|
20
39
|
end
|
21
40
|
|
22
41
|
describe '#initialize' do
|
@@ -24,28 +43,16 @@ module Producer::Core
|
|
24
43
|
expect(dsl.env).to be env
|
25
44
|
end
|
26
45
|
|
46
|
+
it 'assigns the given block' do
|
47
|
+
expect(dsl.block).to be block
|
48
|
+
end
|
49
|
+
|
27
50
|
it 'assigns no action' do
|
28
51
|
expect(dsl.actions).to be_empty
|
29
52
|
end
|
30
53
|
|
31
54
|
it 'assigns true as the condition' do
|
32
|
-
expect(dsl.
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
describe '#actions' do
|
37
|
-
it 'returns the assigned actions' do
|
38
|
-
dsl.instance_eval { @actions = [:some_action] }
|
39
|
-
expect(dsl.actions).to eq [:some_action]
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
describe '#condition' do
|
44
|
-
context 'without block' do
|
45
|
-
it 'returns the assigned condition' do
|
46
|
-
dsl.instance_eval { @condition = :some_condition }
|
47
|
-
expect(dsl.condition).to be :some_condition
|
48
|
-
end
|
55
|
+
expect(dsl.condition).to be true
|
49
56
|
end
|
50
57
|
end
|
51
58
|
|
@@ -65,47 +72,34 @@ module Producer::Core
|
|
65
72
|
.to throw_symbol :some_argument
|
66
73
|
end
|
67
74
|
end
|
75
|
+
end
|
68
76
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
Task::DSL.define_action(:some_action, some_action_class)
|
75
|
-
dsl.evaluate
|
77
|
+
describe '#condition' do
|
78
|
+
context 'when a block is given' do
|
79
|
+
it 'assigns a new evaluated condition' do
|
80
|
+
dsl.condition { :some_return_value }
|
81
|
+
expect(dsl.condition.return_value).to eq :some_return_value
|
76
82
|
end
|
83
|
+
end
|
84
|
+
end
|
77
85
|
|
78
|
-
|
79
|
-
|
80
|
-
|
86
|
+
describe '#ask' do
|
87
|
+
let(:question) { 'Which letter?' }
|
88
|
+
let(:choices) { [[:a, ?A], [:b, ?B]] }
|
89
|
+
let(:prompter_class) { double('prompter class').as_null_object }
|
90
|
+
subject(:ask) { dsl.ask question, choices,
|
91
|
+
prompter: prompter_class }
|
81
92
|
|
82
|
-
|
83
|
-
|
84
|
-
|
93
|
+
it 'builds a prompter' do
|
94
|
+
expect(prompter_class).to receive(:new).with(env.input, env.output)
|
95
|
+
ask
|
85
96
|
end
|
86
|
-
end
|
87
97
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
let(:block) { proc { condition { :some_value } } }
|
94
|
-
|
95
|
-
it 'builds a new evaluated condition' do
|
96
|
-
expect(Condition)
|
97
|
-
.to receive :evaluate do |&b|
|
98
|
-
expect(b.call).to eq :some_value
|
99
|
-
end
|
100
|
-
dsl
|
101
|
-
end
|
102
|
-
|
103
|
-
it 'assigns the new condition' do
|
104
|
-
condition = double('condition').as_null_object
|
105
|
-
allow(Condition).to receive(:evaluate) { condition }
|
106
|
-
expect(dsl.condition).to be condition
|
107
|
-
end
|
108
|
-
end
|
98
|
+
it 'prompts and returns the choice' do
|
99
|
+
prompter = double 'prompter'
|
100
|
+
allow(prompter_class).to receive(:new) { prompter }
|
101
|
+
allow(prompter).to receive(:prompt) { :choice }
|
102
|
+
expect(ask).to eq :choice
|
109
103
|
end
|
110
104
|
end
|
111
105
|
end
|
@@ -8,54 +8,44 @@ module Producer::Core
|
|
8
8
|
subject(:task) { Task.new(name, [action], condition) }
|
9
9
|
|
10
10
|
describe '.evaluate' do
|
11
|
-
let(:
|
12
|
-
let(:
|
13
|
-
let(:block)
|
14
|
-
|
15
|
-
|
16
|
-
dsl = double('dsl').as_null_object
|
17
|
-
expect(Task::DSL).to receive(:new).with(env) do |&b|
|
18
|
-
expect(b).to be block
|
19
|
-
dsl
|
20
|
-
end
|
21
|
-
Task.evaluate(name, env, *args, &block)
|
22
|
-
end
|
11
|
+
let(:name) { :some_task }
|
12
|
+
let(:env) { double 'env' }
|
13
|
+
let(:block) { proc { condition { :condition }; some_action } }
|
14
|
+
let(:some_action_class) { Class.new(Action) }
|
15
|
+
subject(:task) { Task.evaluate(name, env, :some, :args, &block) }
|
23
16
|
|
24
|
-
|
25
|
-
dsl = double('dsl').as_null_object
|
26
|
-
allow(Task::DSL).to receive(:new) { dsl }
|
27
|
-
expect(dsl).to receive(:evaluate).with(*args)
|
28
|
-
Task.evaluate(name, env, *args, &block)
|
29
|
-
end
|
17
|
+
before { Task::DSL.define_action(:some_action, some_action_class) }
|
30
18
|
|
31
|
-
it '
|
32
|
-
|
33
|
-
'dsl', actions: [:some_action], condition: :some_condition
|
34
|
-
).as_null_object
|
35
|
-
allow(Task::DSL).to receive(:new) { dsl }
|
36
|
-
expect(Task)
|
37
|
-
.to receive(:new).with(:some_task, [:some_action], :some_condition)
|
38
|
-
Task.evaluate(name, env, *args, &block)
|
19
|
+
it 'returns an evaluated task' do
|
20
|
+
expect(task).to be_kind_of Task
|
39
21
|
end
|
40
22
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
23
|
+
context 'evaluated task' do
|
24
|
+
it 'has the requested name' do
|
25
|
+
expect(task.name).to eq name
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'has the requested actions' do
|
29
|
+
expect(task.actions.first).to be_kind_of some_action_class
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'has the requested condition' do
|
33
|
+
expect(task.condition.return_value).to be :condition
|
34
|
+
end
|
45
35
|
end
|
46
36
|
end
|
47
37
|
|
48
38
|
describe '#initialize' do
|
49
39
|
it 'assigns the name' do
|
50
|
-
expect(task.
|
40
|
+
expect(task.name).to eq name
|
51
41
|
end
|
52
42
|
|
53
43
|
it 'assigns the actions' do
|
54
|
-
expect(task.
|
44
|
+
expect(task.actions).to eq [action]
|
55
45
|
end
|
56
46
|
|
57
47
|
it 'assigns the condition' do
|
58
|
-
expect(task.
|
48
|
+
expect(task.condition).to eq condition
|
59
49
|
end
|
60
50
|
|
61
51
|
context 'when only the name is given as argument' do
|
@@ -71,24 +61,6 @@ module Producer::Core
|
|
71
61
|
end
|
72
62
|
end
|
73
63
|
|
74
|
-
describe '#name' do
|
75
|
-
it 'returns its name' do
|
76
|
-
expect(task.name).to eq name
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
describe '#actions' do
|
81
|
-
it 'returns the assigned actions' do
|
82
|
-
expect(task.actions).to eq [action]
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
describe '#condition' do
|
87
|
-
it 'returns the assigned condition' do
|
88
|
-
expect(task.condition).to be condition
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
64
|
describe '#condition_met?' do
|
93
65
|
context 'when condition is truthy' do
|
94
66
|
let(:condition) { Condition.new([], true) }
|
@@ -2,41 +2,41 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module Producer::Core
|
4
4
|
describe Test do
|
5
|
-
let(:env) {
|
5
|
+
let(:env) { Env.new }
|
6
6
|
let(:arguments) { [:some, :arguments] }
|
7
7
|
subject(:test) { Test.new(env, *arguments) }
|
8
8
|
|
9
9
|
describe '#initialize' do
|
10
10
|
it 'assigns the env' do
|
11
|
-
expect(test.
|
11
|
+
expect(test.env).to be env
|
12
12
|
end
|
13
13
|
|
14
14
|
it 'assigns the arguments' do
|
15
|
-
expect(test.
|
15
|
+
expect(test.arguments).to eq arguments
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'assigns negated as false by default' do
|
19
|
-
expect(test
|
19
|
+
expect(test).to_not be_negated
|
20
20
|
end
|
21
21
|
|
22
22
|
context 'when negated option is true' do
|
23
|
-
subject(:test) {
|
23
|
+
subject(:test) { described_class.new(env, *arguments, negated: true) }
|
24
24
|
|
25
25
|
it 'assigns negated as true' do
|
26
|
-
expect(test
|
26
|
+
expect(test).to be_negated
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
describe '#
|
32
|
-
it 'returns
|
33
|
-
expect(test.
|
31
|
+
describe '#remote' do
|
32
|
+
it 'returns env remote' do
|
33
|
+
expect(test.remote).to be test.env.remote
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
describe '#
|
38
|
-
it 'returns
|
39
|
-
expect(test.
|
37
|
+
describe '#fs' do
|
38
|
+
it 'returns env remote fs' do
|
39
|
+
expect(test.fs).to be test.env.remote.fs
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -46,7 +46,7 @@ module Producer::Core
|
|
46
46
|
end
|
47
47
|
|
48
48
|
context 'when test is negated' do
|
49
|
-
subject(:test) {
|
49
|
+
subject(:test) { described_class.new(env, *arguments, negated: true) }
|
50
50
|
|
51
51
|
it 'returns true' do
|
52
52
|
expect(test.negated?).to be true
|
@@ -66,7 +66,7 @@ module Producer::Core
|
|
66
66
|
end
|
67
67
|
|
68
68
|
context 'when test is negated' do
|
69
|
-
subject(:test) {
|
69
|
+
subject(:test) { described_class.new(env, *arguments, negated: true) }
|
70
70
|
|
71
71
|
it 'returns false when #verify is true' do
|
72
72
|
allow(test).to receive(:verify) { true }
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: producer-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thibault Jouan
|
@@ -112,6 +112,7 @@ files:
|
|
112
112
|
- features/actions/file_write.feature
|
113
113
|
- features/actions/sh.feature
|
114
114
|
- features/cli/usage.feature
|
115
|
+
- features/recipes/ask.feature
|
115
116
|
- features/recipes/env.feature
|
116
117
|
- features/recipes/evaluation.feature
|
117
118
|
- features/recipes/macro.feature
|
@@ -140,6 +141,7 @@ files:
|
|
140
141
|
- lib/producer/core/condition/dsl.rb
|
141
142
|
- lib/producer/core/env.rb
|
142
143
|
- lib/producer/core/errors.rb
|
144
|
+
- lib/producer/core/prompter.rb
|
143
145
|
- lib/producer/core/recipe.rb
|
144
146
|
- lib/producer/core/recipe/dsl.rb
|
145
147
|
- lib/producer/core/remote.rb
|
@@ -164,6 +166,7 @@ files:
|
|
164
166
|
- spec/producer/core/condition/dsl_spec.rb
|
165
167
|
- spec/producer/core/condition_spec.rb
|
166
168
|
- spec/producer/core/env_spec.rb
|
169
|
+
- spec/producer/core/prompter_spec.rb
|
167
170
|
- spec/producer/core/recipe/dsl_spec.rb
|
168
171
|
- spec/producer/core/recipe_spec.rb
|
169
172
|
- spec/producer/core/remote/environment_spec.rb
|
@@ -179,7 +182,6 @@ files:
|
|
179
182
|
- spec/support/exit_helpers.rb
|
180
183
|
- spec/support/fixtures_helpers.rb
|
181
184
|
- spec/support/net_ssh_story_helpers.rb
|
182
|
-
- spec/support/tests_helpers.rb
|
183
185
|
homepage: https://rubygems.org/gems/producer-core
|
184
186
|
licenses: []
|
185
187
|
metadata: {}
|
@@ -208,6 +210,7 @@ test_files:
|
|
208
210
|
- features/actions/file_write.feature
|
209
211
|
- features/actions/sh.feature
|
210
212
|
- features/cli/usage.feature
|
213
|
+
- features/recipes/ask.feature
|
211
214
|
- features/recipes/env.feature
|
212
215
|
- features/recipes/evaluation.feature
|
213
216
|
- features/recipes/macro.feature
|
@@ -237,6 +240,7 @@ test_files:
|
|
237
240
|
- spec/producer/core/condition/dsl_spec.rb
|
238
241
|
- spec/producer/core/condition_spec.rb
|
239
242
|
- spec/producer/core/env_spec.rb
|
243
|
+
- spec/producer/core/prompter_spec.rb
|
240
244
|
- spec/producer/core/recipe/dsl_spec.rb
|
241
245
|
- spec/producer/core/recipe_spec.rb
|
242
246
|
- spec/producer/core/remote/environment_spec.rb
|
@@ -252,5 +256,4 @@ test_files:
|
|
252
256
|
- spec/support/exit_helpers.rb
|
253
257
|
- spec/support/fixtures_helpers.rb
|
254
258
|
- spec/support/net_ssh_story_helpers.rb
|
255
|
-
- spec/support/tests_helpers.rb
|
256
259
|
has_rdoc:
|