appl 1.9 → 1.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. checksums.yaml +4 -4
  2. data/lib/appl.rb +30 -9
  3. data/lib/applfan.rb +4 -9
  4. metadata +7 -10
  5. data/bin/intar +0 -136
  6. data/lib/intar.rb +0 -447
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 163c100bd1d2a0ab224680a33b33ecc1496dee585e74daffdfe25611057e6037
4
- data.tar.gz: b10b33c7d254a3ff68d53275da766a2ca4668ededd54735c748e7c25826d9017
3
+ metadata.gz: 45ad7f9759023d5910cca734d856a368baf06770ad4e193b6dee940e7b417beb
4
+ data.tar.gz: 55bc842b3ac4fced98fc3c9574bf6a048e838590d26e709b8f4cd3d38cdeab4f
5
5
  SHA512:
6
- metadata.gz: 1fdeab1e5d163954a585149fee970c9a6f552a1224ec803d92351a16807d36bc8a4f71612225a516722477b0490732830044f123b83cebd4c9c086b57138f8e3
7
- data.tar.gz: 00d03be61474b82295ac21ccb600a49d5a2a55dbf1c451ada43b37361612280bf90c012aae63f2d92f121bc2af0faa71ae397723576bc58640d5ff8c2f615367
6
+ metadata.gz: a7a30d4159280cef5ca6692decc3f561fd2073bcac52f45234936c75f4aa32e20175ba41bc1495aed79383e69cc9ac84410d9b72c89fcdf0d8043e2b12245a7b
7
+ data.tar.gz: 82e73a96e8e23b880feeeb783d491b52d0d5c2ae29f368ac2d86c26875b5d86fb39a1c6c244c4b38881423ba171d502e034e51e63354727045f37fce529c2256
data/lib/appl.rb CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  class Application
7
7
 
8
- APPL_VERSION = "1.9".freeze
8
+ APPL_VERSION = "1.14".freeze
9
9
 
10
10
  OPTIONS_ENV = nil
11
11
 
@@ -13,14 +13,16 @@ class Application
13
13
  UNKNOWN = "Unknown option: `%s'."
14
14
  UNPROCA = "Warning: unprocessed arguments: %s"
15
15
 
16
+ ALIASES = [].freeze
17
+
16
18
  W_OPTS = 10
17
19
  W_ARGS = 16
18
20
 
19
21
  class OptionError < StandardError ; end
20
22
  class Done < Exception ; end
21
23
 
