session 2.4.0 → 3.1.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/lib/session.rb CHANGED
@@ -5,8 +5,8 @@ require 'yaml'
5
5
  require 'tempfile'
6
6
 
7
7
  module Session
8
- #--{{{
9
- VERSION = '2.4.0'
8
+ VERSION = '3.1.0'
9
+ def self.version() VERSION end
10
10
 
11
11
  @track_history = ENV['SESSION_HISTORY'] || ENV['SESSION_TRACK_HISTORY']
12
12
  @use_spawn = ENV['SESSION_USE_SPAWN']
@@ -14,43 +14,33 @@ module Session
14
14
  @debug = ENV['SESSION_DEBUG']
15
15
 
16
16
  class << self
17
- #--{{{
18
17
  attr :track_history, true
19
18
  attr :use_spawn, true
20
19
  attr :use_open3, true
21
20
  attr :debug, true
22
21
  def new(*a, &b)
23
- #--{{{
24
22
  Sh::new(*a, &b)
25
- #--}}}
26
23
  end
27
24
  alias [] new
28
- #--}}}
29
25
  end
30
26
 
31
27
  class PipeError < StandardError; end
32
28
  class ExecutionError < StandardError; end
33
29
 
34
30
  class History
35
- #--{{{
36
31
  def initialize; @a = []; end
37
32
  def method_missing(m,*a,&b); @a.send(m,*a,&b); end
38
33
  def to_yaml(*a,&b); @a.to_yaml(*a,&b); end
39
34
  alias to_s to_yaml
40
35
  alias to_str to_yaml
41
- #--}}}
42
36
  end # class History
43
37
  class Command
44
- #--{{{
45
38
  class << self
46
- #--{{{
47
39
  def cmdno; @cmdno ||= 0; end
48
40
  def cmdno= n; @cmdno = n; end
49
- #--}}}
50
41
  end
51
42
 
52
43
  # attributes
53
- #--{{{
54
44
  attr :cmd
55
45
  attr :cmdno
56
46
  attr :out,true
@@ -64,10 +54,8 @@ module Session
64
54
  attr :end_err
65
55
  attr :begin_err_pat
66
56
  attr :end_err_pat
67
- #--}}}
68
57
 
69
58
  def initialize(command)
70
- #--{{{
71
59
  @cmd = command.to_s
72
60
  @cmdno = self.class.cmdno
73
61
  self.class.cmdno += 1
@@ -82,30 +70,21 @@ module Session
82
70
  @end_err = "__CMD_ERR_%s_END__" % cid
83
71
  @begin_err_pat = %r/#{ Regexp.escape(@begin_err) }/
84
72
  @end_err_pat = %r/#{ Regexp.escape(@end_err) }/
85
- #--}}}
86
73
  end
87
74
  def to_hash
88
- #--{{{
89
75
  %w(cmdno cmd out err cid).inject({}){|h,k| h.update k => send(k) }
90
- #--}}}
91
76
  end
92
77
  def to_yaml(*a,&b)
93
- #--{{{
94
78
  to_hash.to_yaml(*a,&b)
95
- #--}}}
96
79
  end
97
80
  alias to_s to_yaml
98
81
  alias to_str to_yaml
99
- #--}}}
100
82
  end # class Command
101
83
  class AbstractSession
102
- #--{{{
103
84
 
104
85
  # class methods
105
86
  class << self
106
- #--{{{
107
87
  def default_prog
108
- #--{{{
109
88
  return @default_prog if defined? @default_prog and @default_prog
110
89
  if defined? self::DEFAULT_PROG
111
90
  return @default_prog = self::DEFAULT_PROG
@@ -113,34 +92,27 @@ module Session
113
92
  @default_prog = ENV["SESSION_#{ self }_PROG"]
114
93
  end
115
94
  nil
116
- #--}}}
117
95
  end
118
96
  def default_prog= prog
119
- #--{{{
120
97
  @default_prog = prog
121
- #--}}}
122
98
  end
123
99
  attr :track_history, true
124
100
  attr :use_spawn, true
125
101
  attr :use_open3, true
126
102
  attr :debug, true
127
103
  def init
128
- #--{{{
129
104
  @track_history = nil
130
105
  @use_spawn = nil
131
106
  @use_open3 = nil
132
107
  @debug = nil
133
- #--}}}
134
108
  end
135
109
  alias [] new
136
- #--}}}
137
110
  end
138
111
 
139
112
  # class init
140
113
  init
141
114
 
142
115
  # attributes
143
- #--{{{
144
116
  attr :opts
