jisota 0.0.1 → 0.0.2

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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +5 -0
  4. data/CHANGELOG.md +21 -0
  5. data/README.md +106 -2
  6. data/Rakefile +10 -0
  7. data/jisota.gemspec +1 -0
  8. data/lib/jisota.rb +4 -2
  9. data/lib/jisota/collection.rb +2 -4
  10. data/lib/jisota/command_script.rb +3 -2
  11. data/lib/jisota/composite_script.rb +2 -2
  12. data/lib/jisota/configuration.rb +3 -3
  13. data/lib/jisota/dsl_base.rb +12 -0
  14. data/lib/jisota/file_script.rb +107 -9
  15. data/lib/jisota/nil_output.rb +14 -0
  16. data/lib/jisota/{logger.rb → output.rb} +16 -35
  17. data/lib/jisota/package.rb +2 -2
  18. data/lib/jisota/package_script.rb +28 -20
  19. data/lib/jisota/packages/gem_install.rb +17 -0
  20. data/lib/jisota/packages/nginx_passenger.rb +34 -0
  21. data/lib/jisota/packages/ruby.rb +2 -2
  22. data/lib/jisota/param_parser.rb +30 -19
  23. data/lib/jisota/provisioner.rb +7 -3
  24. data/lib/jisota/script_block.rb +13 -14
  25. data/lib/jisota/script_context.rb +24 -0
  26. data/lib/jisota/server.rb +2 -1
  27. data/lib/jisota/ssh_engine.rb +6 -2
  28. data/lib/jisota/ssh_session.rb +10 -15
  29. data/lib/jisota/version.rb +1 -1
  30. data/package_files/nginx_passenger/nginx_service +65 -0
  31. data/spec/acceptance/ruby_passenger_nginx_spec.rb +24 -0
  32. data/spec/acceptance/simple_script_spec.rb +8 -24
  33. data/spec/acceptance/upload_blocks_spec.rb +34 -0
  34. data/spec/lib/jisota/collection_spec.rb +10 -0
  35. data/spec/lib/jisota/command_script_spec.rb +4 -3
  36. data/spec/lib/jisota/composite_script_spec.rb +8 -6
  37. data/spec/lib/jisota/configuration_spec.rb +1 -3
  38. data/spec/lib/jisota/dsl_base_spec.rb +37 -0
  39. data/spec/lib/jisota/file_script_spec.rb +63 -8
  40. data/spec/lib/jisota/output_spec.rb +84 -0
  41. data/spec/lib/jisota/package_script_spec.rb +20 -8
  42. data/spec/lib/jisota/package_spec.rb +2 -6
  43. data/spec/lib/jisota/packages/apt_spec.rb +7 -4
  44. data/spec/lib/jisota/packages/gem_install_spec.rb +18 -0
  45. data/spec/lib/jisota/packages/nginx_passenger_spec.rb +17 -0
  46. data/spec/lib/jisota/packages/ruby_spec.rb +6 -3
  47. data/spec/lib/jisota/param_parser_spec.rb +105 -0
  48. data/spec/lib/jisota/provisioner_spec.rb +30 -0
  49. data/spec/lib/jisota/role_spec.rb +1 -3
  50. data/spec/lib/jisota/script_block_spec.rb +7 -4
  51. data/spec/lib/jisota/ssh_engine_spec.rb +26 -0
  52. data/spec/lib/jisota/ssh_session_spec.rb +53 -0
  53. data/spec/spec_helper.rb +11 -1
  54. data/spec/support/acceptance_helpers.rb +45 -0
  55. data/spec/test_files/nginx_default.conf +121 -0
  56. data/spec/vagrant/Vagrantfile +118 -0
  57. data/spec/vagrant/ssh_key +27 -0
  58. metadata +55 -7
  59. data/lib/jisota/upload_file.rb +0 -3
  60. data/spec/lib/jisota/logger_spec.rb +0 -34