22
- def initialize args = nil
23
- @args = args||self.class.cmdline_arguments
24
+ def initialize name = nil, args = nil
25
+ @name, @args = name, args
24
26
  self.class.each_option { |opt,desc,arg,dfl,act|
25
27
  begin
26
28
  send act, dfl if dfl
@@ -92,7 +94,8 @@ class Application
92
94
  private
93
95
 
94
96
  def execute args = nil
95
- i = new args
97
+ n = File.basename $0
98
+ i = new n, args||cmdline_arguments
96
99
  i.execute
97
100
  rescue Done
98
101
  0
@@ -214,14 +217,32 @@ class Application
214
217
  self
215
218
  end
216
219
 
217
- def applname
218
- self::NAME
220
+ def all_names
221
+ [ self::NAME, *self::ALIASES].join "|"
222
+ end
223
+
224
+ def full_name
225
+ n = []
226
+ s = self
227
+ loop do
228
+ l = s.all_names
229
+ n.unshift l
230
+ break if s == root
231
+ s = s.root
232
+ end
233
+ n.join ' '
219
234
  end
220
235
 
221
236
  def help
222
- puts "#{applname} -- #{self::SUMMARY}"
237
+ fn = full_name
238
+ puts "#{fn} -- #{self::SUMMARY}"
223
239
  puts
224
- puts self::DESCRIPTION
240
+ d = self::DESCRIPTION.gsub /#(\w+?)?#/ do
241
+ case $1
242
+ when "NAME" then fn
243
+ end
244
+ end
245
+ puts d
225
246
  puts
226
247
  show_options
227
248
  if block_given? then
@@ -231,7 +252,7 @@ class Application
231
252
  end
232
253
 
233
254
  def version
234
- puts "#{applname} #{self::VERSION} -- #{self::SUMMARY}"
255
+ puts "#{self::NAME} #{self::VERSION} -- #{self::SUMMARY}"
235
256
  puts self::COPYRIGHT if const_defined? :COPYRIGHT
236
257
  puts "License: #{self::LICENSE}" if const_defined? :LICENSE
237
258
  a = []
data/lib/applfan.rb CHANGED
@@ -5,9 +5,7 @@
5
5
  require "appl"
6
6
 
7
7
 
8
- ApplicationFan = Class.new Application
9
-
10
- class ApplicationFan
8
+ class ApplicationFan < Application
11
9
 
12
10
  AVAILCMDS = "Available commands (say -h after one for help)"
13
11
  NOCOMMAND = "No command given. Say -h for a list."
@@ -22,7 +20,7 @@ class ApplicationFan
22
20
  attr_accessor :commands
23
21
 
24
22
  def find_command name
25
- @commands.find { |c| c::NAME == name }
23
+ @commands.find { |c| c::NAME == name or c::ALIASES.include? name }
26
24
  end
27
25
 
28
26
 
@@ -35,7 +33,7 @@ class ApplicationFan
35
33
  puts self::AVAILCMDS
36
34
  puts
37
35
  @commands.each { |c|
38
- puts " %-*s %s" % [ self::W_CMDS, c::NAME, c::SUMMARY]
36
+ puts " %-*s %s" % [ self::W_CMDS, c.all_names, c::SUMMARY]
39
37
  }
40
38
  end
41
39
  end
@@ -54,9 +52,6 @@ class ApplicationFan
54
52
  define_singleton_method :root do
55
53
  sub
56
54
  end
57
- define_singleton_method :applname do
58
- "#{root::NAME} #{self::NAME}"
59
- end
60
55
  end
61
56
  )
62
57
  end
@@ -70,7 +65,7 @@ class ApplicationFan
70
65
  c or raise CommandError, self.class::NOCOMMAND
71
66
  cmd = self.class.find_command c
72
67
  cmd or raise CommandError, self.class::UNKNWNCMD % c
73
- sub = cmd.new @args.slice! 0, @args.length
68
+ sub = cmd.new c, (@args.slice! 0, @args.length)
74
69
  yield sub if block_given?
75
70
  sub.execute
76
71
  end
metadata CHANGED
@@ -1,35 +1,32 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appl
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.9'
4
+ version: '1.14'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bertram Scharpf
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-29 00:00:00.000000000 Z
11
+ date: 2021-08-01 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |
14
14
  A base class for command line applications doing options parsing
15
15
  and generating exit codes.
16
16
  email: "<software@bertram-scharpf.de>"
17
- executables:
18
- - intar
17
+ executables: []
19
18
  extensions: []
20
19
  extra_rdoc_files: []
21
20
  files:
22
- - bin/intar
23
21
  - doc/demoappl
24
22
  - doc/demofan
25
23
  - lib/appl.rb
26
24
  - lib/applfan.rb
27
- - lib/intar.rb
28
25
  homepage: http://www.bertram-scharpf.de/software/appl
29
26
  licenses:
30
27
  - BSD-2-Clause
31
28
  metadata: {}
32
- post_install_message:
29
+ post_install_message:
33
30
  rdoc_options: []
34
31
  require_paths:
35
32
  - lib
@@ -45,8 +42,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
45
42
  version: '0'
46
43
  requirements:
47
44
  - Just Ruby
48
- rubygems_version: 3.0.6
49
- signing_key:
45
+ rubygems_version: 3.0.8
46
+ signing_key:
50
47
  specification_version: 4
51
48
  summary: Easy option parsing
52
49
  test_files: []
