codestrap 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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