appl 1.9 → 1.14

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