merb-gen 1.0.4 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -45,11 +45,6 @@ module Merb
45
45
  #
46
46
 
47
47
  empty_directory :gems, 'gems'
48
- file :thorfile do |file|
49
- file.source = File.join(common_templates_dir, "merb.thor")
50
- file.destination = "merb.thor"
51
- end
52
-
53
48
  template :rakefile do |template|
54
49
  template.source = File.join(common_templates_dir, "Rakefile")
55
50
  template.destination = "Rakefile"
@@ -71,6 +66,11 @@ module Merb
71
66
  directory.source = File.join(source_root, dir)
72
67
  directory.destination = dir
73
68
  end
69
+
70
+ directory :thor_file do |directory|
71
+ directory.source = File.join(common_templates_dir, "merb_thor")
72
+ directory.destination = File.join("tasks", "merb.thor")
73
+ end
74
74
 
75
75
  #
76
76
  # ==== Layout specific things
@@ -45,11 +45,6 @@ module Merb
45
45
  #
46
46
 
47
47
  empty_directory :gems, 'gems'
48
- file :thorfile do |file|
49
- file.source = File.join(common_templates_dir, "merb.thor")
50
- file.destination = "merb.thor"
51
- end
52
-
53
48
  template :rakefile do |template|
54
49
  template.source = File.join(common_templates_dir, "Rakefile")
55
50
  template.destination = "Rakefile"
@@ -66,6 +61,11 @@ module Merb
66
61
  directory.source = File.join(source_root, dir)
67
62
  directory.destination = dir
68
63
  end
64
+
65
+ directory :thor_file do |directory|
66
+ directory.source = File.join(common_templates_dir, "merb_thor")
67
+ directory.destination = File.join("tasks", "merb.thor")
68
+ end
69
69
 
70
70
  #
71
71
  # ==== Layout specific things
@@ -49,11 +49,6 @@ module Merb
49
49
  #
50
50
 
51
51
  empty_directory :gems, 'gems'
52
- file :thorfile do |file|
53
- file.source = File.join(common_templates_dir, "merb.thor")
54
- file.destination = "tasks/merb.thor"
55
- end
56
-
57
52
  template :rakefile do |template|
58
53
  template.source = File.join(common_templates_dir, "Rakefile")
59
54
  template.destination = "Rakefile"
@@ -79,6 +74,11 @@ module Merb
79
74
  file.destination = 'public/javascripts/jquery.js'
80
75
  end
81
76
 
77
+ directory :thor_file do |directory|
78
+ directory.source = File.join(common_templates_dir, "merb_thor")
79
+ directory.destination = File.join("tasks", "merb.thor")
80
+ end
81
+
82
82
  directory :test_dir do |directory|
83
83
  dir = testing_framework == :rspec ? "spec" : "test"
84
84
 
@@ -49,16 +49,16 @@ module Merb
49
49
  directory.destination = dir
50
50
  end
51
51
 
52
+ directory :thor_file do |directory|
53
+ directory.source = File.join(common_templates_dir, "merb_thor")
54
+ directory.destination = File.join("tasks", "merb.thor")
55
+ end
56
+
52
57
  template :rakefile do |template|
53
58
  template.source = File.join(common_templates_dir, "Rakefile")
54
59
  template.destination = "Rakefile"
55
60
  end
56
61
 
57
- file :thorfile do |file|
58
- file.source = File.join(common_templates_dir, "merb.thor")
59
- file.destination = "merb.thor"
60
- end
61
-
62
62
  def class_name
63
63
  self.name.gsub("-", "_").camel_case
64
64
  end