@@ -0,0 +1,84 @@
1
+ require 'spec_helper'
2
+
3
+ module Jisota
4
+ describe Output do
5
+ let(:logger) { Output.new(stdout: stdout, stderr: stderr, verbose: verbose) }
6
+ let(:stdout) { instance_double(IO, write: nil, flush: nil) }
7
+ let(:stderr) { instance_double(IO, write: nil, flush: nil) }
8
+ let(:verbose) { true }
9
+
10
+ describe "initialization" do
11
+ it "initializes with options" do
12
+ logger = Output.new(stdout: :out, stderr: :err, verbose: false)
13
+ expect(logger.stdout).to eq(:out)
14
+ expect(logger.stderr).to eq(:err)
15
+ expect(logger.verbose).to be false
16
+ end
17
+ end
18
+
19
+ describe '#info' do
20
+ it "writes to stdout" do
21
+ logger.info("foo")
22
+ expect(stdout).to have_received(:write).with("foo")
23
+ end
24
+ end
25
+
26
+ describe "#error" do
27
+ it "writes to stderr" do
28
+ logger.error("foo")
29
+ expect(stderr).to have_received(:write).with("foo")
30
+ end
31
+ end
32
+
33
+ describe "#warn" do
34
+ context "verbose" do
35
+ let(:verbose) { true }
36
+ it "outputs" do
37
+ logger.warn("foo")
38
+ expect(stderr).to have_received(:write).with("foo")
39
+ end
40
+ end
41
+
42
+ context "not verbose" do
43
+ let(:verbose) { false }
44
+ it "outputs" do
45
+ logger.warn("foo")
46
+ expect(stderr).to_not have_received(:write).with("foo")
47
+ end
48
+ end
49
+ end
50
+
51
+ describe "#system_message" do
52
+ it "outputs message" do
53
+ logger.system_message("foo")
54
+ expect(stdout).to have_received(:write).with("-----> foo\n")
55
+ end
56
+ end
57
+
58
+ describe "#indent" do
59
+ it "indents subsequent output" do
60
+ logger.indent
61
+ logger.system_message("foo")
62
+ expect(stdout).to have_received(:write).with("-----> foo\n")
63
+
64
+ logger.outdent
65
+ logger.system_message("foo")
66
+ expect(stdout).to have_received(:write).with("-----> foo\n")
67
+ end
68
+
69
+ context "with a block" do
70
+ it "indents logs inside block" do
71
+ result = logger.indent do
72
+ logger.system_message("foo")
73
+ 42
74
+ end
75
+ logger.system_message("bar")
76
+ expect(stdout).to have_received(:write).with("-----> foo\n")
77
+ expect(stdout).to have_received(:write).with("-----> bar\n")
78
+ expect(result).to eq(42)
79
+ end
80
+ end
81
+ end
82
+
83
+ end
84
+ end
@@ -3,17 +3,18 @@ require 'spec_helper'
3
3
  module Jisota
4
4
  describe PackageScript do
5
5
  describe "#execute" do
6
- let(:ssh_session) { instance_double(SSHSession, command: true) }
6
+ let(:ssh_session) { instance_double(SSHSession, command: 0) }
7
+ let(:context) { ScriptContext.new(ssh_session: ssh_session) }
7
8
 
8
9
  it "executes each script from the block" do
9
10
  package = Package.new do
10
11
  run { cmd "foo" }
11
12
  end
12
13
  package_script = PackageScript.new(package)
13
- result = package_script.execute(ssh_session)
14
+ result = package_script.execute(context)
14
15
 
15
16
  expect(result).to be true
16
- expect(ssh_session).to have_received(:command).with("foo", nil)
17
+ expect(ssh_session).to have_received(:command).with("foo", anything)
17
18
  end
18
19
 
19
20
  it "parses args" do
@@ -22,9 +23,9 @@ module Jisota
22
23
  run { cmd "foo #{bar}" }
23
24
  end
24
25
  package_script = PackageScript.new(package, ["baz"])
