sesh 0.1.4 → 0.1.5

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.
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