145
117
  attr :prog
146
118
  attr :stdin
@@ -158,11 +130,9 @@ module Session
158
130
  attr :debug, true
159
131
  alias debug? debug
160
132
  attr :threads
161
- #--}}}
162
133
 
163
134
  # instance methods
164
135
  def initialize(*args)
165
- #--{{{
166
136
  @opts = hashify(*args)
167
137
 
168
138
  @prog = getopt('prog', opts, getopt('program', opts, self.class::default_prog))
@@ -180,10 +150,14 @@ module Session
180
150
  @use_spawn = self.class::use_spawn unless self.class::use_spawn.nil?
181
151
  @use_spawn = getopt('use_spawn', opts) if hasopt('use_spawn', opts)
182
152
 
183
- @use_open3 = nil
184
- @use_open3 = Session::use_open3 unless Session::use_open3.nil?
185
- @use_open3 = self.class::use_open3 unless self.class::use_open3.nil?
186
- @use_open3 = getopt('use_open3', opts) if hasopt('use_open3', opts)
153
+ if defined? JRUBY_VERSION
154
+ @use_open3 = true
155
+ else
156
+ @use_open3 = nil
157
+ @use_open3 = Session::use_open3 unless Session::use_open3.nil?
158
+ @use_open3 = self.class::use_open3 unless self.class::use_open3.nil?
159
+ @use_open3 = getopt('use_open3', opts) if hasopt('use_open3', opts)
160
+ end
187
161
 
188
162
  @debug = nil
189
163
  @debug = Session::debug unless Session::debug.nil?
@@ -220,10 +194,8 @@ module Session
220
194
  end
221
195
 
222
196
  return self
223
- #--}}}
224
197
  end
225
198
  def getopt opt, hash, default = nil
226
- #--{{{
227
199
  key = opt
228
200
  return hash[key] if hash.has_key? key
229
201
  key = "#{ key }"
@@ -231,10 +203,8 @@ module Session
231
203
  key = key.intern
232
204
  return hash[key] if hash.has_key? key
233
205
  return default
234
- #--}}}
235
206
  end
236
207
  def hasopt opt, hash
237
- #--{{{
238
208
  key = opt
239
209
  return key if hash.has_key? key
240
210
  key = "#{ key }"
@@ -242,10 +212,8 @@ module Session
242
212
  key = key.intern
243
213
  return key if hash.has_key? key
244
214
  return false
245
- #--}}}
246
215
  end
247
216
  def __popen3(*cmd)
248
- #--{{{
249
217
  pw = IO::pipe # pipe[0] for read, pipe[1] for write
250
218
  pr = IO::pipe
251
219
  pe = IO::pipe
@@ -283,10 +251,8 @@ module Session
283
251
  end
284
252
  end
285
253
  pi
286
- #--}}}
287
254
  end
288
255
  def __fork(*a, &b)
289
- #--{{{
290
256
  verbose = $VERBOSE
291
257
  begin
292
258
  $VERBOSE = nil
@@ -294,62 +260,44 @@ module Session
294
260
  ensure
295
261
  $VERBOSE = verbose
296
262
  end
297
- #--}}}
298
263
  end
299
264
 
300
265
  # abstract methods
301
266
  def clear
302
- #--{{{
303
267
  raise NotImplementedError
304
- #--}}}
305
268
  end
306
269
  alias flush clear
307
270
  def path
308
- #--{{{
309
271
  raise NotImplementedError
310
- #--}}}
311
272
  end
312
273
  def path=
313
- #--{{{
314
274
  raise NotImplementedError
315
- #--}}}
316
275
  end
317
276
  def send_command cmd
318
- #--{{{
319
277
  raise NotImplementedError
320
- #--}}}
321
278
  end
322
279
 
323
280
  # concrete methods
324
281
  def track_history= bool
325
- #--{{{
326
282
  @history ||= History::new
327
283
  @track_history = bool
328
- #--}}}
329
284
  end
330
285
  def ready?
331
- #--{{{
332
286
  (stdin and stdout and stderr) and
333
287
  (IO === stdin and IO === stdout and IO === stderr) and
334
288
  (not (stdin.closed? or stdout.closed? or stderr.closed?))
335
- #--}}}
336
289
  end
337
290
  def close!
338
- #--{{{
339
291
  [stdin, stdout, stderr].each{|pipe| pipe.close}
340
292
  stdin, stdout, stderr = nil, nil, nil
341
293
  true
342
- #--}}}
343
294
  end
344
295
  alias close close!
345
296
  def hashify(*a)