25
- package_script.execute(ssh_session)
26
+ package_script.execute(context)
26
27
 
27
- expect(ssh_session).to have_received(:command).with("foo baz", nil)
28
+ expect(ssh_session).to have_received(:command).with("foo baz", anything)
28
29
  end
29
30
 
30
31
  it "uses verify block" do
@@ -33,10 +34,21 @@ module Jisota
33
34
  verify { cmd "bar" }
34
35
  end
35
36
  package_script = PackageScript.new(package)
36
- package_script.execute(ssh_session)
37
+ package_script.execute(context)
37
38
 
38
- expect(ssh_session).to have_received(:command).with("bar", nil)
39
- expect(ssh_session).to_not have_received(:command).with("foo", nil)
39
+ expect(ssh_session).to have_received(:command).with("bar", anything)
40
+ expect(ssh_session).to_not have_received(:command).with("foo", anything)
41
+ end
42
+ end
43
+
44
+ describe "#to_s" do
45
+ it "outputs a nice representation of the script" do
46
+ package = Package.new(:nginx)
47
+
48
+ expect(PackageScript.new(package, []).to_s).to eq("nginx")
49
+ expect(PackageScript.new(package, ["foo"]).to_s).to eq('nginx "foo"')
50
+ expect(PackageScript.new(package, ["foo", 42]).to_s).to eq('nginx "foo", 42')
51
+ expect(PackageScript.new(package, [{ foo: 42 }]).to_s).to eq("nginx {:foo=>42}")
40
52
  end
41
53
  end
42
54
  end
@@ -53,12 +53,8 @@ module Jisota
53
53
  description "Does cool stuff"
54
54
  param :foo
55
55
  param :bar, default: 42
56
- run do
57
- cmd "touch #{foo}"
58
- end
59
- verify do
60
- cmd "[ -f foo ]"
61
- end
56
+ run { cmd "touch #{foo}" }
57
+ verify { cmd "[ -f foo ]" }
62
58
  end
63
59
 
64
60
  expect(package.name).to eq(:my_awesome_package)
@@ -2,14 +2,17 @@
2
2
  require 'spec_helper'
3
3
 
4
4
  module Jisota
5
- describe "Ruby package" do
5
+ describe "Apt package" do
6
6
  it "is valid" do
7
7
  script_block = ScriptBlock.new do
8
8
  apt :curl
9
9
  end
10
- script = script_block.evaluate({}, Jisota.global_packages)
11
- ssh_session = instance_double(SSHSession, command: true, upload: true)
12
- expect { script.execute(ssh_session) }.to_not raise_exception
10
+ ssh_session = instance_double(SSHSession, upload: true)
11
+ allow(ssh_session).to receive(:command).and_return(false, true)
12
+ context = ScriptContext.new(ssh_session: ssh_session, packages: Jisota.global_packages)
13
+ script = script_block.evaluate(context)
14
+
15
+ expect { script.execute(context) }.to_not raise_exception
13
16
  end
14
17
  end
15
18
  end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ module Jisota
4
+ describe "Gem-install package" do
5
+ it "is valid" do
6
+ script_block = ScriptBlock.new do
7
+ gem_install :foo
8
+ end
9
+ ssh_session = instance_double(SSHSession)
10
+ allow(ssh_session).to receive(:command).and_return(1, 0)
11
+ context = ScriptContext.new(ssh_session: ssh_session, packages: Jisota.global_packages)
12
+ script = script_block.evaluate(context)
13
+
14
+ expect { script.execute(context) }.to_not raise_exception
15
+ end
16
+ end
17
+ end
18
+
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ module Jisota
4
+ describe "Nginx Passenger package" do
5
+ it "is valid" do
6
+ script_block = ScriptBlock.new do
7
+ nginx_passenger config_file: "foo"
8
+ end
9
+ ssh_session = instance_double(SSHSession, upload: true, command: 0)
10
+ context = ScriptContext.new(ssh_session: ssh_session, packages: Jisota.global_packages)
11
+ script = script_block.evaluate(context)
12
+
13
+ expect { script.execute(context) }.to_not raise_exception
14
+ end
15
+ end
16
+ end
17
+
@@ -6,9 +6,12 @@ module Jisota
6
6
  script_block = ScriptBlock.new do
