hoe 1.12.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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