hq-tools 0.0.0 → 0.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/hq/tools/getopt.rb +158 -0
- metadata +4 -3
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
module HQ
|
|
2
|
+
module Tools
|
|
3
|
+
module Getopt
|
|
4
|
+
|
|
5
|
+
def self.to_long name
|
|
6
|
+
return "--#{name.to_s.gsub "_", "-"}"
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.process argv, easy_specs
|
|
10
|
+
|
|
11
|
+
argv = argv.flatten
|
|
12
|
+
|
|
13
|
+
# convert easy_specs into specs
|
|
14
|
+
specs = {}
|
|
15
|
+
ret = {}
|
|
16
|
+
easy_specs.each do |easy_spec|
|
|
17
|
+
if easy_spec[:options]
|
|
18
|
+
options = easy_spec[:options].clone
|
|
19
|
+
options << easy_spec[:default] if easy_spec[:default]
|
|
20
|
+
options.each do |option|
|
|
21
|
+
spec = {}
|
|
22
|
+
spec[:long_name] = to_long option
|
|
23
|
+
spec[:type] = option == easy_spec[:default] ? :switch_default : :switch
|
|
24
|
+
spec[:key] = easy_spec[:name]
|
|
25
|
+
spec[:arg_value] = option
|
|
26
|
+
specs[spec[:long_name]] = spec
|
|
27
|
+
end
|
|
28
|
+
ret[easy_spec[:name]] = easy_spec[:default]
|
|
29
|
+
else
|
|
30
|
+
easy_spec[:long_name] = to_long easy_spec[:name]
|
|
31
|
+
spec = {}
|
|
32
|
+
spec[:long_name] = to_long easy_spec[:name]
|
|
33
|
+
spec[:type] = case
|
|
34
|
+
when easy_spec[:boolean] then :boolean
|
|
35
|
+
when easy_spec[:required] then :required
|
|
36
|
+
else :optional
|
|
37
|
+
end
|
|
38
|
+
spec[:key] = easy_spec[:name]
|
|
39
|
+
spec[:arg_value] = easy_spec[:default]
|
|
40
|
+
spec[:verify] = easy_spec[:regex]
|
|
41
|
+
spec[:convert] = easy_spec[:convert]
|
|
42
|
+
spec[:multi] = easy_spec[:multi]
|
|
43
|
+
specs[spec[:long_name]] = spec
|
|
44
|
+
if easy_spec[:multi]
|
|
45
|
+
ret[easy_spec[:name]] = []
|
|
46
|
+
elsif easy_spec[:boolean]
|
|
47
|
+
ret[easy_spec[:name]] = false
|
|
48
|
+
elsif easy_spec[:required]
|
|
49
|
+
# do nothing
|
|
50
|
+
else
|
|
51
|
+
ret[easy_spec[:name]] = easy_spec[:default]
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# save main argv value because we clobber it
|
|
57
|
+
old_argv = []
|
|
58
|
+
ARGV.each { |arg| old_argv << arg }
|
|
59
|
+
new_argv = []
|
|
60
|
+
argv.each { |arg| new_argv << arg }
|
|
61
|
+
begin
|
|
62
|
+
|
|
63
|
+
require "getoptlong"
|
|
64
|
+
getopt_args = []
|
|
65
|
+
specs.each do |long_name, spec|
|
|
66
|
+
getopt_flags = case spec[:type]
|
|
67
|
+
when :required then GetoptLong::REQUIRED_ARGUMENT
|
|
68
|
+
when :optional then GetoptLong::REQUIRED_ARGUMENT
|
|
69
|
+
when :boolean then GetoptLong::NO_ARGUMENT
|
|
70
|
+
when :switch then GetoptLong::NO_ARGUMENT
|
|
71
|
+
when :switch_default then GetoptLong::NO_ARGUMENT
|
|
72
|
+
else raise "Invalid getopt argument type: #{spec[:type]}"
|
|
73
|
+
end
|
|
74
|
+
getopt_args << [ spec[:long_name], getopt_flags ]
|
|
75
|
+
#ret[spec[:key]] = spec[:arg_value] if [ :optional, :switch_default ].include? spec[:type]
|
|
76
|
+
#ret[spec[:key]] = [] if spec[:multi]
|
|
77
|
+
#ret[spec[:key]] = false if spec[:type] == :boolean
|
|
78
|
+
end
|
|
79
|
+
ARGV.clear
|
|
80
|
+
new_argv.each { |arg| ARGV << arg }
|
|
81
|
+
GetoptLong.new(*getopt_args).each do |opt, arg|
|
|
82
|
+
spec = specs[opt]
|
|
83
|
+
case spec[:type]
|
|
84
|
+
when :required, :optional
|
|
85
|
+
ret[spec[:key]] << arg if spec[:multi]
|
|
86
|
+
ret[spec[:key]] = arg unless spec[:multi]
|
|
87
|
+
when :switch, :switch_default
|
|
88
|
+
ret[spec[:key]] = spec[:arg_value]
|
|
89
|
+
when :boolean
|
|
90
|
+
ret[spec[:key]] = true
|
|
91
|
+
else
|
|
92
|
+
raise "Error"
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# check for missing required arguments
|
|
97
|
+
specs.values.each do |spec|
|
|
98
|
+
next unless spec[:type] == :required
|
|
99
|
+
next if ! spec[:multi] && ret.include?(spec[:key])
|
|
100
|
+
next if spec[:multi] && ! ret[spec[:key]].empty?
|
|
101
|
+
msg = "#{$0}: option '#{spec[:long_name]}' is required"
|
|
102
|
+
$stderr.puts msg
|
|
103
|
+
raise GetoptError.new msg
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# check for mismatched regex arguments
|
|
107
|
+
easy_specs.each do |easy_spec|
|
|
108
|
+
next unless easy_spec[:regex]
|
|
109
|
+
if easy_spec[:multi]
|
|
110
|
+
ret[easy_spec[:name]].each do |value|
|
|
111
|
+
next if value =~ /^#{easy_spec[:regex]}$/
|
|
112
|
+
msg = "#{$0}: option '#{easy_spec[:long_name]}' is invalid: #{value}"
|
|
113
|
+
$stderr.puts msg
|
|
114
|
+
raise GetoptError.new msg
|
|
115
|
+
end
|
|
116
|
+
else
|
|
117
|
+
next if ret[easy_spec[:name]] == easy_spec[:default]
|
|
118
|
+
next if ret[easy_spec[:name]] =~ /^#{easy_spec[:regex]}$/
|
|
119
|
+
msg = "#{$0}: option '#{easy_spec[:long_name]}' is invalid: #{ret[easy_spec[:name]]}"
|
|
120
|
+
$stderr.puts msg
|
|
121
|
+
raise GetoptError.new msg
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# perform conversions
|
|
126
|
+
specs.values.each do |spec|
|
|
127
|
+
next unless ret[spec[:key]].is_a? String
|
|
128
|
+
case spec[:convert]
|
|
129
|
+
when nil
|
|
130
|
+
# do nothing
|
|
131
|
+
when Symbol
|
|
132
|
+
ret[spec[:key]] = ret[spec[:key]].send spec[:convert]
|
|
133
|
+
when Method
|
|
134
|
+
ret[spec[:key]] = spec[:convert].call ret[spec[:key]]
|
|
135
|
+
else
|
|
136
|
+
raise "Don't know what to do with #{spec[:convert].class}"
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
rest = []
|
|
141
|
+
ARGV.each { |arg| rest << arg }
|
|
142
|
+
return ret, rest
|
|
143
|
+
|
|
144
|
+
rescue GetoptLong::MissingArgument
|
|
145
|
+
raise GetoptError
|
|
146
|
+
|
|
147
|
+
ensure
|
|
148
|
+
ARGV.clear
|
|
149
|
+
old_argv.each { |arg| ARGV << arg }
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
class HQ::Tools::GetoptError < StandardError
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hq-tools
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.1.0
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -97,13 +97,14 @@ email:
|
|
|
97
97
|
executables: []
|
|
98
98
|
extensions: []
|
|
99
99
|
extra_rdoc_files: []
|
|
100
|
-
files:
|
|
100
|
+
files:
|
|
101
|
+
- lib/hq/tools/getopt.rb
|
|
101
102
|
homepage: https://github.com/jamespharaoh/hq-tools
|
|
102
103
|
licenses: []
|
|
103
104
|
post_install_message:
|
|
104
105
|
rdoc_options: []
|
|
105
106
|
require_paths:
|
|
106
|
-
-
|
|
107
|
+
- lib
|
|
107
108
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
108
109
|
none: false
|
|
109
110
|
requirements:
|