7
7
  ruby version: "2.1.1"
8
8
  end
9
- script = script_block.evaluate({}, Jisota.global_packages)
10
- ssh_session = instance_double(SSHSession, command: true, upload: true)
11
- expect { script.execute(ssh_session) }.to_not raise_exception
9
+ ssh_session = instance_double(SSHSession, upload: true)
10
+ allow(ssh_session).to receive(:command).and_return(false, true)
11
+ context = ScriptContext.new(ssh_session: ssh_session, packages: Jisota.global_packages)
12
+ script = script_block.evaluate(context)
13
+
14
+ expect { script.execute(context) }.to_not raise_exception
12
15
  end
13
16
  end
14
17
  end
@@ -0,0 +1,105 @@
1
+ require 'spec_helper'
2
+
3
+ describe Jisota::ParamParser do
4
+ subject { parser.parse() }
5
+ let(:parser) { Jisota::ParamParser.new(params, args) }
6
+ let(:params) { [] }
7
+ let(:args) { [] }
8
+
9
+ def should_raise(error)
10
+ expect { subject }.to raise_exception(error)
11
+ end
12
+
13
+ context "no params" do
14
+ context "no args" do
15
+ it { should eq Hash.new }
16
+ end
17
+
18
+ context "implicit arg" do
19
+ let(:args) { [42] }
20
+ it { should_raise(Jisota::ParameterError) }
21
+ end
22
+
23
+ context "hash arg" do
24
+ let(:args) { [ { foo: 42 } ] }
25
+ it { should_raise(Jisota::ParameterError) }
26
+ end
27
+ end
28
+
29
+ context "param with no options" do
30
+ let(:params) { [Jisota::Param.new(:foo)] }
31
+
32
+ context "no args" do
33
+ it { should eq({foo: nil}) }
34
+ end
35
+
36
+ context "implicit arg" do
37
+ let(:args) { [42] }
38
+ it { should eq({foo: 42}) }
39
+ end
40
+
41
+ context "repeated implicit arg" do
42
+ let(:args) { [42, { foo: 42 }] }
43
+ it { should_raise(Jisota::ParameterError) }
44
+ end
45
+
46
+ context "hash arg" do
47
+ let(:args) { [ { foo: 42 } ] }
48
+ it { should eq({foo: 42}) }
49
+ end
50
+ end
51
+
52
+ context "param with required: true" do
53
+ let(:params) { [Jisota::Param.new(:foo, required: true)] }
54
+
55
+ context "no args" do
56
+ it { should_raise(Jisota::ParameterError) }
57
+ end
58
+
59
+ context "implicit arg" do
60
+ let(:args) { [42] }
61
+ it { should eq({foo: 42}) }
62
+ end
63
+
64
+ context "hash arg" do
65
+ let(:args) { [ { foo: 42 } ] }
66
+ it { should eq({foo: 42}) }
67
+ end
68
+ end
69
+
70
+ context "param with default" do
71
+ let(:params) { [Jisota::Param.new(:foo, default: 48)] }
72
+
73
+ context "no args" do
74
+ it { should eq({foo: 48}) }
75
+ end
76
+
77
+ context "implicit arg" do
78
+ let(:args) { [42] }
79
+ it { should eq({foo: 42}) }
80
+ end
81
+
82
+ context "hash arg" do
83
+ let(:args) { [ { foo: 42 } ] }
84
+ it { should eq({foo: 42}) }
85
+ end
86
+ end
87
+
88
+ context "param with splat: true" do
89
+ let(:params) { [Jisota::Param.new(:foo, splat: true)] }
90
+
91
+ context "no args" do
92
+ it { should eq({foo: []}) }
93
+ end
94
+
95
+ context "implicit arg" do
96
+ let(:args) { [42] }
97
+ it { should eq({foo: [42]}) }
98
+ end
99
+
100
+ context "hash arg" do
101
+ let(:args) { [ { foo: 42 } ] }
102
+ it { should_raise(Jisota::ParameterError) }
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ module Jisota
4
+ describe Provisioner do
5
+ describe "#run" do
6
+
7
+ let(:ssh_engine) do
8
+ instance_double(SSHEngine).tap do |ssh|
9
+ allow(ssh).to receive(:start).with({user: "john", host: "123.456.789.0"}).and_yield(ssh_session)
10
+ end
11
+ end
12
+ let(:ssh_session) { instance_double(SSHSession, command: 0) }
13
+
14
+ it "executes a script" do
15
+ config = Configuration.new do
16
+ role :app do
17
+ cmd "touch foo"
18
+ end
19
+ server "123.456.789.0", user: "john", roles: :app
20
+ end
21
+ config.ssh_engine = ssh_engine
22
+
23
+ provisioner = Provisioner.new
24
+ provisioner.run(config, NilOutput.new)
25
+
26
+ expect(ssh_session).to have_received(:command).with("touch foo", anything)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -20,9 +20,7 @@ module Jisota
20
20
 