data/bin/intar DELETED
@@ -1,136 +0,0 @@
1
- #!/usr/local/bin/ruby
2
-
3
- #
4
- # intar -- Interactive Ruby evaluation
5
- #
6
-
7
- require "intar"
8
- require "appl"
9
-
10
-
11
- class IntarApp < Application
12
-
13
- NAME = "intar"
14
- VERSION = APPL_VERSION
15
- SUMMARY = "Interactive Ruby"
16
- COPYRIGHT = "(C) 2008-2016 Bertram Scharpf <software@bertram-scharpf.de>"
17
- LICENSE = "BSD"
18
- AUTHOR = "Bertram Scharpf <software@bertram-scharpf.de>"
19
-
20
- DESCRIPTION = <<~EOT
21
- Prompt for Ruby statements, evaluate them. This is a replacement
22
- for "irb". The underlying library may be entered from inside any
23
- Ruby program.
24
-
25
- Example:
26
-
27
- $ intar -p '%(33 1)c%t%c%> '
28
-
29
- EOT
30
-
31
- attr_writer :show, :prompt, :histmax
32
- def histfile= f ; @histfile = nil_if_none f ; end
33
- def configfile= f ; @configfile = nil_if_none f ; end
34
- attr_bang :quiet, :bw, :catch_exit, :histall
35
-
36
- define_option "p", :prompt=, "STR",
37
- "prompt - see source code for % escapes"
38
- alias_option "p", "prompt"
39
-
40
- define_option "q", :quiet!, "don't show results"
41
- alias_option "q", "quiet"
42
-
43
- define_option "s", :show=, "N", "show result line limit (0=all)"
44
- alias_option "s", "show"
45
-
46
- define_option "r", :require, "FILE", "Ruby require"
47
- alias_option "r", "require"
48
-
49
- define_option "bw", :bw!, "black & white"
50
-
51
- define_option "c", :configfile=, "FILE", ".intarrc",
52
- "config file, NONE means none"
53
- alias_option "c", "configfile"
54
-
55
- define_option "H", :histfile=, "FILE", ".intar_history",
56
- "history file, NONE means none"
57
- alias_option "H", "histfile"
58
-
59
- define_option "m", :histmax=, "NUM",
60
- "maximum history entries to save"
61
- alias_option "m", "histmax"
62
-
63
- define_option "A", :histall!,
64
- "pass lines starting with blanks to history"
65
- alias_option "A", "histall"
66
-
67
- define_option "E", :encoding=, "ENC", "set encoding (like ruby -E)"
68
- alias_option "E", "encoding"
69
-
70
- define_option "x", :catch_exit!,
71
- "On exit exception: Wait 3 seconds for interrupt"
72
- alias_option "x", "catchexit"
73
- alias_option "x", "catch-exit"
74
-
75
- define_option "h", :help, "show options"
76
- alias_option "h", "help"
77
- define_option "V", :version, "show version"
78
- alias_option "V", "version"
79
-
80
- def run
81
- # @debug = true # Only development.
82
- read_cfg
83
- if @quiet then
84
- Intar.show = 0
85
- elsif @show then
86
- Intar.show = Integer @show
87
- end
88
- Intar.prompt = @prompt if @prompt
89
- Intar.colour = false if @bw
90
- Intar.catch_exit = (Intar.catch_exit||0) + 3 if @catch_exit
91
- Intar.histhid = false if @histall
92
- Intar.histfile = @histfile if @histfile
93
- Intar.histmax = Integer @histmax if @histmax
94
-
95
- main = eval "self", TOPLEVEL_BINDING
96
- Intar.open main do |i|
97
- i.run *(@args.shift @args.length)
98
- end
99
- end
100
-
101
- private
102
-
103
- def encoding= ei
104
- e, i = ei.split ":"
105
- Encoding.default_external = e if e and not e.empty?
106
- Encoding.default_internal = i if i and not i.empty?
107
- [ $stdin, $stdout, $stderr].each do |io|
108
- io.set_encoding e, i
109
- end
110
- end
111
-
112
- def read_cfg
113
- return unless @configfile
114
- h = "~" unless @configfile[ File::SEPARATOR]
115
- c = File.expand_path @configfile, h
116
- return unless File.exists? c
117
- load c
118
- rescue Exception
119
- $@.pop 2
120
- e = $@.shift
121
- puts "#{e}: #$! (#{$!.class})"
122
- $@.each { |l| puts "\t#{l}" }
123
- raise "Error in config file #{c}"
124
- end
125
-
126
- def nil_if_none var
127
- case var
128
- when "", "NONE" then nil
129
- else var
130
- end
131
- end
132
-
133
- end
134
-
135
- IntarApp.run
136
-
data/lib/intar.rb DELETED
@@ -1,447 +0,0 @@
1
- #
2
- # intar.rb -- Interactive Ruby evaluation
3
- #
4
-
5
-
6
- =begin rdoc
7
-
8
- This could be opened not only by the Intar executable but also
9
- everywhere inside your Ruby program.
10
-
11
- = Example 1
12
-
13
- require "intar"
14
-
15
- Intar.prompt = "str(%(length)i):%03n%> "
16
- a = "hello"
17
- Intar.run a
18
-
19
-
20
- = Example 2
21
-
22
- require "intar"
23
-
24
- class C
25
- end
26
-
27
- class IntarC < Intar
28
- @show = 3
29
- @prompt = "%(33 1)c%t%c%> "
30
- @histfile = ".intarc_history"
31
-
32
- class <<self
33
- def open
34
- super C.new
35
- end
36
- end
37
- end
38
-
39
- IntarC.open do |ia| ia.run end
40
-
41
- =end
42
-
43
-
44
- require "readline"
45
- require "supplement"
46
- require "supplement/terminal"
47
-
48
-
49
- class Object
50
- def intar_binding
51
- binding
52
- end
53
- end
54
-
55
- class Intar
56
-
57
- class History
58
-
59
- IND = " "
60
- IND_RE = /^#{IND}/
61
-
62
- def initialize filename
63
- @filename = filename
64
- return unless @filename
65
- h = "~" unless @filename[ File::SEPARATOR]
66
- @filename = File.expand_path @filename, h
67
- File.exists? @filename and File.open @filename do |h|
68
- c = []
69
- h.each { |l|
70
- case l
71
- when IND_RE then c.push $'
72
- else push c.join.chomp ; c.clear
73
- end
74
- }
75
- push c.join.chomp
76
- end
77
- @num = Readline::HISTORY.length
78
- end
79
-
80
- def finish max
81
- return unless @filename
82
- @num.times { Readline::HISTORY.shift }
83
- File.open @filename, "a" do |h|
84
- a = []
85
- while (c = Readline::HISTORY.shift) do a.push c end
86
- if a.any? then
87
- h.puts "# #{Time.now}"
88
- a.each { |c|
89
- c.each_line { |l| h.puts IND + l }
90
- h.puts "-"
91
- }
92
- i = a.length
93
- h.puts "# #{i} #{entry_str i} added"
94
- end
95
- end
96
- n = File.open @filename do |h|
97
- h.inject 0 do |i,l| i += 1 if l =~ IND_RE ; i end
98
- end
99
- i = max - n
100
- if i < 0 then
101
- f = nil
102
- File.open @filename do |h|
103
- h.each_line { |l|
104
- f.push l if f
105
- case l
106
- when IND_RE then i += 1
107
- else f ||= [] if i >= 0
108
- end
109
- }
110
- end
111
- f and File.open @filename, "w" do |h| h.puts f end
112
- end
113
- rescue Errno
114
- # Forget it if there isn't enough disk space.
115
- end
116
-
117
- def push l
118
- Readline::HISTORY.push l unless l.empty?
119
- end
120
-
121
- private
122
-
123
- def entry_str i
124
- i == 1 ? "entry" : "entries"
125
- end
126
-
127
- end
128
-
129
- class <<self
130
-
131
- attr_accessor :prompt, :show, :shownil, :colour
132
-
133
- attr_reader :histfile
134
- def histfile= hf
135
- @histfile = hf
136
- if @history then
137
- @history.finish @histmax
138
- @history = History.new @histfile
139
- end
140
- end
141
-
142
- # Maximum number of history entries.
143
- attr_accessor :histmax
144
-
145
- # Whether to hide entries starting with whitespace.
146
- attr_accessor :histhid
147
-
148
- # Shell prefix and Pipe suffix
149
- attr_accessor :sh_pref, :pi_suff
150
-
151
- # Whether <code>Kernel#exit</code> should be caught.
152
- attr_accessor :catch_exit
153
-
154
- private
155
-
156
- def inherited sub
157
- sub.class_eval {
158
- s = superclass
159
- @prompt = s.prompt
160
- @show = s.show
161
- @shownil = s.shownil
162
- @colour = s.colour
163
- @histfile = s.histfile
164
- @histmax = s.histmax
165
- @histhid = s.histhid
166
- @sh_pref = s.sh_pref
167
- @pi_suff = s.pi_suff
168
- @catch_exit = s.catch_exit
169
- }
170
- end
171
-
172
- def history_file
173
- if @history then
174
- yield
175
- else
176
- @history = History.new @histfile
177
- begin
178
- yield
179
- ensure
180
- @history.finish @histmax
181
- @history = nil
182
- end
183
- end
184
- end
185
-
186
- public
187
-
188
- private :new
189
- def open obj
190
- history_file do
191
- i = new obj
192
- yield i
193
- end
194
- end
195
-
196
- def run obj
197
- open obj do |i| i.run end
198
- end
199
-
200
- def hist_add l
201
- return if @histhid and l == /\A[ \t]+/
202
- lst = Readline::HISTORY[-1] if Readline::HISTORY.length > 0
203
- @history.push l unless l == lst
204
- end
205
-
206
- end
207
-
208
- self.prompt = "%(32)c%i%c:%1c%03n%c%> "
209
- self.show = 1
210
- self.shownil = false
211
- self.colour = true
212
- self.histfile = nil
213
- self.histmax = 500
214
- self.histhid = true
215
- self.sh_pref = "."
216
- self.pi_suff = " |"
217
- self.catch_exit = nil
218
-
219
- private
220
-
221
- def initialize obj
222
- @obj = obj
223
- @n = 0
224
- end
225
-
226
- OLDSET = <<~EOT
227
- _, __, ___ = nil, nil, nil
228
- proc { |r,n|
229
- Array === __ or __ = []
230
- Hash === ___ or ___ = {}
231
- unless r.nil? or r.equal? __ or r.equal? ___ then
232
- _ = r
233
- __.delete r rescue nil
234
- __.unshift r
235
- ___[ n] = r
236
- end
237
- }
238
- EOT
239
-
240
- autoload :Etc, "etc"
241
- autoload :Socket, "socket"
242
-
243
- def cur_prompt prev
244
- t = Time.now
245
- self.class.prompt.gsub /%(?:
246
- \(([^\)]+)?\)
247
- |
248
- ([+-]?[0-9]+(?:\.[0-9]+)?)
249
- )?(.)/nx do
250
- case $3
251
- when "s" then @obj.to_s
252
- when "i" then $1 ? (@obj.send $1) : @obj.inspect
253
- when "n" then "%#$2d" % @n
254
- when "t" then t.strftime $1||"%X"
255
- when "u" then Etc.getpwuid.name
256
- when "h" then Socket.gethostname
257
- when "w" then cwd_short
258
- when "W" then File.basename cwd_short
259
- when "c" then (colour *($1 || $2 || "").split.map { |x| x.to_i }).to_s
260
- when ">" then prev ? "." : Process.uid == 0 ? "#" : ">"
261
- when "%" then $3
262
- else $&
263
- end
264
- end
265
- end
266
-
267
- def colour *c
268
- if self.class.colour then
269
- s = c.map { |i| "%d" % i }.join ";"
270
- "\e[#{s}m"
271
- end
272
- end
273
-
274
- def switchcolour *c
275
- s = colour *c
276
- print s if s
277
- end
278
-
279
- def cwd_short
280
- r = Dir.pwd
281
- h = Etc.getpwuid.dir
282
- r[ 0, h.length] == h and r[ 0, h.length] = "~"
283
- r
284
- end
285
-
286
- def readline
287
- r, @previous = @previous, nil
288
- r or @n += 1
289
- begin
290
- cp = cur_prompt r
291
- begin
292
- l = Readline.readline cp
293
- rescue Interrupt
294
- puts "^C -- #{$!.inspect}"
295
- retry
296
- end
297
- return if l.nil?
298
- if r then
299
- r << $/ << l
300
- else
301
- r = l unless l.empty?
302
- end
303
- self.class.hist_add l
304
- cp.strip!
305
- cp.gsub! /\e\[[0-9]*(;[0-9]*)*m/, ""
306
- @file = "#{self.class}/#{cp}"
307
- end until r
308
- r
309
- end
310
-
311
- # :stopdoc:
312
- ARROW = "=> "
313
- ELLIPSIS = "..."
314
- # :startdoc:
315
-
316
- def display r
317
- return if r.nil? and not self.class.shownil
318
- show = (self.class.show or return)
319
- i = ARROW.dup
320
- i << r.inspect
321
- if show > 0 then
322
- siz, = $stdout.winsize
323
- siz *= show
324
- if i.length > siz then
325
- i.cut! siz-ELLIPSIS.length
326
- i << ELLIPSIS
327
- end
328
- end
329
- puts i
330
- end
331
-
332
- def pager doit
333
- if doit then
334
- IO.popen ENV[ "PAGER"]||"more", "w" do |pg|
335
- begin
336
- stdout = $stdout.dup
337
- $stdout.reopen pg
338
- yield
339
- ensure
340
- $stdout.reopen stdout
341
- end
342
- end
343
- else
344
- yield
345
- end
346
- end
347
-
348
- public
349
-
350
- class Exit < Exception ; end
351
- class CmdFailed < Exception ; end
352
-
353
- def run *precmds
354
- bind = @obj.intar_binding
355
- precmds.each { |l| eval l, bind }
356
- oldset = eval OLDSET, bind
357
- @cl = (eval "caller.length", bind) + 2 # 2 = eval + run()
358
- while l = readline do
359
- re_sh_pref = /\A#{Regexp.quote self.class.sh_pref}/
360
- re_pi_suff = /#{Regexp.quote self.class.pi_suff}\z/
361
- switchcolour
362
- begin
363
- pg = l.slice! re_pi_suff
364
- r = pager pg do
365
- unless l =~ re_sh_pref then
366
- eval l, bind, @file
367
- else
368
- call_system $', bind
369
- end
370
- end
371
- oldset.call r, @n
372
- display r
373
- rescue Exit
374
- wait_exit and break
375
- rescue CmdFailed
376
- oldset.call $?, @n
377
- switchcolour 33
378
- puts "Exit code: #{$?.exitstatus}"
379
- rescue LoadError
380
- oldset.call $!, @n
381
- show_exception
382
- rescue SyntaxError
383
- if l.end_with? $/ then
384
- switchcolour 33
385
- puts $!
386
- else
387
- @previous = l
388
- end
389
- rescue SystemExit
390
- break if wait_exit
391
- oldset.call $!, @n
392
- show_exception
393
- rescue Exception
394
- oldset.call $!, @n
395
- show_exception
396
- ensure
397
- switchcolour
398
- end
399
- end
400
- puts
401
- ensure
402
- done
403
- end
404
-
405
- protected
406
-
407
- def done
408
- end
409
-
410
- private
411
-
412
- def wait_exit
413
- c = self.class.catch_exit
414
- c and c.times { print "." ; $stdout.flush ; sleep 1 }
415
- true
416
- rescue Interrupt
417
- puts
418
- end
419
-
420
- def show_exception
421
- unless $!.to_s.empty? then
422
- switchcolour 31, 1
423
- print $!
424
- print " " unless $!.to_s =~ /\s\z/
425
- end
426
- switchcolour 31, 22
427
- puts "(#{$!.class})"
428
- switchcolour 33
429
- bt = $@.dup
430
- if bt.length > @cl then
431
- bt.pop @cl
432
- end
433
- puts bt
434
- end
435
-
436
- def call_system l, bind
437
- l.strip!
438
- raise Exit if l.empty?
439
- eot = "EOT0001"
440
- eot.succ! while l[ eot]
441
- l = eval "<<#{eot}\n#{l}\n#{eot}", bind, @file
442
- system l or raise CmdFailed
443
- nil
444
- end
445
-
446
- end
447
-