@@ -15,4 +15,9 @@ schema/*.db
15
15
  src/*
16
16
  .hgignore
17
17
  .hg/*
18
- .svn/*
18
+ .svn/*
19
+ gems/gems/*/
20
+ gems/specifications/*
21
+ !gems/gems/thor*/
22
+ !gems/specifications/thor*
23
+ merb_profile_results
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # This was added by Merb's bundler
4
+
5
+ require "rubygems"
6
+ require File.join(File.dirname(__FILE__), "common")
7
+
8
+ gems_dir = File.join(File.dirname(__FILE__), '..', 'gems')
9
+
10
+ if File.directory?(gems_dir)
11
+ $BUNDLE = true
12
+ Gem.clear_paths
13
+ Gem.path.replace([File.expand_path(gems_dir)])
14
+ ENV["PATH"] = "#{File.dirname(__FILE__)}:#{ENV["PATH"]}"
15
+
16
+ gem_file = File.join(gems_dir, "specifications", "<%= spec.name %>-*.gemspec")
17
+
18
+ if local_gem = Dir[gem_file].last
19
+ version = File.basename(local_gem)[/-([\.\d]+)\.gemspec$/, 1]
20
+ end
21
+ end
22
+
23
+ version ||= "<%= Gem::Requirement.default %>"
24
+
25
+ if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
26
+ version = $1
27
+ ARGV.shift
28
+ end
29
+
30
+ gem '<%= @spec.name %>', version
31
+ load '<%= bin_file_name %>'
@@ -0,0 +1,64 @@
1
+ # This was added via Merb's bundler
2
+
3
+ require "rubygems"
4
+ require "rubygems/source_index"
5
+
6
+ module Gem
7
+ BUNDLED_SPECS = File.join(Dir.pwd, "gems", "specifications")
8
+ MAIN_INDEX = Gem::SourceIndex.from_gems_in(BUNDLED_SPECS)
9
+ FALLBACK_INDEX = Gem::SourceIndex.from_installed_gems
10
+
11
+ def self.source_index
12
+ MultiSourceIndex.new
13
+ end
14
+
15
+ def self.searcher
16
+ MultiPathSearcher.new
17
+ end
18
+
19
+ class ArbitrarySearcher < GemPathSearcher
20
+ def initialize(source_index)
21
+ @source_index = source_index
22
+ super()
23
+ end
24
+
25
+ def init_gemspecs
26
+ @source_index.map { |_, spec| spec }.sort { |a,b|
27
+ (a.name <=> b.name).nonzero? || (b.version <=> a.version)
28
+ }
29
+ end
30
+ end
31
+
32
+ class MultiPathSearcher
33
+ def initialize
34
+ @main_searcher = ArbitrarySearcher.new(MAIN_INDEX)
35
+ @fallback_searcher = ArbitrarySearcher.new(FALLBACK_INDEX)
36
+ end
37
+
38
+ def find(path)
39
+ try = @main_searcher.find(path)
40
+ return try if try
41
+ @fallback_searcher.find(path)
42
+ end
43
+
44
+ def find_all(path)
45
+ try = @main_searcher.find_all(path)
46
+ return try unless try.empty?
47
+ @fallback_searcher.find_all(path)
48
+ end
49
+ end
50
+
51
+ class MultiSourceIndex
52
+ def search(*args)
53
+ try = MAIN_INDEX.search(*args)
54
+ return try unless try.empty?
55
+ FALLBACK_INDEX.search(*args)
56
+ end
57
+
58
+ def find_name(*args)
59
+ try = MAIN_INDEX.find_name(*args)
60
+ return try unless try.empty?
61
+ FALLBACK_INDEX.find_name(*args)
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,123 @@
1
+ require "erb"
2
+
3
+ Gem.pre_install_hooks.push(proc do |installer|
4
+ $INSTALLING << installer.spec
5
+
6
+ unless File.file?(installer.bin_dir / "common.rb")
7
+ FileUtils.mkdir_p(installer.bin_dir)
8
+ FileUtils.cp(File.dirname(__FILE__) / "common.rb", installer.bin_dir / "common.rb")
9
+ end
10
+
11
+ include ColorfulMessages
12
+ name = installer.spec.name
13
+ if $GEMS && versions = ($GEMS.assoc(name) || [])[1]
14
+ dep = Gem::Dependency.new(name, versions)
15
+ unless dep.version_requirements.satisfied_by?(installer.spec.version)
16
+ error "Cannot install #{installer.spec.full_name} " \
17
+ "for #{$INSTALLING.map {|x| x.full_name}.join(", ")}; " \
18
+ "you required #{dep}"
19
+ ::Thor::Tasks::Merb::Gem.rollback_trans
20
+ exit!
21
+ end
22
+ end
23
+ success "Installing #{installer.spec.full_name}"
24
+ end)
25
+
26
+ class ::Gem::Uninstaller
27
+ def self._with_silent_ui
28
+
29
+ ui = Gem::DefaultUserInteraction.ui
30
+ def ui.say(str)
31
+ puts "- #{str}"
32
+ end
33
+
34
+ yield
35
+
36
+ class << Gem::DefaultUserInteraction.ui
37
+ undef :say
38
+ end
39
+ end
40
+
41
+ def self._uninstall(source_index, name, op, version)
42
+ unless source_index.find_name(name, "#{op} #{version}").empty?
43
+ uninstaller = Gem::Uninstaller.new(
44
+ name,
45
+ :version => "#{op} #{version}",
46
+ :install_dir => Dir.pwd / "gems",
47
+ :all => true,
48
+ :ignore => true
49
+ )
50
+ _with_silent_ui { uninstaller.uninstall }
51
+ end
52
+ end
53
+
54
+ def self._uninstall_others(source_index, name, version)
55
+ _uninstall(source_index, name, "<", version)
56
+ _uninstall(source_index, name, ">", version)
57
+ end
58
+ end
59
+
60
+ Gem.post_install_hooks.push(proc do |installer|
61
+ $INSTALLING.pop
62
+ source_index = installer.instance_variable_get("@source_index")
63
+ ::Gem::Uninstaller._uninstall_others(
64
+ source_index, installer.spec.name, installer.spec.version
65
+ )
66
+ end)
67
+
68
+ class ::Gem::DependencyInstaller
69
+ alias old_fg find_gems_with_sources
70
+
71
+ def find_gems_with_sources(dep)
72
+ if @source_index.any? { |_, installed_spec|
73
+ installed_spec.satisfies_requirement?(dep)
74
+ }
75
+ return []
76
+ end
77
+
78
+ old_fg(dep)
79
+ end
80
+ end
81
+
82
+ class ::Gem::SpecFetcher
83
+ alias old_fetch fetch
84
+ def fetch(dependency, all = false, matching_platform = true)
85
+ idx = Gem::SourceIndex.from_installed_gems
86
+
87
+ dep = idx.search(dependency).sort.last
88
+
89
+ if dep
90
+ file = dep.loaded_from.dup
91
+ file.gsub!(/specifications/, "cache")
92
+ file.gsub!(/gemspec$/, "gem")
93
+ spec = ::Gem::Format.from_file_by_path(file).spec
94
+ [[spec, file]]
95
+ else
96
+ old_fetch(dependency, all, matching_platform)
97
+ end
98
+ end
99
+ end
100
+
101
+ class ::Gem::Installer
102
+ def app_script_text(bin_file_name)
103
+ template = File.read(File.dirname(__FILE__) / "app_script.rb")
104
+ erb = ERB.new(template)
105
+ erb.result(binding)
106
+ end
107
+ end
108
+
109
+ class ::Gem::Specification
110
+ def recursive_dependencies(from, index = Gem.source_index)
111
+ specs = self.runtime_dependencies.map do |dep|
112
+ spec = index.search(dep).last
113
+ unless spec
114
+ wider_net = index.find_name(dep.name).last
115
+ ThorUI.error "Needed #{dep} for #{from.full_name}, but could not find it"
116
+ ThorUI.error "Found #{wider_net.full_name}" if wider_net
117
+ ::Thor::Tasks::Merb::Gem.rollback_trans
118
+ end
119
+ spec
120
+ end
121
+ specs + specs.map {|s| s.recursive_dependencies(self, index)}.flatten.uniq
122
+ end
123
+ end
@@ -0,0 +1,150 @@
1
+ require "rubygems"
2
+ require "rubygems/source_index"
3
+ require "rubygems/dependency_installer"
4
+ require "rubygems/uninstaller"
5
+ require "fileutils"
6
+ require File.join(File.dirname(__FILE__), "utils")
7
+ require File.join(File.dirname(__FILE__), "gem_ext")
8
+ require File.join(File.dirname(__FILE__), "ops")
9
+
10
+ $INSTALLING = []
11
+
12
+ module Merb
13
+
14
+ class Gem < Thor
15
+ extend ColorfulMessages
16
+
17
+ def initialize
18
+ dirs = [Dir.pwd, File.dirname(__FILE__) / ".."]
19
+ root = dirs.find {|d| File.file?(d / "config" / "dependencies.rb")}
20
+
21
+ if root
22
+ @depsrb = root / "config" / "dependencies.rb"
23
+ else
24
+ self.class.error "dependencies.rb was not found"
25
+ exit!
26
+ end
27
+
28
+ FileUtils.mkdir_p(Dir.pwd / "gems")
29
+
30
+ @list = Collector.collect(File.read(@depsrb))
31
+ @idx = ::Gem::SourceIndex.new.load_gems_in("gems/specifications")
32
+ end
33
+
34
+ def list
35
+ require "pp"
36
+ pp @list
37
+ end
38
+
39
+ desc "redeploy", "Syncs up gems/cache with gems/gems. All gems in the cache " \
40
+ "that are not already installed will be installed from the " \
41
+ "cache. All installed gems that are not in the cache will " \
42
+ "be uninstalled."
43
+ def redeploy
44
+ gem_dir = Dir.pwd / "gems" / "gems"
45
+ cache_dir = Dir.pwd / "gems" / "cache"
46
+
47
+ gems = Dir[gem_dir / "*"].map! {|n| File.basename(n)}
48
+ cache = Dir[cache_dir / "*.gem"].map! {|n| File.basename(n, ".gem")}
49
+ new_gems = cache - gems
50
+ outdated = gems - cache
51
+ idx = ::Gem::SourceIndex.new
52
+ idx.load_gems_in(Dir.pwd / "gems" / "specifications")
53
+
54
+ new_gems.each do |g|
55
+ installer = ::Gem::Installer.new(cache_dir / "#{g}.gem",
56
+ :bin_dir => Dir.pwd / "bin",
57
+ :install_dir => Dir.pwd / "gems",
58
+ :ignore_dependencies => true,
59
+ :user_install => false,
60
+ :wrappers => true,
61
+ :source_index => idx)
62
+
63
+ installer.install
64
+ end
65
+
66
+ outdated.each do |g|
67
+ /(.*)\-(.*)/ =~ g
68
+ name, version = $1, $2
69
+ uninstaller = ::Gem::Uninstaller.new(name,
70
+ :version => version,
71
+ :bin_dir => Dir.pwd / "bin",
72
+ :install_dir => Dir.pwd / "gems",
73
+ :ignore => true,
74
+ :executables => true
75
+ )
76
+ uninstaller.uninstall
77
+ end
78
+ end
79
+
80
+ desc "confirm", "Confirm the current setup. merb:gem:install will " \
81
+ "automatically run this task before committing the " \
82
+ "changes it makes."
83
+ def confirm(gems = @list)
84
+ ::Gem.path.replace([Dir.pwd / "gems"])
85
+ ::Gem.source_index.load_gems_in(Dir.pwd / "gems" / "specifications")
86
+
87
+ self.class.info "Confirming configuration..."
88
+
89
+ ::Gem.loaded_specs.clear
90
+
91
+ begin
92
+ gems.each do |name, versions|
93
+ versions ||= []
94
+ ::Gem.activate name, *versions
95
+ end
96
+ rescue ::Gem::LoadError => e
97
+ self.class.error "Configuration could not be confirmed: #{e.message}"
98
+ self.class.rollback_trans
99
+ end
100
+ self.class.info "Confirmed"
101
+ end
102
+
103
+ desc 'install', 'Sync up your bundled gems with the list in config/dependencies.rb'
104
+ def install(*gems)
105
+ if gems.empty?
106
+ gems = @list
107
+ else
108
+ gems = gems.map {|desc| name, *versions = desc.split(" ") }
109
+ end
110
+
111
+ $GEMS = gems
112
+
113
+ self.class.begin_trans
114
+
115
+ gems.each do |name, versions|
116
+ dep = ::Gem::Dependency.new(name, versions || [])
117
+ unless @idx.search(dep).empty?
118
+ next
119
+ end
120
+
121
+ rescue_failures do
122
+ $INSTALLING = []
123
+ _install(dep)
124
+ end
125
+ end
126
+
127
+ gem_dir = Dir.pwd / "gems" / "gems"
128
+ installed_gems = Dir[gem_dir / "*"].map! {|n| File.basename(n)}
129
+
130
+ list = full_list.map {|x| x.full_name}.compact
131
+
132
+ (installed_gems - list).each do |g|
133
+ /^(.*)\-(.*)$/ =~ g
134
+ name, version = $1, $2
135
+ uninstaller = ::Gem::Uninstaller.new(name,
136
+ :version => version,
137
+ :bin_dir => (Dir.pwd / "bin").to_s,
138
+ :install_dir => (Dir.pwd / "gems").to_s,
139
+ :ignore => true,
140
+ :executables => true
141
+ )
142
+ uninstaller.uninstall
143
+ end
144
+
145
+ confirm(gems)
146
+
147
+ self.class.commit_trans
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,88 @@
1
+ module Thor::Tasks
2
+ module Merb
3
+ class Collector
4
+ attr_reader :dependencies
5
+
6
+ def self.collect(str)
7
+ collector = new
8
+ collector.instance_eval(str)
9
+ collector.dependencies
10
+ end
11
+
12
+ def initialize
13
+ @dependencies = []
14
+ end
15
+
16
+ def dependency(name, *versions)
17
+ @dependencies << [name, versions]
18
+ end
19
+ end
20
+
21
+ class Gem < Thor
22
+ def full_list
23
+ @idx.load_gems_in("gems/specifications")
24
+
25
+ @list.map do |name, versions|
26
+ dep = @idx.find_name(name).last
27
+ unless dep
28
+ self.class.error "A required dependency #{dep} was not found"
29
+ self.class.rollback_trans
30
+ end
31
+ deps = dep.recursive_dependencies(dep, @idx)
32
+ [dep] + deps
33
+ end.flatten.uniq
34
+ end
35
+
36
+ def rescue_failures(error = StandardError, prc = nil)
37
+ begin
38
+ yield
39
+ rescue error => e
40
+ if prc
41
+ prc.call(e)
42
+ else
43
+ puts e.message
44
+ puts e.backtrace
45
+ end
46
+ self.class.rollback_trans
47
+ end
48
+ end
49
+
50
+ def self.begin_trans
51
+ note "Beginning transaction"
52
+ FileUtils.cp_r(Dir.pwd / "gems", Dir.pwd / ".original_gems")
53
+ end
54
+
55
+ def self.commit_trans
56
+ note "Committing transaction"
57
+ FileUtils.rm_rf(Dir.pwd / ".original_gems")
58
+ end
59
+
60
+ def self.rollback_trans
61
+ if File.exist?(Dir.pwd / ".original_gems")
62
+ note "Rolling back transaction"
63
+ FileUtils.rm_rf(Dir.pwd / "gems")
64
+ FileUtils.mv(Dir.pwd / ".original_gems", Dir.pwd / "gems")
65
+ end
66
+ exit!
67
+ end
68
+
69
+ private
70
+ def _install(dep)
71
+ installer = ::Gem::DependencyInstaller.new(
72
+ :bin_dir => Dir.pwd / "bin",
73
+ :install_dir => Dir.pwd / "gems",
74
+ :user_install => false)
75
+
76
+ begin
77
+ installer.install dep.name, dep.version_requirements
78
+ rescue ::Gem::GemNotFoundException => e
79
+ puts "Cannot find #{dep}"
80
+ rescue ::Gem::RemoteFetcher::FetchError => e
81
+ puts e.message
82
+ puts "Retrying..."
83
+ retry
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,40 @@
1
+ class String
2
+ def /(other)
3
+ (Pathname.new(self) + other).to_s
4
+ end
5
+ end
6
+
7
+ module ColorfulMessages
8
+
9
+ # red
10
+ def error(*messages)
11
+ puts messages.map { |msg| "\033[1;31m#{msg}\033[0m" }
12
+ end
13
+
14
+ # yellow
15
+ def warning(*messages)
16
+ puts messages.map { |msg| "\033[1;33m#{msg}\033[0m" }
17
+ end
18
+
19
+ # green
20
+ def success(*messages)
21
+ puts messages.map { |msg| "\033[1;32m#{msg}\033[0m" }
22
+ end
23
+
24
+ alias_method :message, :success
25
+
26
+ # magenta
27
+ def note(*messages)
28
+ puts messages.map { |msg| "\033[1;35m#{msg}\033[0m" }
29
+ end
30
+
31
+ # blue
32
+ def info(*messages)
33
+ puts messages.map { |msg| "\033[1;34m#{msg}\033[0m" }
34
+ end
35
+
36
+ end
37
+
38
+ module ThorUI
39
+ extend ColorfulMessages
40
+ end
@@ -17,4 +17,9 @@ Spec::Runner.configure do |config|
17
17
  config.include(Merb::Test::ViewHelper)
