falsework 1.3.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/Gemfile +1 -1
  2. data/Gemfile.lock +2 -2
  3. data/README.rdoc +6 -5
  4. data/Rakefile +14 -10
  5. data/bin/falsework +25 -25
  6. data/doc/NEWS.rdoc +18 -0
  7. data/doc/README.rdoc +6 -5
  8. data/doc/TODO.org +2 -1
  9. data/lib/falsework/cliconfig.rb +135 -0
  10. data/lib/falsework/cliutils.rb +112 -0
  11. data/lib/falsework/meta.rb +1 -1
  12. data/lib/falsework/mould.rb +23 -20
  13. data/lib/falsework/templates/{ruby-naive → ruby-cli}/#config.yaml +0 -0
  14. data/lib/falsework/templates/{ruby-naive → ruby-cli}/.gitignore.#erb +0 -0
  15. data/lib/falsework/templates/{ruby-naive → ruby-cli}/Gemfile +1 -1
  16. data/lib/falsework/templates/{ruby-naive/doc → ruby-cli}/README.rdoc +1 -1
  17. data/lib/falsework/templates/{ruby-naive → ruby-cli}/Rakefile +0 -0
  18. data/lib/falsework/templates/ruby-cli/bin/%%@project%% +26 -0
  19. data/lib/falsework/templates/{ruby-naive → ruby-cli}/doc/#doc.rdoc +1 -1
  20. data/lib/falsework/templates/{ruby-naive → ruby-cli}/doc/LICENSE +0 -0
  21. data/lib/falsework/templates/{ruby-naive → ruby-cli}/doc/NEWS.rdoc +0 -0
  22. data/lib/falsework/templates/{ruby-naive → ruby-cli/doc}/README.rdoc +1 -1
  23. data/lib/falsework/templates/{ruby-naive → ruby-cli}/etc/%%@project%%.yaml +0 -0
  24. data/lib/falsework/templates/ruby-cli/lib/%%@project%%/cliconfig.rb +137 -0
  25. data/lib/falsework/templates/ruby-cli/lib/%%@project%%/cliutils.rb +114 -0
  26. data/lib/falsework/templates/{ruby-naive → ruby-cli}/lib/%%@project%%/meta.rb +0 -0
  27. data/lib/falsework/templates/{ruby-naive → ruby-cli}/test/helper.rb +1 -1
  28. data/lib/falsework/templates/{ruby-naive/test/helper_trestle.rb → ruby-cli/test/helper_cliutils.rb} +4 -4
  29. data/lib/falsework/templates/{ruby-naive → ruby-cli}/test/rake_git.rb +2 -2
  30. data/lib/falsework/templates/{ruby-naive → ruby-cli}/test/test_%%@project%%.rb +0 -0
  31. data/test/helper.rb +1 -1
  32. data/test/{helper_trestle.rb → helper_cliutils.rb} +3 -3
  33. data/test/rake_erb_templates.rb +3 -3
  34. data/test/rake_git.rb +1 -1
  35. data/test/templates/config-02.yaml +2 -0
  36. data/test/test_cl.rb +9 -5
  37. data/test/test_exe.rb +26 -21
  38. metadata +31 -26
  39. data/lib/falsework/templates/ruby-naive/bin/%%@project%% +0 -31
  40. data/lib/falsework/templates/ruby-naive/lib/%%@project%%/trestle.rb +0 -230
  41. data/lib/falsework/trestle.rb +0 -228
