session 2.4.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+