18
18
  config.include(Merb::Test::RouteHelper)
19
19
  config.include(Merb::Test::ControllerHelper)
20
+
21
+ config.before(:all) do
22
+ DataMapper.auto_migrate! if Merb.orm == :datamapper
23
+ end
24
+
20
25
  end
@@ -1,8 +1,6 @@
1
1
  <% with_modules(modules) do -%>
2
2
  class <%= class_name %> < Application
3
3
 
4
- # ...and remember, everything returned from an action
5
- # goes to the client...
6
4
  def index
7
5
  render
8
6
  end
@@ -0,0 +1,28 @@
1
+ module Merb
2
+ module Generators
3
+ class ThorGenerator < AppGenerator
4
+ #
5
+ # ==== Paths
6
+ #
7
+
8
+ def self.source_root
9
+ File.join(super, 'application', 'common', 'merb_thor')
10
+ end
11
+
12
+ def destination_root
13
+ File.join(@destination_root, 'tasks')
14
+ end
15
+
16
+ def common_templates_dir
17
+ File.expand_path(File.join(File.dirname(__FILE__),
18
+ 'templates', 'application', 'common'))
19
+ end
20
+
21
+ directory :thor_file do |directory|
22
+ directory.source = File.join(common_templates_dir, "merb_thor")
23
+ directory.destination = File.join("merb.thor")
24
+ end
25
+ end
26
+ add :thor, ThorGenerator
27
+ end
28
+ end
@@ -0,0 +1,40 @@
1
+ module Templater
2
+ module Actions
3
+ class Directory < File
4
+ def identical?
5
+ sanity = ::File.directory?(destination) && exists?
6
+ if sanity
7
+ src = Dir[::File.join(source, "**", "*")]
8
+ src.map! {|f| f.gsub(/#{source}/, "")}
9
+ dest = Dir[::File.join(destination, "**", "*")]
10
+ dest.map! {|f| f.gsub(/#{destination}/, "")}
11
+ src == dest
12
+ else
13
+ false
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ module Templater
21
+ module Actions
22
+ class File < Action
23
+
24
+ # Renders the template and copies it to the destination.
25
+ def invoke!
26
+ callback(:before)
27
+ ::FileUtils.mkdir_p(::File.dirname(destination))
28
+ ::FileUtils.rm_rf(destination)
29
+ ::FileUtils.cp_r(source, destination)
30
+ callback(:after)
31
+ end
32
+
33
+ # removes the destination file
34
+ def revoke!
35
+ ::FileUtils.rm_r(destination, :force => true)
36
+ end
37
+
38
+ end
39
+ end
40
+ end