rubycas-client 2.2.1 → 2.3.0.rc1

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 (57) hide show
  1. data/Gemfile +13 -0
  2. data/Gemfile.lock +30 -0
  3. data/History.txt +21 -0
  4. data/README.rdoc +24 -20
  5. data/Rakefile +43 -54
  6. data/VERSION +1 -0
  7. data/examples/rails/README +16 -0
  8. data/examples/rails/app/controllers/advanced_example_controller.rb +31 -0
  9. data/examples/rails/app/controllers/application.rb +2 -0
  10. data/examples/rails/app/controllers/simple_example_controller.rb +16 -0
  11. data/examples/rails/app/views/advanced_example/index.html.erb +13 -0
  12. data/examples/rails/app/views/advanced_example/my_account.html.erb +11 -0
  13. data/examples/rails/app/views/simple_example/index.html.erb +6 -0
  14. data/examples/rails/config/boot.rb +109 -0
  15. data/examples/rails/config/environment.rb +39 -0
  16. data/examples/rails/config/environments/development.rb +17 -0
  17. data/examples/rails/config/environments/production.rb +22 -0
  18. data/examples/rails/config/environments/test.rb +22 -0
  19. data/examples/rails/config/initializers/inflections.rb +10 -0
  20. data/examples/rails/config/initializers/mime_types.rb +5 -0
  21. data/examples/rails/config/initializers/new_rails_defaults.rb +17 -0
  22. data/examples/rails/config/routes.rb +4 -0
  23. data/examples/rails/log/development.log +946 -0
  24. data/examples/rails/log/production.log +0 -0
  25. data/examples/rails/log/server.log +0 -0
  26. data/examples/rails/log/test.log +0 -0
  27. data/examples/rails/script/about +4 -0
  28. data/examples/rails/script/console +3 -0
  29. data/examples/rails/script/server +3 -0
  30. data/lib/casclient/client.rb +49 -36
  31. data/lib/casclient/frameworks/rails/cas_proxy_callback_controller.rb +5 -39
  32. data/lib/casclient/frameworks/rails/filter.rb +86 -113
  33. data/lib/casclient/responses.rb +29 -16
  34. data/lib/casclient/tickets/storage/active_record_ticket_store.rb +67 -0
  35. data/lib/casclient/tickets/storage.rb +167 -0
  36. data/lib/casclient/tickets.rb +3 -3
  37. data/lib/casclient.rb +3 -2
  38. data/lib/rubycas-client.rb +1 -5
  39. data/rails_generators/active_record_ticket_store/USAGE +9 -0
  40. data/rails_generators/active_record_ticket_store/active_record_ticket_store_generator.rb +29 -0
  41. data/rails_generators/active_record_ticket_store/templates/README +1 -0
  42. data/rails_generators/active_record_ticket_store/templates/migration.rb +24 -0
  43. data/rubycas-client.gemspec +103 -0
  44. data/test/teststrap.rb +10 -0
  45. data/test/units/casclient/frameworks/rails/filter_test.rb +184 -0
  46. metadata +148 -47
  47. data/Manifest.txt +0 -23
  48. data/examples/merb/README.textile +0 -12
  49. data/examples/merb/Rakefile +0 -35
  50. data/examples/merb/merb.thor +0 -2020
  51. data/examples/merb/merb_auth_cas.rb +0 -67
  52. data/examples/merb/spec/spec_helper.rb +0 -24
  53. data/init.rb +0 -6
  54. data/lib/casclient/frameworks/merb/filter.rb +0 -105
  55. data/lib/casclient/frameworks/merb/strategy.rb +0 -110
  56. data/lib/casclient/version.rb +0 -9
  57. data/setup.rb +0 -1585
