sesh 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2cc06146a5e15fe6189868ccaa713a1b3ac3cc1d
4
- data.tar.gz: 1289b53289bdaa7e0d2f62411f4216f83399e92d
3
+ metadata.gz: 519e114e15fb6c5fea66d92a8a696ce80308ff4c
4
+ data.tar.gz: fe5045bde290d181b8d8d395b721914a7fd87b17
5
5
  SHA512:
6
- metadata.gz: 5aaa76f37ea82defb160e0bad181f257920cc8fb8dec2036df2f457e8b314fedf4b18c0e0e067dd44e61b1253c2660f7573cb1fa9b6cbea6cb4ba879109951ab
7
- data.tar.gz: 5aed87ec071af36d523f74a96131e8fecfca731e203195073132f042c5722dd0f53324836e972998513251e82d6dab581f1729351f4ed220ce71fa267d1ea860
6
+ metadata.gz: c8ea6c0cf3cf02d4b642bd7cfcd950f990cadafd973f30a02e530c419f038eb12566edd79b69c254608a26d3bf1345ae7c2f17ebf3a6397c5c4fd7e33cca0fa1
7
+ data.tar.gz: 205abe6b579f35abc141abd18b377698914125d3a6ce6758aab73c9e47c5d3da5697ef83cfc834848171369abd5c27854d69e9772926f00c908d4104c3df6514
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sesh (0.1.4)
4
+ sesh (0.1.5)
5
5
  awesome_print
6
6
  colorize
7
7
  deep_merge
data/lib/sesh.rb CHANGED
@@ -30,6 +30,11 @@ module Sesh
30
30
 
