producer-core 0.1.7 → 0.1.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/producer +1 -1
- data/features/actions/echo.feature +3 -3
- data/lib/producer/core/actions/echo.rb +1 -1
- data/lib/producer/core/actions/shell_command.rb +1 -1
- data/lib/producer/core/cli.rb +18 -16
- data/lib/producer/core/env.rb +3 -8
- data/lib/producer/core/remote/environment.rb +11 -12
- data/lib/producer/core/remote.rb +1 -1
- data/lib/producer/core/version.rb +1 -1
- data/producer-core.gemspec +3 -5
- data/spec/producer/core/actions/echo_spec.rb +3 -3
- data/spec/producer/core/actions/shell_command_spec.rb +3 -3
- data/spec/producer/core/cli_spec.rb +49 -31
- data/spec/producer/core/env_spec.rb +12 -5
- data/spec/producer/core/remote/environment_spec.rb +20 -10
- data/spec/producer/core/remote_spec.rb +2 -2
- 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: e267920fce6f6536aa7aeabe841d440bd3ffae7b
|
4
|
+
data.tar.gz: d9f71061074b02737726ccbbb56f468fdc5e8432
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c4fd1d85b8191a94838c39f866f3fcb583c9e4a59c7db09b7a37c84d5c0cf096d55ae92d11bba1362cee35f3c7262b1e044075cba0ff82bb6ba2387284aec9d3
|
7
|
+
data.tar.gz: 5b9e9ea1ec0f4f5ae937c23d53ba115fd9f4427a810b4ea8a674c39dd6289ce59e3389c601244bdc71b0984451ba12e614baafa17e0aea6bebcaa1b90b91887e
|
data/bin/producer
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
Feature: `echo' task action
|
2
2
|
|
3
|
-
Scenario:
|
3
|
+
Scenario: prints text on standard output
|
4
4
|
Given a recipe with:
|
5
5
|
"""
|
6
|
-
task :
|
6
|
+
task :say_hello do
|
7
7
|
echo 'hello'
|
8
8
|
end
|
9
9
|
"""
|
10
10
|
When I successfully execute the recipe
|
11
|
-
Then the output must
|
11
|
+
Then the output must match /\Ahello\n/
|
data/lib/producer/core/cli.rb
CHANGED
@@ -1,24 +1,34 @@
|
|
1
1
|
module Producer
|
2
2
|
module Core
|
3
3
|
class CLI
|
4
|
+
ArgumentError = Class.new(::ArgumentError)
|
5
|
+
|
4
6
|
USAGE = "Usage: #{File.basename $0} recipe_file"
|
5
7
|
|
6
|
-
|
8
|
+
class << self
|
9
|
+
def run!(arguments, output: $stderr)
|
10
|
+
begin
|
11
|
+
cli = new(arguments)
|
12
|
+
rescue ArgumentError
|
13
|
+
output.puts USAGE
|
14
|
+
exit 64
|
15
|
+
end
|
16
|
+
cli.run!
|
17
|
+
end
|
18
|
+
end
|
7
19
|
|
8
|
-
|
9
|
-
|
20
|
+
attr_reader :arguments, :stdout
|
21
|
+
|
22
|
+
def initialize(arguments, stdout: $stdout)
|
23
|
+
raise ArgumentError unless arguments.any?
|
10
24
|
@arguments = arguments
|
25
|
+
@stdout = stdout
|
11
26
|
end
|
12
27
|
|
13
28
|
def run!
|
14
|
-
check_arguments!
|
15
29
|
interpreter.process recipe.tasks
|
16
30
|
end
|
17
31
|
|
18
|
-
def check_arguments!
|
19
|
-
print_usage_and_exit(64) unless @arguments.length == 1
|
20
|
-
end
|
21
|
-
|
22
32
|
def env
|
23
33
|
@env ||= Env.new
|
24
34
|
end
|
@@ -30,14 +40,6 @@ module Producer
|
|
30
40
|
def interpreter
|
31
41
|
@interpreter ||= Interpreter.new
|
32
42
|
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
def print_usage_and_exit(status)
|
37
|
-
@stdout.puts USAGE
|
38
|
-
|
39
|
-
exit status
|
40
|
-
end
|
41
43
|
end
|
42
44
|
end
|
43
45
|
end
|
data/lib/producer/core/env.rb
CHANGED
@@ -1,18 +1,13 @@
|
|
1
1
|
module Producer
|
2
2
|
module Core
|
3
3
|
class Env
|
4
|
-
|
5
|
-
attr_accessor :target
|
4
|
+
attr_accessor :output, :target
|
6
5
|
|
7
|
-
def initialize
|
8
|
-
@output =
|
6
|
+
def initialize(output: $stdout)
|
7
|
+
@output = output
|
9
8
|
@target = nil
|
10
9
|
end
|
11
10
|
|
12
|
-
def output(str)
|
13
|
-
@output.puts str
|
14
|
-
end
|
15
|
-
|
16
11
|
def remote
|
17
12
|
@remote ||= Remote.new(target)
|
18
13
|
end
|
@@ -2,24 +2,23 @@ module Producer
|
|
2
2
|
module Core
|
3
3
|
class Remote
|
4
4
|
class Environment
|
5
|
+
class << self
|
6
|
+
def string_to_hash(str)
|
7
|
+
Hash[str.each_line.map { |l| l.chomp.split '=', 2 }]
|
8
|
+
end
|
9
|
+
|
10
|
+
def new_from_string(str)
|
11
|
+
new string_to_hash str
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
5
15
|
require 'forwardable'
|
6
16
|
|
7
17
|
extend Forwardable
|
8
18
|
def_delegator :@variables, :has_key?
|
9
19
|
|
10
20
|
def initialize(variables)
|
11
|
-
|
12
|
-
when String
|
13
|
-
@variables = parse_from_string variables
|
14
|
-
else
|
15
|
-
@variables = variables
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def parse_from_string(str)
|
22
|
-
Hash[str.each_line.map { |l| l.chomp.split '=', 2 }]
|
21
|
+
@variables = variables
|
23
22
|
end
|
24
23
|
end
|
25
24
|
end
|
data/lib/producer/core/remote.rb
CHANGED
data/producer-core.gemspec
CHANGED
@@ -1,11 +1,9 @@
|
|
1
|
-
|
2
|
-
$LOAD_PATH << lib unless $LOAD_PATH.include? lib
|
3
|
-
require 'producer/core/version'
|
1
|
+
require File.expand_path('../lib/producer/core/version', __FILE__)
|
4
2
|
|
5
3
|
Gem::Specification.new do |s|
|
6
4
|
s.name = 'producer-core'
|
7
|
-
s.version = Producer::Core::VERSION
|
8
|
-
s.summary =
|
5
|
+
s.version = Producer::Core::VERSION.dup
|
6
|
+
s.summary = 'Provisioning tool'
|
9
7
|
s.description = <<-eoh.gsub(/^ +/, '')
|
10
8
|
Software provisioning tool, including a DSL to write "recipes".
|
11
9
|
eoh
|
@@ -2,14 +2,14 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module Producer::Core
|
4
4
|
describe Actions::Echo do
|
5
|
-
let(:env) {
|
5
|
+
let(:env) { Env.new(output: StringIO.new) }
|
6
6
|
let(:text) { 'hello' }
|
7
7
|
subject(:echo) { Actions::Echo.new(env, text) }
|
8
8
|
|
9
9
|
describe '#apply' do
|
10
|
-
it '
|
11
|
-
expect(env).to receive(:output).with(text)
|
10
|
+
it 'writes the given string to env.output with a record separator' do
|
12
11
|
echo.apply
|
12
|
+
expect(env.output.string).to eq "hello\n"
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module Producer::Core
|
4
4
|
describe Actions::ShellCommand do
|
5
|
-
let(:env) { Env.new }
|
5
|
+
let(:env) { Env.new(output: StringIO.new) }
|
6
6
|
let(:command_args) { 'hello from remote host' }
|
7
7
|
let(:command) { "echo #{command_args}" }
|
8
8
|
subject(:sh) { Actions::ShellCommand.new(env, command) }
|
@@ -15,10 +15,10 @@ module Producer::Core
|
|
15
15
|
sh.apply
|
16
16
|
end
|
17
17
|
|
18
|
-
it '
|
18
|
+
it 'writes the returned output to env.output with a record separator' do
|
19
19
|
allow(env.remote).to receive(:execute) { command_args }
|
20
|
-
expect(env).to receive(:output).with(command_args)
|
21
20
|
sh.apply
|
21
|
+
expect(env.output.string).to eq "#{command_args}\n"
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -7,11 +7,53 @@ module Producer::Core
|
|
7
7
|
|
8
8
|
let(:recipe_file) { fixture_path_for 'recipes/empty.rb' }
|
9
9
|
let(:arguments) { [recipe_file] }
|
10
|
-
|
10
|
+
let(:stdout) { StringIO.new }
|
11
|
+
|
12
|
+
subject(:cli) { CLI.new(arguments, stdout: stdout) }
|
13
|
+
|
14
|
+
describe '.run!' do
|
15
|
+
let(:output) { StringIO.new }
|
16
|
+
subject(:run) { described_class.run! arguments, output: output }
|
17
|
+
|
18
|
+
it 'builds a new CLI with given arguments' do
|
19
|
+
expect(CLI).to receive(:new).with(arguments).and_call_original
|
20
|
+
run
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'runs the CLI' do
|
24
|
+
cli = double 'cli'
|
25
|
+
allow(CLI).to receive(:new) { cli }
|
26
|
+
expect(cli).to receive :run!
|
27
|
+
run
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'when recipe argument is missing' do
|
31
|
+
let(:arguments) { [] }
|
32
|
+
|
33
|
+
it 'exits with a return status of 64' do
|
34
|
+
expect { run }.to raise_error(SystemExit) { |e|
|
35
|
+
expect(e.status).to eq 64
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'prints the usage' do
|
40
|
+
trap_exit { run }
|
41
|
+
expect(output.string).to match /\AUsage: .+/
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
11
45
|
|
12
46
|
describe '#initialize' do
|
47
|
+
subject(:cli) { CLI.new(arguments) }
|
48
|
+
|
13
49
|
it 'assigns $stdout as the default standard output' do
|
14
|
-
expect(cli.
|
50
|
+
expect(cli.stdout).to be $stdout
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'without arguments' do
|
54
|
+
let(:arguments) { [] }
|
55
|
+
|
56
|
+
specify { expect { cli }.to raise_error described_class::ArgumentError }
|
15
57
|
end
|
16
58
|
end
|
17
59
|
|
@@ -21,12 +63,13 @@ module Producer::Core
|
|
21
63
|
end
|
22
64
|
end
|
23
65
|
|
24
|
-
describe '#
|
25
|
-
it '
|
26
|
-
expect(cli).to
|
27
|
-
cli.run!
|
66
|
+
describe '#stdout' do
|
67
|
+
it 'returns the assigned standard output' do
|
68
|
+
expect(cli.stdout).to be stdout
|
28
69
|
end
|
70
|
+
end
|
29
71
|
|
72
|
+
describe '#run!' do
|
30
73
|
it 'processes the tasks with the interpreter' do
|
31
74
|
allow(cli.recipe).to receive(:tasks) { [:some_task] }
|
32
75
|
expect(cli.interpreter).to receive(:process).with [:some_task]
|
@@ -34,31 +77,6 @@ module Producer::Core
|
|
34
77
|
end
|
35
78
|
end
|
36
79
|
|
37
|
-
describe '#check_arguments!' do
|
38
|
-
context 'when recipe argument is provided' do
|
39
|
-
it 'does not raise any error' do
|
40
|
-
expect { cli.check_arguments! }.to_not raise_error
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
context 'when recipe argument is missing' do
|
45
|
-
let(:arguments) { [] }
|
46
|
-
let(:stdout) { StringIO.new }
|
47
|
-
subject(:cli) { CLI.new(arguments, stdout) }
|
48
|
-
|
49
|
-
it 'exits with a return status of 64' do
|
50
|
-
expect { cli.check_arguments! }.to raise_error(SystemExit) { |e|
|
51
|
-
expect(e.status).to eq 64
|
52
|
-
}
|
53
|
-
end
|
54
|
-
|
55
|
-
it 'prints the usage' do
|
56
|
-
trap_exit { cli.check_arguments! }
|
57
|
-
expect(stdout.string).to match /\AUsage: .+/
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
80
|
describe '#env' do
|
63
81
|
it 'builds an environment with the current recipe' do
|
64
82
|
expect(Env).to receive :new
|
@@ -2,6 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module Producer::Core
|
4
4
|
describe Env do
|
5
|
+
let(:output) { double 'output' }
|
5
6
|
subject(:env) { Env.new }
|
6
7
|
|
7
8
|
describe '#initialize' do
|
@@ -12,15 +13,21 @@ module Producer::Core
|
|
12
13
|
it 'assigns no default target' do
|
13
14
|
expect(env.target).not_to be
|
14
15
|
end
|
16
|
+
|
17
|
+
context 'when output is given as argument' do
|
18
|
+
subject(:env) { Env.new(output: output) }
|
19
|
+
|
20
|
+
it 'assigns the given output' do
|
21
|
+
expect(env.instance_eval { @output }).to eq output
|
22
|
+
end
|
23
|
+
end
|
15
24
|
end
|
16
25
|
|
17
26
|
describe '#output' do
|
18
|
-
|
27
|
+
subject(:env) { Env.new(output: output) }
|
19
28
|
|
20
|
-
it '
|
21
|
-
env.output
|
22
|
-
env.output 'some content'
|
23
|
-
expect(stdout.string).to eq "some content\n"
|
29
|
+
it 'returns the assigned output' do
|
30
|
+
expect(env.output).to eq output
|
24
31
|
end
|
25
32
|
end
|
26
33
|
|
@@ -7,19 +7,29 @@ module Producer::Core
|
|
7
7
|
let(:argument) { variables }
|
8
8
|
subject(:environment) { Remote::Environment.new(argument) }
|
9
9
|
|
10
|
-
describe '
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
end
|
10
|
+
describe '.string_to_hash' do
|
11
|
+
it 'converts key=value pairs separated by new lines to a hash' do
|
12
|
+
expect(Remote::Environment.string_to_hash(string))
|
13
|
+
.to eq variables
|
15
14
|
end
|
15
|
+
end
|
16
16
|
|
17
|
-
|
18
|
-
|
17
|
+
describe '.new_from_string' do
|
18
|
+
it 'builds a new instance after converting from string' do
|
19
|
+
expect(Remote::Environment).to receive(:new).with(variables)
|
20
|
+
Remote::Environment.new_from_string(string)
|
21
|
+
end
|
19
22
|
|
20
|
-
|
21
|
-
|
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
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#initialize' do
|
31
|
+
it 'assigns the key/value pairs' do
|
32
|
+
expect(environment.instance_eval { @variables }).to eq variables
|
23
33
|
end
|
24
34
|
end
|
25
35
|
|
@@ -128,13 +128,13 @@ module Producer::Core
|
|
128
128
|
end
|
129
129
|
|
130
130
|
it 'builds a remote environment with the result of `env` command' do
|
131
|
-
expect(Remote::Environment).to receive(:
|
131
|
+
expect(Remote::Environment).to receive(:new_from_string).with(output)
|
132
132
|
remote.environment
|
133
133
|
end
|
134
134
|
|
135
135
|
it 'returns the environment' do
|
136
136
|
environment = double 'environment'
|
137
|
-
allow(Remote::Environment).to receive(:
|
137
|
+
allow(Remote::Environment).to receive(:new_from_string) { environment }
|
138
138
|
expect(remote.environment).to be environment
|
139
139
|
end
|
140
140
|
end
|
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.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thibault Jouan
|
@@ -201,7 +201,7 @@ rubyforge_project:
|
|
201
201
|
rubygems_version: 2.4.5
|
202
202
|
signing_key:
|
203
203
|
specification_version: 4
|
204
|
-
summary:
|
204
|
+
summary: Provisioning tool
|
205
205
|
test_files:
|
206
206
|
- features/actions/echo.feature
|
207
207
|
- features/actions/file_write.feature
|