hoe 1.12.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,182 @@
1
+ ##
2
+ # Publish plugin for hoe.
3
+ #
4
+ # === Tasks Provided:
5
+ #
6
+ # announce:: Create news email file and post to rubyforge.
7
+ # email:: Generate email announcement file.
8
+ # post_blog:: Post announcement to blog.
9
+ # post_news:: Post announcement to rubyforge.
10
+ # publish_docs:: Publish RDoc to RubyForge.
11
+ # ridocs:: Generate ri locally for testing.
12
+ #
13
+ # === Extra Configuration Options:
14
+ #
15
+ # publish_on_announce:: Run +publish_docs+ when you run +release+.
16
+ # blogs:: An array of hashes of blog settings.
17
+
18
+ module Hoe::Publish
19
+ Hoe.plugin :publish
20
+
21
+ ##
22
+ # *Optional*: An array of the project's blog categories. Defaults to project name.
23
+
24
+ attr_accessor :blog_categories
25
+
26
+ ##
27
+ # Optional: Name of RDoc destination directory on Rubyforge. [default: +name+]
28
+
29
+ attr_accessor :remote_rdoc_dir
30
+
31
+ ##
32
+ # Optional: Flags for RDoc rsync. [default: "-av --delete"]
33
+
34
+ attr_accessor :rsync_args
35
+
36
+ Hoe::DEFAULT_CONFIG["publish_on_announce"] = true
37
+ Hoe::DEFAULT_CONFIG["blog"] = [
38
+ {
39
+ "user" => "user",
40
+ "password" => "password",
41
+ "url" => "url",
42
+ "blog_id" => "blog_id",
43
+ "extra_headers" => {
44
+ "mt_convert_breaks" => "markdown"
45
+ },
46
+ }
47
+ ]
48
+
49
+ ##
50
+ # Initialize variables for plugin.
51
+
52
+ def initialize_publish
53
+ self.blog_categories ||= [self.name]
54
+ self.remote_rdoc_dir ||= self.name
55
+ self.rsync_args ||= '-av --delete'
56
+ end
57
+
58
+ ##
59
+ # Define tasks for plugin.
60
+
61
+ def define_publish_tasks
62
+ Rake::RDocTask.new(:docs) do |rd|
63
+ rd.main = readme_file
64
+ rd.options << '-d' if (`which dot` =~ /\/dot/) unless
65
+ ENV['NODOT'] || Hoe::WINDOZE
66
+ rd.rdoc_dir = 'doc'
67
+
68
+ rd.rdoc_files += spec.require_paths
69
+ rd.rdoc_files += spec.extra_rdoc_files
70
+
71
+ title = "#{name}-#{version} Documentation"
72
+ title = "#{rubyforge_name}'s " + title if rubyforge_name != name
73
+
74
+ rd.options << "-t" << title
75
+ end
76
+
77
+ desc 'Generate ri locally for testing.'
78
+ task :ridocs => :clean do
79
+ sh %q{ rdoc --ri -o ri . }
80
+ end
81
+
82
+ desc 'Publish RDoc to RubyForge.'
83
+ task :publish_docs => [:clean, :docs] do
84
+ config = YAML.load(File.read(File.expand_path("~/.rubyforge/user-config.yml")))
85
+ host = "#{config["username"]}@rubyforge.org"
86
+
87
+ remote_dir = "/var/www/gforge-projects/#{rubyforge_name}/#{remote_rdoc_dir}"
88
+ local_dir = 'doc'
89
+
90
+ sh %{rsync #{rsync_args} #{local_dir}/ #{host}:#{remote_dir}}
91
+ end
92
+
93
+ # no doco for this one
94
+ task :publish_on_announce do
95
+ with_config do |config, _|
96
+ Rake::Task['publish_docs'].invoke if config["publish_on_announce"]
97
+ end
98
+ end
99
+
100
+ desc 'Generate email announcement file.'
101
+ task :email do
102
+ require 'rubyforge'
103
+ subject, title, body, urls = announcement
104
+
105
+ File.open("email.txt", "w") do |mail|
106
+ mail.puts "Subject: [ANN] #{subject}"
107
+ mail.puts
108
+ mail.puts title
109
+ mail.puts
110
+ mail.puts urls
111
+ mail.puts
112
+ mail.puts body
113
+ mail.puts
114
+ mail.puts urls
115
+ end
116
+ puts "Created email.txt"
117
+ end
118
+
119
+ desc 'Post announcement to blog.'
120
+ task :post_blog do
121
+ require 'xmlrpc/client'
122
+
123
+ with_config do |config, path|
124
+ break unless config['blogs']
125
+
126
+ subject, title, body, urls = announcement
127
+ body += "\n\n#{urls}"
128
+
129
+ config['blogs'].each do |site|
130
+ server = XMLRPC::Client.new2(site['url'])
131
+ content = site['extra_headers'].merge(:title => title,
132
+ :description => body,
133
+ :categories => blog_categories)
134
+
135
+ result = server.call('metaWeblog.newPost',
136
+ site['blog_id'],
137
+ site['user'],
138
+ site['password'],
139
+ content,
140
+ true)
141
+ end
142
+ end
143
+ end
144
+
145
+ desc 'Post announcement to rubyforge.'
146
+ task :post_news do
147
+ require 'rubyforge'
148
+ subject, title, body, urls = announcement
149
+
150
+ rf = RubyForge.new.configure
151
+ rf.login
152
+ rf.post_news(rubyforge_name, subject, "#{title}\n\n#{body}")
153
+ puts "Posted to rubyforge"
154
+ end
155
+
156
+ desc 'Create news email file and post to rubyforge.'
157
+ task :announce => [:email, :post_news, :post_blog, :publish_on_announce ]
158
+ end
159
+
160
+ def announcement # :nodoc:
161
+ changes = self.changes.rdoc_to_markdown
162
+ subject = "#{name} #{version} Released"
163
+ title = "#{name} version #{version} has been released!"
164
+ body = "#{description}\n\nChanges:\n\n#{changes}".rdoc_to_markdown
165
+ urls = Array(url).map { |s| "* <#{s.strip.rdoc_to_markdown}>" }.join("\n")
166
+
167
+ return subject, title, body, urls
168
+ end
169
+ end
170
+
171
+ class ::Rake::SshDirPublisher # :nodoc:
172
+ attr_reader :host, :remote_dir, :local_dir
173
+ end
174
+
175
+ class String
176
+ ##
177
+ # Very basic munge from rdoc to markdown format.
178
+
179
+ def rdoc_to_markdown
180
+ self.gsub(/^mailto:/, '').gsub(/^(=+)/) { "#" * $1.size }
181
+ end
182
+ end
@@ -0,0 +1,44 @@
1
+ module Rake
2
+ module TaskManager
3
+ ##
4
+ # This gives us access to the tasks already defined in rake.
5
+ def all_tasks
6
+ @tasks
7
+ end
8
+ end
9
+
10
+ ##
11
+ # Simple shortcut for Rake.application.all_tasks
12
+ def self.all_tasks
13
+ Rake.application.all_tasks
14
+ end
15
+
16
+ ##
17
+ # Hooks into rake and allows us to clear out a task by name or
18
+ # regexp. Use this if you want to completely override a task instead
19
+ # of extend it.
20
+ def self.clear_tasks(*tasks)
21
+ tasks.flatten.each do |name|
22
+ case name
23
+ when Regexp then
24
+ all_tasks.delete_if { |k,_| k =~ name }
25
+ else
26
+ all_tasks.delete(name)
27
+ end
28
+ end
29
+ end
30
+
31
+ ##
32
+ # Removes the last action added to a task. Use this when two
33
+ # libraries define the same task and you only want one of the
34
+ # actions.
35
+ #
36
+ # require 'hoe'
37
+ # require 'tasks/rails'
38
+ # Rake.undo("test") # rolls out rails' test task
39
+ def self.undo(*names)
40
+ names.each do |name|
41
+ all_tasks[name].actions.delete_at(-1)
42
+ end
43
+ end
44
+ end unless Rake.respond_to? :all_tasks
@@ -0,0 +1,44 @@
1
+ ##
2
+ # RCov plugin for hoe.
3
+ #
4
+ # === Tasks Provided:
5
+ #
6
+ # rcov:: Analyze code coverage with tests
7
+
8
+ module Hoe::RCov
9
+ Hoe.plugin :rcov
10
+
11
+ ##
12
+ # Define tasks for plugin.
13
+
14
+ def define_rcov_tasks
15
+ begin # take a whack at defining rcov tasks
16
+ require 'rcov/rcovtask'
17
+
18
+ Rcov::RcovTask.new do |t|
19
+ pattern = ENV['PATTERN'] || 'test/test_*.rb'
20
+
21
+ t.test_files = FileList[pattern]
22
+ t.verbose = true
23
+ t.rcov_opts << "--no-color"
24
+ t.rcov_opts << "--save coverage.info"
25
+ t.rcov_opts << "-x ^/"
26
+ end
27
+
28
+ # this is for my emacs rcov overlay stuff on emacswiki.
29
+ task :rcov_overlay do
30
+ path = ENV["FILE"]
31
+ rcov, eol = Marshal.load(File.read("coverage.info")).last[path], 1
32
+ puts rcov[:lines].zip(rcov[:coverage]).map { |line, coverage|
33
+ bol, eol = eol, eol + line.length
34
+ [bol, eol, "#ffcccc"] unless coverage
35
+ }.compact.inspect
36
+ end
37
+ rescue LoadError
38
+ # skip
39
+ task :clobber_rcov # in case rcov didn't load
40
+ end
41
+ end
42
+ end
43
+
44
+ task :clean => :clobber_rcov
@@ -0,0 +1,119 @@
1
+ ##
2
+ # Signing plugin for hoe.
3
+ #
4
+ # === Tasks Provided:
5
+ #
6
+ # generate_key:: Generate a key for signing your gems.
7
+ #
8
+ # === Extra Configuration Options:
9
+ #
10
+ # signing_key_file:: Signs your gems with this private key.
11
+ # signing_cert_file:: Signs your gem with this certificate.
12
+ #
13
+ # === Usage:
14
+ #
15
+ # Run the 'generate_key' task. This will:
16
+ #
17
+ # 1. Configure your ~/.hoerc.
18
+ # 2. Generate a signing key and certificate.
19
+ # 3. Install the private key and public certificate files into ~/.gem.
20
+ # 4. Upload the certificate to RubyForge.
21
+ #
22
+ # Hoe will now generate signed gems when the package task is run. If you have
23
+ # multiple machines you build gems on, be sure to install your key and
24
+ # certificate on each machine.
25
+ #
26
+ # Keep your private key secret! Keep your private key safe!
27
+ #
28
+ # To make sure your gems are signed run:
29
+ #
30
+ # rake package; tar tf pkg/yourproject-1.2.3.gem
31
+ #
32
+ # If your gem is signed you will see:
33
+ #
34
+ # data.tar.gz
35
+ # data.tar.gz.sig
36
+ # metadata.gz
37
+ # metadata.gz.sig
38
+
39
+ module Hoe::Signing
40
+ Hoe.plugin :signing
41
+
42
+ Hoe::DEFAULT_CONFIG["signing_key_file"] = "~/.gem/gem-private_key.pem"
43
+ Hoe::DEFAULT_CONFIG["signing_cert_file"] = "~/.gem/gem-public_cert.pem"
44
+
45
+ ##
46
+ # Define tasks for plugin.
47
+
48
+ def define_signing_tasks
49
+ signing_key = nil
50
+ cert_chain = []
51
+
52
+ with_config do |config, path|
53
+ break unless config['signing_key_file'] and config['signing_cert_file']
54
+ key_file = File.expand_path config['signing_key_file'].to_s
55
+ signing_key = key_file if File.exist? key_file
56
+
57
+ cert_file = File.expand_path config['signing_cert_file'].to_s
58
+ cert_chain << cert_file if File.exist? cert_file
59
+ end
60
+
61
+ if signing_key and cert_chain then
62
+ spec.signing_key = signing_key
63
+ spec.cert_chain = cert_chain
64
+ end
65
+
66
+ desc 'Generate a key for signing your gems.'
67
+ task :generate_key do
68
+ email = Array(spec.email)
69
+ abort "No email in your gemspec" if email.nil? or email.empty?
70
+
71
+ key_file = with_config { |config, _| config['signing_key_file'] }
72
+ cert_file = with_config { |config, _| config['signing_cert_file'] }
73
+
74
+ if key_file.nil? or cert_file.nil? then
75
+ ENV['SHOW_EDITOR'] ||= 'no'
76
+ Rake::Task['config_hoe'].invoke
77
+
78
+ key_file = with_config { |config, _| config['signing_key_file'] }
79
+ cert_file = with_config { |config, _| config['signing_cert_file'] }
80
+ end
81
+
82
+ key_file = File.expand_path key_file
83
+ cert_file = File.expand_path cert_file
84
+
85
+ unless File.exist? key_file or File.exist? cert_file then
86
+ warn "NOTICE: using #{email.first} for certificate" if email.size > 1
87
+
88
+ sh "gem cert --build #{email.first}"
89
+ mv "gem-private_key.pem", key_file, :verbose => true
90
+ mv "gem-public_cert.pem", cert_file, :verbose => true
91
+
92
+ puts "Installed key and certificate."
93
+
94
+ rf = RubyForge.new.configure
95
+ rf.login
96
+
97
+ cert_package = "#{rubyforge_name}-certificates"
98
+
99
+ begin
100
+ rf.lookup 'package', cert_package
101
+ rescue
102
+ rf.create_package rubyforge_name, cert_package
103
+ end
104
+
105
+ begin
106
+ rf.lookup('release', cert_package)['certificates']
107
+ rf.add_file rubyforge_name, cert_package, 'certificates', cert_file
108
+ rescue
109
+ rf.create_package rubyforge_name, cert_package
110
+ rf.add_release rubyforge_name, cert_package, 'certificates', cert_file
111
+ end
112
+
113
+ puts "Uploaded certificate to release \"certificates\" in package #{cert_package}"
114
+ else
115
+ puts "Keys already exist: #{key_file} and #{cert_file}"
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,140 @@
1
+ ##
2
+ # Test plugin for hoe.
3
+ #
4
+ # === Tasks Provided:
5
+ #
6
+ # audit:: Run ZenTest against the package.
7
+ # default:: Run the default task(s).
8
+ # multi:: Run the test suite using multiruby.
9
+ # test:: Run the test suite.
10
+ # test_deps:: Show which test files fail when run alone.
11
+
12
+ module Hoe::Test
13
+ Hoe.plugin :test # activate globally, fine for general purpose tasks
14
+
15
+ ##
16
+ # Configuration for the supported test frameworks for test task.
17
+
18
+ SUPPORTED_TEST_FRAMEWORKS = {
19
+ :testunit => "test/unit",
20
+ :minitest => "minitest/autorun",
21
+ }
22
+
23
+ ##
24
+ # Used to add flags to test_unit (e.g., -n test_borked).
25
+ #
26
+ # eg FILTER="-n test_blah"
27
+
28
+ FILTER = ENV['FILTER'] || ENV['TESTOPTS']
29
+
30
+ ##
31
+ # Optional: Array of incompatible versions for multiruby filtering.
32
+ # Used as a regex.
33
+
34
+ attr_accessor :multiruby_skip
35
+
36
+ ##
37
+ # Optional: What test library to require [default: :testunit]
38
+
39
+ attr_accessor :testlib
40
+
41
+ ##
42
+ # Optional: RSpec dirs. [default: %w(spec lib)]
43
+
44
+ attr_accessor :rspec_dirs
45
+
46
+ ##
47
+ # Optional: RSpec options. [default: []]
48
+
49
+ attr_accessor :rspec_options
50
+
51
+ ##
52
+ # Initialize variables for plugin.
53
+
54
+ def initialize_test
55
+ self.multiruby_skip ||= []
56
+ self.testlib ||= :testunit
57
+ self.rspec_dirs ||= %w(spec lib)
58
+ self.rspec_options ||= []
59
+ end
60
+
61
+ ##
62
+ # Define tasks for plugin.
63
+
64
+ def define_test_tasks
65
+ default_tasks = []
66
+
67
+ if File.directory? "test" then
68
+ desc 'Run the test suite. Use FILTER or TESTOPTS to add flags/args.'
69
+ task :test do
70
+ ruby make_test_cmd
71
+ end
72
+
73
+ desc 'Run the test suite using multiruby.'
74
+ task :multi do
75
+ ruby make_test_cmd(:multi)
76
+ end
77
+
78
+ desc 'Show which test files fail when run alone.'
79
+ task :test_deps do
80
+ tests = Dir["test/**/test_*.rb"] + Dir["test/**/*_test.rb"]
81
+
82
+ paths = ['bin', 'lib', 'test'].join(File::PATH_SEPARATOR)
83
+ null_dev = Hoe::WINDOZE ? '> NUL 2>&1' : '&> /dev/null'
84
+
85
+ tests.each do |test|
86
+ if not system "ruby -I#{paths} #{test} #{null_dev}" then
87
+ puts "Dependency Issues: #{test}"
88
+ end
89
+ end
90
+ end
91
+
92
+ default_tasks << :test
93
+ end
94
+
95
+ if File.directory? "spec" then
96
+ begin
97
+ require 'spec/rake/spectask'
98
+
99
+ desc "Run all specifications"
100
+ Spec::Rake::SpecTask.new(:spec) do |t|
101
+ t.libs = self.rspec_dirs
102
+ t.spec_opts = self.rspec_options
103
+ end
104
+ rescue LoadError
105
+ # do nothing
106
+ end
107
+ default_tasks << :spec
108
+ end
109
+
110
+ desc 'Run the default task(s).'
111
+ task :default => default_tasks
112
+
113
+ desc 'Run ZenTest against the package.'
114
+ task :audit do
115
+ libs = %w(lib test ext).join(File::PATH_SEPARATOR)
116
+ sh "zentest -I=#{libs} #{spec.files.grep(/^(lib|test)/).join(' ')}"
117
+ end
118
+ end
119
+
120
+ ##
121
+ # Generate the test command-line.
122
+
123
+ def make_test_cmd multi = false # :nodoc:
124
+ framework = SUPPORTED_TEST_FRAMEWORKS[testlib]
125
+ raise "unsupported test framework #{testlib}" unless framework
126
+
127
+ tests = ["rubygems", framework] +
128
+ test_globs.map { |g| Dir.glob(g) }.flatten
129
+ tests.map! {|f| %(require "#{f}")}
130
+
131
+ cmd = "#{Hoe::RUBY_FLAGS} -e '#{tests.join("; ")}' #{FILTER}"
132
+
133
+ if multi then
134
+ ENV['EXCLUDED_VERSIONS'] = multiruby_skip.join ":"
135
+ cmd = "-S multiruby #{cmd}"
136
+ end
137
+
138
+ cmd
139
+ end
140
+ end