346
- #--{{{
347
297
  a.inject({}){|o,h| o.update(h)}
348
- #--}}}
349
298
  end
350
299
  private :hashify
351
300
  def execute(command, redirects = {})
352
- #--{{{
353
301
  $session_command = command if @debug
354
302
 
355
303
  raise(PipeError, command) unless ready?
@@ -485,12 +433,9 @@ module Session
485
433
  out = err = iodat = nil
486
434
 
487
435
  return [cmd.out, cmd.err]
488
- #--}}}
489
436
  end
490
- #--}}}
491
437
  end # class AbstractSession
492
438
  class Sh < AbstractSession
493
- #--{{{
494
439
  DEFAULT_PROG = 'sh'
495
440
  ECHO = 'echo'
496
441
 
@@ -499,17 +444,14 @@ module Session
499
444
  alias exitstatus status
500
445
 
501
446
  def clear
502
- #--{{{
503
447
  stdin.puts "#{ ECHO } __clear__ 1>&2"
504
448
  stdin.puts "#{ ECHO } __clear__"
505
449
  stdin.flush
506
450
  while((line = stderr.gets) and line !~ %r/__clear__/o); end
507
451
  while((line = stdout.gets) and line !~ %r/__clear__/o); end
508
452
  self
509
- #--}}}
510
453
  end
511
454
  def send_command cmd
512
- #--{{{
513
455
  stdin.printf "%s '%s' 1>&2\n", ECHO, cmd.begin_err
514
456
  stdin.printf "%s '%s' \n", ECHO, cmd.begin_out
515
457
 
@@ -520,26 +462,20 @@ module Session
520
462
  stdin.printf "%s '%s' \n", ECHO, cmd.end_out
521
463
 
522
464
  stdin.flush
523
- #--}}}
524
465
  end
525
466
  def get_status
526
- #--{{{
527
467
  @status = get_var '__exit_status__'
528
468
  unless @status =~ /^\s*\d+\s*$/o
529
469
  raise ExecutionError, "could not determine exit status from <#{ @status.inspect }>"
530
470
  end
531
471
 
532
472
  @status = Integer @status
533
- #--}}}
534
473
  end
535
474
  def set_var name, value
536
- #--{{{
537
475
  stdin.puts "export #{ name }=#{ value }"
538
476
  stdin.flush
539
- #--}}}
540
477
  end
541
478
  def get_var name
542
- #--{{{
543
479
  stdin.puts "#{ ECHO } \"#{ name }=${#{ name }}\""
544
480
  stdin.flush
545
481
 
@@ -554,16 +490,12 @@ module Session
554
490
  end
555
491
 
556
492
  var
557
- #--}}}
558
493
  end
559
494
  def path
560
- #--{{{
561
495
  var = get_var 'PATH'
562
496
  var.strip.split %r/:/o
563
- #--}}}
564
497
  end
565
498
  def path= arg
566
- #--{{{
567
499
  case arg
568
500
  when Array
569
501
  arg = arg.join ':'
@@ -573,10 +505,8 @@ module Session
573
505
 
574
506
  set_var 'PATH', "'#{ arg }'"
575
507
  self.path
576
- #--}}}
577
508
  end
578
509
  def execute(command, redirects = {}, &block)
579
- #--{{{
580
510
  # setup redirect on stdin
581
511
  rin = redirects[:i] || redirects[:in] || redirects[:stdin] ||
582
512
  redirects['stdin'] || redirects['i'] || redirects['in'] ||
@@ -611,27 +541,21 @@ module Session
611
541
  else
612
542
  super
613
543
  end
614
- #--}}}
615
544
  end
616
- #--}}}
617
545
  end # class Sh
618
546
  class Bash < Sh
619
- #--{{{
620
547
  DEFAULT_PROG = 'bash'
621
548
  class Login < Bash
622
549
  DEFAULT_PROG = 'bash --login'
623
550
  end
624
- #--}}}
625
551
  end # class Bash
626
552
  class Shell < Bash; end
627
553
  # IDL => interactive data language - see http://www.rsinc.com/
628
554
  class IDL < AbstractSession
629
- #--{{{
630
555
  class LicenseManagerError < StandardError; end
631
556
  DEFAULT_PROG = 'idl'
632
557
  MAX_TRIES = 32
633
558
  def initialize(*args)
634
- #--{{{
635
559
  tries = 0
636
560
  ret = nil
637
561
  begin
@@ -646,10 +570,8 @@ module Session
646
570
  end
647
571
  end
648
572
  ret
649
- #--}}}
650
573
  end
651
574
  def clear
