inprovise 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +4 -0
  3. data/.travis.yml +28 -0
  4. data/Gemfile +9 -0
  5. data/LICENSE +8 -0
  6. data/README.md +197 -0
  7. data/Rakefile.rb +9 -0
  8. data/bin/rig +5 -0
  9. data/inprovise.gemspec +22 -0
  10. data/lib/inprovise/channel/ssh.rb +202 -0
  11. data/lib/inprovise/cli/group.rb +86 -0
  12. data/lib/inprovise/cli/node.rb +95 -0
  13. data/lib/inprovise/cli/provision.rb +84 -0
  14. data/lib/inprovise/cli.rb +105 -0
  15. data/lib/inprovise/cmd_channel.rb +100 -0
  16. data/lib/inprovise/cmd_helper.rb +150 -0
  17. data/lib/inprovise/control.rb +326 -0
  18. data/lib/inprovise/execution_context.rb +277 -0
  19. data/lib/inprovise/group.rb +67 -0
  20. data/lib/inprovise/helper/cygwin.rb +43 -0
  21. data/lib/inprovise/helper/linux.rb +181 -0
  22. data/lib/inprovise/helper/windows.rb +123 -0
  23. data/lib/inprovise/infra.rb +122 -0
  24. data/lib/inprovise/local_file.rb +120 -0
  25. data/lib/inprovise/logger.rb +79 -0
  26. data/lib/inprovise/node.rb +271 -0
  27. data/lib/inprovise/remote_file.rb +128 -0
  28. data/lib/inprovise/resolver.rb +36 -0
  29. data/lib/inprovise/script.rb +175 -0
  30. data/lib/inprovise/script_index.rb +46 -0
  31. data/lib/inprovise/script_runner.rb +110 -0
  32. data/lib/inprovise/sniff.rb +46 -0
  33. data/lib/inprovise/sniffer/linux.rb +64 -0
  34. data/lib/inprovise/sniffer/platform.rb +46 -0
  35. data/lib/inprovise/sniffer/unknown.rb +11 -0
  36. data/lib/inprovise/sniffer/windows.rb +32 -0
  37. data/lib/inprovise/template/inprovise.rb.erb +92 -0
  38. data/lib/inprovise/template.rb +38 -0
  39. data/lib/inprovise/trigger_runner.rb +36 -0
  40. data/lib/inprovise/version.rb +10 -0
  41. data/lib/inprovise.rb +145 -0
  42. data/test/cli_test.rb +314 -0
  43. data/test/cli_test_helper.rb +19 -0
  44. data/test/dsl_test.rb +43 -0
  45. data/test/fixtures/example.txt +1 -0
  46. data/test/fixtures/include.rb +4 -0
  47. data/test/fixtures/inprovise.rb +1 -0
  48. data/test/fixtures/myscheme.rb +1 -0
  49. data/test/infra_test.rb +189 -0
  50. data/test/local_file_test.rb +64 -0
  51. data/test/remote_file_test.rb +106 -0
  52. data/test/resolver_test.rb +66 -0
  53. data/test/script_index_test.rb +53 -0
  54. data/test/script_test.rb +56 -0
  55. data/test/test_helper.rb +237 -0
  56. metadata +182 -0
