necktie 0.1.1 → 0.2.0
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/bin/necktie +1 -1
- data/lib/necktie/rush.rb +11 -0
- data/lib/necktie/services.rb +31 -11
- data/lib/necktie.rb +10 -6
- data/necktie.gemspec +2 -2
- data/rush/README.rdoc +87 -0
- data/rush/Rakefile +60 -0
- data/rush/VERSION +1 -0
- data/rush/bin/rush +13 -0
- data/rush/bin/rushd +7 -0
- data/rush/lib/rush/access.rb +130 -0
- data/rush/lib/rush/array_ext.rb +19 -0
- data/rush/lib/rush/box.rb +112 -0
- data/rush/lib/rush/commands.rb +55 -0
- data/rush/lib/rush/config.rb +154 -0
- data/rush/lib/rush/dir.rb +160 -0
- data/rush/lib/rush/embeddable_shell.rb +26 -0
- data/rush/lib/rush/entry.rb +185 -0
- data/rush/lib/rush/exceptions.rb +31 -0
- data/rush/lib/rush/file.rb +85 -0
- data/rush/lib/rush/find_by.rb +39 -0
- data/rush/lib/rush/fixnum_ext.rb +18 -0
- data/rush/lib/rush/head_tail.rb +11 -0
- data/rush/lib/rush/local.rb +402 -0
- data/rush/lib/rush/process.rb +59 -0
- data/rush/lib/rush/process_set.rb +62 -0
- data/rush/lib/rush/remote.rb +156 -0
- data/rush/lib/rush/search_results.rb +58 -0
- data/rush/lib/rush/server.rb +117 -0
- data/rush/lib/rush/shell.rb +187 -0
- data/rush/lib/rush/ssh_tunnel.rb +122 -0
- data/rush/lib/rush/string_ext.rb +3 -0
- data/rush/lib/rush.rb +87 -0
- data/rush/rush.gemspec +113 -0
- data/rush/spec/access_spec.rb +134 -0
- data/rush/spec/array_ext_spec.rb +15 -0
- data/rush/spec/base.rb +24 -0
- data/rush/spec/box_spec.rb +64 -0
- data/rush/spec/commands_spec.rb +47 -0
- data/rush/spec/config_spec.rb +108 -0
- data/rush/spec/dir_spec.rb +164 -0
- data/rush/spec/embeddable_shell_spec.rb +17 -0
- data/rush/spec/entry_spec.rb +133 -0
- data/rush/spec/file_spec.rb +83 -0
- data/rush/spec/find_by_spec.rb +58 -0
- data/rush/spec/fixnum_ext_spec.rb +19 -0
- data/rush/spec/local_spec.rb +352 -0
- data/rush/spec/process_set_spec.rb +50 -0
- data/rush/spec/process_spec.rb +73 -0
- data/rush/spec/remote_spec.rb +140 -0
- data/rush/spec/rush_spec.rb +28 -0
- data/rush/spec/search_results_spec.rb +44 -0
- data/rush/spec/shell_spec.rb +23 -0
- data/rush/spec/ssh_tunnel_spec.rb +122 -0
- data/rush/spec/string_ext_spec.rb +23 -0
- metadata +53 -3
- data/lib/necktie/files.rb +0 -14
@@ -0,0 +1,73 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/base'
|
2
|
+
|
3
|
+
describe Rush::Process do
|
4
|
+
before do
|
5
|
+
@pid = fork do
|
6
|
+
sleep 999
|
7
|
+
end
|
8
|
+
@process = Rush::Process.all.detect { |p| p.pid == @pid }
|
9
|
+
end
|
10
|
+
|
11
|
+
after do
|
12
|
+
system "kill -9 #{@pid}"
|
13
|
+
end
|
14
|
+
|
15
|
+
if !RUBY_PLATFORM.match(/darwin/) # OS x reports pids weird
|
16
|
+
it "knows all its child processes" do
|
17
|
+
parent = Rush::Process.all.detect { |p| p.pid == Process.pid }
|
18
|
+
parent.children.should == [ @process ]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
it "gets the list of all processes" do
|
23
|
+
list = Rush::Process.all
|
24
|
+
list.size.should > 5
|
25
|
+
list.first.should be_kind_of(Rush::Process)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "knows the pid" do
|
29
|
+
@process.pid.should == @pid
|
30
|
+
end
|
31
|
+
|
32
|
+
it "knows the uid" do
|
33
|
+
@process.uid.should == ::Process.uid
|
34
|
+
end
|
35
|
+
|
36
|
+
it "knows the executed binary" do
|
37
|
+
@process.command.should match(/ruby/)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "knows the command line" do
|
41
|
+
@process.cmdline.should match(/process_spec.rb/)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "knows the memory used" do
|
45
|
+
@process.mem.should > 0
|
46
|
+
end
|
47
|
+
|
48
|
+
it "knows the cpu used" do
|
49
|
+
@process.cpu.should >= 0
|
50
|
+
end
|
51
|
+
|
52
|
+
it "knows the parent process pid" do
|
53
|
+
@process.parent_pid.should == Process.pid
|
54
|
+
end
|
55
|
+
|
56
|
+
it "knows the parent process" do
|
57
|
+
this = Rush::Box.new.processes.select { |p| p.pid == Process.pid }.first
|
58
|
+
@process.parent.should == this
|
59
|
+
end
|
60
|
+
|
61
|
+
it "can kill itself" do
|
62
|
+
process = Rush.bash("sleep 30", :background => true)
|
63
|
+
process.alive?.should be_true
|
64
|
+
process.kill
|
65
|
+
sleep 0.1
|
66
|
+
process.alive?.should be_false
|
67
|
+
end
|
68
|
+
|
69
|
+
it "if box and pid are the same, process is equal" do
|
70
|
+
other = Rush::Process.new({ :pid => @process.pid }, @process.box)
|
71
|
+
@process.should == other
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/base'
|
2
|
+
|
3
|
+
describe Rush::Connection::Local do
|
4
|
+
before do
|
5
|
+
@sandbox_dir = "/tmp/rush_spec.#{Process.pid}"
|
6
|
+
system "rm -rf #{@sandbox_dir}; mkdir -p #{@sandbox_dir}"
|
7
|
+
|
8
|
+
@con = Rush::Connection::Remote.new('spec.example.com')
|
9
|
+
end
|
10
|
+
|
11
|
+
after do
|
12
|
+
system "rm -rf #{@sandbox_dir}"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "transmits write_file" do
|
16
|
+
@con.should_receive(:transmit).with(:action => 'write_file', :full_path => 'file', :payload => 'contents')
|
17
|
+
@con.write_file('file', 'contents')
|
18
|
+
end
|
19
|
+
|
20
|
+
it "transmits append_to_file" do
|
21
|
+
@con.should_receive(:transmit).with(:action => 'append_to_file', :full_path => 'file', :payload => 'contents')
|
22
|
+
@con.append_to_file('file', 'contents')
|
23
|
+
end
|
24
|
+
|
25
|
+
it "transmits file_contents" do
|
26
|
+
@con.should_receive(:transmit).with(:action => 'file_contents', :full_path => 'file').and_return('contents')
|
27
|
+
@con.file_contents('file').should == 'contents'
|
28
|
+
end
|
29
|
+
|
30
|
+
it "transmits destroy" do
|
31
|
+
@con.should_receive(:transmit).with(:action => 'destroy', :full_path => 'file')
|
32
|
+
@con.destroy('file')
|
33
|
+
end
|
34
|
+
|
35
|
+
it "transmits purge" do
|
36
|
+
@con.should_receive(:transmit).with(:action => 'purge', :full_path => 'dir')
|
37
|
+
@con.purge('dir')
|
38
|
+
end
|
39
|
+
|
40
|
+
it "transmits create_dir" do
|
41
|
+
@con.should_receive(:transmit).with(:action => 'create_dir', :full_path => 'file')
|
42
|
+
@con.create_dir('file')
|
43
|
+
end
|
44
|
+
|
45
|
+
it "transmits rename" do
|
46
|
+
@con.should_receive(:transmit).with(:action => 'rename', :path => 'path', :name => 'name', :new_name => 'new_name')
|
47
|
+
@con.rename('path', 'name', 'new_name')
|
48
|
+
end
|
49
|
+
|
50
|
+
it "transmits copy" do
|
51
|
+
@con.should_receive(:transmit).with(:action => 'copy', :src => 'src', :dst => 'dst')
|
52
|
+
@con.copy('src', 'dst')
|
53
|
+
end
|
54
|
+
|
55
|
+
it "transmits read_archive" do
|
56
|
+
@con.should_receive(:transmit).with(:action => 'read_archive', :full_path => 'full_path').and_return('archive data')
|
57
|
+
@con.read_archive('full_path').should == 'archive data'
|
58
|
+
end
|
59
|
+
|
60
|
+
it "transmits write_archive" do
|
61
|
+
@con.should_receive(:transmit).with(:action => 'write_archive', :dir => 'dir', :payload => 'archive')
|
62
|
+
@con.write_archive('archive', 'dir')
|
63
|
+
end
|
64
|
+
|
65
|
+
it "transmits index" do
|
66
|
+
@con.should_receive(:transmit).with(:action => 'index', :base_path => 'base_path', :glob => '*').and_return("1\n2\n")
|
67
|
+
@con.index('base_path', '*').should == %w(1 2)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "transmits stat" do
|
71
|
+
@con.should_receive(:transmit).with(:action => 'stat', :full_path => 'full_path').and_return(YAML.dump(1 => 2))
|
72
|
+
@con.stat('full_path').should == { 1 => 2 }
|
73
|
+
end
|
74
|
+
|
75
|
+
it "transmits set_access" do
|
76
|
+
@con.should_receive(:transmit).with(:action => 'set_access', :full_path => 'full_path', :user => 'joe', :user_read => 1)
|
77
|
+
@con.set_access('full_path', :user => 'joe', :user_read => 1)
|
78
|
+
end
|
79
|
+
|
80
|
+
it "transmits size" do
|
81
|
+
@con.should_receive(:transmit).with(:action => 'size', :full_path => 'full_path').and_return("123")
|
82
|
+
@con.size('full_path').should == 123
|
83
|
+
end
|
84
|
+
|
85
|
+
it "transmits processes" do
|
86
|
+
@con.should_receive(:transmit).with(:action => 'processes').and_return(YAML.dump([ { :pid => 1 } ]))
|
87
|
+
@con.processes.should == [ { :pid => 1 } ]
|
88
|
+
end
|
89
|
+
|
90
|
+
it "transmits process_alive" do
|
91
|
+
@con.should_receive(:transmit).with(:action => 'process_alive', :pid => 123).and_return(true)
|
92
|
+
@con.process_alive(123).should == true
|
93
|
+
end
|
94
|
+
|
95
|
+
it "transmits kill_process" do
|
96
|
+
@con.should_receive(:transmit).with(:action => 'kill_process', :pid => 123, :payload => YAML.dump(:wait => 10))
|
97
|
+
@con.kill_process(123, :wait => 10)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "transmits bash" do
|
101
|
+
@con.should_receive(:transmit).with(:action => 'bash', :payload => 'cmd', :user => 'user', :background => 'bg').and_return('output')
|
102
|
+
@con.bash('cmd', 'user', 'bg').should == 'output'
|
103
|
+
end
|
104
|
+
|
105
|
+
it "an http result code of 401 raises NotAuthorized" do
|
106
|
+
lambda { @con.process_result("401", "") }.should raise_error(Rush::NotAuthorized)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "an http result code of 400 raises the exception passed in the result body" do
|
110
|
+
@con.stub!(:parse_exception).and_return(Rush::DoesNotExist, "message")
|
111
|
+
lambda { @con.process_result("400", "") }.should raise_error(Rush::DoesNotExist)
|
112
|
+
end
|
113
|
+
|
114
|
+
it "an http result code of 501 (or anything other than the other defined codes) raises FailedTransmit" do
|
115
|
+
lambda { @con.process_result("501", "") }.should raise_error(Rush::FailedTransmit)
|
116
|
+
end
|
117
|
+
|
118
|
+
it "parse_exception takes the class from the first line and the message from the second" do
|
119
|
+
@con.parse_exception("Rush::DoesNotExist\nthe message\n").should == [ Rush::DoesNotExist, "the message" ]
|
120
|
+
end
|
121
|
+
|
122
|
+
it "parse_exception rejects unrecognized exceptions" do
|
123
|
+
lambda { @con.parse_exception("NotARushException\n") }.should raise_error
|
124
|
+
end
|
125
|
+
|
126
|
+
it "passes through ensure_tunnel" do
|
127
|
+
@con.tunnel.should_receive(:ensure_tunnel)
|
128
|
+
@con.ensure_tunnel
|
129
|
+
end
|
130
|
+
|
131
|
+
it "is alive if the box is responding to commands" do
|
132
|
+
@con.should_receive(:index).and_return(:dummy)
|
133
|
+
@con.should be_alive
|
134
|
+
end
|
135
|
+
|
136
|
+
it "not alive if an attempted command throws an exception" do
|
137
|
+
@con.should_receive(:index).and_raise(RuntimeError)
|
138
|
+
@con.should_not be_alive
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/base'
|
2
|
+
|
3
|
+
describe Rush do
|
4
|
+
it "fetches a local file path" do
|
5
|
+
Rush['/etc/hosts'].full_path.should == '/etc/hosts'
|
6
|
+
end
|
7
|
+
|
8
|
+
it "fetches the dir of __FILE__" do
|
9
|
+
Rush.dir(__FILE__).name.should == 'spec'
|
10
|
+
end
|
11
|
+
|
12
|
+
it "fetches the launch dir (aka current working directory or pwd)" do
|
13
|
+
Dir.stub!(:pwd).and_return('/tmp')
|
14
|
+
Rush.launch_dir.should == Rush::Box.new['/tmp/']
|
15
|
+
end
|
16
|
+
|
17
|
+
it "runs a bash command" do
|
18
|
+
Rush.bash('echo hi').should == "hi\n"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "gets the list of local processes" do
|
22
|
+
Rush.processes.should be_kind_of(Rush::ProcessSet)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "gets my process" do
|
26
|
+
Rush.my_process.pid.should == Process.pid
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/base'
|
2
|
+
|
3
|
+
describe Rush::SearchResults do
|
4
|
+
before do
|
5
|
+
@results = Rush::SearchResults.new(/pat/)
|
6
|
+
@file = Rush::File.new("file")
|
7
|
+
end
|
8
|
+
|
9
|
+
it "returns its list of entries" do
|
10
|
+
@results.add(@file, %w(a))
|
11
|
+
@results.entries.should == [ @file ]
|
12
|
+
end
|
13
|
+
|
14
|
+
it "only returns each entry once no matter how many line matches it has" do
|
15
|
+
@results.add(@file, %w(a b))
|
16
|
+
@results.entries.should == [ @file ]
|
17
|
+
end
|
18
|
+
|
19
|
+
it "returns its list of matched lines" do
|
20
|
+
@results.add(@file, %w(a b))
|
21
|
+
@results.lines.should == %w(a b)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "returns all lines for each entry in a flattened form" do
|
25
|
+
file2 = Rush::File.new("another file")
|
26
|
+
@results.add(@file, %w(a b))
|
27
|
+
@results.add(file2, %w(c d))
|
28
|
+
@results.lines.should == %w(a b c d)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "returns a hash of entries_with_lines" do
|
32
|
+
@results.add(@file, %w(a))
|
33
|
+
@results.entries_with_lines.should == { @file => %w(a) }
|
34
|
+
end
|
35
|
+
|
36
|
+
it "mixes in Commands to operate like a dir or entry array" do
|
37
|
+
@results.methods.include?("search").should be_true
|
38
|
+
end
|
39
|
+
|
40
|
+
it "mixes in Enumerable to behave like an array" do
|
41
|
+
@results.add(@file, %w(a))
|
42
|
+
@results.map { |e| e }.should == [ @file ]
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/base'
|
2
|
+
require 'rush/shell'
|
3
|
+
|
4
|
+
describe Rush::Shell do
|
5
|
+
before do
|
6
|
+
@shell = Rush::Shell.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it "matches open path commands for readline tab completion" do
|
10
|
+
@shell.path_parts("dir['app").should == [ "dir", "[", "'", "app", "" ]
|
11
|
+
@shell.path_parts('dir/"app').should == [ "dir", "/", '"', "app", "" ]
|
12
|
+
end
|
13
|
+
|
14
|
+
it "matches open path commands on globals for readline tab completion" do
|
15
|
+
@shell.path_parts("$dir['app").should == [ "$dir", "[", "'", "app", "" ]
|
16
|
+
@shell.path_parts('$dir/"app').should == [ "$dir", "/", '"', "app", "" ]
|
17
|
+
end
|
18
|
+
|
19
|
+
it "matches open path commands on instance vars for readline tab completion" do
|
20
|
+
@shell.path_parts("@dir['app").should == [ "@dir", "[", "'", "app", "" ]
|
21
|
+
@shell.path_parts('@dir/"app').should == [ "@dir", "/", '"', "app", "" ]
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/base'
|
2
|
+
|
3
|
+
describe Rush::SshTunnel do
|
4
|
+
before do
|
5
|
+
@tunnel = Rush::SshTunnel.new('spec.example.com')
|
6
|
+
@tunnel.stub!(:config).and_return(mock_config_start)
|
7
|
+
@tunnel.stub!(:display)
|
8
|
+
end
|
9
|
+
|
10
|
+
after do
|
11
|
+
mock_config_cleanup
|
12
|
+
end
|
13
|
+
|
14
|
+
it "ensure_tunnel sets everything up for the tunnel when one does not already exist" do
|
15
|
+
@tunnel.should_receive(:push_credentials)
|
16
|
+
@tunnel.should_receive(:launch_rushd)
|
17
|
+
@tunnel.should_receive(:establish_tunnel)
|
18
|
+
@tunnel.ensure_tunnel
|
19
|
+
end
|
20
|
+
|
21
|
+
it "ensure_tunnel uses the existing port as long as the tunnel is still alive" do
|
22
|
+
@tunnel.should_receive(:tunnel_alive?).and_return(true)
|
23
|
+
@tunnel.instance_eval("@port = 2345")
|
24
|
+
@tunnel.ensure_tunnel
|
25
|
+
@tunnel.port.should == 2345
|
26
|
+
end
|
27
|
+
|
28
|
+
it "existing tunnel is used when it is specified in the tunnels file" do
|
29
|
+
@tunnel.config.tunnels_file.write "spec.example.com:4567\n"
|
30
|
+
@tunnel.should_receive(:tunnel_alive?).and_return(true)
|
31
|
+
@tunnel.should_not_receive(:setup_everything)
|
32
|
+
@tunnel.ensure_tunnel
|
33
|
+
@tunnel.port.should == 4567
|
34
|
+
end
|
35
|
+
|
36
|
+
it "tunnel host is always local" do
|
37
|
+
@tunnel.host.should == 'localhost'
|
38
|
+
end
|
39
|
+
|
40
|
+
it "picks the first port number when there are no tunnels yet" do
|
41
|
+
@tunnel.next_available_port.should == 7771
|
42
|
+
end
|
43
|
+
|
44
|
+
it "picks the next port number when there is already a tunnel" do
|
45
|
+
@tunnel.config.tunnels_file.write("#{@tunnel.host}:7771")
|
46
|
+
@tunnel.next_available_port.should == 7772
|
47
|
+
end
|
48
|
+
|
49
|
+
it "establishes a tunnel and saves it to ~/.rush/tunnels" do
|
50
|
+
@tunnel.should_receive(:make_ssh_tunnel)
|
51
|
+
@tunnel.should_receive(:port).exactly(0).times.and_return('7771') # avoid infinite loop
|
52
|
+
@tunnel.establish_tunnel
|
53
|
+
@tunnel.config.tunnels_file.contents.should == "spec.example.com:7771\n"
|
54
|
+
end
|
55
|
+
|
56
|
+
it "converts instance vars to options hash for ssh_tunnel_command" do
|
57
|
+
@tunnel.instance_eval("@port = 1234")
|
58
|
+
@tunnel.tunnel_options.should == {
|
59
|
+
:local_port => 1234,
|
60
|
+
:remote_port => 7770,
|
61
|
+
:ssh_host => 'spec.example.com'
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
it "ssh_stall_command uses an infinite loop for :timeout => :infinite" do
|
66
|
+
@tunnel.ssh_stall_command(:timeout => :infinite).should match(/while .* sleep .* done/)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "ssh_stall_command sleeps for the number of seconds given as the :timeout option" do
|
70
|
+
@tunnel.ssh_stall_command(:timeout => 123).should == "sleep 123"
|
71
|
+
end
|
72
|
+
|
73
|
+
it "ssh_stall_command uses the default timeout when no options are given" do
|
74
|
+
@tunnel.ssh_stall_command.should == "sleep 9000"
|
75
|
+
end
|
76
|
+
|
77
|
+
it "constructs the ssh tunnel command (everything but stall) from the options hash" do
|
78
|
+
@tunnel.should_receive(:tunnel_options).at_least(:once).and_return(
|
79
|
+
:local_port => 123,
|
80
|
+
:remote_port => 456,
|
81
|
+
:ssh_host => 'example.com'
|
82
|
+
)
|
83
|
+
@tunnel.ssh_tunnel_command_without_stall.should == "ssh -f -L 123:127.0.0.1:456 example.com"
|
84
|
+
end
|
85
|
+
|
86
|
+
it "combines the tunnel command without stall and the stall command into the final command" do
|
87
|
+
@tunnel.should_receive(:ssh_tunnel_command_without_stall).and_return('ssh command')
|
88
|
+
@tunnel.should_receive(:ssh_stall_command).and_return('sleep 123')
|
89
|
+
@tunnel.ssh_tunnel_command.should == 'ssh command "sleep 123"'
|
90
|
+
end
|
91
|
+
|
92
|
+
it "ssh_tunnel_command request that the port be set" do
|
93
|
+
@tunnel.should_receive(:tunnel_options).at_least(:once).and_return(:local_port => nil)
|
94
|
+
lambda { @tunnel.ssh_tunnel_command }.should raise_error(Rush::SshTunnel::NoPortSelectedYet)
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
it "push_credentials uses ssh to append to remote host's passwords file" do
|
99
|
+
@tunnel.should_receive(:ssh_append_to_credentials).and_return(true)
|
100
|
+
@tunnel.push_credentials
|
101
|
+
end
|
102
|
+
|
103
|
+
it "launches rushd on the remote host via ssh" do
|
104
|
+
@tunnel.should_receive(:ssh) do |cmd|
|
105
|
+
cmd.should match(/rushd/)
|
106
|
+
end
|
107
|
+
@tunnel.launch_rushd
|
108
|
+
end
|
109
|
+
|
110
|
+
it "tunnel_alive? checks whether a tunnel is still up" do
|
111
|
+
@tunnel.should_receive(:tunnel_count_command).and_return("echo 1")
|
112
|
+
@tunnel.tunnel_alive?.should be_true
|
113
|
+
end
|
114
|
+
|
115
|
+
it "tunnel_count_command greps ps to find the ssh tunnel" do
|
116
|
+
@tunnel.should_receive(:ssh_tunnel_command_without_stall).and_return('ssh command')
|
117
|
+
command = @tunnel.tunnel_count_command
|
118
|
+
command.should match(/ps/)
|
119
|
+
command.should match(/grep/)
|
120
|
+
command.should match(/ssh command/)
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/base'
|
2
|
+
|
3
|
+
describe String do
|
4
|
+
before do
|
5
|
+
@string = "abc"
|
6
|
+
end
|
7
|
+
|
8
|
+
it "heads from the front of the string" do
|
9
|
+
@string.head(1).should == 'a'
|
10
|
+
end
|
11
|
+
|
12
|
+
it "tails from the back of the string" do
|
13
|
+
@string.tail(1).should == 'c'
|
14
|
+
end
|
15
|
+
|
16
|
+
it "gives the whole string when head exceeds length" do
|
17
|
+
@string.head(999).should == @string
|
18
|
+
end
|
19
|
+
|
20
|
+
it "gives the whole string when tail exceeds length" do
|
21
|
+
@string.tail(999).should == @string
|
22
|
+
end
|
23
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: necktie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Assaf Arkin
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-10-
|
12
|
+
date: 2009-10-10 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -23,10 +23,60 @@ extra_rdoc_files: []
|
|
23
23
|
|
24
24
|
files:
|
25
25
|
- bin/necktie
|
26
|
-
- lib/necktie/files.rb
|
27
26
|
- lib/necktie/gems.rb
|
27
|
+
- lib/necktie/rush.rb
|
28
28
|
- lib/necktie/services.rb
|
29
29
|
- lib/necktie.rb
|
30
|
+
- rush/bin/rush
|
31
|
+
- rush/bin/rushd
|
32
|
+
- rush/lib/rush/access.rb
|
33
|
+
- rush/lib/rush/array_ext.rb
|
34
|
+
- rush/lib/rush/box.rb
|
35
|
+
- rush/lib/rush/commands.rb
|
36
|
+
- rush/lib/rush/config.rb
|
37
|
+
- rush/lib/rush/dir.rb
|
38
|
+
- rush/lib/rush/embeddable_shell.rb
|
39
|
+
- rush/lib/rush/entry.rb
|
40
|
+
- rush/lib/rush/exceptions.rb
|
41
|
+
- rush/lib/rush/file.rb
|
42
|
+
- rush/lib/rush/find_by.rb
|
43
|
+
- rush/lib/rush/fixnum_ext.rb
|
44
|
+
- rush/lib/rush/head_tail.rb
|
45
|
+
- rush/lib/rush/local.rb
|
46
|
+
- rush/lib/rush/process.rb
|
47
|
+
- rush/lib/rush/process_set.rb
|
48
|
+
- rush/lib/rush/remote.rb
|
49
|
+
- rush/lib/rush/search_results.rb
|
50
|
+
- rush/lib/rush/server.rb
|
51
|
+
- rush/lib/rush/shell.rb
|
52
|
+
- rush/lib/rush/ssh_tunnel.rb
|
53
|
+
- rush/lib/rush/string_ext.rb
|
54
|
+
- rush/lib/rush.rb
|
55
|
+
- rush/Rakefile
|
56
|
+
- rush/README.rdoc
|
57
|
+
- rush/rush.gemspec
|
58
|
+
- rush/spec/access_spec.rb
|
59
|
+
- rush/spec/array_ext_spec.rb
|
60
|
+
- rush/spec/base.rb
|
61
|
+
- rush/spec/box_spec.rb
|
62
|
+
- rush/spec/commands_spec.rb
|
63
|
+
- rush/spec/config_spec.rb
|
64
|
+
- rush/spec/dir_spec.rb
|
65
|
+
- rush/spec/embeddable_shell_spec.rb
|
66
|
+
- rush/spec/entry_spec.rb
|
67
|
+
- rush/spec/file_spec.rb
|
68
|
+
- rush/spec/find_by_spec.rb
|
69
|
+
- rush/spec/fixnum_ext_spec.rb
|
70
|
+
- rush/spec/local_spec.rb
|
71
|
+
- rush/spec/process_set_spec.rb
|
72
|
+
- rush/spec/process_spec.rb
|
73
|
+
- rush/spec/remote_spec.rb
|
74
|
+
- rush/spec/rush_spec.rb
|
75
|
+
- rush/spec/search_results_spec.rb
|
76
|
+
- rush/spec/shell_spec.rb
|
77
|
+
- rush/spec/ssh_tunnel_spec.rb
|
78
|
+
- rush/spec/string_ext_spec.rb
|
79
|
+
- rush/VERSION
|
30
80
|
- necktie.gemspec
|
31
81
|
has_rdoc: true
|
32
82
|
homepage: ""
|
data/lib/necktie/files.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
def fix_file(file, &block)
|
2
|
-
text = block.call(File.read(file))
|
3
|
-
File.open file, "w" do |out|
|
4
|
-
out.write text
|
5
|
-
end
|
6
|
-
end
|
7
|
-
|
8
|
-
def touch(name)
|
9
|
-
if File.exist?(name)
|
10
|
-
File.utime time = Time.now, time, "foo"
|
11
|
-
else
|
12
|
-
File.open(name, "a").close
|
13
|
-
end
|
14
|
-
end
|