652
- #--{{{
653
575
  stdin.puts "retall"
654
576
  stdin.puts "printf, -2, '__clear__'"
655
577
  stdin.puts "printf, -1, '__clear__'"
@@ -661,10 +583,8 @@ module Session
661
583
  raise LicenseManagerError, line if line =~ %r/license\s*manager/io
662
584
  end
663
585
  self
664
- #--}}}
665
586
  end
666
587
  def send_command cmd
667
- #--{{{
668
588
  stdin.printf "printf, -2, '%s'\n", cmd.begin_err
669
589
  stdin.printf "printf, -1, '%s'\n", cmd.begin_out
670
590
 
@@ -674,16 +594,12 @@ module Session
674
594
  stdin.printf "printf, -2, '%s'\n", cmd.end_err
675
595
  stdin.printf "printf, -1, '%s'\n", cmd.end_out
676
596
  stdin.flush
677
- #--}}}
678
597
  end
679
598
  def path
680
- #--{{{
681
599
  stdout, stderr = execute "print, !path"
682
600
  stdout.strip.split %r/:/o
683
- #--}}}
684
601
  end
685
602
  def path= arg
686
- #--{{{
687
603
  case arg
688
604
  when Array
689
605
  arg = arg.join ':'
@@ -693,15 +609,11 @@ module Session
693
609
  stdout, stderr = execute "!path='#{ arg }'"
694
610
 
695
611
  self.path
696
- #--}}}
697
612
  end
698
- #--}}}
699
613
  end # class IDL
700
614
  module Spawn
701
- #--{{{
702
615
  class << self
703
616
  def spawn command
704
- #--{{{
705
617
  ipath = tmpfifo
706
618
  opath = tmpfifo
707
619
  epath = tmpfifo
@@ -714,10 +626,8 @@ module Session
714
626
  e = open epath, 'r'
715
627
 
716
628
  [i,o,e]
717
- #--}}}
718
629
  end
719
630
  def tmpfifo
720
- #--{{{
721
631
  path = nil
722
632
  42.times do |i|
723
633
  tpath = File::join(Dir::tmpdir, "#{ $$ }.#{ rand }.#{ i }")
@@ -735,10 +645,7 @@ module Session
735
645
  end
736
646
  raise "could not generate tmpfifo" unless path
737
647
  path
738
- #--}}}
739
648
  end
740
649
  end
741
- #--}}}
742
650
  end # module Spawn
743
- #--}}}
744
651
  end # module Session
data/sample/bash.rb ADDED
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift '.', '..', 'lib', File.join('..','lib')
3
+
4
+ require 'session'
5
+
6
+
7
+ bash = Session::Bash.new
8
+
9
+
10
+ puts "======== ======== ======== ========"
11
+ puts "#1"
12
+ puts "======== ======== ======== ========"
13
+
14
+ stdout, stderr = bash.execute 'ls'
15
+
16
+ puts "STDOUT:\n#{ stdout }"
17
+ puts "STDERR:\n#{ stderr }"
18
+
19
+ puts "STATUS: #{ bash.status }"
20
+ puts "======== ======== ======== ========"
21
+
22
+
23
+ puts "======== ======== ======== ========"
24
+ puts "#2"
25
+ puts "======== ======== ======== ========"
26
+
27
+ bash.execute 'ls' do |stdout, stderr|
28
+ puts "STDOUT:\n#{ stdout }"
29
+ puts "STDERR:\n#{ stderr }"
30
+ end
31
+
32
+ puts "STATUS: #{ bash.status }"
33
+ puts "======== ======== ======== ========"
34
+
35
+
36
+ puts "======== ======== ======== ========"
37
+ puts "#3"
38
+ puts "======== ======== ======== ========"
39
+
40
+ stdout, stderr = '', ''
41
+ bash.execute 'ls', :stdout => stdout, :stderr => stderr
42
+
43
+ puts "STDOUT:\n#{ stdout }"
44
+ puts "STDERR:\n#{ stderr }"
45
+
46
+ puts "STATUS: #{ bash.status }"
47
+ puts "======== ======== ======== ========"
48
+
49
+
50
+ puts "======== ======== ======== ========"
51
+ puts "#4"
52
+ puts "======== ======== ======== ========"
53
+
54
+ bash.outproc = lambda{|out| puts "#{ out }"}
55
+ bash.errproc = lambda{|err| raise err}
56
+
57
+ bash.execute('while test 1; do echo 42; sleep 1; done') # => 42 ... 42 ... 42
58
+ puts "======== ======== ======== ========"
59
+
60
+