@@ -0,0 +1,106 @@
1
+ # Remote file tests for Inprovise
2
+ #
3
+ # Author:: Martin Corino
4
+ # License:: Distributes under the same license as Ruby
5
+
6
+ require_relative 'test_helper'
7
+
8
+ describe Inprovise::RemoteFile do
9
+ before :each do
10
+ @node = Inprovise::Infrastructure::Node.new('Node1', {host: 'host.address.net', channel: 'test', helper: 'test'})
11
+ @log = Inprovise::Logger.new(@node, 'remote_file_test')
12
+ @local_file_path = File.join(File.dirname(__FILE__), 'fixtures', 'example.txt')
13
+ @local_file = Inprovise::LocalFile.new(@local_file_path)
14
+ @remote_file_path = '/tmp/example.txt'
15
+ @context = Inprovise::ExecutionContext.new(@node, @log, Inprovise::ScriptIndex.default)
16
+ @remote_file = Inprovise::RemoteFile.new(@context, @remote_file_path)
17
+ end
18
+
19
+ after :each do
20
+ reset_infrastructure!
21
+ end
22
+
23
+ describe 'path' do
24
+ it 'returns the absolute path of a local file' do
25
+ @remote_file.path.must_equal @remote_file_path
26
+ end
27
+ end
28
+
29
+ describe 'hash' do
30
+ it 'returns the sha1 of a remote file' do
31
+ @remote_file.hash.must_equal Digest::SHA1.hexdigest("RUN: sha1sum #{@remote_file.path}")
32
+ end
33
+ end
34
+
35
+ describe 'matches' do
36
+ it 'returns true if the passed file has a matching hash' do
37
+ @node.helper.expects(:hash_for)
38
+ .with(@remote_file.path)
39
+ .returns(Digest::SHA1.hexdigest("RUN: sha1sum #{@remote_file.path}"))
40
+ @remote_file.matches?(@remote_file).must_equal true
41
+ end
42
+ end
43
+
44
+ describe 'exists?' do
45
+ it 'checks if a file exists' do
46
+ @node.helper.expects(:exists?)
47
+ .with(@remote_file.path)
48
+ .returns(true)
49
+ @remote_file.exists?.must_equal true
50
+ end
51
+
52
+ it 'checks if a missing file exists' do
53
+ @node.helper.expects(:exists?)
54
+ .with(@remote_file.path)
55
+ .returns(false)
56
+ @remote_file.exists?.must_equal false
57
+ end
58
+ end
59
+
60
+ describe 'copy_to' do
61
+ it 'copies a file to another remote location' do
62
+ @remote_destination = Inprovise::RemoteFile.new(@context, '/tmp/example-dest.txt')
63
+ @node.helper.expects(:copy)
64
+ .with(@remote_file.path, @remote_destination.path)
65
+ .returns(nil)
66
+ @remote_file.copy_to(@remote_destination).must_equal @remote_destination
67
+ end
68
+
69
+ it 'copies a file to local location by downlaoding it' do
70
+ @local_destination = Inprovise::LocalFile.new("/tmp/example-#{Time.now.to_i}.txt")
71
+ @node.helper.expects(:download)
72
+ .with(@remote_file.path, @local_destination.path)
73
+ .returns(nil)
74
+ @remote_file.copy_to(@local_destination).must_equal @local_destination
75
+ end
76
+ end
77
+
78
+ describe 'delete!' do
79
+ it 'removes the file from the remote server' do
80
+ @node.helper.expects(:delete)
81
+ .with(@remote_file.path)
82
+ .returns(nil)
83
+ @remote_file.delete!
84
+ end
85
+
86
+ it "doesn't delete missing files" do
87
+ @node.helper.expects(:exists?)
88
+ .with(@remote_file.path)
89
+ .returns(false)
90
+ @node.helper.expects(:delete)
91
+ .with(@remote_file.path)
92
+ .never
93
+ @remote_file.delete!
94
+ end
95
+ end
96
+
97
+ describe 'set_permissions' do
98
+ it 'sets permissions on the file based on a mask' do
99
+ @node.helper.expects(:permissions)
100
+ .with(@remote_file.path)
101
+ .returns(0644)
102
+ @remote_file.set_permissions(0644).must_equal @remote_file
103
+ @remote_file.permissions.must_equal 0644
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,66 @@
1
+ # Resolver tests for Inprovise
2
+ #
3
+ # Author:: Martin Corino
4
+ # License:: Distributes under the same license as Ruby
5
+
6
+ require_relative 'test_helper'
7
+
8
+ describe Inprovise::Resolver do
9
+ before :each do
10
+ @pkg_a = Inprovise::DSL.script('a') {}
11
+ @pkg_b = Inprovise::DSL.script('b') {}
12
+ @pkg_c = Inprovise::DSL.script('c') {}
13
+ @pkg_d = Inprovise::DSL.script('d') {}
14
+ end
15
+
16
+ after :each do
17
+ reset_script_index!
18
+ end
19
+
20
+ describe 'resolving a tree of script dependancies' do
21
+ it 'resolves single scripts to a single script' do
22
+ resolver = Inprovise::Resolver.new(@pkg_a)
23
+ resolver.resolve
24
+ resolver.scripts.must_equal [@pkg_a]
25
+ end
26
+
27
+ it 'resolves a chain of 2 scripts to a list of 2 scripts' do
28
+ @pkg_a.depends_on(@pkg_b.name)
29
+ resolver = Inprovise::Resolver.new(@pkg_a)
30
+ resolver.resolve
31
+ resolver.scripts.must_equal [@pkg_b, @pkg_a]
32
+ end
33
+
34
+ it 'resolves a chain of 3 scripts to a list of 3 scripts' do
35
+ @pkg_a.depends_on(@pkg_b.name)
36
+ @pkg_b.depends_on(@pkg_c.name)
37
+ resolver = Inprovise::Resolver.new(@pkg_a)
38
+ resolver.resolve
39
+ resolver.scripts.must_equal [@pkg_c, @pkg_b, @pkg_a]
40
+ end
41
+
42
+ it 'resolves a tree of 3 scripts to a list of 3 scripts' do
43
+ @pkg_a.depends_on(@pkg_b.name)
44
+ @pkg_a.depends_on(@pkg_c.name)
45
+ resolver = Inprovise::Resolver.new(@pkg_a)
46
+ resolver.resolve
47
+ resolver.scripts.must_equal [@pkg_b, @pkg_c, @pkg_a]
48
+ end
49
+
50
+ it 'resolves a tree of 4 scripts to a list of 4 scripts' do
51
+ @pkg_a.depends_on(@pkg_b.name)
52
+ @pkg_a.depends_on(@pkg_c.name)
53
+ @pkg_c.depends_on(@pkg_d.name)
54
+ resolver = Inprovise::Resolver.new(@pkg_a)
55
+ resolver.resolve
56
+ resolver.scripts.must_equal [@pkg_b, @pkg_d, @pkg_c, @pkg_a]
57
+ end
58
+
59
+ it 'errors out on circular dependancies' do
60
+ @pkg_a.depends_on(@pkg_b.name)
61
+ @pkg_b.depends_on(@pkg_a.name)
62
+ resolver = Inprovise::Resolver.new(@pkg_a)
63
+ assert_raises(Inprovise::Resolver::CircularDependencyError) { resolver.resolve }
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,53 @@
1
+ # Script index tests for Inprovise
2
+ #
3
+ # Author:: Martin Corino
4
+ # License:: Distributes under the same license as Ruby
5
+
6
+ require_relative 'test_helper'
7
+
8
+ describe Inprovise::ScriptIndex do
9
+ before :each do
10
+ @script = Inprovise::Script.new('my-script')
11
+ @default = Inprovise::ScriptIndex.default
12
+ end
13
+
14
+ after :each do
15
+ reset_script_index!
16
+ end
17
+
18
+ describe "default" do
19
+ it "returns a script index singleton named default" do
20
+ Inprovise::ScriptIndex.default.index_name.must_equal 'default'
21
+ end
22
+
23
+ it "allways returns the same script index" do
24
+ Inprovise::ScriptIndex.default.must_equal Inprovise::ScriptIndex.default
25
+ end
26
+ end
27
+
28
+ describe "add" do
29
+ it "adds a script to the index" do
30
+ @default.add(@script)
31
+ @default.get(@script.name).must_equal @script
32
+ end
33
+ end
34
+
35
+ describe 'get' do
36
+ it "fetches a script by name" do
37
+ @default.add(@script)
38
+ @default.get(@script.name).must_equal @script
39
+ end
40
+
41
+ it "throws an execption if the script doesn't exist" do
42
+ assert_raises(Inprovise::ScriptIndex::MissingScriptError) { @default.get(@script.name) }
43
+ end
44
+ end
45
+
46
+ describe "clear!" do
47
+ it "wipes the index clean of scripts" do
48
+ @default.add(@script)
49
+ @default.clear!
50
+ assert_raises(Inprovise::ScriptIndex::MissingScriptError) { @default.get(@script.name) }
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,56 @@
1
+ # Script tests for Inprovise
2
+ #
3
+ # Author:: Martin Corino
4
+ # License:: Distributes under the same license as Ruby
5
+
6
+ require_relative 'test_helper'
7
+
8
+ describe Inprovise::Script do
9
+ before :each do
10
+ @script = Inprovise::Script.new('my-script')
11
+ end
12
+
13
+ describe "depends_on" do
14
+ it "adds a dependency" do
15
+ @script.dependencies.must_equal []
16
+ @script.depends_on('other-script')
17
+ @script.dependencies.must_equal ['other-script']
18
+ end
19
+
20
+ it "adds multiple dependancies at once" do
21
+ @script.dependencies.must_equal []
22
+ @script.depends_on('other-script', 'third-script')
23
+ @script.dependencies.must_equal ['other-script', 'third-script']
24
+ end
25
+ end
26
+
27
+ describe "action" do
28
+ it "allows defining actions with a name and a block" do
29
+ @script.action('my-action') { 'foo' }
30
+ @script.actions['my-action'].call.must_equal 'foo'
31
+ end
32
+ end
33
+
34
+ describe "commands" do
35
+ it "can add an 'apply' command" do
36
+ @script.apply { 'my-apply' }
37
+ @script.command(:apply).first.call.must_equal 'my-apply'
38
+ end
39
+
40
+ it "can add an 'revert' command" do
41
+ @script.revert { 'my-revert' }
42
+ @script.command(:revert).first.call.must_equal 'my-revert'
43
+ end
44
+
45
+ it "can add an 'validate' command" do
46
+ @script.validate { 'my-validate' }
47
+ @script.command(:validate).first.call.must_equal 'my-validate'
48
+ end
49
+
50
+ it 'knows if a command is provided' do
51
+ @script.provides_command?(:apply).must_equal false
52
+ @script.apply { 'my-apply' }
53
+ @script.provides_command?(:apply).must_equal true
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,237 @@
1
+ # Test helper for Inprovise
2
+ #
3
+ # Author:: Martin Corino
4
+ # License:: Distributes under the same license as Ruby
5
+ require "codeclimate-test-reporter"
6
+ CodeClimate::TestReporter.start
7
+
8
+ gem 'minitest'
9
+ require 'minitest/autorun'
10
+ require 'mocha/setup'
11
+ require_relative '../lib/inprovise'
12
+
13
+ # force root file
14
+ ENV['INPROVISE_INFRA'] = File.join(File.dirname(__FILE__), 'fixtures', Inprovise::INFRA_FILE)
15
+
16
+ def reset_script_index!
17
+ Inprovise::ScriptIndex.default.clear!
18
+ end
19
+
20
+ def reset_infrastructure!
21
+ Inprovise::Infrastructure.reset
22
+ end
23
+
24
+ # patch Infrastructure#load and #save to do nothing
25
+ module Inprovise::Infrastructure
26
+ class << self
27
+ def load
28
+ # noop
29
+ end
30
+ def save
31
+ # noop
32
+ end
33
+
34
+ # add reset
35
+ def reset
36
+ targets.synchronize do
37
+ targets.clear
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ # create mock test channel
44
+
45
+ Inprovise::CmdChannel.define('test') do
46
+
47
+ def initialize(node, user=nil)
48
+ @node = node
49
+ @user = user || node.user
50
+ end
51
+
52
+ # command execution
53
+
54
+ def run(command, forcelog=false)
55
+ @node.log.execute("RUN: #{command}") if Inprovise.verbosity > 0
56
+ "RUN: #{command}"
57
+ end
58
+
59
+ # file management
60
+
61
+ def upload(from, to)
62
+ @node.log.execute("UPLOAD: #{from} => #{to}") if Inprovise.verbosity > 0
63
+ end
64
+
65
+ def download(from, to)
66
+ @node.log.execute("DOWNLOAD: #{from} => #{to}") if Inprovise.verbosity > 0
67
+ end
68
+
69
+ def mkdir(path)
70
+ @node.log.execute("MKDIR: #{path}") if Inprovise.verbosity > 0
71
+ end
72
+
73
+ def exists?(path)
74
+ @node.log.execute("EXISTS?: #{path}") if Inprovise.verbosity > 0
75
+ true
76
+ end
77
+
78
+ def file?(path)
79
+ @node.log.execute("FILE?: #{path}") if Inprovise.verbosity > 0
80
+ true
81
+ end
82
+
83
+ def directory?(path)
84
+ @node.log.execute("DIRECTORY?: #{path}") if Inprovise.verbosity > 0
85
+ true
86
+ end
87
+
88
+ def content(path)
89
+ @node.log.execute("READ: #{path}") if Inprovise.verbosity > 0
90
+ "READ: #{path}"
91
+ end
92
+
93
+ def delete(path)
94
+ @node.log.execute("DELETE: #{path}") if Inprovise.verbosity > 0
95
+ end
96
+
97
+ def permissions(path)
98
+ @node.log.execute("PERMISSIONS: #{path}") if Inprovise.verbosity > 0
99
+ 0
100
+ end
101
+
102
+ def set_permissions(path, perm)
103
+ @node.log.execute("SETPERMISSIONS: #{path} #{perm}") if Inprovise.verbosity > 0
104
+ end
105
+
106
+ def owner(path)
107
+ @node.log.execute("OWNER: #{path}") if Inprovise.verbosity > 0
108
+ {:user => @user, :group => 'users'}
109
+ end
110
+
111
+ def set_owner(path, user, group=nil)
112
+ @node.log.execute("SET_OWNER: #{path} #{user} #{group}") if Inprovise.verbosity > 0
113
+ end
114
+
115
+ end
116
+
117
+ # create mock test helper
118
+
119
+ Inprovise::CmdHelper.define('test') do
120
+
121
+ def initialize(channel, sudo=false)
122
+ super(channel)
123
+ end
124
+
125
+ # platform properties
126
+
127
+ def admin_user
128
+ 'root'
129
+ end
130
+
131
+ def env_reference(varname)
132
+ "\$#{varname}"
133
+ end
134
+
135
+ # generic command execution
136
+
137
+ def sudo
138
+ return self
139
+ end
140
+
141
+ # basic commands
142
+
143
+ def echo(arg)
144
+ run("echo #{arg}")
145
+ end
146
+
147
+ def cat(path)
148
+ begin
149
+ @channel.content(path)
150
+ rescue
151
+ run("cat #{path}")
152
+ end
153
+ end
154
+
155
+ def hash_for(path)
156
+ Digest::SHA1.hexdigest(run("sha1sum #{path}"))
157
+ end
158
+
159
+ def mkdir(path)
160
+ run("mkdir -p #{path}")
161
+ end
162
+
163
+ def exists?(path)
164
+ begin
165
+ @channel.exists?(path)
166
+ rescue
167
+ run(%{if [ -f #{path} ]; then echo "true"; else echo "false"; fi}).strip == 'true'
168
+ end
169
+ end
170
+
171
+ def file?(path)
172
+ begin
173
+ @channel.file?(path)
174
+ rescue
175
+ (run("stat --format=%f #{path}").chomp.hex & 0x8000) == 0x8000
176
+ end
177
+ end
178
+
179
+ def directory?(path)
180
+ begin
181
+ @channel.file?(path)
182
+ rescue
183
+ (run("stat --format=%f #{path}").chomp.hex & 0x4000) == 0x4000
184
+ end
185
+ end
186
+
187
+ def copy(from, to)
188
+ run("cp #{from} #{to}")
189
+ end
190
+
191
+ def delete(path)
192
+ begin
193
+ @channel.delete(path)
194
+ rescue
195
+ run("rm #{path}")
196
+ end
197
+ end
198
+
199
+ def permissions(path)
200
+ begin
201
+ @channel.permissions(path)
202
+ rescue
203
+ run("stat --format=%a #{path}").strip.to_i(8)
204
+ end
205
+ end
206
+
207
+ def set_permissions(path, perm)
208
+ begin
209
+ @channel.set_permissions(path, perm)
210
+ rescue
211
+ run("chmod -R #{sprintf("%o",perm)} #{path}")
212
+ end
213
+ end
214
+
215
+ def owner(path)
216
+ begin
217
+ @channel.owner(path)
218
+ rescue
219
+ user, group = run("stat --format=%U:%G #{path}").chomp.split(":")
220
+ {:user => user, :group => group}
221
+ end
222
+ end
223
+
224
+ def set_owner(path, user, group=nil)
225
+ begin
226
+ @channel.set_owner(path, user, group)
227
+ rescue
228
+ run(%{chown -R #{user}#{group ? ":#{group}" : ''} #{path}})
229
+ end
230
+ end
231
+
232
+ def binary_exists?(bin)
233
+ run("which #{bin}") =~ /\/#{bin}/
234
+ end
235
+
236
+ end
237
+
metadata ADDED
@@ -0,0 +1,182 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: inprovise
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.2
5
+ platform: ruby
6
+ authors:
7
+ - Martin Corino
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-09-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: colored
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: net-ssh
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: net-sftp
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: gli
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: tilt
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: InProvisE is Intuitive Provisioning Environment
84
+ email:
85
+ - mcorino@remedy.nl
86
+ executables:
87
+ - rig
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - .gitignore
92
+ - .travis.yml
93
+ - Gemfile
94
+ - LICENSE
95
+ - README.md
96
+ - Rakefile.rb
97
+ - bin/rig
98
+ - inprovise.gemspec
99
+ - lib/inprovise.rb
100
+ - lib/inprovise/channel/ssh.rb
101
+ - lib/inprovise/cli.rb
102
+ - lib/inprovise/cli/group.rb
103
+ - lib/inprovise/cli/node.rb
104
+ - lib/inprovise/cli/provision.rb
105
+ - lib/inprovise/cmd_channel.rb
106
+ - lib/inprovise/cmd_helper.rb
107
+ - lib/inprovise/control.rb
108
+ - lib/inprovise/execution_context.rb
109
+ - lib/inprovise/group.rb
110
+ - lib/inprovise/helper/cygwin.rb
111
+ - lib/inprovise/helper/linux.rb
112
+ - lib/inprovise/helper/windows.rb
113
+ - lib/inprovise/infra.rb
114
+ - lib/inprovise/local_file.rb
115
+ - lib/inprovise/logger.rb
116
+ - lib/inprovise/node.rb
117
+ - lib/inprovise/remote_file.rb
118
+ - lib/inprovise/resolver.rb
119
+ - lib/inprovise/script.rb
120
+ - lib/inprovise/script_index.rb
121
+ - lib/inprovise/script_runner.rb
122
+ - lib/inprovise/sniff.rb
123
+ - lib/inprovise/sniffer/linux.rb
124
+ - lib/inprovise/sniffer/platform.rb
125
+ - lib/inprovise/sniffer/unknown.rb
126
+ - lib/inprovise/sniffer/windows.rb
127
+ - lib/inprovise/template.rb
128
+ - lib/inprovise/template/inprovise.rb.erb
129
+ - lib/inprovise/trigger_runner.rb
130
+ - lib/inprovise/version.rb
131
+ - test/cli_test.rb
132
+ - test/cli_test_helper.rb
133
+ - test/dsl_test.rb
134
+ - test/fixtures/example.txt
135
+ - test/fixtures/include.rb
136
+ - test/fixtures/inprovise.rb
137
+ - test/fixtures/myscheme.rb
138
+ - test/infra_test.rb
139
+ - test/local_file_test.rb
140
+ - test/remote_file_test.rb
141
+ - test/resolver_test.rb
142
+ - test/script_index_test.rb
143
+ - test/script_test.rb
144
+ - test/test_helper.rb
145
+ homepage: ''
146
+ licenses: []
147
+ metadata: {}
148
+ post_install_message: ''
149
+ rdoc_options: []
150
+ require_paths:
151
+ - lib
152
+ required_ruby_version: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - ! '>='
155
+ - !ruby/object:Gem::Version
156
+ version: '0'
157
+ required_rubygems_version: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - ! '>='
160
+ - !ruby/object:Gem::Version
161
+ version: '0'
162
+ requirements: []
163
+ rubyforge_project:
164
+ rubygems_version: 2.4.5
165
+ signing_key:
166
+ specification_version: 4
167
+ summary: Simple, easy and intuitive infrastructure provisioning
168
+ test_files:
169
+ - test/cli_test.rb
170
+ - test/cli_test_helper.rb
171
+ - test/dsl_test.rb
172
+ - test/fixtures/example.txt
173
+ - test/fixtures/include.rb
174
+ - test/fixtures/inprovise.rb
175
+ - test/fixtures/myscheme.rb
176
+ - test/infra_test.rb
177
+ - test/local_file_test.rb
178
+ - test/remote_file_test.rb
179
+ - test/resolver_test.rb
180
+ - test/script_index_test.rb
181
+ - test/script_test.rb
182
+ - test/test_helper.rb