codestrap 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.
Files changed (150) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.travis.yml +4 -0
  4. data/.yardopts +3 -0
  5. data/BOILERPLATE.md +151 -0
  6. data/CODESTRAPFILE.md +28 -0
  7. data/Gemfile +6 -0
  8. data/LICENSE.txt +13 -0
  9. data/README.md +69 -0
  10. data/Rakefile +51 -0
  11. data/bin/strap +8 -0
  12. data/bin/upstrap +8 -0
  13. data/codestrap.gemspec +37 -0
  14. data/config/projects/codestrap.rb +22 -0
  15. data/config/software/codestrap.rb +20 -0
  16. data/config/software/ruby.rb +247 -0
  17. data/config/software/zlib.rb +86 -0
  18. data/features/client.feature +99 -0
  19. data/features/fixtures/client/home/codestrap/bin/.empty +0 -0
  20. data/features/fixtures/client/home/codestrap/content/bash.erb +3 -0
  21. data/features/fixtures/client/home/codestrap/content/gem/dir/file +0 -0
  22. data/features/fixtures/client/home/codestrap/content/gem/dir/template +3 -0
  23. data/features/fixtures/client/home/codestrap/content/gem/file +1 -0
  24. data/features/fixtures/client/home/codestrap/content/gem/template +3 -0
  25. data/features/fixtures/client/home/codestrap/content/local_remote.erb +1 -0
  26. data/features/fixtures/client/home/codestrap/content/local_remote/dir/file +0 -0
  27. data/features/fixtures/client/home/codestrap/content/local_remote/dir/template +3 -0
  28. data/features/fixtures/client/home/codestrap/content/local_remote/file +1 -0
  29. data/features/fixtures/client/home/codestrap/content/local_remote/template +3 -0
  30. data/features/fixtures/client/home/codestrap/objects/local.json +3 -0
  31. data/features/fixtures/client/output/.empty +0 -0
  32. data/features/fixtures/client/var/lib/codestrap/bin/.empty +0 -0
  33. data/features/fixtures/client/var/lib/codestrap/content/bashremote.erb +3 -0
  34. data/features/fixtures/client/var/lib/codestrap/content/gemremote/dir/file +0 -0
  35. data/features/fixtures/client/var/lib/codestrap/content/gemremote/dir/template +3 -0
  36. data/features/fixtures/client/var/lib/codestrap/content/gemremote/file +0 -0
  37. data/features/fixtures/client/var/lib/codestrap/content/gemremote/template +3 -0
  38. data/features/fixtures/client/var/lib/codestrap/content/remote_local.erb +1 -0
  39. data/features/fixtures/client/var/lib/codestrap/content/remote_local/dir/file +0 -0
  40. data/features/fixtures/client/var/lib/codestrap/content/remote_local/dir/template +3 -0
  41. data/features/fixtures/client/var/lib/codestrap/content/remote_local/file +1 -0
  42. data/features/fixtures/client/var/lib/codestrap/content/remote_local/template +3 -0
  43. data/features/fixtures/client/var/lib/codestrap/content/remote_remote.erb +1 -0
  44. data/features/fixtures/client/var/lib/codestrap/content/remote_remote/dir/file +0 -0
  45. data/features/fixtures/client/var/lib/codestrap/content/remote_remote/dir/template +3 -0
  46. data/features/fixtures/client/var/lib/codestrap/content/remote_remote/file +0 -0
  47. data/features/fixtures/client/var/lib/codestrap/content/remote_remote/template +3 -0
  48. data/features/fixtures/client/var/lib/codestrap/objects/remote.json +3 -0
  49. data/features/fixtures/logging/home/logging/codestrap/bin/stubdirectory/.empty +0 -0
  50. data/features/fixtures/logging/home/logging/codestrap/bin/stubnotlink +0 -0
  51. data/features/fixtures/logging/home/logging/codestrap/content/.empty +0 -0
  52. data/features/fixtures/logging/home/logging/codestrap/objects/.empty +0 -0
  53. data/features/fixtures/server/mixed/var/lib/stub/content/address.erb +3 -0
  54. data/features/fixtures/server/mixed/var/lib/stub/content/cell.erb +3 -0
  55. data/features/fixtures/server/mixed/var/lib/stub/content/email.erb +3 -0
  56. data/features/fixtures/server/mixed/var/lib/stub/content/mobile.erb +3 -0
  57. data/features/fixtures/server/mixed/var/lib/stub/content/name.erb +3 -0
  58. data/features/fixtures/server/mixed/var/lib/stub/content/phone.erb +3 -0
  59. data/features/fixtures/server/mixed/var/lib/stub/content/puppetmodule/Modulefile +12 -0
  60. data/features/fixtures/server/mixed/var/lib/stub/content/puppetmodule/README +17 -0
  61. data/features/fixtures/server/mixed/var/lib/stub/content/puppetmodule/manifests/init.pp +42 -0
  62. data/features/fixtures/server/mixed/var/lib/stub/content/puppetmodule/spec/spec_helper.rb +18 -0
  63. data/features/fixtures/server/mixed/var/lib/stub/content/puppetmodule/tests/init.pp +13 -0
  64. data/features/fixtures/server/mixed/var/lib/stub/objects/contact.json +8 -0
  65. data/features/fixtures/server/mixed/var/lib/stub/objects/shadow/contact.json +8 -0
  66. data/features/fixtures/strap/projects/etc/.empty +0 -0
  67. data/features/fixtures/strap/projects/home/user/dir/bin/.empty +0 -0
  68. data/features/fixtures/strap/projects/home/user/dir/content/puppetmodule/Modulefile +12 -0
  69. data/features/fixtures/strap/projects/home/user/dir/content/puppetmodule/README +17 -0
  70. data/features/fixtures/strap/projects/home/user/dir/content/puppetmodule/manifests/:stub:project.name:/subclass.pp +3 -0
  71. data/features/fixtures/strap/projects/home/user/dir/content/puppetmodule/manifests/init.pp +42 -0
  72. data/features/fixtures/strap/projects/home/user/dir/content/puppetmodule/spec/spec_helper.rb +18 -0
  73. data/features/fixtures/strap/projects/home/user/dir/content/puppetmodule/tests/init.pp +13 -0
  74. data/features/fixtures/strap/projects/home/user/dir/objects/contact.json +8 -0
  75. data/features/fixtures/strap/projects/home/user/dir/objects/shadow/contact.json +8 -0
  76. data/features/fixtures/strap/projects/output/.empty +0 -0
  77. data/features/fixtures/stub/contact/etc/.empty +0 -0
  78. data/features/fixtures/stub/contact/home/user/dir/bin/.empty +0 -0
  79. data/features/fixtures/stub/contact/home/user/dir/content/address.erb +3 -0
  80. data/features/fixtures/stub/contact/home/user/dir/content/cell.erb +3 -0
  81. data/features/fixtures/stub/contact/home/user/dir/content/email.erb +3 -0
  82. data/features/fixtures/stub/contact/home/user/dir/content/mobile.erb +3 -0
  83. data/features/fixtures/stub/contact/home/user/dir/content/name.erb +3 -0
  84. data/features/fixtures/stub/contact/home/user/dir/content/phone.erb +3 -0
  85. data/features/fixtures/stub/contact/home/user/dir/objects/contact.json +8 -0
  86. data/features/fixtures/stub/contact/home/user/dir/objects/shadow/contact.json +8 -0
  87. data/features/fixtures/stub/contact/output/.empty +0 -0
  88. data/features/fixtures/stub/date/etc/.empty +0 -0
  89. data/features/fixtures/stub/date/home/user/stub/bin/.empty +0 -0
  90. data/features/fixtures/stub/date/home/user/stub/content/day.erb +3 -0
  91. data/features/fixtures/stub/date/home/user/stub/content/hour.erb +3 -0
  92. data/features/fixtures/stub/date/home/user/stub/content/minute.erb +3 -0
  93. data/features/fixtures/stub/date/home/user/stub/content/month.erb +3 -0
  94. data/features/fixtures/stub/date/home/user/stub/content/second.erb +3 -0
  95. data/features/fixtures/stub/date/home/user/stub/content/year.erb +3 -0
  96. data/features/fixtures/stub/date/home/user/stub/objects/.empty +0 -0
  97. data/features/fixtures/stub/date/output/.empty +0 -0
  98. data/features/fixtures/stub/script/etc/.empty +0 -0
  99. data/features/fixtures/stub/script/home/user/stub/bin/.empty +0 -0
  100. data/features/fixtures/stub/script/home/user/stub/content/credentials.erb +6 -0
  101. data/features/fixtures/stub/script/home/user/stub/objects/credentials.rb +11 -0
  102. data/features/fixtures/stub/script/output/.empty +0 -0
  103. data/features/logging.feature +39 -0
  104. data/features/object_scripts.feature +13 -0
  105. data/features/server.feature +36 -0
  106. data/features/step_definitions/client_steps.rb +99 -0
  107. data/features/step_definitions/logging_steps.rb +65 -0
  108. data/features/step_definitions/object_scripts_steps.rb +26 -0
  109. data/features/step_definitions/server_steps.rb +112 -0
  110. data/features/step_definitions/strap_steps.rb +69 -0
  111. data/features/step_definitions/stub_option_simple_steps.rb +31 -0
  112. data/features/step_definitions/stub_steps.rb +94 -0
  113. data/features/strap.feature +34 -0
  114. data/features/stub.feature +157 -0
  115. data/features/stub_option_simple.feature +14 -0
  116. data/features/stub_packages.feature +15 -0
  117. data/features/support/env.rb +197 -0
  118. data/lib/codestrap.rb +415 -0
  119. data/lib/codestrap/cli.rb +76 -0
  120. data/lib/codestrap/client.rb +179 -0
  121. data/lib/codestrap/config.rb +199 -0
  122. data/lib/codestrap/log.rb +56 -0
  123. data/lib/codestrap/mixin.rb +20 -0
  124. data/lib/codestrap/namespace.rb +19 -0
  125. data/lib/codestrap/object/abstract.rb +33 -0
  126. data/lib/codestrap/object/factory.rb +86 -0
  127. data/lib/codestrap/object/standard/datetime.rb +24 -0
  128. data/lib/codestrap/object/standard/files.rb +40 -0
  129. data/lib/codestrap/object/standard/project.rb +33 -0
  130. data/lib/codestrap/object/standard/rest.rb +30 -0
  131. data/lib/codestrap/patch.rb +122 -0
  132. data/lib/codestrap/server/rest.rb +177 -0
  133. data/lib/codestrap/server/version.rb +5 -0
  134. data/lib/codestrap/strap/abstract.rb +135 -0
  135. data/lib/codestrap/strap/factory.rb +85 -0
  136. data/lib/codestrap/strap/standard.rb +95 -0
  137. data/lib/codestrap/stub/abstract.rb +156 -0
  138. data/lib/codestrap/stub/factory.rb +87 -0
  139. data/lib/codestrap/stub/standard.rb +23 -0
  140. data/lib/codestrap/version.rb +3 -0
  141. data/omnibus.rb +53 -0
  142. data/package-scripts/codestrap/postinst +25 -0
  143. data/package-scripts/codestrap/postrm +17 -0
  144. data/package-scripts/codestrap/preinst +7 -0
  145. data/package-scripts/codestrap/prerm +15 -0
  146. data/resources/codestrap/pkg/background.png +0 -0
  147. data/resources/codestrap/pkg/distribution.xml.erb +22 -0
  148. data/resources/codestrap/pkg/license.html.erb +202 -0
  149. data/resources/codestrap/pkg/welcome.html.erb +7 -0
  150. metadata +466 -0
