thor-ssh 0.1.5 → 0.1.6
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.
- data/lib/thor-ssh/actions.rb +12 -6
- data/lib/thor-ssh/local_file.rb +58 -0
- data/lib/thor-ssh/local_server.rb +34 -0
- data/lib/thor-ssh/remote_file.rb +0 -4
- data/lib/thor-ssh/version.rb +1 -1
- data/spec/actions_spec.rb +94 -53
- data/thor-ssh.gemspec +2 -1
- metadata +24 -6
data/lib/thor-ssh/actions.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'thor-ssh/local_file'
|
2
|
+
require 'thor-ssh/local_server'
|
1
3
|
require 'thor-ssh/remote_file'
|
2
4
|
require 'thor-ssh/remote_server'
|
3
5
|
require 'thor-ssh/actions/empty_directory'
|
@@ -23,18 +25,22 @@ module ThorSsh
|
|
23
25
|
# or change the state of files. If there is no destination_server
|
24
26
|
# it is assumed to be local and a normal File class is returned
|
25
27
|
def destination_files
|
26
|
-
if self.
|
28
|
+
if self.destination_connection
|
27
29
|
return @destination_files ||= RemoteFile.new(self.destination_connection)
|
28
30
|
else
|
29
|
-
return
|
31
|
+
return @destination_files ||= LocalFile.new
|
30
32
|
end
|
31
33
|
end
|
32
34
|
|
33
|
-
# Returns a
|
34
|
-
#
|
35
|
-
#
|
35
|
+
# Returns a RemoteServer instance or a LocalServer instance.
|
36
|
+
# Makes it so calls to run events can be called the same reguardless of
|
37
|
+
# the destination.
|
36
38
|
def destination_server
|
37
|
-
|
39
|
+
if self.destination_connection
|
40
|
+
return @destination_server ||= RemoteServer.new(self.destination_connection)
|
41
|
+
else
|
42
|
+
return @destination_server ||= LocalServer.new
|
43
|
+
end
|
38
44
|
end
|
39
45
|
|
40
46
|
def inside(dir='', config={}, &block)
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module ThorSsh
|
4
|
+
class LocalFile
|
5
|
+
def exists?(path)
|
6
|
+
File.exists?(path)
|
7
|
+
end
|
8
|
+
|
9
|
+
def run(command)
|
10
|
+
return system(command)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Creates the directory at the path on the remote server
|
14
|
+
def mkdir_p(path)
|
15
|
+
FileUtils.mkdir_p(path)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Remote the file/folder on the remote server
|
19
|
+
def rm_rf(path)
|
20
|
+
FileUtils.rm_rf(path)
|
21
|
+
end
|
22
|
+
alias :unlink :rm_rf
|
23
|
+
|
24
|
+
def symlink(old_name, new_name)
|
25
|
+
File.symlink(old_name, new_name)
|
26
|
+
end
|
27
|
+
|
28
|
+
def link(old_name, new_name)
|
29
|
+
File.link(old_name, new_name)
|
30
|
+
end
|
31
|
+
|
32
|
+
def binread(path)
|
33
|
+
data = nil
|
34
|
+
File.open(path, "rb") do |f|
|
35
|
+
data = f.read
|
36
|
+
end
|
37
|
+
|
38
|
+
return data
|
39
|
+
end
|
40
|
+
|
41
|
+
# TODO: we should just move this to a more standard thing
|
42
|
+
def binwrite(path, data)
|
43
|
+
File.open(path, 'wb') do |file|
|
44
|
+
file.write(data)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def chmod(mode, file_name)
|
49
|
+
File.chmod(mode, file_name)
|
50
|
+
end
|
51
|
+
|
52
|
+
# See if these paths point to the same inode
|
53
|
+
def identical?(file1, file2)
|
54
|
+
File.identical?(file1, file2)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'popen4'
|
2
|
+
|
3
|
+
module ThorSsh
|
4
|
+
class LocalServer
|
5
|
+
def run_with_codes(command)
|
6
|
+
# pid, stdin, stdout, stderr = Open4::popen4(command)
|
7
|
+
# ignored, status = Process::waitpid2 pid
|
8
|
+
# exit_code = status.to_i
|
9
|
+
exit_signal = nil
|
10
|
+
|
11
|
+
stdout_data = ''
|
12
|
+
stderr_data = ''
|
13
|
+
status = POpen4::popen4(command) do |stdout, stderr, stdin, pid|
|
14
|
+
stdin.close
|
15
|
+
stdout_data = stdout.read
|
16
|
+
stderr_data = stderr.read.strip
|
17
|
+
end
|
18
|
+
|
19
|
+
exit_code = status.to_i
|
20
|
+
|
21
|
+
return stdout_data, stderr_data, exit_code, exit_signal
|
22
|
+
end
|
23
|
+
|
24
|
+
def run(command, with_codes=false)
|
25
|
+
if with_codes
|
26
|
+
return run_with_codes(command)
|
27
|
+
else
|
28
|
+
stdout, stdin, exit_code, exit_signal = run_with_codes(command)
|
29
|
+
return stdout
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
data/lib/thor-ssh/remote_file.rb
CHANGED
data/lib/thor-ssh/version.rb
CHANGED
data/spec/actions_spec.rb
CHANGED
@@ -1,108 +1,149 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'thor_test'
|
3
3
|
require 'vagrant/vagrant_manager'
|
4
|
+
require 'fileutils'
|
4
5
|
|
5
6
|
|
6
7
|
describe ThorSsh do
|
7
8
|
before do
|
8
9
|
# Setup the test and connect to a test server
|
9
|
-
@
|
10
|
-
@
|
10
|
+
@remote_test = ThorTest.new
|
11
|
+
@remote_test.destination_connection = VagrantManager.connect
|
12
|
+
|
13
|
+
@local_test = ThorTest.new
|
14
|
+
@local_test.destination_root = File.join(File.dirname(__FILE__), '/tmp/')
|
11
15
|
end
|
12
16
|
|
13
17
|
after do
|
14
18
|
# Close the connection
|
15
|
-
|
16
|
-
|
19
|
+
@remote_test.destination_connection.close
|
20
|
+
|
21
|
+
# Clear local tmp dir
|
22
|
+
FileUtils.rm_rf(File.join(File.dirname(__FILE__), '/tmp/test/'))
|
17
23
|
end
|
18
24
|
|
19
25
|
before(:all) do
|
20
|
-
@
|
26
|
+
@remote_base_path = '/home/vagrant/thortest'
|
27
|
+
@local_base_path = File.join(File.dirname(__FILE__), '/tmp/test/')
|
21
28
|
|
22
|
-
@
|
23
|
-
@
|
24
|
-
@
|
25
|
-
|
26
|
-
@thor_test.destination_connection.close
|
29
|
+
@remote_test = ThorTest.new
|
30
|
+
@remote_test.destination_connection = VagrantManager.connect
|
31
|
+
@remote_test.destination_files.rm_rf(@remote_base_path)
|
32
|
+
@remote_test.destination_connection.close
|
27
33
|
|
28
34
|
end
|
29
35
|
|
30
|
-
it 'should create an empty directory' do
|
31
|
-
@
|
32
|
-
@
|
36
|
+
it 'should create an empty directory remotely' do
|
37
|
+
@remote_test.empty_directory(@remote_base_path)
|
38
|
+
@remote_test.destination_files.exists?(@remote_base_path)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should create an empty directory locally' do
|
42
|
+
@local_test.empty_directory(@local_base_path)
|
43
|
+
@local_test.destination_files.exists?(@local_base_path)
|
33
44
|
end
|
34
45
|
|
35
|
-
it 'should create
|
36
|
-
@
|
37
|
-
@
|
46
|
+
it 'should create get a url remotely' do
|
47
|
+
@remote_test.get('http://www.google.com/', "#{@remote_base_path}/google.txt")
|
48
|
+
@remote_test.destination_files.binread("#{@remote_base_path}/google.txt").should match(/Google/)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should create get a url locally' do
|
52
|
+
@local_test.get('http://www.google.com/', "#{@local_base_path}/google.txt")
|
53
|
+
@local_test.destination_files.binread("#{@local_base_path}/google.txt").should match(/Google/)
|
38
54
|
end
|
39
55
|
|
40
|
-
it 'should create a file and set the text' do
|
41
|
-
@
|
42
|
-
@
|
56
|
+
it 'should create a file and set the text remotely' do
|
57
|
+
@remote_test.create_file("#{@remote_base_path}/createdFile", "More awesome content\nSecond Line of content")
|
58
|
+
@remote_test.destination_files.binread("#{@remote_base_path}/createdFile").should == "More awesome content\nSecond Line of content"
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should create a file and set the text locally' do
|
62
|
+
@local_test.create_file("#{@local_base_path}/createdFile", "More awesome content\nSecond Line of content")
|
63
|
+
@local_test.destination_files.binread("#{@local_base_path}/createdFile").should == "More awesome content\nSecond Line of content"
|
43
64
|
end
|
44
65
|
|
45
|
-
it "should copy in text" do
|
46
|
-
@
|
47
|
-
@
|
48
|
-
@
|
66
|
+
it "should copy in text remotely" do
|
67
|
+
@remote_test.destination_root = @remote_base_path + "/"
|
68
|
+
@remote_test.template "templates/test_template.rb.tt"
|
69
|
+
@remote_test.destination_files.binread("#{@remote_base_path}/templates/test_template.rb").should match(/Test Ruby File/)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should copy in text locally" do
|
73
|
+
@local_test.destination_root = @local_base_path + "/"
|
74
|
+
@local_test.template "templates/test_template.rb.tt"
|
75
|
+
@local_test.destination_files.binread("#{@local_base_path}/templates/test_template.rb").should match(/Test Ruby File/)
|
49
76
|
end
|
50
77
|
|
51
|
-
def
|
52
|
-
ls = @
|
78
|
+
def remote_mode(path)
|
79
|
+
ls = @remote_test.destination_server.run("ls -lh \"#{@remote_base_path}/#{path}\"")
|
53
80
|
mode = ls.strip.split(/ /).first.strip
|
54
81
|
return mode
|
55
82
|
end
|
56
83
|
|
57
|
-
it "should set the mode" do
|
58
|
-
@
|
59
|
-
@
|
60
|
-
|
61
|
-
@
|
62
|
-
|
84
|
+
it "should set the mode remotely" do
|
85
|
+
@remote_test.create_file("#{@remote_base_path}/modeFile", "More awesome content")
|
86
|
+
@remote_test.chmod("#{@remote_base_path}/modeFile", 0644)
|
87
|
+
remote_mode('modeFile').should == '-rw-r--r--'
|
88
|
+
@remote_test.chmod("#{@remote_base_path}/modeFile", 0600)
|
89
|
+
remote_mode('modeFile').should == '-rw-------'
|
90
|
+
end
|
91
|
+
|
92
|
+
def local_mode(path)
|
93
|
+
ls = @local_test.destination_server.run("ls -lh \"#{@local_base_path}/#{path}\"")
|
94
|
+
mode = ls.strip.split(/ /).first.strip
|
95
|
+
return mode
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should set the mode locally" do
|
99
|
+
@local_test.create_file("#{@local_base_path}/modeFile", "More awesome content")
|
100
|
+
@local_test.chmod("#{@local_base_path}/modeFile", 0644)
|
101
|
+
local_mode('modeFile').should == '-rw-r--r--'
|
102
|
+
@local_test.chmod("#{@local_base_path}/modeFile", 0600)
|
103
|
+
local_mode('modeFile').should == '-rw-------'
|
63
104
|
end
|
64
105
|
|
65
106
|
it "should gsub files" do
|
66
|
-
file = "#{@
|
67
|
-
@
|
68
|
-
@
|
69
|
-
@
|
107
|
+
file = "#{@remote_base_path}/gsubFile"
|
108
|
+
@remote_test.create_file(file, "More awesome content")
|
109
|
+
@remote_test.gsub_file file, /awesome/, 'cool'
|
110
|
+
@remote_test.destination_files.binread(file).should == 'More cool content'
|
70
111
|
end
|
71
112
|
|
72
113
|
it "should remove files" do
|
73
|
-
file = "#{@
|
74
|
-
@
|
75
|
-
@
|
76
|
-
@
|
77
|
-
@
|
114
|
+
file = "#{@remote_base_path}/removeFile"
|
115
|
+
@remote_test.create_file(file, "More awesome content")
|
116
|
+
@remote_test.destination_files.exists?(file).should == true
|
117
|
+
@remote_test.remove_file(file)
|
118
|
+
@remote_test.destination_files.exists?(file).should == false
|
78
119
|
end
|
79
120
|
|
80
121
|
it "should inject text into files" do
|
81
|
-
file = "#{@
|
82
|
-
@
|
83
|
-
@
|
84
|
-
@
|
122
|
+
file = "#{@remote_base_path}/injectFile"
|
123
|
+
@remote_test.create_file(file, "First line\nSecond Line\nThird Line")
|
124
|
+
@remote_test.insert_into_file(file, "2.5 line\n", :after => "Second Line\n")
|
125
|
+
@remote_test.destination_files.binread(file).should == "First line\nSecond Line\n2.5 line\nThird Line"
|
85
126
|
end
|
86
127
|
|
87
128
|
it "should create links" do
|
88
|
-
file = "#{@
|
89
|
-
link_file = "#{@
|
90
|
-
@
|
129
|
+
file = "#{@remote_base_path}/symFile"
|
130
|
+
link_file = "#{@remote_base_path}/linkedFile"
|
131
|
+
@remote_test.create_file(file, "Text")
|
91
132
|
|
92
|
-
@
|
133
|
+
@remote_test.create_link(link_file, file)
|
93
134
|
|
94
|
-
@
|
135
|
+
@remote_test.destination_files.binread(link_file).should == "Text"
|
95
136
|
end
|
96
137
|
|
97
138
|
it "should download a file remotely" do
|
98
|
-
@
|
139
|
+
@remote_test.get('http://nginx.org/download/nginx-1.2.0.tar.gz', '/home/vagrant/nginx-1.2.0.tar.gz')
|
99
140
|
end
|
100
141
|
|
101
142
|
it "should run exec with an exit code" do
|
102
|
-
stdout, stderr, exit_code, exit_signal = @
|
143
|
+
stdout, stderr, exit_code, exit_signal = @remote_test.exec('false', true)
|
103
144
|
exit_code.should == 1
|
104
|
-
|
105
|
-
stdout, stderr, exit_code, exit_signal = @
|
145
|
+
|
146
|
+
stdout, stderr, exit_code, exit_signal = @remote_test.exec('true', true)
|
106
147
|
exit_code.should == 0
|
107
148
|
end
|
108
149
|
end
|
data/thor-ssh.gemspec
CHANGED
@@ -16,9 +16,10 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.add_runtime_dependency 'thor', '~> 0.15.2'
|
17
17
|
gem.add_runtime_dependency 'net-ssh'#, '= 2.2.2'
|
18
18
|
gem.add_runtime_dependency 'net-sftp'#, '= 2.0.5'
|
19
|
+
gem.add_runtime_dependency 'popen4', '~> 0.1.2'
|
19
20
|
gem.add_development_dependency 'rspec', '~> 2.10'
|
20
21
|
gem.add_development_dependency 'vagrant', '= 1.0.3'
|
21
|
-
gem.add_development_dependency 'sahara'
|
22
|
+
gem.add_development_dependency 'sahara', '>= 0.0.11'
|
22
23
|
gem.add_development_dependency 'rake', '~> 0.9'
|
23
24
|
gem.add_development_dependency 'rdoc', '~> 3.9'
|
24
25
|
gem.rdoc_options = ['--charset=UTF-8']
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thor-ssh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-05-
|
12
|
+
date: 2012-05-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: thor
|
@@ -59,6 +59,22 @@ dependencies:
|
|
59
59
|
- - ! '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: popen4
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 0.1.2
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 0.1.2
|
62
78
|
- !ruby/object:Gem::Dependency
|
63
79
|
name: rspec
|
64
80
|
requirement: !ruby/object:Gem::Requirement
|
@@ -98,7 +114,7 @@ dependencies:
|
|
98
114
|
requirements:
|
99
115
|
- - ! '>='
|
100
116
|
- !ruby/object:Gem::Version
|
101
|
-
version:
|
117
|
+
version: 0.0.11
|
102
118
|
type: :development
|
103
119
|
prerelease: false
|
104
120
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -106,7 +122,7 @@ dependencies:
|
|
106
122
|
requirements:
|
107
123
|
- - ! '>='
|
108
124
|
- !ruby/object:Gem::Version
|
109
|
-
version:
|
125
|
+
version: 0.0.11
|
110
126
|
- !ruby/object:Gem::Dependency
|
111
127
|
name: rake
|
112
128
|
requirement: !ruby/object:Gem::Requirement
|
@@ -160,6 +176,8 @@ files:
|
|
160
176
|
- lib/thor-ssh/actions/empty_directory.rb
|
161
177
|
- lib/thor-ssh/actions/file_manipulation.rb
|
162
178
|
- lib/thor-ssh/actions/inject_into_file.rb
|
179
|
+
- lib/thor-ssh/local_file.rb
|
180
|
+
- lib/thor-ssh/local_server.rb
|
163
181
|
- lib/thor-ssh/remote_file.rb
|
164
182
|
- lib/thor-ssh/remote_server.rb
|
165
183
|
- lib/thor-ssh/version.rb
|
@@ -187,7 +205,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
187
205
|
version: '0'
|
188
206
|
segments:
|
189
207
|
- 0
|
190
|
-
hash: -
|
208
|
+
hash: -1434051545551031789
|
191
209
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
192
210
|
none: false
|
193
211
|
requirements:
|
@@ -196,7 +214,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
196
214
|
version: '0'
|
197
215
|
segments:
|
198
216
|
- 0
|
199
|
-
hash: -
|
217
|
+
hash: -1434051545551031789
|
200
218
|
requirements: []
|
201
219
|
rubyforge_project:
|
202
220
|
rubygems_version: 1.8.22
|