21
21
  describe "DSL" do
22
22
  it "initializes with DSL" do
23
- role = Role.new(:app) do
24
- cmd "touch foo"
25
- end
23
+ role = Role.new(:app) { cmd "touch foo" }
26
24
  expect(role.name).to eq(:app)
27
25
  expect(role.script_block).to be_a(ScriptBlock)
28
26
  end
@@ -23,13 +23,15 @@ module Jisota
23
23
  expect(script.scripts[0]).to be_a(CommandScript)
24
24
  expect(script.scripts[0].command).to eq("foo")
25
25
  expect(script.scripts[1]).to be_a(FileScript)
26
- expect(script.scripts[1].file).to eq(UploadFile.new("x", "y"))
26
+ expect(script.scripts[1].from).to eq("x")
27
+ expect(script.scripts[1].to).to eq("y")
27
28
  end
28
29
 
29
30
  it "parses args" do
30
31
  script_block = ScriptBlock.new { cmd "touch #{foo}" }
31
- args = { foo: "bar" }
32
- script = script_block.evaluate(args)
32
+ params = { foo: "bar" }
33
+ context = ScriptContext.new(params: params)
34
+ script = script_block.evaluate(context)
33
35
 
34
36
  expect(script.scripts.first.command).to eq("touch bar")
35
37
  end
@@ -38,8 +40,9 @@ module Jisota
38
40
  script_block = ScriptBlock.new { touch "file" }
39
41
  packages = Collection.new
40
42
  packages << Package.new(:touch)
43
+ context = ScriptContext.new(packages: packages)
41
44
 
42
- script = script_block.evaluate({}, packages)
45
+ script = script_block.evaluate(context)
43
46
  script = script.scripts.first
44
47
 
45
48
  expect(script).to be_a(PackageScript)
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ module Jisota
4
+ describe SSHEngine do
5
+ describe "#start" do
6
+ let(:engine) do
7
+ class_double(Net::SSH).tap do |engine|
8
+ allow(engine).to receive(:start).and_yield(nil)
9
+ end
10
+ end
11
+ let(:wrapper) { SSHEngine.new(engine: engine) }
12
+
13
+ it "starts the engine" do
14
+ wrapper.start(user: "john", host: "foo") { |ssh_session| }
15
+
16
+ expect(engine).to have_received(:start).with("foo", "john", {})
17
+ end
18
+
19
+ it "passes extra options to engine" do
20
+ wrapper.start(user: "john", host: "foo", foo: "bar", bar: "baz") { |ssh_session| }
21
+
22
+ expect(engine).to have_received(:start).with("foo", "john", { foo: "bar", bar: "baz" })
23
+ end
24
+ end
25
+ end
26
+ end