data/lib/codestrap.rb ADDED
@@ -0,0 +1,415 @@
1
+ require 'etc'
2
+ require 'logger'
3
+ require 'codestrap/cli'
4
+ require 'codestrap/client'
5
+ require 'codestrap/config'
6
+ require 'codestrap/log'
7
+ require 'codestrap/namespace'
8
+ require 'codestrap/object/factory'
9
+ require 'codestrap/object/standard/datetime'
10
+ require 'codestrap/strap/factory'
11
+ require 'codestrap/strap/abstract'
12
+ require 'codestrap/strap/standard'
13
+ require 'codestrap/stub/factory'
14
+ require 'codestrap/stub/abstract'
15
+ require 'codestrap/stub/standard'
16
+ require 'codestrap/version'
17
+
18
+ module Codestrap
19
+ class Core
20
+ # Codestrap template path
21
+ #
22
+ # @return [String]
23
+ attr_reader :template
24
+
25
+ # Boilerplate template path
26
+ #
27
+ # @return [String]
28
+ attr_reader :project
29
+
30
+ # Command line object
31
+ #
32
+ # @return [Codestrap::Cli]
33
+ attr_accessor :cli
34
+
35
+ # List of client objects
36
+ #
37
+ # @return [Array<Codestrap::Client>]
38
+ attr_accessor :clients
39
+
40
+ # Configuration object created from Codestrapfile
41
+ #
42
+ # @return [Codestrap::Config]
43
+ attr_accessor :config
44
+
45
+ # Set stub template
46
+ # @param [String] template
47
+ # Codestrap name
48
+ # @return [String|nil]
49
+ # Codestrap name or nil
50
+ def template=(template)
51
+ # Local templates
52
+ @config.local.content.each do |path|
53
+ next unless File.directory? path
54
+ ['.erb'].each do |prefix|
55
+ templatepath = File.join(path, "#{template}#{prefix}")
56
+ next unless File.exist? templatepath
57
+ @template = templatepath
58
+ return @template
59
+ end
60
+ end
61
+
62
+ # Remote templates
63
+ @clients.each do |client|
64
+ templatepath = client.getstub(template)
65
+ next unless templatepath and File.exist? templatepath
66
+ @template = templatepath
67
+ return @template
68
+ end
69
+
70
+ logger.error :STUBMISSING, template
71
+ exit 1
72
+ end
73
+
74
+ # Set strap project
75
+ # @param [String] project
76
+ # Boilerplate name
77
+ # @return [String|nil]
78
+ # Boilerplate name or nil
79
+ def project=(project)
80
+ # Local templates
81
+ @config.local.content.each do |path|
82
+ next unless File.directory? path
83
+ projectpath = File.join(path, project)
84
+ next unless File.directory?(projectpath)
85
+ @project = projectpath
86
+ return @project
87
+ end
88
+
89
+ # Remote templates
90
+ @clients.each do |client|
91
+ projectpath = client.getstrap(project)
92
+ next unless projectpath and File.exist? projectpath
93
+ @project = projectpath
94
+ return @project
95
+ end
96
+
97
+ logger.error :STRAPMISSING, project
98
+ exit 1
99
+ end
100
+
101
+ # Logging object
102
+ # @return [Codestrap::Log]
103
+ def logger
104
+ self.class.logger
105
+ end
106
+
107
+ # Logging object
108
+ # @return [Codestrap::Log]
109
+ def self.logger
110
+ @@logger ||= begin
111
+ logger = Codestrap::Log.new
112
+ @@logger = logger
113
+ end
114
+ end
115
+
116
+ def initialize(argv=nil)
117
+ # CLI options
118
+ if argv
119
+ self.cli = Codestrap::Cli.new argv
120
+ self.cli.options
121
+ end
122
+
123
+ # Config
124
+ @config = Codestrap::Config.new
125
+
126
+ case @config.local.urls
127
+ when Array
128
+ @config.local.urls.each do |url|
129
+ @clients ||= []
130
+ @clients << Codestrap::Client.new(url)
131
+ end
132
+ when String
133
+ @clients ||= []
134
+ @clients << Codestrap::Client.new(@config.local.urls)
135
+ when NilClass
136
+ else
137
+ raise Exception, 'Unknown data structure'
138
+ end
139
+ self
140
+ end
141
+
142
+ def execute!
143
+ # Run type
144
+ case
145
+ when cli.command =~ /stub(.+)$/
146
+ self.template = $1
147
+ stub
148
+ when cli.command =~ /strap(.+)$/
149
+ self.project = $1
150
+ strap
151
+ when self.cli.options.generate
152
+ strap_links
153
+ else
154
+ logger.error :INVALIDCMD, cli.command
155
+ exit 1
156
+ end
157
+
158
+ exit 0
159
+ end
160
+
161
+ def stub(dst=nil, src=nil)
162
+ # Create objects
163
+ obj = Codestrap::Object::Factory.new
164
+ obj.dirs = @config.local.objects
165
+ obj.clients = @clients
166
+ obj.cli = @cli
167
+ obj.config = @config
168
+
169
+ argv = self.cli.argv
170
+
171
+ # Render setup
172
+ renderer = Codestrap::Stub::Factory.new('Standard').construct(argv)
173
+ renderer.objects = obj
174
+ renderer.src = src || self.template
175
+ renderer.dst = dst || self.cli.argv[0]
176
+ renderer.pre
177
+ renderer.execute
178
+ renderer.post
179
+ renderer.to_disk
180
+ end
181
+
182
+ def strap(dst=nil, src=nil)
183
+ # Create objects
184
+ obj = Codestrap::Object::Factory.new
185
+ obj.dirs = @config.local.objects
186
+ obj.clients = @clients
187
+ obj.cli = @cli
188
+ obj.config = @config
189
+
190
+ argv = self.cli.argv
191
+ renderer = Codestrap::Strap::Factory.new('Standard').construct(argv)
192
+ renderer.ignore = @config.local.ignore
193
+ renderer.objects = obj
194
+ renderer.src = src || self.project
195
+ renderer.dst = dst || self.cli.argv[0]
196
+ renderer.pre
197
+ renderer.execute
198
+ renderer.post
199
+ renderer.to_disk
200
+ end
201
+
202
+ def strap_links
203
+ # FixMe - Move to Codestrap::Log
204
+ unless cli.command =~ /^strap$/
205
+ logger.error(:LINKTARGET, cli.command, 'strap')
206
+ exit 1
207
+ end
208
+
209
+ # stub templates
210
+ newtemplates = list_stubs.map { |f| File.basename(f, '.erb') } - list_cmds.select { |f| f =~ /^stub/ }.map { |f| f =~ /^stub(.+)$/; $1 }
211
+
212
+ newtemplates.each do |file|
213
+ link = File.expand_path(File.join(@config.local.links, 'stub' + file))
214
+ if File.symlink?(link) and File.exist?(File.readlink(link))
215
+ next
216
+ elsif File.symlink?(link)
217
+ File.unlink link
218
+ end
219
+
220
+ File.symlink cli.abspath, link
221
+ end
222
+
223
+ # strap templates
224
+ newprojects = list_straps - list_cmds.select { |f| f =~ /^strap/ }.map { |f| f =~ /^strap(.+)$/; $1 }
225
+
226
+ newprojects.each do |project|
227
+ link = File.expand_path File.join(@config.local.links, 'strap' + project)
228
+ if File.symlink?(link) and File.exist?(File.readlink(link))
229
+ next
230
+ elsif File.symlink?(link)
231
+ File.unlink link
232
+ end
233
+
234
+ File.symlink cli.abspath, link
235
+ end
236
+ end
237
+
238
+ # Generate strap metadata
239
+ #
240
+ # @param [String] name
241
+ # Optional module name
242
+ # @param [Hash] options
243
+ # Flags to turn off/on metadata
244
+ # {
245
+ # :src => [true|false]
246
+ # :ftype => [true|false]
247
+ # :mode => [true|false]
248
+ # }
249
+ # @param [Array] paths
250
+ # Optional path list for content search
251
+ # @return [Hash]
252
+ # Strap directory structure metadata
253
+ # {
254
+ # 'strap_name' => {
255
+ # :files => [
256
+ # {
257
+ # :file => 'relative/tree/file/path',
258
+ # :src => '/absolute/file/source',
259
+ # :ftype => 'File type as returned by File::Stat.new(file).ftype, EG "file", "directory"'
260
+ # :mode => 'File mode as returned by File::Stat.new(file).mode'
261
+ # }
262
+ # ]
263
+ # }
264
+ # }
265
+ def strap_metadata(name=nil, options=nil, paths=@config.local.content)
266
+ # TODO - rename
267
+ tree = {}
268
+ options ||= {src: false, ftype: true, mode: true}
269
+ cur_dir = Dir.pwd
270
+ paths.each do |path|
271
+ next unless File.directory? path
272
+ Dir.chdir(path) do
273
+ Dir.entries('.').each do |mod|
274
+ next if mod =~ /^\.{1,2}$/
275
+ next unless File.directory? mod
276
+ next if name and not name.eql? mod
277
+ next if tree.has_key? mod
278
+ tree[mod] = {files: []}
279
+ Dir.chdir(mod) do
280
+ Dir.glob('**/**').each do |file|
281
+ stat = File.stat file
282
+ obj = {}
283
+ obj[:file] = file
284
+ if options[:src]
285
+ case path
286
+ when %r{^/}
287
+ obj[:src] = File.expand_path(File.join(path, mod, file))
288
+ else
289
+ obj[:src] = File.expand_path(File.join(cur_dir, path, mod, file))
290
+ end
291
+ end
292
+ obj[:ftype] = stat.ftype if options[:ftype]
293
+ obj[:mode] = sprintf('%o', stat.mode) if options[:mode]
294
+ tree[mod][:files] << obj
295
+ end
296
+ end
297
+ end
298
+ end
299
+ end
300
+ tree
301
+ end
302
+
303
+ # Generate strap metadata
304
+ #
305
+ # @param [String] name
306
+ # Optional module name
307
+ # @param [Hash] options
308
+ # Flags to turn off/on metadata
309
+ # {
310
+ # :src => [true|false]
311
+ # :ftype => [true|false]
312
+ # :mode => [true|false]
313
+ # }
314
+ # @param [Array] paths
315
+ # Optional path list for content search
316
+ # @return [Hash]
317
+ # Strap directory structure metadata
318
+ # {
319
+ # 'stub_name' => {
320
+ # :src => 'relative/tree/file/path.erb',
321
+ # :ftype => 'File type as returned by File::Stat.new(file).ftype, EG "file", "directory"'
322
+ # :mode => 'File mode as returned by File::Stat.new(file).mode'
323
+ # }
324
+ # }
325
+ def stub_metadata(name=nil, options=nil, paths=@config.local.content)
326
+ # TODO - rename
327
+ codestraps = {}
328
+ options ||= {src: false, ftype: true, mode: true}
329
+ paths.each do |path|
330
+ full_path = File.expand_path path
331
+ next unless File.directory? full_path
332
+ Dir.chdir(full_path) do
333
+ Dir.entries('.').each do |file|
334
+ next if file =~ /^\.{1,2}$/
335
+ next unless File.file? file
336
+ next if name and not name.eql? File.basename(file, '.erb')
337
+ mod = File.basename(file, '.erb')
338
+ stat = File.stat file
339
+ codestraps[mod] = {}
340
+ codestraps[mod][:src] = File.expand_path(File.join(full_path, file)) if options[:src]
341
+ codestraps[mod][:ftype] = stat.ftype if options[:ftype]
342
+ codestraps[mod][:mode] = sprintf('%o', stat.mode) if options[:mode]
343
+ end
344
+ end
345
+ end
346
+ codestraps
347
+ end
348
+
349
+ # Available codestraps from local and server
350
+ #
351
+ # @return [Array]
352
+ def list_stubs
353
+ codestraps = []
354
+ if @clients
355
+ @clients.each do |client|
356
+ codestraps ||= []
357
+ codestraps += client.stublist || []
358
+ codestraps.flatten!
359
+ end
360
+ end
361
+ @config.local.content.each do |dir|
362
+ next unless File.directory? dir
363
+ Dir.chdir(dir) do
364
+ codestraps += Dir.glob('*.erb').select { |f| File.file? f }
365
+ end
366
+ end
367
+ codestraps.uniq
368
+ end
369
+
370
+ # Available projects from local and server
371
+ #
372
+ # @return [Array]
373
+ def list_straps
374
+ straps = []
375
+ if @clients
376
+ @clients.each do |client|
377
+ straps ||= []
378
+ straps += client.straplist || []
379
+ straps.flatten!
380
+ end
381
+ end
382
+ @config.local.content.each do |dir|
383
+ next unless File.directory? dir
384
+ if File.directory? dir
385
+ Dir.chdir(dir) do
386
+ straps += Dir.glob('*').select { |f| File.directory? f }
387
+ end
388
+ end
389
+ end
390
+ straps.uniq
391
+ end
392
+
393
+ # List all stub.. and strap.. commands
394
+ #
395
+ # @return [Array]
396
+ def list_cmds
397
+ links = []
398
+ dir = @config.local.links
399
+ if File.directory? dir
400
+ Dir.chdir(dir) do
401
+ Dir.glob('*').each do |f|
402
+ next unless File.symlink? f
403
+ next unless f =~ /^(?:stub|strap)[A-Za-z0-9._-]+$/
404
+ links.push f
405
+ end
406
+ end
407
+ end
408
+ links
409
+ end
410
+
411
+ alias_method :ls_codestrap, :list_stubs
412
+ alias_method :ls_strap, :list_straps
413
+ alias_method :ls_cmd, :list_cmds
414
+ end
415
+ end
@@ -0,0 +1,76 @@
1
+ require 'ostruct'
2
+ require 'optparse'
3
+ module Codestrap
4
+ class Cli
5
+ class CodestrapPathError < Exception; end
6
+ # Calling command
7
+ # @!attribute [rw] command
8
+ # @return [String]
9
+ attr_accessor :command
10
+
11
+ # Same as ARGV
12
+ # @!attribute [rw] argv
13
+ # @return [String]
14
+ attr_accessor :argv
15
+
16
+ # Absolute path of calling command
17
+ #
18
+ # @param [String] path
19
+ # Path to command
20
+ # @return [String]
21
+ # Absolute path to command
22
+ def abspath path=nil
23
+ return @abspath if @abspath and not path
24
+ if path =~ /\//
25
+ p = File.expand_path(path)
26
+ @abspath = p if File.exist? p
27
+ else
28
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |d|
29
+ p = File.join(d, path)
30
+ next unless d.length > 0
31
+ next unless File.exist? p
32
+ @abspath = File.expand_path(p)
33
+ break
34
+ end
35
+ end
36
+ if @abspath
37
+ @abspath
38
+ else
39
+ raise CodestrapPathError, "Could not find #{path}"
40
+ end
41
+ end
42
+
43
+ def initialize argv
44
+ self.abspath(argv.shift)
45
+ @command = File.basename self.abspath
46
+ @argv = argv
47
+ end
48
+
49
+ def options
50
+ @options ||= (
51
+ options = OpenStruct.new
52
+ options.generate = false
53
+ OptionParser.new do |opts|
54
+ opts.banner = "Usage: #{self.command} [-?|-h|--help]"
55
+ opts.separator ''
56
+ opts.separator 'Specific options:'
57
+
58
+ opts.on('--version', 'Show version') do
59
+ puts Codestrap::VERSION
60
+ exit 0
61
+ end
62
+
63
+ opts.on('-?', '-h', '--help', 'Show this message') do
64
+ puts opts
65
+ exit 0
66
+ end
67
+
68
+ opts.on('-g', '--generate', 'Generate links') do
69
+ options.generate = true
70
+ end
71
+ end.parse!(self.argv)
72
+ options
73
+ )
74
+ end
75
+ end
76
+ end