@@ -1,228 +0,0 @@
1
- # :erb:
2
- require 'yaml'
3
- require 'shellwords.rb'
4
- require 'optparse'
5
- require 'pp'
6
- require 'open4'
7
-
8
- require_relative 'meta'
9
-
10
- module Falsework
11
- # A common routines from falsework with love.
12
- class Trestle
13
-
14
- # Execute _cmd_ and return a list [exit_status, stderr,
15
- # stdout]. Very handy.
16
- def self.cmd_run(cmd)
17
- so = sr = ''
18
- status = Open4::popen4(cmd) { |pid, stdin, stdout, stderr|
19
- so = stdout.read
20
- sr = stderr.read
21
- }
22
- [status.exitstatus, sr, so]
23
- end
24
-
25
- # Return a directory with program libraries.
26
- def self.gem_libdir
27
- t = ["#{File.dirname(File.realpath($0))}/../lib/#{Falsework::Meta::NAME}",
28
- "#{Gem.dir}/gems/#{Falsework::Meta::NAME}-#{Falsework::Meta::VERSION}/lib/#{Falsework::Meta::NAME}",
29
- "lib/#{Falsework::Meta::NAME}"]
30
- t.each {|i| return i if File.readable?(i) }
31
- fail "all paths are invalid: #{t}"
32
- end
33
-
34
- # Analogue to shell command +which+.
35
- def self.in_path?(file)
36
- return true if file =~ %r%\A/% and File.exist? file
37
-
38
- ENV['PATH'].split(File::PATH_SEPARATOR).any? do |path|
39
- File.exist? File.join(path, file)
40
- end
41
- end
42
-
43
- # Print an error message _t_ and exit if _ec_ > 0.
44
- def self.errx(ec, t)
45
- $stderr.puts File.basename($0) + ' error: ' + t.to_s
46
- exit ec if ec > 0
47
- end
48
-
49
- # Print a warning.
50
- def self.warnx(t)
51
- $stderr.puts File.basename($0) + ' warning: ' + t.to_s
52
- end
53
-
54
- # #veputs uses this to decide to put a newline or not to put.
55
- NNL_MARK = '__NNL__'
56
-
57
- # Use this in your CL options to check if modifying some variable is
58
- # not an idempotent act.
59
- attr_reader :cl_opt_protect
60
-
61
- # [conf] Typically must be a reference to some global variable.
62
- def initialize(conf)
63
- @conf = conf
64
- @conf[:verbose] = 0
65
- @conf[:banner] = "Usage: #{File.basename($0)} [options]"
66
- @conf[:config] = Meta::NAME + '.yaml'
67
- @conf[:config_dirs] = [ENV['HOME']+'/.'+Meta::NAME,
68
- File.absolute_path("#{File.dirname(File.realpath($0))}/../etc"),
69
- '/usr/etc', '/usr/local/etc', '/etc',
70
- "#{Gem.dir}/gems/#{Meta::NAME}-#{Meta::VERSION}/etc"
71
- ]
72
- @conf[:config_env] = [Meta::NAME.upcase + '_CONF']
73
-
74
- @cl_parsing_times = 0 # not used
75
- @cl_opt_protect = false
76
- end
77
-
78
- # [level] A verbose level.
79
- # [t] A string to print.
80
- #
81
- # Don't print _t_ with a newline if it contains NNL_MARK at the end.
82
- def veputs(level, t)
83
- t = t.dup
84
- nnl = nil
85
- if t.match(/#{NNL_MARK}$/)
86
- t.sub!(/#{$&}/, '')
87
- nnl = 1
88
- end
89
-
90
- if @conf[:verbose] >= level
91
- nnl ? print(t) : print("#{t}\n")
92
- $stdout.flush
93
- end
94
- end
95
-
96
- # Run all configuration parsing in a batch.
97
- #
98
- # [rvars] A list of variable names which must be in the
99
- # configuration file.
100
- #
101
- # If no block is given, only standard CL options will be analysed.
102
- def config_parse(rvars, &block)
103
- cb = ->(b, src) {
104
- if b
105
- block.call src
106
- else
107
- # very basic default options
108
- cl_parse(src, nil, true)
109
- end
110
- }
111
-
112
- # 1. parse env
113
- @conf[:config_env].each {|i|
114
- # puts '0 run:'
115
- cb.call(block_given?, ENV[i].shellsplit) if ENV.key?(i)
116
- }
117
-
118
- # 2. parse CL in case of '--config' option
119
- # puts "\n1 run"
120
- @cl_opt_protect = true
121
- cb.call(block_given?, ARGV.dup)
122
- @cl_opt_protect = false
123
-
124
- # 3. load the configuration file & do the final CL parsing
125
- begin
126
- # puts "\n2 run"
127
- r = config_flat_load(rvars)
128
- rescue
129
- Trestle.errx(1, "cannot load config: #{Trestle.get_backtrace}")
130
- end
131
- veputs(1, "OK") if r
132
- cb.call(block_given?, ARGV)
133
- end
134
-
135
- # Load a config file immediately if it contains '/' in its name,
136
- # otherwise search through several dirs for it.
137
- #
138
- # [rvars] a list of requied variables in the config
139
- #
140
- # Return a loaded filename or nil on error.
141
- def config_flat_load(rvars)
142
- p = ->(f) {
143
- veputs(1, "Loading #{f}... " + NNL_MARK)
144
- if File.file?(f)
145
- begin
146
- myconf = YAML.load_file(f)
147
- rescue
148
- abort("cannot parse #{f}: #{$!}")
149
- end
150
- rvars.each { |i|
151
- fail "missing or nil '#{i}' in #{f}" if ! myconf.key?(i.to_sym) || ! myconf[i.to_sym]
152
- }
153
- @conf.merge!(myconf)
154
- return @conf[:config]
155
- end
156
-
157
- veputs(1, "FAILED")
158
- return nil
159
- }
160
-
161
- if @conf[:config].index('/')
162
- return p.call(@conf[:config])
163
- else
164
- @conf[:config_dirs].each {|dir|
165
- return dir+'/'+@conf[:config] if p.call(dir + '/' + @conf[:config])
166
- }
167
- end
168
-
169
- return nil
170
- end
171
-
172
-
173
- # Parses CL-like options.
174
- #
175
- # [src] An array of options (usually +ARGV+).
176
- #
177
- # If _o_ is non nil function parses _src_ immediately, otherwise it
178
- # only creates +OptionParser+ object and return it (if _simple_ is
179
- # false).
180
- def cl_parse(src, o = nil, simple = false)
181
- if ! o then
182
- # puts "NEW o (#{cl_opt_protect})" + src.to_s
183
- o = OptionParser.new
184
- o.banner = @conf[:banner]
185
- o.on('-v', 'Be more verbose.') { |i|
186
- # puts "cl_parsing_times "+cl_parsing_times.to_s
187
- @conf[:verbose] += 1 unless cl_opt_protect
188
- }
189
- o.on('-V', 'Show version & exit.') { |i|
190
- puts Meta::VERSION
191
- exit 0
192
- }
193
- o.on('--config NAME', "Set a config name (default is #{@conf[:config]}).") {|i|
194
- @conf[:config] = i
195
- }
196
- o.on('--config-dirs', 'Show possible config locations.') {
197
- mark = false
198
- @conf[:config_dirs].each { |idx|
199
- f = idx + '/' + @conf[:config]
200
- if File.readable?(f) && !mark
201
- puts "* " + f
202
- mark = true
203
- else
204
- puts " " + f
205
- end
206
- }
207
- exit 0
208
- }
209
-
210
- return o if ! simple
211
- end
212
-
213
- begin
214
- o.parse!(src)
215
- @cl_parsing_times += 1
216
- rescue
217
- Trestle.errx(1, $!.to_s)
218
- end
219
- end
220
-
221
- # A handy proc that return a nice formatted current global
222
- # backtrace.
223
- def self.get_backtrace
224
- "#{$!}\n\nBacktrace:\n\n#{$!.backtrace.join("\n")}"
225
- end
226
-
227
- end # trestle
228
- end