31
31
  DEFAULT_OPTIONS = {
32
32
  project: nil,
33
+ shell: {
34
+ command: nil,
35
+ pane: nil,
36
+ spec: nil
37
+ },
33
38
  ssh: {
34
39
  local_addr: nil,
35
40
  remote_addr: nil
data/lib/sesh/cli.rb CHANGED
@@ -12,119 +12,10 @@ module Sesh
12
12
  puts; puts " Sesh v#{VERSION}".green; puts ' ==========='.green; puts
13
13
  if ARGV.empty? or ARGV.include? '-h' or ARGV.include? '--help'
14
14
  puts HELP_BANNER.blue; exit end
15
-
16
15
  parse_options!
17
16
  @tmux_control = TmuxControl.new @options[:project], @options[:tmux]
18
17
  @ssh_control = SshControl.new @tmux_control, @options[:ssh]
19
-
20
- if @command
21
- case @command
22
- when 'start'
23
- if @tmux_control.already_running?
24
- Logger.fatal "Sesh project '#{@options[:project]}' is already running!"
25
- else
26
- Logger.info "Starting Sesh project '#{@options[:project]}'..."
27
- end
28
- @tmux_control.kill_running_processes
29
- if @tmux_control.issue_start_command! &&
30
- Logger.show_progress_until(-> { @tmux_control.already_running? })
31
- sleep 1
32
- if @tmux_control.already_running?
33
- @tmux_control.store_pids_from_session!
34
- Logger.success 'Sesh started successfully.'
35
- puts
36
- else Logger.fatal 'Sesh failed to start!' end
37
- else Logger.fatal 'Sesh failed to start after ten seconds!' end
38
- when 'stop'
39
- if @tmux_control.already_running?
40
- Logger.info "Stopping Sesh project '#{@options[:project]}'..."
41
- else
42
- Logger.fatal "Sesh project '#{@options[:project]}' is not running!"
43
- end
44
- @tmux_control.kill_running_processes
45
- @tmux_control.issue_stop_command!
46
- if $? && Logger.show_progress_until(-> { !@tmux_control.already_running? })
47
- Logger.success 'Sesh stopped successfully.'
48
- puts
49
- else
50
- Logger.fatal 'Sesh failed to stop after ten seconds!'
51
- end
52
- when 'restart'
53
- Logger.fatal("Sesh project '#{@options[:project]}' is not running!") unless already_running?
54
- puts `sesh stop #{@options[:project]} #{@options if @options.any?}`.strip
55
- sleep 0.5
56
- puts `sesh start #{@options[:project]} #{@options if @options.any?}`.strip
57
- when 'new'
58
- config = Tmuxinator::Config.project(@options[:project])
59
- unless Tmuxinator::Config.exists?(@options[:project])
60
- template = File.join(File.dirname(File.expand_path(__FILE__)),
61
- "../lib/sesh/assets/sample.yml")
62
- erb = Erubis::Eruby.new(File.read(template)).result(binding)
63
- File.open(config, "w") { |f| f.write(erb) }
64
- end
65
-
66
- Kernel.system("#{Inferences.infer_default_editor} #{config}") ||
67
- Tmuxinator::Cli.new.doctor
68
- puts
69
- when 'edit'
70
- config = Tmuxinator::Config.project(@options[:project])
71
- if Tmuxinator::Config.exists? @options[:project]
72
- Kernel.system("#{Inferences.infer_default_editor} #{config}") ||
73
- Tmuxinator::Cli.new.doctor
74
- puts
75
- else
76
- Logger.fatal "Sesh project '#{@options[:project]}' does not exist yet!"
77
- end
78
- when 'list'
79
- output = Sesh.format_and_run_command <<-BASH
80
- ps aux | grep tmux | grep "sesh begin" | grep -v "[g]rep" \
81
- | sed -e "s/.*\\/tmp\\/\\(.*\\)\\.sock.*/\\1/"
82
- BASH
83
- running_projects = output.split("\n")
84
- pcount = running_projects.count
85
- if pcount > 0
86
- Logger.success "#{pcount} project#{pcount>1 ? 's':''} currently running:"
87
- puts; running_projects.each {|rp| Logger.info rp, 1 }
88
- puts
89
- else
90
- Logger.fatal "There are no Sesh projects currently running."
91
- end
92
- when 'connect'
93
- if @options[:ssh][:local_addr] == @options[:ssh][:remote_addr]
94
- unless @tmux_control.already_running?
95
- Logger.fatal "Sesh project '#{@options[:project]}' is not running!"
96
- end
97
- end
98
- system @ssh_control.enter_slave_mode_command
99
- when 'enslave'
100
- Logger.fatal("Sesh project '#{@options[:project]}' is not running!") unless @tmux_control.already_running?
101
- Logger.fatal("You must specify a machine to enslave! Eg: user@ip") if @options[:ssh][:remote_addr].nil?
102
- Logger.info "Attempting to connect #{@options[:ssh][:remote_addr]} to Sesh project '#{@options[:project]}'..."
103
- if @ssh_control.enslave_peer!
104
- Logger.success "Sesh client connected successfully."
105
- else
106
- Logger.fatal 'Sesh client failed to start.'
107
- end
108
- when 'begin' then @tmux_control.begin_tmuxinator_session!
109
- when 'run'
110
- unless ARGV.any?
111
- Logger.fatal 'A second command is required!'
112
- end
113
- @shell_command = ARGV.join(' ')
114
- puts "Subcommand: #{@shell_command}"
115
- when 'rspec'
116
- unless ARGV.any?
117
- Logger.fatal 'A path to a spec is required!'
118
- end
119
- @shell_command = ARGV.join(' ')
120
- puts "Spec: #{@shell_command}"
121
- else
122
- Logger.fatal "Command not recognized!"
123
- end
124
- exit 0
125
- end
126
-
127
- Logger.fatal 'You must specify a command.'
18
+ handle_command!
128
19
  end
129
20
 
130
21
  def self.parse_options!
@@ -164,9 +55,16 @@ module Sesh
164
55
  opts.on('-S', '--tmux-socket-file=path', 'Path to Tmux Socket File') {|v|
165
56
  # fatal("Socket file #{v} does not exist.") unless File.exist?(v)
166
57
  parsed_options[:tmux][:socket_file] = v }
167
- opts.on('-P', '--tmux-pids-file=path', 'Path to Tmux Pids File') {|v|
58
+ opts.on('--tmux-pids-file=path', 'Path to Tmux Pids File') {|v|
168
59
  parsed_options[:tmux][:pids_file] = v }
169
60
 
61
+ opts.on('-C', '--shell-command=cmd', 'Shell Command to Execute') {|v|
62
+ parsed_options[:shell][:command] = v }
63
+ opts.on('-P', '--shell-pane=pane', 'Pane to Execute Shell Command in') {|v|
64
+ parsed_options[:shell][:pane] = v }
65
+ opts.on('--spec-path=path', 'Path to Spec File to Run') {|v|
66
+ parsed_options[:shell][:spec] = v }
67
+
170
68
  # # target_opts = DEPLOYMENT_TARGETS.join '|'
171
69
  # opts.on("-T", "--target=target", 'Titanium Deployment Target') do |v|
172
70
  # if DEPLOYMENT_TARGETS.include? v
@@ -221,9 +119,9 @@ module Sesh
221
119
  end
222
120
  @options[:tmux][:socket_file] ||= "/tmp/#{@options[:project]}.sock"
223
121
  @options[:tmux][:pids_file] ||= "/tmp/#{@options[:project]}.pids.txt"
224
- @options[:ssh][:local_addr] ||= Sesh::Inferences.infer_local_ssh_addr
225
- if @options[:ssh][:remote_addr].nil?
226
- if ARGV.any?
122
+ if %w(enslave connect).include? @command
123
+ @options[:ssh][:local_addr] ||= Sesh::Inferences.infer_local_ssh_addr
124
+ if @options[:ssh][:remote_addr].nil? && ARGV.any?
227
125
  ARGV.each {|a|
228
126
  if a =~ /\.local$/ || a =~ /[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/ || a =~ /^(.+)@(.+)$/
229
127
  @options[:ssh][:remote_addr] = a
@@ -231,7 +129,7 @@ module Sesh
231
129
  @options[:ssh][:remote_addr] ||= ARGV.shift
232
130
  end
233
131
  if @options[:ssh][:remote_addr].nil?
234
- if %w(enslave run rspec).include? @command
132
+ if %w(enslave).include? @command
235
133
  Logger.warn 'A remote address is required.'
236
134
  Logger.fatal 'Hint: specify a remote ssh address using the -R flag.'
237
135
  elsif %w(connect).include? @command
@@ -239,6 +137,85 @@ module Sesh
239
137
  end
240
138
  end
241
139
  end
140
+ # TODO: parse a spec file
141
+ # This block should always go at the end because it eats the rest of ARGV.
142
+ if %w(run).include?(@command) && @options[:shell][:command].nil?
143
+ if ARGV.any?
144
+ argv_cmd_parts = []
145
+ argv_cmd_parts << ARGV.shift while ARGV.any?
146
+ @options[:shell][:command] = argv_cmd_parts.join(' ')
147
+ end
148
+ if @options[:shell][:command].nil? || @options[:shell][:command].length == 0
149
+ Logger.fatal 'You must specify a command to run.'
150
+ end
151
+ end
152
+ end
153
+
154
+ def self.handle_command!
155
+ if @command
156
+ case @command
157
+ when 'start' then @tmux_control.start_project!
158
+ when 'stop' then @tmux_control.stop_project!
159
+ when 'restart' then @tmux_control.restart_project!
160
+ when 'new'
161
+ config = Tmuxinator::Config.project(@options[:project])
162
+ unless Tmuxinator::Config.exists?(@options[:project])
163
+ template = File.join(File.dirname(File.expand_path(__FILE__)),
164
+ "../lib/sesh/assets/sample.yml")
165
+ erb = Erubis::Eruby.new(File.read(template)).result(binding)
166
+ File.open(config, "w") { |f| f.write(erb) }
167
+ end
168
+
169
+ Kernel.system("#{Inferences.infer_default_editor} #{config}") ||
170
+ Tmuxinator::Cli.new.doctor
171
+ puts
172
+ when 'edit'
173
+ config = Tmuxinator::Config.project(@options[:project])
174
+ if Tmuxinator::Config.exists? @options[:project]
175
+ Kernel.system("#{Inferences.infer_default_editor} #{config}") ||
176
+ Tmuxinator::Cli.new.doctor
177
+ puts
178
+ else
179
+ Logger.fatal "Sesh project '#{@options[:project]}' does not exist yet!"
180
+ end
181
+ when 'list'
182
+ output = Sesh.format_and_run_command <<-BASH
183
+ ps aux | grep tmux | grep "sesh begin" | grep -v "[g]rep" \
184
+ | sed -e "s/.*\\/tmp\\/\\(.*\\)\\.sock.*/\\1/"
185
+ BASH
186
+ running_projects = output.split("\n")
187
+ pcount = running_projects.count
188
+ if pcount > 0
189
+ Logger.success "#{pcount} project#{pcount>1 ? 's':''} currently running:"
190
+ puts; running_projects.each {|rp| Logger.info rp, 1 }
191
+ puts
192
+ else Logger.fatal "There are no Sesh projects currently running." end
193
+ when 'connect'
194
+ if @options[:ssh][:local_addr] == @options[:ssh][:remote_addr]
195
+ unless @tmux_control.already_running?
196
+ Logger.fatal "Sesh project '#{@options[:project]}' is not running!"
197
+ end
198
+ end
199
+ system @ssh_control.enter_slave_mode_command
200
+ when 'enslave'
201
+ Logger.fatal("Sesh project '#{@options[:project]}' is not running!") unless @tmux_control.already_running?
202
+ Logger.fatal("You must specify a machine to enslave! Eg: user@ip") if @options[:ssh][:remote_addr].nil?
203
+ Logger.info "Attempting to connect #{@options[:ssh][:remote_addr]} to Sesh project '#{@options[:project]}'..."
204
+ if @ssh_control.enslave_peer!
205
+ Logger.success "Sesh client connected successfully."
206
+ else Logger.fatal 'Sesh client failed to start.' end
207
+ when 'begin' then @tmux_control.begin_tmuxinator_session!
208
+ when 'run'
209
+ @tmux_control.do_shell_operation! @options[:shell]
210
+ when 'rspec'
211
+ puts "Spec: #{@options[:shell][:spec]}"
212
+ else
213
+ Logger.fatal "Command not recognized!"
214
+ end
215
+ exit 0
216
+ end
217
+
218
+ Logger.fatal 'You must specify a command.'
242
219
  end
243
220
  end
244
221
  end
@@ -19,7 +19,6 @@ module Sesh
19
19
  cmd = Sesh.format_command <<-BASH
20
20
  tmux -S "#{@options[:socket_file]}" new-session -d "eval \\"\$SHELL -l -c 'rvm use default; sesh begin'\\"" 2>&1
21
21
  BASH
22
- # puts cmd
23
22
  output = `#{cmd}`.strip
24
23
  return true if $? && output.length == 0
25
24
  Logger.warn "Tmux failed to start with the following error: #{output}"; false
@@ -30,7 +29,6 @@ module Sesh
30
29
  def connection_command; "tmux -S #{@options[:socket_file]} a" end
31
30
 
32
31
  def obtain_pids_from_session
33
- # TODO: grep this to just those pids from the current project
34
32
  `tmux -S "#{@options[:socket_file]}" list-panes -s -F "\#{pane_pid} \#{pane_current_command}" | grep -v tmux | awk '{print $1}'`.strip.lines
35
33
  end
36
34
  def store_pids_from_session!
@@ -49,6 +47,66 @@ module Sesh
49
47
  def begin_tmuxinator_session!
50
48
  %x[env TMUX='' mux start #{@project}] end
51
49
 
50
+ def start_project!
51
+ if already_running?
52
+ Logger.fatal "Sesh project '#{@project}' is already running!" end
53
+ Logger.info "Starting Sesh project '#{@project}'..."
54
+ kill_running_processes
55
+ if issue_start_command! && Logger.show_progress_until(-> { already_running? })
56
+ sleep 1
57
+ if already_running?
58
+ store_pids_from_session!
59
+ Logger.success 'Sesh started successfully.'
60
+ puts
61
+ else Logger.fatal 'Sesh failed to start!' end
62
+ else Logger.fatal 'Sesh failed to start after ten seconds!' end
63
+ end
64
+ def stop_project!
65
+ unless already_running?
66
+ Logger.fatal "Sesh project '#{@project}' is not running!" end
67
+ Logger.info "Stopping Sesh project '#{@project}'..."
68
+ kill_running_processes
69
+ issue_stop_command!
70
+ if $? && Logger.show_progress_until(-> { !already_running? })
71
+ Logger.success 'Sesh stopped successfully.'
72
+ puts
73
+ else Logger.fatal 'Sesh failed to stop after ten seconds!' end
74
+ end
75
+ def restart_project!; stop_project!; sleep 0.5; start_project! end
76
+
77
+ def send_keys_to_project!(keys)
78
+ `tmux -S "#{@options[:socket_file]}" send-keys #{keys}`.strip.length == 0
79
+ end
80
+ def send_interrupt!; send_keys_to_project! 'C-c' end
81
+ def interrupt_and_send_keys_to_project!(keys)
82
+ send_interrupt!; send_keys_to_project! keys end
83
+ def send_keys_to_pane!(pane, keys)
84
+ move_cursor_to_pane! pane
85
+ send_keys_to_project! keys end
86
+ def interrupt_and_send_keys_to_pane!(pane, keys)
87
+ move_cursor_to_pane_and_interrupt! pane
88
+ send_keys_to_project! keys end
89
+ def send_command_to_project!(command)
90
+ send_keys_to_project! "\"#{command}\" Enter" end
91
+ def interrupt_and_send_command_to_project!(command)
92
+ send_interrupt!; send_command_to_project!(command) end
93
+ def send_command_to_pane!(pane, command)
94
+ send_keys_to_pane! pane, "\"#{command}\" Enter" end
95
+ def interrupt_and_send_command_to_pane!(pane, command)
96
+ interrupt_and_send_keys_to_pane!(pane, "\"#{command}\" Enter") end
97
+ def move_cursor_to_pane!(pane); send_keys_to_project! "C-a q #{pane}" end
98
+ def move_cursor_to_pane_and_interrupt!(pane)
99
+ move_cursor_to_pane!(pane); send_interrupt! end
100
+ def do_shell_operation!(options=DEFAULT_OPTIONS[:shell])
101
+ unless options[:spec].nil?
102
+ options[:command] ||= "spring rspec #{options[:spec]}" end
103
+ if options[:pane].nil?
104
+ interrupt_and_send_command_to_project! options[:command]
105
+ else
106
+ interrupt_and_send_command_to_pane! options[:pane], options[:command]
107
+ end
108
+ end
109
+
52
110
  # Getter methods for passthru to SshControl class
53
111
  def project; @project end
54
112
  def options; @options end
data/lib/sesh/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Sesh
2
- VERSION = '0.1.4'
2
+ VERSION = '0.1.5'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sesh
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - MacKinley Smith