data/Manifest.txt DELETED
@@ -1,23 +0,0 @@
1
- CHANGELOG.txt
2
- History.txt
3
- LICENSE.txt
4
- Manifest.txt
5
- README.rdoc
6
- Rakefile
7
- examples/merb/README.textile
8
- examples/merb/Rakefile
9
- examples/merb/merb.thor
10
- examples/merb/merb_auth_cas.rb
11
- examples/merb/spec/spec_helper.rb
12
- init.rb
13
- lib/casclient.rb
14
- lib/casclient/client.rb
15
- lib/casclient/frameworks/merb/filter.rb
16
- lib/casclient/frameworks/merb/strategy.rb
17
- lib/casclient/frameworks/rails/cas_proxy_callback_controller.rb
18
- lib/casclient/frameworks/rails/filter.rb
19
- lib/casclient/responses.rb
20
- lib/casclient/tickets.rb
21
- lib/casclient/version.rb
22
- lib/rubycas-client.rb
23
- setup.rb
@@ -1,12 +0,0 @@
1
- h1. Very flat merb app with casclient support
2
-
3
- Run rubycas-server or other CAS server on localhost:7777
4
-
5
- Then type this:
6
- <pre><code>
7
- merb -I merb_auth_cas.rb
8
- </code></pre>
9
-
10
- Then point your web browser to http://localhost:4000.
11
- You should be redirected to the CAS login screen, then
12
- to your Merb application showing your username.
@@ -1,35 +0,0 @@
1
- require 'rubygems'
2
- require 'rake/rdoctask'
3
-
4
- require 'merb-core'
5
- require 'merb-core/tasks/merb'
6
-
7
- include FileUtils
8
-
9
- # Load the basic runtime dependencies; this will include
10
- # any plugins and therefore plugin rake tasks.
11
- init_env = ENV['MERB_ENV'] || 'rake'
12
- Merb.load_dependencies(:environment => init_env)
13
-
14
- # Get Merb plugins and dependencies
15
- Merb::Plugins.rakefiles.each { |r| require r }
16
-
17
- # Load any app level custom rakefile extensions from lib/tasks
18
- tasks_path = File.join(File.dirname(__FILE__), "lib", "tasks")
19
- rake_files = Dir["#{tasks_path}/*.rake"]
20
- rake_files.each{|rake_file| load rake_file }
21
-
22
- desc "Start runner environment"
23
- task :merb_env do
24
- Merb.start_environment(:environment => init_env, :adapter => 'runner')
25
- end
26
-
27
- require 'spec/rake/spectask'
28
- require 'merb-core/test/tasks/spectasks'
29
- desc 'Default: run spec examples'
30
- task :default => 'spec'
31
-
32
- ##############################################################################
33
- # ADD YOUR CUSTOM TASKS IN /lib/tasks
34
- # NAME YOUR RAKE FILES file_name.rake
35
- ##############################################################################
@@ -1,2020 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'rubygems'
3
- require 'thor'
4
- require 'fileutils'
5
- require 'yaml'
6
-
7
- # Important - don't change this line or its position
8
- MERB_THOR_VERSION = '0.2.1'
9
-
10
- ##############################################################################
11
-
12
- module ColorfulMessages
13
-
14
- # red
15
- def error(*messages)
16
- puts messages.map { |msg| "\033[1;31m#{msg}\033[0m" }
17
- end
18
-
19
- # yellow
20
- def warning(*messages)
21
- puts messages.map { |msg| "\033[1;33m#{msg}\033[0m" }
22
- end
23
-
24
- # green
25
- def success(*messages)
26
- puts messages.map { |msg| "\033[1;32m#{msg}\033[0m" }
27
- end
28
-
29
- alias_method :message, :success
30
-
31
- # magenta
32
- def note(*messages)
33
- puts messages.map { |msg| "\033[1;35m#{msg}\033[0m" }
34
- end
35
-
36
- # blue
37
- def info(*messages)
38
- puts messages.map { |msg| "\033[1;34m#{msg}\033[0m" }
39
- end
40
-
41
- end
42
-
43
- ##############################################################################
44
-
45
- require 'rubygems/dependency_installer'
46
- require 'rubygems/uninstaller'
47
- require 'rubygems/dependency'
48
-
49
- module GemManagement
50
-
51
- include ColorfulMessages
52
-
53
- # Install a gem - looks remotely and local gem cache;
54
- # won't process rdoc or ri options.
55
- def install_gem(gem, options = {})
56
- refresh = options.delete(:refresh) || []
57
- from_cache = (options.key?(:cache) && options.delete(:cache))
58
- if from_cache
59
- install_gem_from_cache(gem, options)
60
- else
61
- version = options.delete(:version)
62
- Gem.configuration.update_sources = false
63
-
64
- # Limit source index to install dir
65
- update_source_index(options[:install_dir]) if options[:install_dir]
66
-
67
- installer = Gem::DependencyInstaller.new(options.merge(:user_install => false))
68
-
69
- # Force-refresh certain gems by excluding them from the current index
70
- if !options[:ignore_dependencies] && refresh.respond_to?(:include?) && !refresh.empty?
71
- source_index = installer.instance_variable_get(:@source_index)
72
- source_index.gems.each do |name, spec|
73
- source_index.gems.delete(name) if refresh.include?(spec.name)
74
- end
75
- end
76
-
77
- exception = nil
78
- begin
79
- installer.install gem, version
80
- rescue Gem::InstallError => e
81
- exception = e
82
- rescue Gem::GemNotFoundException => e
83
- if from_cache && gem_file = find_gem_in_cache(gem, version)
84
- puts "Located #{gem} in gem cache..."
85
- installer.install gem_file
86
- else
87
- exception = e
88
- end
89
- rescue => e
90
- exception = e
91
- end
92
- if installer.installed_gems.empty? && exception
93
- error "Failed to install gem '#{gem} (#{version || 'any version'})' (#{exception.message})"
94
- end
95
- ensure_bin_wrapper_for_installed_gems(installer.installed_gems, options)
96
- installer.installed_gems.each do |spec|
97
- success "Successfully installed #{spec.full_name}"
98
- end
99
- return !installer.installed_gems.empty?
100
- end
101
- end
102
-
103
- # Install a gem - looks in the system's gem cache instead of remotely;
104
- # won't process rdoc or ri options.
105
- def install_gem_from_cache(gem, options = {})
106
- version = options.delete(:version)
107
- Gem.configuration.update_sources = false
108
- installer = Gem::DependencyInstaller.new(options.merge(:user_install => false))
109
- exception = nil
110
- begin
111
- if gem_file = find_gem_in_cache(gem, version)
112
- puts "Located #{gem} in gem cache..."
113
- installer.install gem_file
114
- else
115
- raise Gem::InstallError, "Unknown gem #{gem}"
116
- end
117
- rescue Gem::InstallError => e
118
- exception = e
119
- end
120
- if installer.installed_gems.empty? && exception
121
- error "Failed to install gem '#{gem}' (#{e.message})"
122
- end
123
- ensure_bin_wrapper_for_installed_gems(installer.installed_gems, options)
124
- installer.installed_gems.each do |spec|
125
- success "Successfully installed #{spec.full_name}"
126
- end
127
- end
128
-
129
- # Install a gem from source - builds and packages it first then installs.
130
- #
131
- # Examples:
132
- # install_gem_from_source(source_dir, :install_dir => ...)
133
- # install_gem_from_source(source_dir, gem_name)
134
- # install_gem_from_source(source_dir, :skip => [...])
135
- def install_gem_from_source(source_dir, *args)
136
- installed_gems = []
137
- opts = args.last.is_a?(Hash) ? args.pop : {}
138
- Dir.chdir(source_dir) do
139
- gem_name = args[0] || File.basename(source_dir)
140
- gem_pkg_dir = File.join(source_dir, 'pkg')
141
- gem_pkg_glob = File.join(gem_pkg_dir, "#{gem_name}-*.gem")
142
- skip_gems = opts.delete(:skip) || []
143
-
144
- # Cleanup what's already there
145
- clobber(source_dir)
146
- FileUtils.mkdir_p(gem_pkg_dir) unless File.directory?(gem_pkg_dir)
147
-
148
- # Recursively process all gem packages within the source dir
149
- skip_gems << gem_name
150
- packages = package_all(source_dir, skip_gems)
151
-
152
- if packages.length == 1
153
- # The are no subpackages for the main package
154
- refresh = [gem_name]
155
- else
156
- # Gather all packages into the top-level pkg directory
157
- packages.each do |pkg|
158
- FileUtils.copy_entry(pkg, File.join(gem_pkg_dir, File.basename(pkg)))
159
- end
160
-
161
- # Finally package the main gem - without clobbering the already copied pkgs
162
- package(source_dir, false)
163
-
164
- # Gather subgems to refresh during installation of the main gem
165
- refresh = packages.map do |pkg|
166
- File.basename(pkg, '.gem')[/^(.*?)-([\d\.]+)$/, 1] rescue nil
167
- end.compact
168
-
169
- # Install subgems explicitly even if ignore_dependencies is set
170
- if opts[:ignore_dependencies]
171
- refresh.each do |name|
172
- gem_pkg = Dir[File.join(gem_pkg_dir, "#{name}-*.gem")][0]
173
- install_pkg(gem_pkg, opts)
174
- end
175
- end
176
- end
177
-
178
- ensure_bin_wrapper_for(opts[:install_dir], opts[:bin_dir], *installed_gems)
179
-
180
- # Finally install the main gem
181
- if install_pkg(Dir[gem_pkg_glob][0], opts.merge(:refresh => refresh))
182
- installed_gems = refresh
183
- else
184
- installed_gems = []
185
- end
186
- end
187
- installed_gems
188
- end
189
-
190
- def install_pkg(gem_pkg, opts = {})
191
- if (gem_pkg && File.exists?(gem_pkg))
192
- # Needs to be executed from the directory that contains all packages
193
- Dir.chdir(File.dirname(gem_pkg)) { install_gem(gem_pkg, opts) }
194
- else
195
- false
196
- end
197
- end
198
-
199
- # Uninstall a gem.
200
- def uninstall_gem(gem, options = {})
201
- if options[:version] && !options[:version].is_a?(Gem::Requirement)
202
- options[:version] = Gem::Requirement.new ["= #{options[:version]}"]
203
- end
204
- update_source_index(options[:install_dir]) if options[:install_dir]
205
- Gem::Uninstaller.new(gem, options).uninstall rescue nil
206
- end
207
-
208
- def clobber(source_dir)
209
- Dir.chdir(source_dir) do
210
- system "#{Gem.ruby} -S rake -s clobber" unless File.exists?('Thorfile')
211
- end
212
- end
213
-
214
- def package(source_dir, clobber = true)
215
- Dir.chdir(source_dir) do
216
- if File.exists?('Thorfile')
217
- thor ":package"
218
- elsif File.exists?('Rakefile')
219
- rake "clobber" if clobber
220
- rake "package"
221
- end
222
- end
223
- Dir[File.join(source_dir, 'pkg/*.gem')]
224
- end
225
-
226
- def package_all(source_dir, skip = [], packages = [])
227
- if Dir[File.join(source_dir, '{Rakefile,Thorfile}')][0]
228
- name = File.basename(source_dir)
229
- Dir[File.join(source_dir, '*', '{Rakefile,Thorfile}')].each do |taskfile|
230
- package_all(File.dirname(taskfile), skip, packages)
231
- end
232
- packages.push(*package(source_dir)) unless skip.include?(name)
233
- end
234
- packages.uniq
235
- end
236
-
237
- def rake(cmd)
238
- cmd << " >/dev/null" if $SILENT && !Gem.win_platform?
239
- system "#{Gem.ruby} -S #{which('rake')} -s #{cmd} >/dev/null"
240
- end
241
-
242
- def thor(cmd)
243
- cmd << " >/dev/null" if $SILENT && !Gem.win_platform?
244
- system "#{Gem.ruby} -S #{which('thor')} #{cmd}"
245
- end
246
-
247
- # Use the local bin/* executables if available.
248
- def which(executable)
249
- if File.executable?(exec = File.join(Dir.pwd, 'bin', executable))
250
- exec
251
- else
252
- executable
253
- end
254
- end
255
-
256
- # Partition gems into system, local and missing gems
257
- def partition_dependencies(dependencies, gem_dir)
258
- system_specs, local_specs, missing_deps = [], [], []
259
- if gem_dir && File.directory?(gem_dir)
260
- gem_dir = File.expand_path(gem_dir)
261
- ::Gem.clear_paths; ::Gem.path.unshift(gem_dir)
262
- ::Gem.source_index.refresh!
263
- dependencies.each do |dep|
264
- gemspecs = ::Gem.source_index.search(dep)
265
- local = gemspecs.reverse.find { |s| s.loaded_from.index(gem_dir) == 0 }
266
- if local
267
- local_specs << local
268
- elsif gemspecs.last
269
- system_specs << gemspecs.last
270
- else
271
- missing_deps << dep
272
- end
273
- end
274
- ::Gem.clear_paths
275
- else
276
- dependencies.each do |dep|
277
- gemspecs = ::Gem.source_index.search(dep)
278
- if gemspecs.last
279
- system_specs << gemspecs.last
280
- else
281
- missing_deps << dep
282
- end
283
- end
284
- end
285
- [system_specs, local_specs, missing_deps]
286
- end
287
-
288
- # Create a modified executable wrapper in the specified bin directory.
289
- def ensure_bin_wrapper_for(gem_dir, bin_dir, *gems)
290
- options = gems.last.is_a?(Hash) ? gems.last : {}
291
- options[:no_minigems] ||= []
292
- if bin_dir && File.directory?(bin_dir)
293
- gems.each do |gem|
294
- if gemspec_path = Dir[File.join(gem_dir, 'specifications', "#{gem}-*.gemspec")].last
295
- spec = Gem::Specification.load(gemspec_path)
296
- enable_minigems = !options[:no_minigems].include?(spec.name)
297
- spec.executables.each do |exec|
298
- executable = File.join(bin_dir, exec)
299
- message "Writing executable wrapper #{executable}"
300
- File.open(executable, 'w', 0755) do |f|
301
- f.write(executable_wrapper(spec, exec, enable_minigems))
302
- end
303
- end
304
- end
305
- end
306
- end
307
- end
308
-
309
- def ensure_bin_wrapper_for_installed_gems(gemspecs, options)
310
- if options[:install_dir] && options[:bin_dir]
311
- gems = gemspecs.map { |spec| spec.name }
312
- ensure_bin_wrapper_for(options[:install_dir], options[:bin_dir], *gems)
313
- end
314
- end
315
-
316
- private
317
-
318
- def executable_wrapper(spec, bin_file_name, minigems = true)
319
- requirements = ['minigems', 'rubygems']
320
- requirements.reverse! unless minigems
321
- try_req, then_req = requirements
322
- <<-TEXT
323
- #!/usr/bin/env ruby
324
- #
325
- # This file was generated by Merb's GemManagement
326
- #
327
- # The application '#{spec.name}' is installed as part of a gem, and
328
- # this file is here to facilitate running it.
329
-
330
- begin
331
- require '#{try_req}'
332
- rescue LoadError
333
- require '#{then_req}'
334
- end
335
-
336
- # use gems dir if ../gems exists - eg. only for ./bin/#{bin_file_name}
337
- if File.directory?(gems_dir = File.join(File.dirname(__FILE__), '..', 'gems'))
338
- $BUNDLE = true; Gem.clear_paths; Gem.path.replace([File.expand_path(gems_dir)])
339
- ENV["PATH"] = "\#{File.dirname(__FILE__)}:\#{gems_dir}/bin:\#{ENV["PATH"]}"
340
- if (local_gem = Dir[File.join(gems_dir, "specifications", "#{spec.name}-*.gemspec")].last)
341
- version = File.basename(local_gem)[/-([\\.\\d]+)\\.gemspec$/, 1]
342
- end
343
- end
344
-
345
- version ||= "#{Gem::Requirement.default}"
346
-
347
- if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
348
- version = $1
349
- ARGV.shift
350
- end
351
-
352
- gem '#{spec.name}', version
353
- load '#{bin_file_name}'
354
- TEXT
355
- end
356
-
357
- def find_gem_in_cache(gem, version)
358
- spec = if version
359
- version = Gem::Requirement.new ["= #{version}"] unless version.is_a?(Gem::Requirement)
360
- Gem.source_index.find_name(gem, version).first
361
- else
362
- Gem.source_index.find_name(gem).sort_by { |g| g.version }.last
363
- end
364
- if spec && File.exists?(gem_file = "#{spec.installation_path}/cache/#{spec.full_name}.gem")
365
- gem_file
366
- end
367
- end
368
-
369
- def update_source_index(dir)
370
- Gem.source_index.load_gems_in(File.join(dir, 'specifications'))
371
- end
372
-
373
- end
374
-
375
- ##############################################################################
376
-
377
- class SourceManager
378
-
379
- include ColorfulMessages
380
-
381
- attr_accessor :source_dir
382
-
383
- def initialize(source_dir)
384
- self.source_dir = source_dir
385
- end
386
-
387
- def clone(name, url)
388
- FileUtils.cd(source_dir) do
389
- raise "destination directory already exists" if File.directory?(name)
390
- system("git clone --depth 1 #{url} #{name}")
391
- end
392
- rescue => e
393
- error "Unable to clone #{name} repository (#{e.message})"
394
- end
395
-
396
- def update(name, url)
397
- if File.directory?(repository_dir = File.join(source_dir, name))
398
- FileUtils.cd(repository_dir) do
399
- repos = existing_repos(name)
400
- fork_name = url[/.com\/+?(.+)\/.+\.git/u, 1]
401
- if url == repos["origin"]
402
- # Pull from the original repository - no branching needed
403
- info "Pulling from origin: #{url}"
404
- system "git fetch; git checkout master; git rebase origin/master"
405
- elsif repos.values.include?(url) && fork_name
406
- # Update and switch to a remote branch for a particular github fork
407
- info "Switching to remote branch: #{fork_name}"
408
- system "git checkout -b #{fork_name} #{fork_name}/master"
409
- system "git rebase #{fork_name}/master"
410
- elsif fork_name
411
- # Create a new remote branch for a particular github fork
412
- info "Adding a new remote branch: #{fork_name}"
413
- system "git remote add -f #{fork_name} #{url}"
414
- system "git checkout -b #{fork_name} #{fork_name}/master"
415
- else
416
- warning "No valid repository found for: #{name}"
417
- end
418
- end
419
- return true
420
- else
421
- warning "No valid repository found at: #{repository_dir}"
422
- end
423
- rescue => e
424
- error "Unable to update #{name} repository (#{e.message})"
425
- return false
426
- end
427
-
428
- def existing_repos(name)
429
- repos = []
430
- FileUtils.cd(File.join(source_dir, name)) do
431
- repos = %x[git remote -v].split("\n").map { |branch| branch.split(/\s+/) }
432
- end
433
- Hash[*repos.flatten]
434
- end
435
-
436
- end
437
-
438
- ##############################################################################
439
-
440
- module MerbThorHelper
441
-
442
- attr_accessor :force_gem_dir
443
-
444
- def self.included(base)
445
- base.send(:include, ColorfulMessages)
446
- base.extend ColorfulMessages
447
- end
448
-
449
- def use_edge_gem_server
450
- ::Gem.sources << 'http://edge.merbivore.com'
451
- end
452
-
453
- def source_manager
454
- @_source_manager ||= SourceManager.new(source_dir)
455
- end
456
-
457
- def extract_repositories(names)
458
- repos = []
459
- names.each do |name|
460
- if repo_url = Merb::Source.repo(name, options[:sources])
461
- # A repository entry for this dependency exists
462
- repo = [name, repo_url]
463
- repos << repo unless repos.include?(repo)
464
- elsif (repo_name = Merb::Stack.lookup_repository_name(name)) &&
465
- (repo_url = Merb::Source.repo(repo_name, options[:sources]))
466
- # A parent repository entry for this dependency exists
467
- repo = [repo_name, repo_url]
468
- unless repos.include?(repo)
469
- puts "Found #{repo_name}/#{name} at #{repo_url}"
470
- repos << repo
471
- end
472
- end
473
- end
474
- repos
475
- end
476
-
477
- def update_dependency_repositories(dependencies)
478
- repos = extract_repositories(dependencies.map { |d| d.name })
479
- update_repositories(repos)
480
- end
481
-
482
- def update_repositories(repos)
483
- repos.each do |(name, url)|
484
- if File.directory?(repository_dir = File.join(source_dir, name))
485
- message "Updating or branching #{name}..."
486
- source_manager.update(name, url)
487
- else
488
- message "Cloning #{name} repository from #{url}..."
489
- source_manager.clone(name, url)
490
- end
491
- end
492
- end
493
-
494
- def install_dependency(dependency, opts = {})
495
- version = dependency.version_requirements.to_s
496
- install_opts = default_install_options.merge(:version => version)
497
- Merb::Gem.install(dependency.name, install_opts.merge(opts))
498
- end
499
-
500
- def install_dependency_from_source(dependency, opts = {})
501
- matches = Dir[File.join(source_dir, "**", dependency.name, "{Rakefile,Thorfile}")]
502
- matches.reject! { |m| File.basename(m) == 'Thorfile' }
503
- if matches.length == 1 && matches[0]
504
- if File.directory?(gem_src_dir = File.dirname(matches[0]))
505
- begin
506
- Merb::Gem.install_gem_from_source(gem_src_dir, default_install_options.merge(opts))
507
- puts "Installed #{dependency.name}"
508
- return true
509
- rescue => e
510
- warning "Unable to install #{dependency.name} from source (#{e.message})"
511
- end
512
- else
513
- msg = "Unknown directory: #{gem_src_dir}"
514
- warning "Unable to install #{dependency.name} from source (#{msg})"
515
- end
516
- elsif matches.length > 1
517
- error "Ambigous source(s) for dependency: #{dependency.name}"
518
- matches.each { |m| puts "- #{m}" }
519
- end
520
- return false
521
- end
522
-
523
- def clobber_dependencies!
524
- if options[:force] && gem_dir && File.directory?(gem_dir)
525
- # Remove all existing local gems by clearing the gems directory
526
- if dry_run?
527
- note 'Clearing existing local gems...'
528
- else
529
- message 'Clearing existing local gems...'
530
- FileUtils.rm_rf(gem_dir) && FileUtils.mkdir_p(default_gem_dir)
531
- end
532
- elsif !local.empty?
533
- # Uninstall all local versions of the gems to install
534
- if dry_run?
535
- note 'Uninstalling existing local gems:'
536
- local.each { |gemspec| note "Uninstalled #{gemspec.name}" }
537
- else
538
- message 'Uninstalling existing local gems:' if local.size > 1
539
- local.each do |gemspec|
540
- Merb::Gem.uninstall(gemspec.name, default_uninstall_options)
541
- end
542
- end
543
- end
544
- end
545
-
546
- def display_gemspecs(gemspecs)
547
- if gemspecs.empty?
548
- puts "- none"
549
- else
550
- gemspecs.each do |spec|
551
- if hint = Dir[File.join(spec.full_gem_path, '*.strategy')][0]
552
- strategy = File.basename(hint, '.strategy')
553
- puts "- #{spec.full_name} (#{strategy})"
554
- else
555
- puts "~ #{spec.full_name}" # unknown strategy
556
- end
557
- end
558
- end
559
- end
560
-
561
- def display_dependencies(dependencies)
562
- if dependencies.empty?
563
- puts "- none"
564
- else
565
- dependencies.each { |d| puts "- #{d.name} (#{d.version_requirements})" }
566
- end
567
- end
568
-
569
- def default_install_options
570
- { :install_dir => gem_dir, :bin_dir => bin_dir, :ignore_dependencies => ignore_dependencies? }
571
- end
572
-
573
- def default_uninstall_options
574
- { :install_dir => gem_dir, :bin_dir => bin_dir, :ignore => true, :all => true, :executables => true }
575
- end
576
-
577
- def dry_run?
578
- options[:"dry-run"]
579
- end
580
-
581
- def ignore_dependencies?
582
- options[:"ignore-dependencies"]
583
- end
584
-
585
- # The current working directory, or Merb app root (--merb-root option).
586
- def working_dir
587
- @_working_dir ||= File.expand_path(options['merb-root'] || Dir.pwd)
588
- end
589
-
590
- # We should have a ./src dir for local and system-wide management.
591
- def source_dir
592
- @_source_dir ||= File.join(working_dir, 'src')
593
- create_if_missing(@_source_dir)
594
- @_source_dir
595
- end
596
-
597
- # If a local ./gems dir is found, return it.
598
- def gem_dir
599
- return force_gem_dir if force_gem_dir
600
- if File.directory?(dir = default_gem_dir)
601
- dir
602
- end
603
- end
604
-
605
- def default_gem_dir
606
- File.join(working_dir, 'gems')
607
- end
608
-
609
- # If we're in a Merb app, we can have a ./bin directory;
610
- # create it if it's not there.
611
- def bin_dir
612
- @_bin_dir ||= begin
613
- if gem_dir
614
- dir = File.join(working_dir, 'bin')
615
- create_if_missing(dir)
616
- dir
617
- end
618
- end
619
- end
620
-
621
- # Helper to create dir unless it exists.
622
- def create_if_missing(path)
623
- FileUtils.mkdir(path) unless File.exists?(path)
624
- end
625
-
626
- def sudo
627
- ENV['THOR_SUDO'] ||= "sudo"
628
- sudo = Gem.win_platform? ? "" : ENV['THOR_SUDO']
629
- end
630
-
631
- def local_gemspecs(directory = gem_dir)
632
- if File.directory?(specs_dir = File.join(directory, 'specifications'))
633
- Dir[File.join(specs_dir, '*.gemspec')].map do |gemspec_path|
634
- gemspec = Gem::Specification.load(gemspec_path)
635
- gemspec.loaded_from = gemspec_path
636
- gemspec
637
- end
638
- else
639
- []
640
- end
641
- end
642
-
643
- end
644
-
645
- ##############################################################################
646
-
647
- $SILENT = true # don't output all the mess some rake package tasks spit out
648
-
649
- module Merb
650
-
651
- class Gem < Thor
652
-
653
- include MerbThorHelper
654
- extend GemManagement
655
-
656
- attr_accessor :system, :local, :missing
657
-
658
- global_method_options = {
659
- "--merb-root" => :optional, # the directory to operate on
660
- "--version" => :optional, # gather specific version of gem
661
- "--ignore-dependencies" => :boolean # don't install sub-dependencies
662
- }
663
-
664
- method_options global_method_options
665
- def initialize(*args); super; end
666
-
667
- # List gems that match the specified criteria.
668
- #
669
- # By default all local gems are listed. When the first argument is 'all' the
670
- # list is partitioned into system an local gems; specify 'system' to show
671
- # only system gems. A second argument can be used to filter on a set of known
672
- # components, like all merb-more gems for example.
673
- #
674
- # Examples:
675
- #
676
- # merb:gem:list # list all local gems - the default
677
- # merb:gem:list all # list system and local gems
678
- # merb:gem:list system # list only system gems
679
- # merb:gem:list all merb-more # list only merb-more related gems
680
- # merb:gem:list --version 0.9.8 # list gems that match the version
681
-
682
- desc 'list [all|local|system] [comp]', 'Show installed gems'
683
- def list(filter = 'local', comp = nil)
684
- deps = comp ? Merb::Stack.select_component_dependencies(dependencies, comp) : dependencies
685
- self.system, self.local, self.missing = Merb::Gem.partition_dependencies(deps, gem_dir)
686
- case filter
687
- when 'all'
688
- message 'Installed system gems:'
689
- display_gemspecs(system)
690
- message 'Installed local gems:'
691
- display_gemspecs(local)
692
- when 'system'
693
- message 'Installed system gems:'
694
- display_gemspecs(system)
695
- when 'local'
696
- message 'Installed local gems:'
697
- display_gemspecs(local)
698
- else
699
- warning "Invalid listing filter '#{filter}'"
700
- end
701
- end
702
-
703
- # Install the specified gems.
704
- #
705
- # All arguments should be names of gems to install.
706
- #
707
- # When :force => true then any existing versions of the gems to be installed
708
- # will be uninstalled first. It's important to note that so-called meta-gems
709
- # or gems that exactly match a set of Merb::Stack.components will have their
710
- # sub-gems uninstalled too. For example, uninstalling merb-more will install
711
- # all contained gems: merb-action-args, merb-assets, merb-gen, ...
712
- #
713
- # Examples:
714
- #
715
- # merb:gem:install merb-core merb-slices # install all specified gems
716
- # merb:gem:install merb-core --version 0.9.8 # install a specific version of a gem
717
- # merb:gem:install merb-core --force # uninstall then subsequently install the gem
718
- # merb:gem:install merb-core --cache # try to install locally from system gems
719
- # merb:gem:install merb --merb-edge # install from edge.merbivore.com
720
-
721
- desc 'install GEM_NAME [GEM_NAME, ...]', 'Install a gem from rubygems'
722
- method_options "--cache" => :boolean,
723
- "--dry-run" => :boolean,
724
- "--force" => :boolean,
725
- "--merb-edge" => :boolean
726
- def install(*names)
727
- opts = { :version => options[:version], :cache => options[:cache] }
728
- use_edge_gem_server if options[:"merb-edge"]
729
- current_gem = nil
730
-
731
- # uninstall existing gems of the ones we're going to install
732
- uninstall(*names) if options[:force]
733
-
734
- message "Installing #{names.length} #{names.length == 1 ? 'gem' : 'gems'}..."
735
- puts "This may take a while..."
736
-
737
- names.each do |gem_name|
738
- current_gem = gem_name
739
- if dry_run?
740
- note "Installing #{current_gem}..."
741
- else
742
- message "Installing #{current_gem}..."
743
- self.class.install(gem_name, default_install_options.merge(opts))
744
- end
745
- end
746
- rescue => e
747
- error "Failed to install #{current_gem ? current_gem : 'gem'} (#{e.message})"
748
- end
749
-
750
- # Uninstall the specified gems.
751
- #
752
- # By default all specified gems are uninstalled. It's important to note that
753
- # so-called meta-gems or gems that match a set of Merb::Stack.components will
754
- # have their sub-gems uninstalled too. For example, uninstalling merb-more
755
- # will install all contained gems: merb-action-args, merb-assets, ...
756
- #
757
- # Existing dependencies will be clobbered; when :force => true then all gems
758
- # will be cleared, otherwise only existing local dependencies of the
759
- # matching component set will be removed.
760
- #
761
- # Examples:
762
- #
763
- # merb:gem:uninstall merb-core merb-slices # uninstall all specified gems
764
- # merb:gem:uninstall merb-core --version 0.9.8 # uninstall a specific version of a gem
765
-
766
- desc 'uninstall GEM_NAME [GEM_NAME, ...]', 'Unstall a gem'
767
- method_options "--dry-run" => :boolean
768
- def uninstall(*names)
769
- opts = { :version => options[:version] }
770
- current_gem = nil
771
- if dry_run?
772
- note "Uninstalling any existing gems of: #{names.join(', ')}"
773
- else
774
- message "Uninstalling any existing gems of: #{names.join(', ')}"
775
- names.each do |gem_name|
776
- current_gem = gem_name
777
- Merb::Gem.uninstall(gem_name, default_uninstall_options) rescue nil
778
- # if this gem is a meta-gem or a component set name, remove sub-gems
779
- (Merb::Stack.components(gem_name) || []).each do |comp|
780
- Merb::Gem.uninstall(comp, default_uninstall_options) rescue nil
781
- end
782
- end
783
- end
784
- rescue => e
785
- error "Failed to uninstall #{current_gem ? current_gem : 'gem'} (#{e.message})"
786
- end
787
-
788
- # Recreate all gems from gems/cache on the current platform.
789
- #
790
- # This task should be executed as part of a deployment setup, where the
791
- # deployment system runs this after the app has been installed.
792
- # Usually triggered by Capistrano, God...
793
- #
794
- # It will regenerate gems from the bundled gems cache for any gem that has
795
- # C extensions - which need to be recompiled for the target deployment platform.
796
- #
797
- # Note: at least gems/cache and gems/specifications should be in your SCM.
798
-
799
- desc 'redeploy', 'Recreate all gems on the current platform'
800
- method_options "--dry-run" => :boolean, "--force" => :boolean
801
- def redeploy
802
- require 'tempfile' # for Dir::tmpdir access
803
- if gem_dir && File.directory?(cache_dir = File.join(gem_dir, 'cache'))
804
- specs = local_gemspecs
805
- message "Recreating #{specs.length} gems from cache..."
806
- puts "This may take a while..."
807
- specs.each do |gemspec|
808
- if File.exists?(gem_file = File.join(cache_dir, "#{gemspec.full_name}.gem"))
809
- gem_file_copy = File.join(Dir::tmpdir, File.basename(gem_file))
810
- if dry_run?
811
- note "Recreating #{gemspec.full_name}"
812
- else
813
- message "Recreating #{gemspec.full_name}"
814
- if options[:force] && File.directory?(gem = File.join(gem_dir, 'gems', gemspec.full_name))
815
- puts "Removing existing #{gemspec.full_name}"
816
- FileUtils.rm_rf(gem)
817
- end
818
- # Copy the gem to a temporary file, because otherwise RubyGems/FileUtils
819
- # will complain about copying identical files (same source/destination).
820
- FileUtils.cp(gem_file, gem_file_copy)
821
- Merb::Gem.install(gem_file_copy, :install_dir => gem_dir, :ignore_dependencies => true)
822
- File.delete(gem_file_copy)
823
- end
824
- end
825
- end
826
- else
827
- error "No application local gems directory found"
828
- end
829
- end
830
-
831
- private
832
-
833
- # Return dependencies for all installed gems; both system-wide and locally;
834
- # optionally filters on :version requirement.
835
- def dependencies
836
- version_req = if options[:version]
837
- ::Gem::Requirement.create(options[:version])
838
- else
839
- ::Gem::Requirement.default
840
- end
841
- if gem_dir
842
- ::Gem.clear_paths; ::Gem.path.unshift(gem_dir)
843
- ::Gem.source_index.refresh!
844
- end
845
- deps = []
846
- ::Gem.source_index.each do |fullname, gemspec|
847
- if version_req.satisfied_by?(gemspec.version)
848
- deps << ::Gem::Dependency.new(gemspec.name, "= #{gemspec.version}")
849
- end
850
- end
851
- ::Gem.clear_paths if gem_dir
852
- deps.sort
853
- end
854
-
855
- public
856
-
857
- # Install gem with some default options.
858
- def self.install(name, options = {})
859
- defaults = {}
860
- defaults[:cache] = false unless opts[:install_dir]
861
- install_gem(name, defaults.merge(options))
862
- end
863
-
864
- # Uninstall gem with some default options.
865
- def self.uninstall(name, options = {})
866
- defaults = { :ignore => true, :executables => true }
867
- uninstall_gem(name, defaults.merge(options))
868
- end
869
-
870
- end
871
-
872
- class Tasks < Thor
873
-
874
- include MerbThorHelper
875
-
876
- # Show merb.thor version information
877
- #
878
- # merb:tasks:version # show the current version info
879
- # merb:tasks:version --info # show extended version info
880
-
881
- desc 'version', 'Show verion info'
882
- method_options "--info" => :boolean
883
- def version
884
- message "Currently installed merb.thor version: #{MERB_THOR_VERSION}"
885
- if options[:version]
886
- self.options = { :"dry-run" => true }
887
- self.update # run update task with dry-run enabled
888
- end
889
- end
890
-
891
- # Update merb.thor tasks from remotely available version
892
- #
893
- # merb:tasks:update # update merb.thor
894
- # merb:tasks:update --force # force-update merb.thor
895
- # merb:tasks:update --dry-run # show version info only
896
-
897
- desc 'update [URL]', 'Fetch the latest merb.thor and install it locally'
898
- method_options "--dry-run" => :boolean, "--force" => :boolean
899
- def update(url = 'http://merbivore.com/merb.thor')
900
- require 'open-uri'
901
- require 'rubygems/version'
902
- remote_file = open(url)
903
- code = remote_file.read
904
-
905
- # Extract version information from the source code
906
- if version = code[/^MERB_THOR_VERSION\s?=\s?('|")([\.\d]+)('|")/,2]
907
- # borrow version comparison from rubygems' Version class
908
- current_version = ::Gem::Version.new(MERB_THOR_VERSION)
909
- remote_version = ::Gem::Version.new(version)
910
-
911
- if current_version >= remote_version
912
- puts "currently installed: #{current_version}"
913
- if current_version != remote_version
914
- puts "available version: #{remote_version}"
915
- end
916
- info "No update of merb.thor necessary#{options[:force] ? ' (forced)' : ''}"
917
- proceed = options[:force]
918
- elsif current_version < remote_version
919
- puts "currently installed: #{current_version}"
920
- puts "available version: #{remote_version}"
921
- proceed = true
922
- end
923
-
924
- if proceed && !dry_run?
925
- File.open(File.join(__FILE__), 'w') do |f|
926
- f.write(code)
927
- end
928
- success "Installed the latest merb.thor (v#{version})"
929
- end
930
- else
931
- raise "invalid source-code data"
932
- end
933
- rescue OpenURI::HTTPError
934
- error "Error opening #{url}"
935
- rescue => e
936
- error "An error occurred (#{e.message})"
937
- end
938
-
939
- end
940
-
941
- #### MORE LOW-LEVEL TASKS ####
942
-
943
- class Source < Thor
944
-
945
- group 'core'
946
-
947
- include MerbThorHelper
948
- extend GemManagement
949
-
950
- attr_accessor :system, :local, :missing
951
-
952
- global_method_options = {
953
- "--merb-root" => :optional, # the directory to operate on
954
- "--ignore-dependencies" => :boolean, # don't install sub-dependencies
955
- "--sources" => :optional # a yml config to grab sources from
956
- }
957
-
958
- method_options global_method_options
959
- def initialize(*args); super; end
960
-
961
- # List source repositories, of either local or known sources.
962
- #
963
- # Examples:
964
- #
965
- # merb:source:list # list all local sources
966
- # merb:source:list available # list all known sources
967
-
968
- desc 'list [local|available]', 'Show git source repositories'
969
- def list(mode = 'local')
970
- if mode == 'available'
971
- message 'Available source repositories:'
972
- repos = self.class.repos(options[:sources])
973
- repos.keys.sort.each { |name| puts "- #{name}: #{repos[name]}" }
974
- elsif mode == 'local'
975
- message 'Current source repositories:'
976
- Dir[File.join(source_dir, '*')].each do |src|
977
- next unless File.directory?(src)
978
- src_name = File.basename(src)
979
- unless (repos = source_manager.existing_repos(src_name)).empty?
980
- puts "#{src_name}"
981
- repos.keys.sort.each { |b| puts "- #{b}: #{repos[b]}" }
982
- end
983
- end
984
- else
985
- error "Unknown listing: #{mode}"
986
- end
987
- end
988
-
989
- # Install the specified gems.
990
- #
991
- # All arguments should be names of gems to install.
992
- #
993
- # When :force => true then any existing versions of the gems to be installed
994
- # will be uninstalled first. It's important to note that so-called meta-gems
995
- # or gems that exactly match a set of Merb::Stack.components will have their
996
- # sub-gems uninstalled too. For example, uninstalling merb-more will install
997
- # all contained gems: merb-action-args, merb-assets, merb-gen, ...
998
- #
999
- # Examples:
1000
- #
1001
- # merb:source:install merb-core merb-slices # install all specified gems
1002
- # merb:source:install merb-core --force # uninstall then subsequently install the gem
1003
- # merb:source:install merb-core --wipe # clear repo then install the gem
1004
-
1005
- desc 'install GEM_NAME [GEM_NAME, ...]', 'Install a gem from git source/edge'
1006
- method_options "--dry-run" => :boolean,
1007
- "--force" => :boolean,
1008
- "--wipe" => :boolean
1009
- def install(*names)
1010
- use_edge_gem_server
1011
- # uninstall existing gems of the ones we're going to install
1012
- uninstall(*names) if options[:force] || options[:wipe]
1013
-
1014
- # We want dependencies instead of just names
1015
- deps = names.map { |n| ::Gem::Dependency.new(n, ::Gem::Requirement.default) }
1016
-
1017
- # Selectively update repositories for the matching dependencies
1018
- update_dependency_repositories(deps) unless dry_run?
1019
-
1020
- current_gem = nil
1021
- deps.each do |dependency|
1022
- current_gem = dependency.name
1023
- if dry_run?
1024
- note "Installing #{current_gem} from source..."
1025
- else
1026
- message "Installing #{current_gem} from source..."
1027
- puts "This may take a while..."
1028
- unless install_dependency_from_source(dependency)
1029
- raise "gem source not found"
1030
- end
1031
- end
1032
- end
1033
- rescue => e
1034
- error "Failed to install #{current_gem ? current_gem : 'gem'} (#{e.message})"
1035
- end
1036
-
1037
- # Uninstall the specified gems.
1038
- #
1039
- # By default all specified gems are uninstalled. It's important to note that
1040
- # so-called meta-gems or gems that match a set of Merb::Stack.components will
1041
- # have their sub-gems uninstalled too. For example, uninstalling merb-more
1042
- # will install all contained gems: merb-action-args, merb-assets, ...
1043
- #
1044
- # Existing dependencies will be clobbered; when :force => true then all gems
1045
- # will be cleared, otherwise only existing local dependencies of the
1046
- # matching component set will be removed. Additionally when :wipe => true,
1047
- # the matching git repositories will be removed from the source directory.
1048
- #
1049
- # Examples:
1050
- #
1051
- # merb:source:uninstall merb-core merb-slices # uninstall all specified gems
1052
- # merb:source:uninstall merb-core --wipe # force-uninstall a gem and clear repo
1053
-
1054
- desc 'uninstall GEM_NAME [GEM_NAME, ...]', 'Unstall a gem (specify --force to remove the repo)'
1055
- method_options "--version" => :optional, "--dry-run" => :boolean, "--wipe" => :boolean
1056
- def uninstall(*names)
1057
- # Remove the repos that contain the gem
1058
- if options[:wipe]
1059
- extract_repositories(names).each do |(name, url)|
1060
- if File.directory?(src = File.join(source_dir, name))
1061
- if dry_run?
1062
- note "Removing #{src}..."
1063
- else
1064
- info "Removing #{src}..."
1065
- FileUtils.rm_rf(src)
1066
- end
1067
- end
1068
- end
1069
- end
1070
-
1071
- # Use the Merb::Gem#uninstall task to handle this
1072
- gem_tasks = Merb::Gem.new
1073
- gem_tasks.options = options
1074
- gem_tasks.uninstall(*names)
1075
- end
1076
-
1077
- # Update the specified source repositories.
1078
- #
1079
- # The arguments can be actual repository names (from Merb::Source.repos)
1080
- # or names of known merb stack gems. If the repo doesn't exist already,
1081
- # it will be created and cloned.
1082
- #
1083
- # merb:source:pull merb-core # update source of specified gem
1084
- # merb:source:pull merb-slices # implicitly updates merb-more
1085
-
1086
- desc 'pull REPO_NAME [GEM_NAME, ...]', 'Update git source repository from edge'
1087
- def pull(*names)
1088
- repos = extract_repositories(names)
1089
- update_repositories(repos)
1090
- unless repos.empty?
1091
- message "Updated the following repositories:"
1092
- repos.each { |name, url| puts "- #{name}: #{url}" }
1093
- else
1094
- warning "No repositories found to update!"
1095
- end
1096
- end
1097
-
1098
- # Clone a git repository into ./src.
1099
-
1100
- # The repository can be a direct git url or a known -named- repository.
1101
- #
1102
- # Examples:
1103
- #
1104
- # merb:source:clone merb-core
1105
- # merb:source:clone dm-core awesome-repo
1106
- # merb:source:clone dm-core --sources ./path/to/sources.yml
1107
- # merb:source:clone git://github.com/sam/dm-core.git
1108
-
1109
- desc 'clone (REPO_NAME|URL) [DIR_NAME]', 'Clone git source repository by name or url'
1110
- def clone(repository, name = nil)
1111
- if repository =~ /^git:\/\//
1112
- repository_url = repository
1113
- repository_name = File.basename(repository_url, '.git')
1114
- elsif url = Merb::Source.repo(repository, options[:sources])
1115
- repository_url = url
1116
- repository_name = repository
1117
- end
1118
- source_manager.clone(name || repository_name, repository_url)
1119
- end
1120
-
1121
- # Git repository sources - pass source_config option to load a yaml
1122
- # configuration file - defaults to ./config/git-sources.yml and
1123
- # ~/.merb/git-sources.yml - which you need to create yourself.
1124
- #
1125
- # Example of contents:
1126
- #
1127
- # merb-core: git://github.com/myfork/merb-core.git
1128
- # merb-more: git://github.com/myfork/merb-more.git
1129
-
1130
- def self.repos(source_config = nil)
1131
- source_config ||= begin
1132
- local_config = File.join(Dir.pwd, 'config', 'git-sources.yml')
1133
- user_config = File.join(ENV["HOME"] || ENV["APPDATA"], '.merb', 'git-sources.yml')
1134
- File.exists?(local_config) ? local_config : user_config
1135
- end
1136
- if source_config && File.exists?(source_config)
1137
- default_repos.merge(YAML.load(File.read(source_config)))
1138
- else
1139
- default_repos
1140
- end
1141
- end
1142
-
1143
- def self.repo(name, source_config = nil)
1144
- self.repos(source_config)[name]
1145
- end
1146
-
1147
- # Default Git repositories
1148
- def self.default_repos
1149
- @_default_repos ||= {
1150
- 'merb' => "git://github.com/wycats/merb.git",
1151
- 'merb-plugins' => "git://github.com/wycats/merb-plugins.git",
1152
- 'extlib' => "git://github.com/sam/extlib.git",
1153
- 'dm-core' => "git://github.com/sam/dm-core.git",
1154
- 'dm-more' => "git://github.com/sam/dm-more.git",
1155
- 'sequel' => "git://github.com/wayneeseguin/sequel.git",
1156
- 'do' => "git://github.com/sam/do.git",
1157
- 'thor' => "git://github.com/wycats/thor.git",
1158
- 'rake' => "git://github.com/jimweirich/rake.git"
1159
- }
1160
- end
1161
-
1162
- end
1163
-
1164
- class Dependencies < Thor
1165
-
1166
- group 'core'
1167
-
1168
- # The Dependencies tasks will install dependencies based on actual application
1169
- # dependencies. For this, the application is queried for any dependencies.
1170
- # All operations will be performed within this context.
1171
-
1172
- attr_accessor :system, :local, :missing, :extract_dependencies
1173
-
1174
- include MerbThorHelper
1175
-
1176
- global_method_options = {
1177
- "--merb-root" => :optional, # the directory to operate on
1178
- "--ignore-dependencies" => :boolean, # ignore sub-dependencies
1179
- "--stack" => :boolean, # gather only stack dependencies
1180
- "--no-stack" => :boolean, # gather only non-stack dependencies
1181
- "--extract" => :boolean, # gather dependencies from the app itself
1182
- "--config-file" => :optional, # gather from the specified yaml config
1183
- "--version" => :optional # gather specific version of framework
1184
- }
1185
-
1186
- method_options global_method_options
1187
- def initialize(*args); super; end
1188
-
1189
- # List application dependencies.
1190
- #
1191
- # By default all dependencies are listed, partitioned into system, local and
1192
- # currently missing dependencies. The first argument allows you to filter
1193
- # on any of the partitionings. A second argument can be used to filter on
1194
- # a set of known components, like all merb-more gems for example.
1195
- #
1196
- # Examples:
1197
- #
1198
- # merb:dependencies:list # list all dependencies - the default
1199
- # merb:dependencies:list local # list only local gems
1200
- # merb:dependencies:list all merb-more # list only merb-more related dependencies
1201
- # merb:dependencies:list --stack # list framework dependencies
1202
- # merb:dependencies:list --no-stack # list 3rd party dependencies
1203
- # merb:dependencies:list --extract # list dependencies by extracting them
1204
- # merb:dependencies:list --config-file file.yml # list from the specified config file
1205
-
1206
- desc 'list [all|local|system|missing] [comp]', 'Show application dependencies'
1207
- def list(filter = 'all', comp = nil)
1208
- deps = comp ? Merb::Stack.select_component_dependencies(dependencies, comp) : dependencies
1209
- self.system, self.local, self.missing = Merb::Gem.partition_dependencies(deps, gem_dir)
1210
- case filter
1211
- when 'all'
1212
- message 'Installed system gem dependencies:'
1213
- display_gemspecs(system)
1214
- message 'Installed local gem dependencies:'
1215
- display_gemspecs(local)
1216
- unless missing.empty?
1217
- error 'Missing gem dependencies:'
1218
- display_dependencies(missing)
1219
- end
1220
- when 'system'
1221
- message 'Installed system gem dependencies:'
1222
- display_gemspecs(system)
1223
- when 'local'
1224
- message 'Installed local gem dependencies:'
1225
- display_gemspecs(local)
1226
- when 'missing'
1227
- error 'Missing gem dependencies:'
1228
- display_dependencies(missing)
1229
- else
1230
- warning "Invalid listing filter '#{filter}'"
1231
- end
1232
- if missing.size > 0
1233
- info "Some dependencies are currently missing!"
1234
- elsif local.size == deps.size
1235
- info "All dependencies have been bundled with the application."
1236
- elsif local.size > system.size
1237
- info "Most dependencies have been bundled with the application."
1238
- elsif system.size > 0 && local.size > 0
1239
- info "Some dependencies have been bundled with the application."
1240
- elsif local.empty? && system.size == deps.size
1241
- info "All dependencies are available on the system."
1242
- end
1243
- end
1244
-
1245
- # Install application dependencies.
1246
- #
1247
- # By default all required dependencies are installed. The first argument
1248
- # specifies which strategy to use: stable or edge. A second argument can be
1249
- # used to filter on a set of known components.
1250
- #
1251
- # Existing dependencies will be clobbered; when :force => true then all gems
1252
- # will be cleared first, otherwise only existing local dependencies of the
1253
- # gems to be installed will be removed.
1254
- #
1255
- # Examples:
1256
- #
1257
- # merb:dependencies:install # install all dependencies using stable strategy
1258
- # merb:dependencies:install stable --version 0.9.8 # install a specific version of the framework
1259
- # merb:dependencies:install stable missing # install currently missing gems locally
1260
- # merb:dependencies:install stable merb-more # install only merb-more related dependencies
1261
- # merb:dependencies:install stable --stack # install framework dependencies
1262
- # merb:dependencies:install stable --no-stack # install 3rd party dependencies
1263
- # merb:dependencies:install stable --extract # extract dependencies from the actual app
1264
- # merb:dependencies:install stable --config-file file.yml # read from the specified config file
1265
- #
1266
- # In addition to the options above, edge install uses the following:
1267
- #
1268
- # merb:dependencies:install edge # install all dependencies using edge strategy
1269
- # merb:dependencies:install edge --sources file.yml # install edge from the specified git sources config
1270
-
1271
- desc 'install [stable|edge] [comp]', 'Install application dependencies'
1272
- method_options "--sources" => :optional, # only for edge strategy
1273
- "--local" => :boolean, # force local install
1274
- "--dry-run" => :boolean,
1275
- "--force" => :boolean
1276
- def install(strategy = 'stable', comp = nil)
1277
- if strategy?(strategy)
1278
- # Force local dependencies by creating ./gems before proceeding
1279
- create_if_missing(default_gem_dir) if options[:local]
1280
-
1281
- where = gem_dir ? 'locally' : 'system-wide'
1282
-
1283
- # When comp == 'missing' then filter on missing dependencies
1284
- if only_missing = comp == 'missing'
1285
- message "Preparing to install missing gems #{where} using #{strategy} strategy..."
1286
- comp = nil
1287
- clobber = false
1288
- else
1289
- message "Preparing to install #{where} using #{strategy} strategy..."
1290
- clobber = true
1291
- end
1292
-
1293
- # If comp given, filter on known stack components
1294
- deps = comp ? Merb::Stack.select_component_dependencies(dependencies, comp) : dependencies
1295
- self.system, self.local, self.missing = Merb::Gem.partition_dependencies(deps, gem_dir)
1296
-
1297
- # Only install currently missing gems (for comp == missing)
1298
- if only_missing
1299
- deps.reject! { |dep| not missing.include?(dep) }
1300
- end
1301
-
1302
- if deps.empty?
1303
- warning "No dependencies to install..."
1304
- else
1305
- puts "#{deps.length} dependencies to install..."
1306
- puts "This may take a while..."
1307
- install_dependencies(strategy, deps, clobber)
1308
- end
1309
-
1310
- # Show current dependency info now that we're done
1311
- puts # Seperate output
1312
- list('local', comp)
1313
- else
1314
- warning "Invalid install strategy '#{strategy}'"
1315
- puts
1316
- message "Please choose one of the following installation strategies: stable or edge:"
1317
- puts "$ thor merb:dependencies:install stable"
1318
- puts "$ thor merb:dependencies:install edge"
1319
- end
1320
- end
1321
-
1322
- # Uninstall application dependencies.
1323
- #
1324
- # By default all required dependencies are installed. An optional argument
1325
- # can be used to filter on a set of known components.
1326
- #
1327
- # Existing dependencies will be clobbered; when :force => true then all gems
1328
- # will be cleared, otherwise only existing local dependencies of the
1329
- # matching component set will be removed.
1330
- #
1331
- # Examples:
1332
- #
1333
- # merb:dependencies:uninstall # uninstall all dependencies - the default
1334
- # merb:dependencies:uninstall merb-more # uninstall merb-more related gems locally
1335
-
1336
- desc 'uninstall [comp]', 'Uninstall application dependencies'
1337
- method_options "--dry-run" => :boolean, "--force" => :boolean
1338
- def uninstall(comp = nil)
1339
- # If comp given, filter on known stack components
1340
- deps = comp ? Merb::Stack.select_component_dependencies(dependencies, comp) : dependencies
1341
- self.system, self.local, self.missing = Merb::Gem.partition_dependencies(deps, gem_dir)
1342
- # Clobber existing local dependencies - based on self.local
1343
- clobber_dependencies!
1344
- end
1345
-
1346
- # Recreate all gems from gems/cache on the current platform.
1347
- #
1348
- # Note: use merb:gem:redeploy instead
1349
-
1350
- desc 'redeploy', 'Recreate all gems on the current platform'
1351
- method_options "--dry-run" => :boolean, "--force" => :boolean
1352
- def redeploy
1353
- warning 'Warning: merb:dependencies:redeploy has been deprecated - use merb:gem:redeploy instead'
1354
- gem = Merb::Gem.new
1355
- gem.options = options
1356
- gem.redeploy
1357
- end
1358
-
1359
- # Create a dependencies configuration file.
1360
- #
1361
- # A configuration yaml file will be created from the extracted application
1362
- # dependencies. The format of the configuration is as follows:
1363
- #
1364
- # ---
1365
- # - merb-core (= 0.9.8, runtime)
1366
- # - merb-slices (= 0.9.8, runtime)
1367
- #
1368
- # This format is exactly the same as Gem::Dependency#to_s returns.
1369
- #
1370
- # Examples:
1371
- #
1372
- # merb:dependencies:configure --force # overwrite the default config file
1373
- # merb:dependencies:configure --version 0.9.8 # configure specific framework version
1374
- # merb:dependencies:configure --config-file file.yml # write to the specified config file
1375
-
1376
- desc 'configure [comp]', 'Create a dependencies config file'
1377
- method_options "--dry-run" => :boolean, "--force" => :boolean, "--versions" => :boolean
1378
- def configure(comp = nil)
1379
- self.extract_dependencies = true # of course we need to consult the app itself
1380
- # If comp given, filter on known stack components
1381
- deps = comp ? Merb::Stack.select_component_dependencies(dependencies, comp) : dependencies
1382
-
1383
- # If --versions is set, update the version_requirements with the actual version available
1384
- if options[:versions]
1385
- specs = local_gemspecs
1386
- deps.each do |dep|
1387
- if spec = specs.find { |s| s.name == dep.name }
1388
- dep.version_requirements = ::Gem::Requirement.create(spec.version)
1389
- end
1390
- end
1391
- end
1392
-
1393
- config = YAML.dump(deps.map { |d| d.to_s })
1394
- puts "#{config}\n"
1395
- if File.exists?(config_file) && !options[:force]
1396
- error "File already exists! Use --force to overwrite."
1397
- else
1398
- if dry_run?
1399
- note "Written #{config_file}"
1400
- else
1401
- FileUtils.mkdir_p(config_dir) unless File.directory?(config_dir)
1402
- File.open(config_file, 'w') { |f| f.write config }
1403
- success "Written #{config_file}"
1404
- end
1405
- end
1406
- rescue
1407
- error "Failed to write to #{config_file}"
1408
- end
1409
-
1410
- ### Helper Methods
1411
-
1412
- def strategy?(strategy)
1413
- if self.respond_to?(method = :"#{strategy}_strategy", true)
1414
- method
1415
- end
1416
- end
1417
-
1418
- def install_dependencies(strategy, deps, clobber = true)
1419
- if method = strategy?(strategy)
1420
- # Clobber existing local dependencies
1421
- clobber_dependencies! if clobber
1422
-
1423
- # Run the chosen strategy - collect files installed from stable gems
1424
- installed_from_stable = send(method, deps).map { |d| d.name }
1425
-
1426
- unless dry_run?
1427
- # Sleep a bit otherwise the following steps won't see the new files
1428
- sleep(deps.length) if deps.length > 0 && deps.length <= 10
1429
-
1430
- # Leave a file to denote the strategy that has been used for this dependency
1431
- self.local.each do |spec|
1432
- next unless File.directory?(spec.full_gem_path)
1433
- unless installed_from_stable.include?(spec.name)
1434
- FileUtils.touch(File.join(spec.full_gem_path, "#{strategy}.strategy"))
1435
- else
1436
- FileUtils.touch(File.join(spec.full_gem_path, "stable.strategy"))
1437
- end
1438
- end
1439
- end
1440
- return true
1441
- end
1442
- false
1443
- end
1444
-
1445
- def dependencies
1446
- if extract_dependencies?
1447
- # Extract dependencies from the current application
1448
- deps = Merb::Stack.core_dependencies(gem_dir, ignore_dependencies?)
1449
- deps += Merb::Dependencies.extract_dependencies(working_dir)
1450
- else
1451
- # Use preconfigured dependencies from yaml file
1452
- deps = config_dependencies
1453
- end
1454
-
1455
- stack_components = Merb::Stack.components
1456
-
1457
- if options[:stack]
1458
- # Limit to stack components only
1459
- deps.reject! { |dep| not stack_components.include?(dep.name) }
1460
- elsif options[:"no-stack"]
1461
- # Limit to non-stack components
1462
- deps.reject! { |dep| stack_components.include?(dep.name) }
1463
- end
1464
-
1465
- if options[:version]
1466
- version_req = ::Gem::Requirement.create("= #{options[:version]}")
1467
- elsif core = deps.find { |d| d.name == 'merb-core' }
1468
- version_req = core.version_requirements
1469
- end
1470
-
1471
- if version_req
1472
- # Handle specific version requirement for framework components
1473
- framework_components = Merb::Stack.framework_components
1474
- deps.each do |dep|
1475
- if framework_components.include?(dep.name)
1476
- dep.version_requirements = version_req
1477
- end
1478
- end
1479
- end
1480
-
1481
- deps
1482
- end
1483
-
1484
- def config_dependencies
1485
- if File.exists?(config_file)
1486
- self.class.parse_dependencies_yaml(File.read(config_file))
1487
- else
1488
- warning "No dependencies.yml file found at: #{config_file}"
1489
- []
1490
- end
1491
- end
1492
-
1493
- def extract_dependencies?
1494
- options[:extract] || extract_dependencies
1495
- end
1496
-
1497
- def config_file
1498
- @config_file ||= begin
1499
- options[:"config-file"] || File.join(working_dir, 'config', 'dependencies.yml')
1500
- end
1501
- end
1502
-
1503
- def config_dir
1504
- File.dirname(config_file)
1505
- end
1506
-
1507
- ### Strategy handlers
1508
-
1509
- private
1510
-
1511
- def stable_strategy(deps)
1512
- installed_from_rubygems = []
1513
- if core = deps.find { |d| d.name == 'merb-core' }
1514
- if dry_run?
1515
- note "Installing #{core.name}..."
1516
- else
1517
- if install_dependency(core)
1518
- installed_from_rubygems << core
1519
- else
1520
- msg = "Try specifying a lower version of merb-core with --version"
1521
- if version_no = core.version_requirements.to_s[/([\.\d]+)$/, 1]
1522
- num = "%03d" % (version_no.gsub('.', '').to_i - 1)
1523
- puts "The required version (#{version_no}) probably isn't available as a stable rubygem yet."
1524
- info "#{msg} #{num.split(//).join('.')}"
1525
- else
1526
- puts "The required version probably isn't available as a stable rubygem yet."
1527
- info msg
1528
- end
1529
- end
1530
- end
1531
- end
1532
-
1533
- deps.each do |dependency|
1534
- next if dependency.name == 'merb-core'
1535
- if dry_run?
1536
- note "Installing #{dependency.name}..."
1537
- else
1538
- install_dependency(dependency)
1539
- installed_from_rubygems << dependency
1540
- end
1541
- end
1542
- installed_from_rubygems
1543
- end
1544
-
1545
- def edge_strategy(deps)
1546
- use_edge_gem_server
1547
- installed_from_rubygems = []
1548
-
1549
- # Selectively update repositories for the matching dependencies
1550
- update_dependency_repositories(deps) unless dry_run?
1551
-
1552
- if core = deps.find { |d| d.name == 'merb-core' }
1553
- if dry_run?
1554
- note "Installing #{core.name}..."
1555
- else
1556
- if install_dependency_from_source(core)
1557
- elsif install_dependency(core)
1558
- info "Installed #{core.name} from rubygems..."
1559
- installed_from_rubygems << core
1560
- end
1561
- end
1562
- end
1563
-
1564
- deps.each do |dependency|
1565
- next if dependency.name == 'merb-core'
1566
- if dry_run?
1567
- note "Installing #{dependency.name}..."
1568
- else
1569
- if install_dependency_from_source(dependency)
1570
- elsif install_dependency(dependency)
1571
- info "Installed #{dependency.name} from rubygems..."
1572
- installed_from_rubygems << dependency
1573
- end
1574
- end
1575
- end
1576
-
1577
- installed_from_rubygems
1578
- end
1579
-
1580
- ### Class Methods
1581
-
1582
- public
1583
-
1584
- def self.list(filter = 'all', comp = nil, options = {})
1585
- instance = Merb::Dependencies.new
1586
- instance.options = options
1587
- instance.list(filter, comp)
1588
- end
1589
-
1590
- # Extract application dependencies by querying the app directly.
1591
- def self.extract_dependencies(merb_root)
1592
- require 'merb-core'
1593
- if !@_merb_loaded || Merb.root != merb_root
1594
- Merb.start_environment(
1595
- :log_level => :fatal,
1596
- :testing => true,
1597
- :adapter => 'runner',
1598
- :environment => ENV['MERB_ENV'] || 'development',
1599
- :merb_root => merb_root
1600
- )
1601
- @_merb_loaded = true
1602
- end
1603
- Merb::BootLoader::Dependencies.dependencies
1604
- rescue StandardError => e
1605
- error "Couldn't extract dependencies from application!"
1606
- error e.message
1607
- puts "Make sure you're executing the task from your app (--merb-root)"
1608
- return []
1609
- rescue SystemExit
1610
- error "Couldn't extract dependencies from application!"
1611
- error "application failed to run"
1612
- puts "Please check if your application runs using 'merb'; for example,"
1613
- puts "look for any gem version mismatches in dependencies.rb"
1614
- return []
1615
- end
1616
-
1617
- # Parse the basic YAML config data, and process Gem::Dependency output.
1618
- # Formatting example: merb_helpers (>= 0.9.8, runtime)
1619
- def self.parse_dependencies_yaml(yaml)
1620
- dependencies = []
1621
- entries = YAML.load(yaml) rescue []
1622
- entries.each do |entry|
1623
- if matches = entry.match(/^(\S+) \(([^,]+)?, ([^\)]+)\)/)
1624
- name, version_req, type = matches.captures
1625
- dependencies << ::Gem::Dependency.new(name, version_req, type.to_sym)
1626
- else
1627
- error "Invalid entry: #{entry}"
1628
- end
1629
- end
1630
- dependencies
1631
- end
1632
-
1633
- end
1634
-
1635
- class Stack < Thor
1636
-
1637
- group 'core'
1638
-
1639
- # The Stack tasks will install dependencies based on known sets of gems,
1640
- # regardless of actual application dependency settings.
1641
-
1642
- DM_STACK = %w[
1643
- extlib
1644
- data_objects
1645
- dm-core
1646
- dm-aggregates
1647
- dm-migrations
1648
- dm-timestamps
1649
- dm-types
1650
- dm-validations
1651
- merb_datamapper
1652
- ]
1653
-
1654
- MERB_STACK = %w[
1655
- extlib
1656
- merb-core
1657
- merb-action-args
1658
- merb-assets
1659
- merb-cache
1660
- merb-helpers
1661
- merb-mailer
1662
- merb-slices
1663
- merb-auth
1664
- merb-auth-core
1665
- merb-auth-more
1666
- merb-auth-slice-password
1667
- merb-param-protection
1668
- merb-exceptions
1669
- ] + DM_STACK
1670
-
1671
- MERB_BASICS = %w[
1672
- extlib
1673
- merb-core
1674
- merb-action-args
1675
- merb-assets
1676
- merb-cache
1677
- merb-helpers
1678
- merb-mailer
1679
- merb-slices
1680
- ]
1681
-
1682
- # The following sets are meant for repository lookup; unlike the sets above
1683
- # these correspond to specific git repository items.
1684
-
1685
- MERB_MORE = %w[
1686
- merb-action-args
1687
- merb-assets
1688
- merb-auth
1689
- merb-auth-core
1690
- merb-auth-more
1691
- merb-auth-slice-password
1692
- merb-cache
1693
- merb-exceptions
1694
- merb-gen
1695
- merb-haml
1696
- merb-helpers
1697
- merb-mailer
1698
- merb-param-protection
1699
- merb-slices
1700
- merb_datamapper
1701
- ]
1702
-
1703
- MERB_PLUGINS = %w[
1704
- merb_activerecord
1705
- merb_builder
1706
- merb_jquery
1707
- merb_laszlo
1708
- merb_parts
1709
- merb_screw_unit
1710
- merb_sequel
1711
- merb_stories
1712
- merb_test_unit
1713
- ]
1714
-
1715
- DM_MORE = %w[
1716
- dm-adjust
1717
- dm-aggregates
1718
- dm-ar-finders
1719
- dm-cli
1720
- dm-constraints
1721
- dm-is-example
1722
- dm-is-list
1723
- dm-is-nested_set
1724
- dm-is-remixable
1725
- dm-is-searchable
1726
- dm-is-state_machine
1727
- dm-is-tree
1728
- dm-is-versioned
1729
- dm-migrations
1730
- dm-observer
1731
- dm-querizer
1732
- dm-serializer
1733
- dm-shorthand
1734
- dm-sweatshop
1735
- dm-tags
1736
- dm-timestamps
1737
- dm-types
1738
- dm-validations
1739
-
1740
- dm-couchdb-adapter
1741
- dm-ferret-adapter
1742
- dm-rest-adapter
1743
- ]
1744
-
1745
- DATA_OBJECTS = %w[
1746
- data_objects
1747
- do_derby do_hsqldb
1748
- do_jdbc
1749
- do_mysql
1750
- do_postgres
1751
- do_sqlite3
1752
- ]
1753
-
1754
- attr_accessor :system, :local, :missing
1755
-
1756
- include MerbThorHelper
1757
-
1758
- global_method_options = {
1759
- "--merb-root" => :optional, # the directory to operate on
1760
- "--ignore-dependencies" => :boolean, # skip sub-dependencies
1761
- "--version" => :optional # gather specific version of framework
1762
- }
1763
-
1764
- method_options global_method_options
1765
- def initialize(*args); super; end
1766
-
1767
- # List components and their dependencies.
1768
- #
1769
- # Examples:
1770
- #
1771
- # merb:stack:list # list all standard stack components
1772
- # merb:stack:list all # list all component sets
1773
- # merb:stack:list merb-more # list all dependencies of merb-more
1774
-
1775
- desc 'list [all|comp]', 'List available components (optionally filtered, defaults to merb stack)'
1776
- def list(comp = 'stack')
1777
- if comp == 'all'
1778
- Merb::Stack.component_sets.keys.sort.each do |comp|
1779
- unless (components = Merb::Stack.component_sets[comp]).empty?
1780
- message "Dependencies for '#{comp}' set:"
1781
- components.each { |c| puts "- #{c}" }
1782
- end
1783
- end
1784
- else
1785
- message "Dependencies for '#{comp}' set:"
1786
- Merb::Stack.components(comp).each { |c| puts "- #{c}" }
1787
- end
1788
- end
1789
-
1790
- # Install stack components or individual gems - from stable rubygems by default.
1791
- #
1792
- # See also: Merb::Dependencies#install and Merb::Dependencies#install_dependencies
1793
- #
1794
- # Examples:
1795
- #
1796
- # merb:stack:install # install the default merb stack
1797
- # merb:stack:install basics # install a basic set of dependencies
1798
- # merb:stack:install merb-core # install merb-core from stable
1799
- # merb:stack:install merb-more --edge # install merb-core from edge
1800
- # merb:stack:install merb-core thor merb-slices # install the specified gems
1801
-
1802
- desc 'install [COMP, ...]', 'Install stack components'
1803
- method_options "--edge" => :boolean,
1804
- "--sources" => :optional,
1805
- "--force" => :boolean,
1806
- "--dry-run" => :boolean,
1807
- "--strategy" => :optional
1808
- def install(*comps)
1809
- use_edge_gem_server if options[:edge]
1810
- mngr = self.dependency_manager
1811
- deps = gather_dependencies(comps)
1812
- mngr.system, mngr.local, mngr.missing = Merb::Gem.partition_dependencies(deps, gem_dir)
1813
- mngr.install_dependencies(strategy, deps)
1814
- end
1815
-
1816
- # Uninstall stack components or individual gems.
1817
- #
1818
- # See also: Merb::Dependencies#uninstall
1819
- #
1820
- # Examples:
1821
- #
1822
- # merb:stack:uninstall # uninstall the default merb stack
1823
- # merb:stack:uninstall merb-more # uninstall merb-more
1824
- # merb:stack:uninstall merb-core thor merb-slices # uninstall the specified gems
1825
-
1826
- desc 'uninstall [COMP, ...]', 'Uninstall stack components'
1827
- method_options "--dry-run" => :boolean, "--force" => :boolean
1828
- def uninstall(*comps)
1829
- deps = gather_dependencies(comps)
1830
- self.system, self.local, self.missing = Merb::Gem.partition_dependencies(deps, gem_dir)
1831
- # Clobber existing local dependencies - based on self.local
1832
- clobber_dependencies!
1833
- end
1834
-
1835
- # Install or uninstall minigems from the system.
1836
- #
1837
- # Due to the specific nature of MiniGems it can only be installed system-wide.
1838
- #
1839
- # Examples:
1840
- #
1841
- # merb:stack:minigems install # install minigems
1842
- # merb:stack:minigems uninstall # uninstall minigems
1843
-
1844
- desc 'minigems (install|uninstall)', 'Install or uninstall minigems (needs sudo privileges)'
1845
- def minigems(action)
1846
- case action
1847
- when 'install'
1848
- Kernel.system "#{sudo} thor merb:stack:install_minigems"
1849
- when 'uninstall'
1850
- Kernel.system "#{sudo} thor merb:stack:uninstall_minigems"
1851
- else
1852
- error "Invalid command: merb:stack:minigems #{action}"
1853
- end
1854
- end
1855
-
1856
- # hidden minigems install task
1857
- def install_minigems
1858
- message "Installing MiniGems"
1859
- mngr = self.dependency_manager
1860
- deps = gather_dependencies('minigems')
1861
- mngr.system, mngr.local, mngr.missing = Merb::Gem.partition_dependencies(deps, gem_dir)
1862
- mngr.force_gem_dir = ::Gem.dir
1863
- mngr.install_dependencies(strategy, deps)
1864
- Kernel.system "#{sudo} minigem install"
1865
- end
1866
-
1867
- # hidden minigems uninstall task
1868
- def uninstall_minigems
1869
- message "Uninstalling MiniGems"
1870
- Kernel.system "#{sudo} minigem uninstall"
1871
- deps = gather_dependencies('minigems')
1872
- self.system, self.local, self.missing = Merb::Gem.partition_dependencies(deps, gem_dir)
1873
- # Clobber existing local dependencies - based on self.local
1874
- clobber_dependencies!
1875
- end
1876
-
1877
- protected
1878
-
1879
- def gather_dependencies(comps = [])
1880
- if comps.empty?
1881
- gems = MERB_STACK
1882
- else
1883
- gems = comps.map { |c| Merb::Stack.components(c) }.flatten
1884
- end
1885
-
1886
- version_req = if options[:version]
1887
- ::Gem::Requirement.create(options[:version])
1888
- end
1889
-
1890
- framework_components = Merb::Stack.framework_components
1891
-
1892
- gems.map do |gem|
1893
- if version_req && framework_components.include?(gem)
1894
- ::Gem::Dependency.new(gem, version_req)
1895
- else
1896
- ::Gem::Dependency.new(gem, ::Gem::Requirement.default)
1897
- end
1898
- end
1899
- end
1900
-
1901
- def strategy
1902
- options[:strategy] || (options[:edge] ? 'edge' : 'stable')
1903
- end
1904
-
1905
- def dependency_manager
1906
- @_dependency_manager ||= begin
1907
- instance = Merb::Dependencies.new
1908
- instance.options = options
1909
- instance
1910
- end
1911
- end
1912
-
1913
- public
1914
-
1915
- def self.repository_sets
1916
- @_repository_sets ||= begin
1917
- # the component itself as a fallback
1918
- comps = Hash.new { |(hsh,c)| [c] }
1919
-
1920
- # git repository based component sets
1921
- comps["merb"] = ["merb-core"] + MERB_MORE
1922
- comps["merb-more"] = MERB_MORE.sort
1923
- comps["merb-plugins"] = MERB_PLUGINS.sort
1924
- comps["dm-more"] = DM_MORE.sort
1925
- comps["do"] = DATA_OBJECTS.sort
1926
-
1927
- comps
1928
- end
1929
- end
1930
-
1931
- def self.component_sets
1932
- @_component_sets ||= begin
1933
- # the component itself as a fallback
1934
- comps = Hash.new { |(hsh,c)| [c] }
1935
- comps.update(repository_sets)
1936
-
1937
- # specific set of dependencies
1938
- comps["stack"] = MERB_STACK.sort
1939
- comps["basics"] = MERB_BASICS.sort
1940
-
1941
- # orm dependencies
1942
- comps["datamapper"] = DM_STACK.sort
1943
- comps["sequel"] = ["merb_sequel", "sequel"]
1944
- comps["activerecord"] = ["merb_activerecord", "activerecord"]
1945
-
1946
- comps
1947
- end
1948
- end
1949
-
1950
- def self.framework_components
1951
- %w[merb-core merb-more].inject([]) do |all, comp|
1952
- all + components(comp)
1953
- end
1954
- end
1955
-
1956
- def self.components(comp = nil)
1957
- if comp
1958
- component_sets[comp]
1959
- else
1960
- comps = %w[merb-core merb-more merb-plugins dm-core dm-more]
1961
- comps.inject([]) do |all, grp|
1962
- all + (component_sets[grp] || [])
1963
- end
1964
- end
1965
- end
1966
-
1967
- def self.select_component_dependencies(dependencies, comp = nil)
1968
- comps = components(comp) || []
1969
- dependencies.select { |dep| comps.include?(dep.name) }
1970
- end
1971
-
1972
- def self.base_components
1973
- %w[thor rake extlib]
1974
- end
1975
-
1976
- def self.all_components
1977
- base_components + framework_components
1978
- end
1979
-
1980
- # Find the latest merb-core and gather its dependencies.
1981
- # We check for 0.9.8 as a minimum release version.
1982
- def self.core_dependencies(gem_dir = nil, ignore_deps = false)
1983
- @_core_dependencies ||= begin
1984
- if gem_dir # add local gems to index
1985
- orig_gem_path = ::Gem.path
1986
- ::Gem.clear_paths; ::Gem.path.unshift(gem_dir)
1987
- end
1988
- deps = []
1989
- merb_core = ::Gem::Dependency.new('merb-core', '>= 0.9.8')
1990
- if gemspec = ::Gem.source_index.search(merb_core).last
1991
- deps << ::Gem::Dependency.new('merb-core', gemspec.version)
1992
- if ignore_deps
1993
- deps += gemspec.dependencies.select do |d|
1994
- base_components.include?(d.name)
1995
- end
1996
- else
1997
- deps += gemspec.dependencies
1998
- end
1999
- end
2000
- ::Gem.path.replace(orig_gem_path) if gem_dir # reset
2001
- deps
2002
- end
2003
- end
2004
-
2005
- def self.lookup_repository_name(item)
2006
- set_name = nil
2007
- # The merb repo contains -more as well, so it needs special attention
2008
- return 'merb' if self.repository_sets['merb'].include?(item)
2009
-
2010
- # Proceed with finding the item in a known component set
2011
- self.repository_sets.find do |set, items|
2012
- next if set == 'merb'
2013
- items.include?(item) ? (set_name = set) : nil
2014
- end
2015
- set_name
2016
- end
2017
-
2018
- end
2019
-
2020
- end