appl 1.6.2 → 1.13
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 +4 -4
- data/doc/demoappl +3 -3
- data/doc/demofan +90 -0
- data/lib/appl.rb +62 -72
- data/lib/applfan.rb +74 -0
- metadata +9 -10
- data/bin/intar +0 -147
- data/lib/intar.rb +0 -447
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9e3306b330c4d69ef88e6b75511d7b0ab1e030f990aac1800305dcfa4afd0f65
|
4
|
+
data.tar.gz: eff477635d40b6ff9c443b0fe1256107c85d31bf6aa7c0a2088f26ffa239111c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6ae84d8de622e2e2b4763ef8fbda40b9210edd326d48358707364f4a4c99b0fbee05c1ed1dc5b31d83d3f7429e74922a81af5eb22de7572a1a3c6ad7bec99925
|
7
|
+
data.tar.gz: ab2ea5f6b9f7850bd62e741201cc10bdaa1c1c6be549c0a45fa435bb7ee55779fabfade33a0801fd931d7313d0b90f3a991b1ec38ee6749db19562ee6969afe2
|
data/doc/demoappl
CHANGED
@@ -46,9 +46,9 @@ class DemoAppl < Application
|
|
46
46
|
define_option "V", :version, "show version information"
|
47
47
|
alias_option "V", "version"
|
48
48
|
|
49
|
-
|
50
|
-
|
51
|
-
UNPROCA = "Warning
|
49
|
+
STOPOPT = "Stop option processing"
|
50
|
+
UNKNOWN = "Not a valid option: `%s'."
|
51
|
+
UNPROCA = "Warning. Unprocessed arguments: %s"
|
52
52
|
|
53
53
|
def run
|
54
54
|
puts inspect
|
data/doc/demofan
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#
|
4
|
+
# demofan -- Test the Application class with commands
|
5
|
+
#
|
6
|
+
|
7
|
+
require "applfan"
|
8
|
+
|
9
|
+
|
10
|
+
class DemoFan < ApplicationFan
|
11
|
+
|
12
|
+
NAME = "demofan"
|
13
|
+
VERSION = "1.0"
|
14
|
+
SUMMARY = "Test the Application class with commands"
|
15
|
+
COPYRIGHT = "(C) 2020 Bertram Scharpf"
|
16
|
+
LICENSE = "For internal use only"
|
17
|
+
AUTHOR = "Bertram Scharpf <software@bertram-scharpf.de>"
|
18
|
+
|
19
|
+
DESCRIPTION = <<~EOT
|
20
|
+
This is an example how to define an Application subclass
|
21
|
+
with commands inside.
|
22
|
+
EOT
|
23
|
+
|
24
|
+
attr_bang :verbose
|
25
|
+
define_option "v", :verbose!, "verbose mode"
|
26
|
+
|
27
|
+
define_option "h", :help, "show this options list"
|
28
|
+
alias_option "h", "help"
|
29
|
+
define_option "V", :version, "show version information"
|
30
|
+
alias_option "V", "version"
|
31
|
+
|
32
|
+
def run
|
33
|
+
super do |cmd|
|
34
|
+
cmd.verbose! if @verbose
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class Init < Command
|
39
|
+
NAME = "init"
|
40
|
+
SUMMARY = "Initialize"
|
41
|
+
DESCRIPTION = <<~EOT
|
42
|
+
Initialization of nothing.
|
43
|
+
EOT
|
44
|
+
define_option "h", :help, "show init's options list"
|
45
|
+
alias_option "h", "help"
|
46
|
+
def verbose! ; end
|
47
|
+
def run
|
48
|
+
puts "Initializing...done."
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class Run < Command
|
53
|
+
NAME = "run"
|
54
|
+
SUMMARY = "Run a job"
|
55
|
+
DESCRIPTION = <<~EOT
|
56
|
+
Running nothing.
|
57
|
+
EOT
|
58
|
+
define_option "h", :help, "show run's options list"
|
59
|
+
alias_option "h", "help"
|
60
|
+
def verbose! ; @verbose = true ; end
|
61
|
+
def run
|
62
|
+
if @verbose then
|
63
|
+
puts "Starting..."
|
64
|
+
puts "Running..."
|
65
|
+
puts "Done."
|
66
|
+
else
|
67
|
+
puts "Running...done."
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class Cleanup < Command
|
73
|
+
NAME = "cleanup"
|
74
|
+
SUMMARY = "Cleanup"
|
75
|
+
DESCRIPTION = <<~EOT
|
76
|
+
Cleanup of nothing.
|
77
|
+
EOT
|
78
|
+
define_option "h", :help, "show cleanup's options list"
|
79
|
+
alias_option "h", "help"
|
80
|
+
def verbose! ; end
|
81
|
+
def run
|
82
|
+
puts "Cleaning up...done."
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
DemoFan.run
|
90
|
+
|
data/lib/appl.rb
CHANGED
@@ -5,19 +5,24 @@
|
|
5
5
|
|
6
6
|
class Application
|
7
7
|
|
8
|
-
APPL_VERSION = "1.
|
8
|
+
APPL_VERSION = "1.13".freeze
|
9
9
|
|
10
10
|
OPTIONS_ENV = nil
|
11
11
|
|
12
12
|
STOPOPT = "stop option processing"
|
13
|
-
UNKNOWN = "Unknown option"
|
14
|
-
UNPROCA = "Warning: unprocessed arguments"
|
13
|
+
UNKNOWN = "Unknown option: `%s'."
|
14
|
+
UNPROCA = "Warning: unprocessed arguments: %s"
|
15
|
+
|
16
|
+
ALIASES = [].freeze
|
17
|
+
|
18
|
+
W_OPTS = 10
|
19
|
+
W_ARGS = 16
|
15
20
|
|
16
21
|
class OptionError < StandardError ; end
|
17
22
|
class Done < Exception ; end
|
18
23
|
|
19
|
-
def initialize args = nil
|
20
|
-
@args = args
|
24
|
+
def initialize name = nil, args = nil
|
25
|
+
@name, @args = name, args
|
21
26
|
self.class.each_option { |opt,desc,arg,dfl,act|
|
22
27
|
begin
|
23
28
|
send act, dfl if dfl
|
@@ -46,41 +51,29 @@ class Application
|
|
46
51
|
end
|
47
52
|
|
48
53
|
def help
|
49
|
-
|
50
|
-
puts c.version
|
51
|
-
puts
|
52
|
-
puts c::DESCRIPTION
|
53
|
-
puts
|
54
|
-
c.show_options
|
55
|
-
if block_given? then
|
56
|
-
puts
|
57
|
-
yield
|
58
|
-
end
|
54
|
+
self.class.help
|
59
55
|
raise Done
|
60
56
|
end
|
61
57
|
|
62
58
|
def version
|
63
|
-
self.class.
|
59
|
+
self.class.version
|
64
60
|
raise Done
|
65
61
|
end
|
66
62
|
|
67
|
-
VERSION = "0"
|
68
|
-
NAME = "appl"
|
69
|
-
SUMMARY = "Dummy application"
|
70
|
-
DESCRIPTION = <<~EOT
|
71
|
-
This base class does nothing by default.
|
72
|
-
EOT
|
73
|
-
|
74
63
|
def run
|
75
64
|
end
|
76
65
|
|
77
|
-
def
|
78
|
-
run
|
66
|
+
def warn_unprocessed
|
79
67
|
if @args.any? then
|
80
|
-
|
81
|
-
puts "#{self.class::UNPROCA}: #{u}"
|
68
|
+
$stderr.puts self.class.root::UNPROCA % (@args.join " ")
|
82
69
|
end
|
83
|
-
|
70
|
+
end
|
71
|
+
|
72
|
+
def execute
|
73
|
+
r = run
|
74
|
+
r = 0 unless Integer === r
|
75
|
+
warn_unprocessed
|
76
|
+
r
|
84
77
|
rescue SignalException
|
85
78
|
raise if @debug
|
86
79
|
self.class.show_message $!.inspect
|
@@ -98,18 +91,11 @@ class Application
|
|
98
91
|
exit e
|
99
92
|
end
|
100
93
|
|
101
|
-
def version
|
102
|
-
if self::VERSION =~ %r/\s/ then
|
103
|
-
self::VERSION
|
104
|
-
else
|
105
|
-
"#{self::NAME} #{self::VERSION} -- #{self::SUMMARY}"
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
94
|
private
|
110
95
|
|
111
96
|
def execute args = nil
|
112
|
-
|
97
|
+
n = File.basename $0
|
98
|
+
i = new n, args||cmdline_arguments
|
113
99
|
i.execute
|
114
100
|
rescue Done
|
115
101
|
0
|
@@ -119,7 +105,9 @@ class Application
|
|
119
105
|
end
|
120
106
|
|
121
107
|
def inherited sub
|
122
|
-
sub.
|
108
|
+
sub.name or return
|
109
|
+
o, a = @options.dup.to_h, @aliases.dup.to_h
|
110
|
+
sub.instance_eval { @options, @aliases = o, a }
|
123
111
|
end
|
124
112
|
|
125
113
|
def attr_bang *syms
|
@@ -162,16 +150,12 @@ class Application
|
|
162
150
|
end
|
163
151
|
|
164
152
|
def delete_option opt
|
165
|
-
self < Application or return
|
166
|
-
superclass.delete_option opt
|
167
|
-
@options.delete opt
|
168
153
|
@aliases.reject! { |k,v| v == opt }
|
154
|
+
@options.delete opt
|
169
155
|
nil
|
170
156
|
end
|
171
157
|
|
172
158
|
def unalias_option opt
|
173
|
-
self < Application or return
|
174
|
-
superclass.unalias_option opt
|
175
159
|
@aliases.delete opt
|
176
160
|
nil
|
177
161
|
end
|
@@ -179,32 +163,12 @@ class Application
|
|
179
163
|
protected
|
180
164
|
|
181
165
|
def find_option_act opt
|
182
|
-
|
183
|
-
@options[ opt] || @options[ @aliases[ opt]] ||
|
184
|
-
(superclass.find_option_act opt)
|
185
|
-
end
|
186
|
-
|
187
|
-
def all_options
|
188
|
-
if self < Application then
|
189
|
-
r = superclass.all_options
|
190
|
-
r.update @options
|
191
|
-
else
|
192
|
-
{}
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
def all_aliases
|
197
|
-
if self < Application then
|
198
|
-
r = superclass.all_aliases
|
199
|
-
r.update @aliases
|
200
|
-
else
|
201
|
-
{}
|
202
|
-
end
|
166
|
+
@options[ opt] || @options[ @aliases[ opt]]
|
203
167
|
end
|
204
168
|
|
205
169
|
def options_desc &block
|
206
170
|
a = Hash.new do |h,k| h[ k] = [] end
|
207
|
-
|
171
|
+
@aliases.each { |k,v|
|
208
172
|
a[ v].push k
|
209
173
|
}
|
210
174
|
each_option { |opt,desc,arg,dfl,|
|
@@ -213,14 +177,13 @@ class Application
|
|
213
177
|
yield l, nil, nil, nil
|
214
178
|
}
|
215
179
|
}
|
216
|
-
yield "", nil, nil,
|
180
|
+
yield "", nil, nil, root::STOPOPT
|
217
181
|
end
|
218
182
|
|
219
183
|
public
|
220
184
|
|
221
185
|
def each_option
|
222
|
-
|
223
|
-
o.each { |opt,(desc,arg,dfl,act)|
|
186
|
+
@options.each { |opt,(desc,arg,dfl,act)|
|
224
187
|
case dfl
|
225
188
|
when Symbol then dfl = const_get dfl
|
226
189
|
end
|
@@ -230,7 +193,7 @@ class Application
|
|
230
193
|
|
231
194
|
def option_act args, opt, rest
|
232
195
|
dada = find_option_act opt
|
233
|
-
dada or raise OptionError,
|
196
|
+
dada or raise OptionError, root::UNKNOWN % opt
|
234
197
|
desc, arg, dfl, act = *dada
|
235
198
|
r = [ act]
|
236
199
|
if arg then
|
@@ -246,12 +209,39 @@ class Application
|
|
246
209
|
arg &&= "#{arg}"
|
247
210
|
dfl &&= "[#{dfl}]"
|
248
211
|
arg << dfl if arg && dfl
|
249
|
-
puts "
|
212
|
+
puts " %-*s %-*s %s" % [ root::W_OPTS, opt, root::W_ARGS, arg, desc]
|
250
213
|
end
|
251
214
|
end
|
252
215
|
|
253
|
-
def
|
254
|
-
|
216
|
+
def root
|
217
|
+
self
|
218
|
+
end
|
219
|
+
|
220
|
+
def all_names
|
221
|
+
[ self::NAME, *self::ALIASES].join "|"
|
222
|
+
end
|
223
|
+
|
224
|
+
def help
|
225
|
+
n = []
|
226
|
+
s = self
|
227
|
+
begin
|
228
|
+
l = s.all_names
|
229
|
+
n.unshift l
|
230
|
+
s = s.root
|
231
|
+
end while s != root
|
232
|
+
puts "#{n.join ' '} -- #{self::SUMMARY}"
|
233
|
+
puts
|
234
|
+
puts self::DESCRIPTION
|
235
|
+
puts
|
236
|
+
show_options
|
237
|
+
if block_given? then
|
238
|
+
puts
|
239
|
+
yield
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
def version
|
244
|
+
puts "#{self::NAME} #{self::VERSION} -- #{self::SUMMARY}"
|
255
245
|
puts self::COPYRIGHT if const_defined? :COPYRIGHT
|
256
246
|
puts "License: #{self::LICENSE}" if const_defined? :LICENSE
|
257
247
|
a = []
|
data/lib/applfan.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
#
|
2
|
+
# lib/applfan.rb -- ApplicationFan class
|
3
|
+
#
|
4
|
+
|
5
|
+
require "appl"
|
6
|
+
|
7
|
+
|
8
|
+
class ApplicationFan < Application
|
9
|
+
|
10
|
+
AVAILCMDS = "Available commands (say -h after one for help)"
|
11
|
+
NOCOMMAND = "No command given. Say -h for a list."
|
12
|
+
UNKNWNCMD = "Unknown command: `%s'. Say -h for a list."
|
13
|
+
|
14
|
+
W_CMDS = 16
|
15
|
+
|
16
|
+
class CommandError < StandardError ; end
|
17
|
+
|
18
|
+
class <<self
|
19
|
+
|
20
|
+
attr_accessor :commands
|
21
|
+
|
22
|
+
def find_command name
|
23
|
+
@commands.find { |c| c::NAME == name or c::ALIASES.include? name }
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
def help
|
28
|
+
super do
|
29
|
+
if block_given? then
|
30
|
+
yield
|
31
|
+
puts
|
32
|
+
end
|
33
|
+
puts self::AVAILCMDS
|
34
|
+
puts
|
35
|
+
@commands.each { |c|
|
36
|
+
puts " %-*s %s" % [ self::W_CMDS, c.all_names, c::SUMMARY]
|
37
|
+
}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def inherited sub
|
44
|
+
sub.instance_eval do
|
45
|
+
@commands = []
|
46
|
+
const_set :Command, (
|
47
|
+
Class.new Application do
|
48
|
+
define_singleton_method :inherited do |c|
|
49
|
+
sub.commands.push c
|
50
|
+
super c
|
51
|
+
end
|
52
|
+
define_singleton_method :root do
|
53
|
+
sub.root
|
54
|
+
end
|
55
|
+
end
|
56
|
+
)
|
57
|
+
end
|
58
|
+
super
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
def run
|
64
|
+
c = @args.shift
|
65
|
+
c or raise CommandError, self.class::NOCOMMAND
|
66
|
+
cmd = self.class.find_command c
|
67
|
+
cmd or raise CommandError, self.class::UNKNWNCMD % c
|
68
|
+
sub = cmd.new c, (@args.slice! 0, @args.length)
|
69
|
+
yield sub if block_given?
|
70
|
+
sub.execute
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
metadata
CHANGED
@@ -1,33 +1,32 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: appl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: '1.13'
|
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:
|
11
|
+
date: 2021-04-11 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
|
22
|
+
- doc/demofan
|
24
23
|
- lib/appl.rb
|
25
|
-
- lib/
|
24
|
+
- lib/applfan.rb
|
26
25
|
homepage: http://www.bertram-scharpf.de/software/appl
|
27
26
|
licenses:
|
28
27
|
- BSD-2-Clause
|
29
28
|
metadata: {}
|
30
|
-
post_install_message:
|
29
|
+
post_install_message:
|
31
30
|
rdoc_options: []
|
32
31
|
require_paths:
|
33
32
|
- lib
|
@@ -43,8 +42,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
43
42
|
version: '0'
|
44
43
|
requirements:
|
45
44
|
- Just Ruby
|
46
|
-
rubygems_version: 3.0.
|
47
|
-
signing_key:
|
45
|
+
rubygems_version: 3.0.8
|
46
|
+
signing_key:
|
48
47
|
specification_version: 4
|
49
48
|
summary: Easy option parsing
|
50
49
|
test_files: []
|
data/bin/intar
DELETED
@@ -1,147 +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
|
-
def quiet!
|
32
|
-
Intar.show = nil
|
33
|
-
end
|
34
|
-
def show= s
|
35
|
-
Intar.show = s.to_i
|
36
|
-
end
|
37
|
-
def prompt= p
|
38
|
-
Intar.prompt = p if p
|
39
|
-
end
|
40
|
-
def bw!
|
41
|
-
Intar.colour = false
|
42
|
-
end
|
43
|
-
def catch_exit!
|
44
|
-
Intar.catch_exit = (Intar.catch_exit||0) + 3
|
45
|
-
end
|
46
|
-
def histall!
|
47
|
-
Intar.histhid = false
|
48
|
-
end
|
49
|
-
def histfile= h
|
50
|
-
Intar.histfile = nil_if_none h
|
51
|
-
end
|
52
|
-
def histmax= m
|
53
|
-
Intar.histmax = (Integer m rescue m.to_i)
|
54
|
-
end
|
55
|
-
def configfile= c
|
56
|
-
@configfile = nil_if_none c
|
57
|
-
end
|
58
|
-
|
59
|
-
define_option "p", :prompt=, "STR",
|
60
|
-
"prompt - see source code for % escapes"
|
61
|
-
alias_option "p", "prompt"
|
62
|
-
|
63
|
-
define_option "q", :quiet!, "don't show results"
|
64
|
-
alias_option "q", "quiet"
|
65
|
-
|
66
|
-
define_option "S", :show=, "N", 1, "show result line limit (0=all)"
|
67
|
-
alias_option "S", "show"
|
68
|
-
|
69
|
-
define_option "r", :require, "FILE", "Ruby require"
|
70
|
-
alias_option "r", "require"
|
71
|
-
|
72
|
-
define_option "bw", :bw!, "black & white"
|
73
|
-
|
74
|
-
define_option "c", :configfile=, "FILE", ".intarrc",
|
75
|
-
"config file, NONE means none"
|
76
|
-
alias_option "c", "configfile"
|
77
|
-
|
78
|
-
define_option "H", :histfile=, "FILE", ".intar_history",
|
79
|
-
"history file, NONE means none"
|
80
|
-
alias_option "H", "histfile"
|
81
|
-
|
82
|
-
define_option "m", :histmax=, "NUM",
|
83
|
-
"maximum history entries to save"
|
84
|
-
alias_option "m", "histmax"
|
85
|
-
|
86
|
-
define_option "A", :histall!,
|
87
|
-
"pass lines starting with blanks to history"
|
88
|
-
alias_option "A", "histall"
|
89
|
-
|
90
|
-
define_option "E", :encoding=, "ENC", "set encoding (like ruby -E)"
|
91
|
-
alias_option "E", "encoding"
|
92
|
-
|
93
|
-
define_option "x", :catch_exit!,
|
94
|
-
"On exit exception: Wait 3 seconds for interrupt"
|
95
|
-
alias_option "x", "catchexit"
|
96
|
-
alias_option "x", "catch-exit"
|
97
|
-
|
98
|
-
define_option "h", :help, "show options"
|
99
|
-
alias_option "h", "help"
|
100
|
-
define_option "V", :version, "show version"
|
101
|
-
alias_option "V", "version"
|
102
|
-
|
103
|
-
def run
|
104
|
-
# @debug = true # Only development.
|
105
|
-
read_cfg
|
106
|
-
main = eval "self", TOPLEVEL_BINDING
|
107
|
-
Intar.open main do |i|
|
108
|
-
i.run *(@args.shift @args.length)
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
private
|
113
|
-
|
114
|
-
def encoding= ei
|
115
|
-
e, i = ei.split ":"
|
116
|
-
Encoding.default_external = e if e and not e.empty?
|
117
|
-
Encoding.default_internal = i if i and not i.empty?
|
118
|
-
[ $stdin, $stdout, $stderr].each do |io|
|
119
|
-
io.set_encoding e, i
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
def read_cfg
|
124
|
-
return unless @configfile
|
125
|
-
h = "~" unless @configfile[ File::SEPARATOR]
|
126
|
-
c = File.expand_path @configfile, h
|
127
|
-
return unless File.exists? c
|
128
|
-
load c
|
129
|
-
rescue Exception
|
130
|
-
$@.pop 2
|
131
|
-
e = $@.shift
|
132
|
-
puts "#{e}: #$! (#{$!.class})"
|
133
|
-
$@.each { |l| puts "\t#{l}" }
|
134
|
-
raise "Error in config file #{c}"
|
135
|
-
end
|
136
|
-
|
137
|
-
def nil_if_none var
|
138
|
-
case var
|
139
|
-
when "", "NONE" then nil
|
140
|
-
else var
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
end
|
145
|
-
|
146
|
-
IntarApp.run
|
147
|
-
|
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
|
-
|