-
1
require 'corundum/tasklib'
-
-
#require 'rubygems'
-
#require 'rubygems/installer'
-
-
1
module Corundum
-
1
extend Rake::DSL
-
-
1
class Toolkit < TaskLib
-
settings(
-
:gemspec => nil,
-
:gemspec_path => nil,
-
:finished_dir => "corundum",
-
:package_dir => "pkg",
-
:doc_dir => "rubydoc",
-
:browser => "chromium",
-
:finished_files => nested.nil_fields(:build, :qa, :package, :release, :press),
-
:files => nested.nil_fields(:code, :test, :docs),
-
:rubyforge => nested.nil_fields(:group_id, :package_id, :release_name, :home_page, :project_page),
-
:email => nested(
-
:servers => [ nested({ :server => "ruby-lang.org", :helo => "gmail.com" }) ],
-
:announce_to_email => "ruby-talk@ruby-lang.org"
-
),
-
:file_lists => nested(:code => FileList['lib/**/*.rb'],
-
:test => FileList['test/**/*.rb','spec/**/*.rb','features/**/*.rb'],
-
:docs => FileList['doc/**/*.rb'],
-
:project => FileList['Rakefile'],
-
1
:all => nil)
-
)
-
-
1
def load_gemspec
-
1
@gemspec_path ||= guess_gemspec
-
1
@gemspec ||= Gem::Specification::load(gemspec_path)
-
1
return gemspec
-
end
-
-
1
def resolve_configuration
-
1
load_gemspec
-
-
1
@finished_files.build ||= File::join( package_dir, "#{gemspec.full_name}.gem")
-
-
1
@finished_files.qa ||= File::join( finished_dir, "qa_#{gemspec.version}")
-
1
@finished_files.release ||= File::join( finished_dir, "release_#{gemspec.version}")
-
1
@finished_files.press ||= File::join( finished_dir, "press_#{gemspec.version}")
-
-
1
@files.code ||= gemspec.files.grep(%r{^lib/})
-
1
@files.test ||= gemspec.files.grep(%r{^spec/})
-
1
@files.docs ||= gemspec.files.grep(%r{^doc/})
-
-
1
@file_lists.project << gemspec_path
-
1
@file_lists.all ||=
-
file_lists.code +
-
file_lists.test +
-
file_lists.docs
-
-
1
@rubyforge.group_id ||= gemspec.rubyforge_project
-
1
@rubyforge.package_id ||= gemspec.name.downcase
-
1
@rubyforge.release_name ||= gemspec.full_name
-
1
@rubyforge.home_page ||= gemspec.homepage
-
1
@rubyforge.project_page ||= "http://rubyforge.org/project/#{gemspec.rubyforge_project}/"
-
end
-
-
1
def guess_gemspec
-
1
speclist = Dir[File.expand_path("*.gemspec", Rake::original_dir)]
-
1
if speclist.length == 0
-
puts "Found no *.gemspec files"
-
exit 1
-
elsif speclist.length > 1
-
puts "Found too many *.gemspec files: #{speclist.inspect}"
-
exit 1
-
end
-
1
speclist[0]
-
end
-
-
1
def define
-
1
in_namespace do
-
1
directory finished_dir
-
-
1
desc "Run preflight checks"
-
1
task :preflight
-
-
1
desc "Run quality assurance tasks"
-
1
task :qa => [:preflight, finished_files.qa]
-
file finished_files.qa =>
-
1
[finished_dir] + file_lists.project + file_lists.code + file_lists.test do |task|
-
Rake::Task[:qa].invoke #because I don't want this to be needed if it's not
-
touch task.name
-
end
-
-
1
desc "Build the package"
-
1
task :build => [finished_files.qa, :preflight, finished_files.build]
-
file finished_files.build =>
-
1
[finished_dir] + file_lists.code + file_lists.project do |task|
-
Rake::Task[:build].invoke
-
touch task.name
-
end
-
-
1
desc "Push package out to the world"
-
1
task :release => [finished_files.build, :preflight, finished_files.release]
-
1
file finished_files.release => [finished_dir] do |task|
-
Rake::Task[:release].invoke
-
touch task.name
-
end
-
-
1
desc "Announce publication"
-
1
task :press => [finished_files.release, finished_files.press]
-
1
file finished_files.press => [finished_dir] do |task|
-
Rake::Task[:press].invoke
-
touch task.name
-
end
-
end
-
end
-
end
-
end
-
1
require 'mattock/command-task'
-
-
1
module Corundum
-
1
class BrowserTask < Mattock::CommandTask
-
1
setting(:browser, "chromium")
-
1
setting(:index_html)
-
1
setting(:task_name, "view")
-
-
1
def default_configuration(parent)
-
2
self.browser = parent.browser
-
end
-
-
1
def task_args
-
2
[{task_name => index_html}]
-
end
-
-
1
def resolve_configuration
-
2
self.command = Mattock::CommandLine.new(browser, index_html)
-
end
-
end
-
end
-
1
require 'corundum/tasklib'
-
-
1
module Corundum
-
1
class Email < TaskLib
-
1
default_namespace :email
-
-
1
setting(:rubyforge)
-
1
setting(:email_servers, [])
-
1
setting(:gemspec)
-
1
setting(:announce_to_email, nil)
-
1
setting(:urls, nested.required_fields(:home_page, :project_page))
-
-
1
def default_configuration(toolkit)
-
1
self.rubyforge = toolkit.rubyforge
-
1
self.gemspec = toolkit.gemspec
-
1
self.urls.home_page = toolkit.gemspec.homepage
-
1
self.urls.project_page = toolkit.rubyforge.project_page
-
end
-
-
1
def announcement
-
changes = ""
-
begin
-
File::open("./Changelog", "r") do |changelog|
-
changes = "Changes:\n\n"
-
changes += changelog.read
-
end
-
rescue Exception
-
end
-
-
urls = "Project: #{urls.project_page}\n" +
-
"Homepage: #{urls.home_page}"
-
-
subject = "#{gemspec.name} #{gemspec.version} Released"
-
title = "#{gemspec.name} version #{gemspec.version} has been released!"
-
body = "#{gemspec.description}\n\n#{changes}\n\n#{urls}"
-
-
return subject, title, body
-
end
-
-
1
def define
-
1
desc 'Announce release on email'
-
1
task root_task => in_namespace("rubyforge", "email")
-
1
in_namespace do
-
1
file "email.txt" do |t|
-
require 'mailfactory'
-
-
subject, title, body= announcement
-
-
mail = MailFactory.new
-
mail.To = announce_to_email
-
mail.From = gemspec.email
-
mail.Subject = "[ANN] " + subject
-
mail.text = [title, body].join("\n\n")
-
-
File.open(t.name, "w") do |mailfile|
-
mailfile.write mail.to_s
-
end
-
end
-
-
1
task :email => "email.txt" do
-
require 'net/smtp'
-
-
email_servers.each do |server_config|
-
begin
-
File::open("email.txt", "r") do |email|
-
Net::SMTP.start(server_config[:server], 25, server_config[:helo], server_config[:username], server_config[:password]) do |smtp|
-
smtp.data do |mta|
-
mta.write(email.read)
-
end
-
end
-
end
-
break
-
rescue Object => ex
-
puts ex.message
-
end
-
end
-
end
-
end
-
end
-
end
-
end
-
1
require 'corundum/tasklib'
-
-
1
module Corundum
-
1
class GemBuilding < TaskLib
-
1
setting(:gemspec)
-
1
setting(:qa_finished_file)
-
1
setting(:package_dir, "pkg")
-
-
1
def default_configuration(toolkit)
-
1
self.gemspec = toolkit.gemspec
-
1
self.qa_finished_file = toolkit.finished_files.qa
-
end
-
-
1
def define
-
1
require 'rubygems/package_task'
-
-
1
in_namespace do
-
1
package = Gem::PackageTask.new(gemspec) do |t|
-
1
t.need_tar_gz = true
-
1
t.need_tar_bz2 = true
-
1
t.package_dir = package_dir
-
end
-
-
1
task(:package).prerequisites.each do |package_type|
-
3
file package_type => qa_finished_file
-
end
-
end
-
-
1
task :build => in_namespace("gem")
-
end
-
end
-
end
-
1
require 'corundum/tasklib'
-
-
1
module Corundum
-
1
class GemCutter < TaskLib
-
1
default_namespace :gemcutter
-
-
1
setting(:gem_path, nil)
-
1
setting(:build)
-
1
setting(:gemspec)
-
1
setting(:build_finished_path)
-
1
setting(:gem_name)
-
1
setting(:package_dir)
-
-
1
def default_configuration(toolkit, build)
-
1
self.build = build
-
1
self.gemspec = toolkit.gemspec
-
1
self.build_finished_path = toolkit.finished_files.build
-
1
self.gem_name = toolkit.gemspec.full_name
-
1
self.package_dir = build.package_dir
-
end
-
-
1
def resolve_configuration
-
1
self.gem_path ||= File::join(package_dir, gemspec.file_name)
-
end
-
-
1
module CommandTweaks
-
1
def setup_args(args = nil)
-
args ||= []
-
handle_options(args)
-
end
-
-
1
def gem_list=(list)
-
gems = list
-
end
-
-
1
def get_all_gem_names
-
return gems if defined?(gems)
-
super
-
end
-
-
1
def get_one_gem_name
-
return gems.first if defined?(gems)
-
super
-
end
-
end
-
-
1
def get_command(klass, args=nil)
-
cmd = klass.new
-
cmd.extend(CommandTweaks)
-
cmd.setup_args(args)
-
cmd
-
end
-
-
1
def define
-
1
in_namespace do
-
1
task :uninstall do |t|
-
when_writing("Uninstalling #{gem_name}") do
-
require "rubygems/commands/uninstall_command"
-
uninstall = get_command Gem::Commands::UninstallCommand
-
uninstall.options[:args] = [gem_path]
-
uninstall.execute
-
end
-
end
-
-
1
task :install => [gem_path] do |t|
-
when_writing("Installing #{gem_path}") do
-
require "rubygems/commands/install_command"
-
install = get_command Gem::Commands::InstallCommand
-
install.options[:args] = [gem_path]
-
install.execute
-
end
-
end
-
-
1
task :reinstall => [:uninstall, :install]
-
-
1
task :dependencies_available do
-
checker = Gem::SpecFetcher.new
-
gemspec.runtime_dependencies.each do |dep|
-
fulfilling = checker.find_matching(dep,false,false,false)
-
if fulfilling.empty?
-
fail "Dependency #{dep} is unfulfilled remotely"
-
else
-
puts "Remotely fulfilled: #{dep}" if verbose
-
end
-
end
-
end
-
-
1
task :is_unpushed do
-
checker = Gem::SpecFetcher.new
-
dep = Gem::Dependency.new(gemspec.name, "= #{gemspec.version}")
-
fulfilling = checker.find_matching(dep,false,false,false)
-
unless fulfilling.empty?
-
p fulfilling
-
fail "Gem #{gemspec.full_name} is already pushed"
-
end
-
end
-
-
1
desc 'Push a gem up to Gemcutter'
-
1
task :push => [:dependencies_available, :is_unpushed] do
-
require "rubygems/commands/push_command"
-
push = get_command(Gem::Commands::PushCommand)
-
push.options[:args] = [gem_path]
-
push.execute
-
end
-
1
task :push => build_finished_path
-
end
-
1
task :release => in_namespace(:push)
-
1
task :preflight => in_namespace(:dependencies_available, :is_unpushed)
-
end
-
end
-
end
-
1
require 'corundum/tasklib'
-
-
1
module Corundum
-
1
class GemspecSanity < TaskLib
-
1
default_namespace :gemspec_sanity
-
-
1
setting(:gemspec)
-
-
1
def default_configuration(toolkit)
-
self.gemspec = toolkit.gemspec
-
end
-
-
1
def define
-
in_namespace do
-
task :has_files do
-
if gemspec.files.nil? or gemspec.files.empty?
-
fail "No files mentioned in gemspec - do you intend an empty gem?"
-
end
-
end
-
-
task :files_exist do
-
missing = gemspec.files.find_all do |path|
-
not File::exists?(path)
-
end
-
-
fail "Files mentioned in gemspec are missing: #{missing.join(", ")}" unless missing.empty?
-
end
-
end
-
-
task :preflight => in_namespace(:files_exist, :has_files)
-
end
-
end
-
end
-
1
require 'corundum/tasklib'
-
1
require 'mattock/task'
-
-
1
module Corundum
-
1
class GitTask < Mattock::CommandTask
-
1
setting(:subcommand)
-
1
setting(:arguments, [])
-
-
1
def command
-
Mattock::CommandLine.new("git", "--no-pager") do |cmd|
-
cmd.options << subcommand
-
arguments.each do |arg|
-
cmd.options += [*arg]
-
end
-
end
-
end
-
end
-
-
1
class InDirCommandTask < Mattock::CommandTask
-
1
setting :target_dir
-
-
1
def default_configuration(parent)
-
parent.copy_settings_to(self)
-
end
-
-
1
def needed?
-
FileUtils.cd target_dir do
-
super
-
end
-
end
-
-
1
def action
-
FileUtils.cd target_dir do
-
super
-
end
-
end
-
end
-
-
1
class GithubPages < TaskLib
-
1
default_namespace :publish_docs
-
-
1
setting(:target_dir, "gh-pages")
-
1
setting(:source_dir)
-
-
1
nil_fields :repo_dir
-
-
1
def branch
-
"gh-pages"
-
end
-
-
1
def default_configuration(doc_gen)
-
self.source_dir = doc_gen.target_dir
-
end
-
-
1
def resolve_configuration
-
self.repo_dir ||= File::join(target_dir, ".git")
-
end
-
-
1
def git_command(*args)
-
Mattock::CommandLine.new("git", "--no-pager") do |cmd|
-
args.each do |arg|
-
cmd.options += [*arg]
-
end
-
end
-
end
-
-
1
def git(*args)
-
result = git_command(*args).run
-
result.must_succeed!
-
result.stdout.lines.to_a
-
end
-
-
1
$verbose = true
-
-
1
def define
-
in_namespace do
-
InDirCommandTask.new(self) do |t|
-
t.task_name = :on_branch
-
t.verify_command = Mattock::PipelineChain.new do |chain|
-
chain.add git_command(%w{branch})
-
chain.add Mattock::CommandLine.new("grep", "-q", "'^[*] #{branch}'")
-
end
-
t.command = Mattock::PrereqChain.new do |chain|
-
chain.add git_command("checkout", branch)
-
end
-
end
-
-
file repo_dir do
-
fail "Refusing to clobber existing #{target_dir}" if File.exists?(target_dir)
-
-
url = git("config", "--get", "remote.origin.url").first
-
-
git("clone", url.chomp, "-b", branch, target_dir)
-
Mattock::CommandLine.new("rm", File::join(repo_dir, "hooks", "*")).must_succeed!
-
end
-
-
task :pull => [repo_dir, :on_branch] do
-
FileUtils.cd target_dir do
-
git("pull")
-
end
-
end
-
-
InDirCommandTask.new(self) do |t|
-
t.task_name = :setup
-
t.verify_command = Mattock::PipelineChain.new do |chain|
-
chain.add git_command(%w{branch -r})
-
chain.add Mattock::CommandLine.new("grep", "-q", branch)
-
end
-
t.command = Mattock::PrereqChain.new do |cmd|
-
cmd.add git_command("checkout", "-b", branch)
-
cmd.add Mattock::CommandLine.new("rm -rf *")
-
cmd.add git_command(%w{commit -a -m} + ["'Creating pages'"])
-
cmd.add git_command("push", "origin", branch)
-
cmd.add git_command("branch", "--set-upstream", branch, "origin/" + branch)
-
end
-
end
-
task :setup => repo_dir
-
-
task :pre_publish => [repo_dir, :setup, :pull]
-
-
task :clobber_target => :on_branch do
-
Mattock::CommandLine.new(*%w{rm -rf}) do |cmd|
-
cmd.options << target_dir + "/*"
-
end.must_succeed!
-
end
-
-
task :assemble_docs => [:pre_publish, :clobber_target] do
-
Mattock::CommandLine.new(*%w{cp -a}) do |cmd|
-
cmd.options << source_dir + "/*"
-
cmd.options << target_dir
-
end.must_succeed!
-
end
-
-
task :publish => [:assemble_docs, :on_branch] do
-
FileUtils.cd target_dir do
-
git("add", ".")
-
git("commit", "-m", "'Corundum auto-publish'")
-
git("push", "origin", branch)
-
end
-
end
-
end
-
-
desc "Push documentation files to Github Pages"
-
task root_task => self[:publish]
-
end
-
end
-
end
-
1
require 'corundum/tasklib'
-
1
require 'rspec/core'
-
1
require 'mattock/command-task'
-
1
require 'rbconfig'
-
-
1
module Corundum
-
1
class RSpecTask < Mattock::CommandTask
-
1
setting :ruby_command, Mattock::CommandLine.new(RbConfig.ruby) do |cmd|
-
if /^1\.8/ =~ RUBY_VERSION
-
cmd.options << "-S"
-
end
-
end
-
-
1
setting :runner_command
-
-
1
required_fields :pattern, :ruby_opts, :rspec_configs, :rspec_opts,
-
:warning, :rspec_path, :rspec_opts, :failure_message, :files_to_run
-
-
1
def default_configuration(rspec)
-
4
self.pattern = rspec.pattern
-
4
self.ruby_opts = rspec.ruby_opts
-
4
self.rspec_configs = rspec.rspec_configs
-
4
self.rspec_opts = rspec.rspec_opts
-
4
self.warning = rspec.warning
-
4
self.rspec_path = rspec.rspec_path
-
4
self.rspec_opts = rspec.rspec_opts
-
4
self.failure_message = rspec.failure_message
-
4
self.files_to_run = rspec.files_to_run
-
end
-
-
1
def resolve_configuration
-
4
self.rspec_configs = rspec_opts
-
4
self.rspec_path = %x"which #{rspec_path}".chomp
-
-
4
ruby_command.options << ruby_opts if ruby_opts
-
4
ruby_command.options << "-w" if warning
-
-
4
self.runner_command = Mattock::CommandLine.new(rspec_path) do |cmd|
-
4
cmd.options << rspec_opts
-
4
cmd.options << files_to_run
-
end
-
-
4
self.command = Mattock::WrappingChain.new do |cmd|
-
4
cmd.add ruby_command
-
4
cmd.add runner_command
-
end
-
end
-
end
-
-
-
1
class RSpec < TaskLib
-
1
default_namespace :rspec
-
-
settings(
-
:pattern => './spec{,/*/**}/*_spec.rb',
-
:rspec_configs => nil,
-
:rspec_opts => nil,
-
:warning => false,
-
:verbose => true,
-
:ruby_opts => [],
-
:rspec_path => 'rspec',
-
:rspec_opts => %w{--format documentation --out last_run --color --format documentation},
-
:failure_message => "Spec examples failed.",
-
1
:files_to_run => "spec"
-
)
-
-
1
required_fields :gemspec_path, :qa_finished_path
-
-
1
def default_configuration(toolkit)
-
1
self.gemspec_path = toolkit.gemspec_path
-
1
self.qa_finished_path = toolkit.finished_files.qa
-
end
-
-
1
def resolve_configuration
-
#XXX Que?
-
1
self.rspec_configs = rspec_opts
-
1
self.rspec_opts = []
-
1
self.rspec_path = %x"which #{rspec_path}".chomp
-
end
-
-
1
def define
-
1
in_namespace do
-
1
desc "Always run every spec"
-
1
RSpecTask.new(self) do |t|
-
1
t.task_name = :all
-
end
-
-
1
desc "Generate specifications documentation"
-
1
RSpecTask.new(self) do |t|
-
1
t.task_name = :doc
-
1
t.rspec_opts = %w{-o /dev/null -f d -o doc/Specifications}
-
1
t.failure_message = "Failed generating specification docs"
-
end
-
-
1
desc "Run only failing examples listed in last_run"
-
1
RSpecTask.new(self) do |t|
-
1
t.task_name = :quick
-
1
examples = []
-
1
begin
-
1
File.open("last_run", "r") do |fail_list|
-
1
fail_list.lines.grep(%r{^\s*\d+\)\s*(.*)}) do |line|
-
examples << $1.gsub(/'/){"[']"}
-
end
-
end
-
rescue
-
end
-
1
unless examples.empty?
-
t.rspec_opts << "--example"
-
t.rspec_opts << "\"#{examples.join("|")}\""
-
end
-
1
t.failure_message = "Spec examples failed."
-
end
-
end
-
-
1
desc "Run failing examples if any exist, otherwise, run the whole suite"
-
1
task root_task => in_namespace(:quick)
-
-
1
task :qa => in_namespace(:doc)
-
end
-
end
-
end
-
1
require 'corundum/tasklib'
-
-
#Big XXX: this totally isn't done. It's some notes against ever wanting to
-
#publish announcements to rubyforge ever again
-
-
1
module Corundum
-
1
class Publishing < TaskLib
-
1
default_namespace :rubyforge
-
-
1
setting(:rubyforge, nested(:package_id => nil, :group_id => nil, :release_name => nil))
-
1
setting(:package_dir, nil)
-
1
setting(:gemspec, nil)
-
-
1
def define
-
desc "Publish the gem and its documentation to Rubyforge and Gemcutter"
-
task root_task => in_namespace(:docs, :rubyforge)
-
-
in_namespace do
-
desc 'Publish RDoc to RubyForge'
-
task :docs do
-
config = YAML.load(File.read(File.expand_path("~/.rubyforge/user-config.yml")))
-
host = "#{config["username"]}@rubyforge.org"
-
remote_dir = "/var/www/gforge-projects/#{@rubyforge[:group_id]}"
-
local_dir = 'rubydoc'
-
sh %{rsync -av --delete #{local_dir}/ #{host}:#{remote_dir}}
-
end
-
-
task :scrape_rubyforge do
-
require 'rubyforge'
-
forge = RubyForge.new
-
forge.configure
-
forge.scrape_project(@rubyforge[:package_id])
-
end
-
-
desc "Publishes to RubyForge"
-
task :rubyforge => [:docs, :scrape_rubyforge] do |t|
-
require 'rubyforge'
-
forge = RubyForge.new
-
forge.configure
-
files = [".gem", ".tar.gz", ".tar.bz2"].map do |extension|
-
File::join(@package_dir, @gemspec.full_name) + extension
-
end
-
release = forge.lookup("release", @rubyforge[:package_id])[@rubyforge[:release_name]] rescue nil
-
if release.nil?
-
forge.add_release(@rubyforge[:group_id], @rubyforge[:package_id], @rubyforge[:release_name], *files)
-
else
-
files.each do |file|
-
forge.add_file(@rubyforge[:group_id], @rubyforge[:package_id], @rubyforge[:release_name], file)
-
end
-
end
-
end
-
end
-
end
-
end
-
end
-
1
require 'corundum/tasklib'
-
1
require 'corundum/browser-task'
-
-
1
module Corundum
-
1
class RSpecReportTask < RSpecTask
-
1
def command_task
-
@command_task ||= file task_name do
-
decorated(command).must_succeed!
-
end
-
end
-
end
-
-
1
class SimpleCov < TaskLib
-
1
default_namespace :coverage
-
-
1
setting(:test_lib)
-
1
setting(:browser)
-
1
setting(:code_files)
-
1
setting(:all_files)
-
-
1
setting(:report_path, nil)
-
1
setting(:config_path, nil)
-
-
1
setting(:report_dir, "doc/coverage")
-
1
setting(:config_file, ".simplecov")
-
1
setting(:filters, ["./spec"])
-
1
setting(:threshold, 80)
-
1
setting(:groups, {})
-
1
setting(:coverage_filter, proc do |path|
-
/\.rb$/ =~ path
-
end)
-
-
1
def default_configuration(toolkit, testlib)
-
1
self.test_lib = testlib
-
1
self.browser = toolkit.browser
-
1
self.code_files = toolkit.files.code
-
1
self.all_files = toolkit.file_lists.project + toolkit.file_lists.code + toolkit.file_lists.test
-
end
-
-
1
def resolve_configuration
-
1
self.config_path ||= File::expand_path(config_file, Rake::original_dir)
-
1
self.report_path ||= File::join(report_dir, "index.html")
-
end
-
-
1
def filter_lines
-
return filters.map do |pattern|
-
"add_filter \"#{pattern}\""
-
end
-
end
-
-
1
def group_lines
-
lines = []
-
groups.each_pair do |group, pattern|
-
lines << "add_group \"#{group}\", \"#{pattern}\""
-
end
-
lines
-
end
-
-
1
def config_file_contents
-
contents = ["SimpleCov.start do"]
-
contents << " coverage_dir \"#{report_dir}\""
-
contents += filter_lines.map{|line| " " + line}
-
contents += group_lines.map{|line| " " + line}
-
contents << "end"
-
return contents.join("\n")
-
end
-
-
1
def define
-
1
in_namespace do
-
1
file "Rakefile"
-
-
1
task :example_config do
-
$stderr.puts "Try this in #{config_path}"
-
$stderr.puts "(You can just do #$0 > #{config_path})"
-
$stderr.puts
-
puts config_file_contents
-
end
-
-
1
task :config_exists do
-
File::exists?(File::join(Rake::original_dir, ".simplecov")) or fail "No .simplecov (try: rake #{self[:example_config]})"
-
end
-
-
1
directory File::dirname(report_path)
-
1
RSpecReportTask.new(@test_lib) do |t|
-
1
t.task_name = report_path
-
1
t.rspec_opts += %w{-r simplecov}
-
end
-
1
file report_path => all_files
-
-
1
task :generate_report => [:preflight, report_path]
-
-
1
desc "View coverage in browser"
-
1
BrowserTask.new(self) do |t|
-
1
t.index_html = report_path
-
end
-
-
1
task :verify_coverage => :generate_report do
-
require 'nokogiri'
-
-
doc = Nokogiri::parse(File::read(report_path))
-
-
coverage_total_xpath = "//span[@class='covered_percent']/span"
-
percentage = doc.xpath(coverage_total_xpath).first.content.to_f
-
-
raise "Coverage must be at least #{threshold} but was #{percentage}" if percentage < threshold
-
puts "Coverage is #{percentage}% (required: #{threshold}%)"
-
end
-
-
1
task :find_stragglers => :generate_report do
-
require 'nokogiri'
-
-
doc = Nokogiri::parse(File::read(report_path))
-
-
covered_files = doc.xpath(
-
"//table[@class='file_list']//td//a[@class='src_link']").map do |link|
-
link.content
-
end
-
need_coverage = @code_files.find_all(&coverage_filter)
-
-
not_listed = covered_files - need_coverage
-
not_covered = need_coverage - covered_files
-
unless not_listed.empty? and not_covered.empty?
-
raise ["Covered files and gemspec manifest don't match:",
-
"Not in gemspec: #{not_listed.inspect}",
-
"Not covered: #{not_covered.inspect}"].join("\n")
-
end
-
end
-
end
-
1
task :preflight => in_namespace(:config_exists)
-
-
1
task :qa => in_namespace(:verify_coverage, :find_stragglers)
-
end
-
end
-
end
-
1
require 'mattock/tasklib'
-
-
1
module Corundum
-
#TODO Add functionality or refactor away
-
1
class TaskLib < Mattock::TaskLib
-
end
-
end
-
1
require 'corundum'
-
1
require 'corundum/rspec'
-
1
require 'corundum/simplecov'
-
1
require 'corundum/gemspec_sanity'
-
1
require 'corundum/gem_building'
-
1
require 'corundum/gemcutter'
-
1
require 'corundum/email'
-
1
require 'corundum/version_control/monotone'
-
1
require 'corundum/version_control/git'
-
1
require 'corundum/yardoc'
-
1
require 'corundum/github-pages'
-
1
require 'corundum/tasklib'
-
-
1
module Corundum
-
1
class VersionControl < TaskLib
-
1
default_namespace :version_control
-
-
1
required_fields(:gemspec, :build_finished_file, :gemspec_files, :tag)
-
-
1
def default_configuration(toolkit)
-
1
self.gemspec = toolkit.gemspec
-
1
self.build_finished_file = toolkit.finished_files.build
-
1
self.gemspec_files = toolkit.files.code + toolkit.files.test
-
1
self.tag = toolkit.gemspec.version.to_s
-
end
-
-
1
def define
-
1
in_namespace do
-
1
task :not_tagged
-
1
task :gemspec_files_added
-
1
task :workspace_committed
-
1
task :is_checked_in => %w{gemspec_files_added workspace_committed}
-
1
task :tag
-
1
task :check_in => :tag
-
end
-
-
1
task :preflight => in_namespace(:not_tagged)
-
1
task :build => in_namespace(:is_checked_in)
-
1
in_namespace(:tag, :check_in).each do |taskname|
-
2
task taskname => build_finished_file
-
end
-
1
task :release => in_namespace(:tag, :check_in)
-
end
-
end
-
end
-
1
require 'corundum/version_control'
-
-
1
module Corundum
-
1
class Git < VersionControl
-
1
setting(:branch, nil)
-
-
1
def resolve_configuration
-
@branch ||= guess_branch
-
end
-
-
1
def git_command(*args)
-
Mattock::CommandLine.new("git", "--no-pager") do |cmd|
-
args.each do |arg|
-
cmd.options += [*arg]
-
end
-
end
-
end
-
-
1
def git(*args)
-
result = git_command(*args).run
-
result.must_succeed!
-
return result.stdout.lines.to_a
-
end
-
-
1
def guess_branch
-
puts "Guessing branch - configure Git > branch"
-
branch = git("branch").grep(/^\*/).first.sub(/\*\s*/,"").chomp
-
puts " Guessed: #{branch}"
-
return branch
-
end
-
-
1
def define
-
super
-
-
in_namespace do
-
task :on_branch do
-
current_branch = git("branch").grep(/^\*/).first.sub(/\*\s*/,"").chomp
-
unless current_branch == branch
-
fail "Current branch \"#{current_branch}\" is not #{branch}"
-
end
-
end
-
-
task :not_tagged => :on_branch do
-
tags = git("tag", "-l", tag)
-
unless tags.empty?
-
fail "Tag #{tag} already exists in branch #{branch}"
-
end
-
end
-
-
task :workspace_committed => :on_branch do
-
diffs = git("diff", "--stat", "HEAD")
-
unless diffs.empty?
-
fail "Workspace not committed:\n #{diffs.join(" \n")}"
-
end
-
end
-
-
task :gemspec_files_added => :on_branch do
-
list = git(%w{ls-tree -r HEAD})
-
list.map! do |line|
-
line.split(/\s+/)[3]
-
end
-
-
missing = gemspec_files - list
-
unless missing.empty?
-
fail "Gemspec files not in version control: #{missing.join(", ")}"
-
end
-
end
-
-
task :is_pulled do
-
fetch = git("fetch", "--dry-run")
-
unless fetch.empty?
-
fail "Remote branch has unpulled changes"
-
end
-
-
remote = git("config", "--get", "branch.#{branch}.remote").first.chomp
-
merge = git("config", "--get", "branch.#{branch}.merge").first.split("/").last.chomp
-
-
ancestor = git("merge-base", branch, "#{remote}/#{merge}").first.chomp
-
remote_rev = File::read(".git/refs/remotes/#{remote}/#{merge}").chomp
-
-
unless ancestor == remote_rev
-
fail "Unmerged changes with remote branch #{remote}/#{merge}\n#{ancestor.inspect}\n#{remote_rev.inspect}"
-
end
-
end
-
task :is_checked_in => :is_pulled
-
-
task :tag => :on_branch do
-
git("tag", tag)
-
end
-
-
task :push => :on_branch do
-
git("push")
-
end
-
-
task :check_in => [:push]
-
end
-
end
-
end
-
end
-
1
require 'corundum/version_control'
-
1
require 'strscan'
-
-
1
module Corundum
-
1
class Monotone < VersionControl
-
-
1
setting(:branch, nil)
-
-
1
def resolve_configuration
-
1
@branch ||= guess_branch
-
end
-
-
1
def mtn_automate(cmd, *args)
-
2
result = Mattock::CommandLine.new("mtn", "automate", cmd) do |cmd|
-
2
cmd.options += args
-
end.run
-
2
result.must_succeed!
-
2
result.stdout
-
end
-
-
1
def parse_basic_io(string)
-
1
items = []
-
1
scanner = StringScanner.new(string)
-
1
scanner.scan(/\s*/m)
-
1
until scanner.eos? do
-
-
20
symbol = scanner.scan(/[a-z_]*/)
-
20
scanner.scan(/\s*/)
-
20
value = ""
-
20
case scanner.scan(/["\[]/)
-
when '"'
-
16
while (value += scanner.scan(/[^"]*/)) =~ /\\$/
-
end
-
16
scanner.scan(/"/)
-
when '['
-
4
value = scanner.scan(/[^\]]*/)
-
4
scanner.scan(/]/)
-
else
-
raise "Improperly formatted basic_io: \
-
\n Got: #{items.inspect} + #{symbol}\
-
\n Rest:\
-
\n #{scanner.rest}"
-
end
-
20
items << [symbol, value]
-
20
scanner.scan(/\s*/m)
-
end
-
1
return items
-
end
-
-
1
def parse_certs(string)
-
1
items = parse_basic_io(string)
-
1
pair = []
-
1
hash = Hash.new do |h,k|
-
4
h[k] = []
-
end
-
1
items.each do |name, value|
-
20
case name
-
when "name"
-
4
pair[0] = value
-
when "value"
-
4
pair[1] = value
-
when "trust"
-
4
if value == "trusted"
-
4
hash[pair[0]] << pair[1]
-
end
-
4
pair = []
-
end
-
end
-
1
hash
-
end
-
-
1
def base_revision
-
1
mtn_automate("get_base_revision_id").chomp
-
end
-
-
1
def guess_branch
-
1
puts "Guessing branch - configure Monotone > branch"
-
1
certs = parse_certs(mtn_automate("certs", base_revision))
-
1
puts " Guessed: #{certs["branch"].first}"
-
1
certs["branch"].first
-
end
-
-
-
-
1
def stanzas(first_item, items)
-
stanzas = []
-
current_stanza = {}
-
items.each do |name, value|
-
if name == first_item
-
current_stanza = {}
-
stanzas << current_stanza
-
end
-
current_stanza[name] = value
-
end
-
return stanzas
-
end
-
-
1
def define
-
1
super
-
-
1
in_namespace do
-
1
task :on_branch do
-
branches = parse_certs(mtn_automate("certs", base_revision))["branch"] || []
-
unless branches.include?(branch)
-
fail "Not on branch #{branch}"
-
end
-
end
-
-
1
task :not_tagged do
-
items = parse_basic_io(mtn_automate("tags", branch))
-
tags = items.find{|pair| pair[0] == "tag" && pair[1] == tag}
-
unless tags.nil?
-
fail "Tag #{tag} already exists in branch #{branch}"
-
end
-
end
-
-
1
task :workspace_committed => :on_branch do
-
items = parse_basic_io(mtn_automate("inventory"))
-
changed = items.find{|pair| pair[0] == "changes"}
-
unless changed.nil?
-
fail "Uncommitted changes exist in workspace"
-
end
-
end
-
-
1
task :gemspec_files_added => :on_branch do
-
items = stanzas("path", parse_basic_io(mtn_automate("inventory")))
-
items.delete_if{|item| item["status"] == "unknown"}
-
known_paths = items.each_with_object({}) do |item, hash|
-
hash[item["path"]] = true
-
end
-
-
files = gemspec_files.dup
-
files.delete_if{|path| known_paths[path]}
-
unless files.empty?
-
fail "Gemspec files not in version control: #{files.join(" ")}"
-
end
-
end
-
-
1
task :tag => :on_branch do
-
mtn_automate("cert", base_revision, "tag", tag)
-
end
-
-
1
task :sync do
-
mtn_automate("sync")
-
end
-
-
1
task :check_in => [:sync]
-
end
-
end
-
end
-
end
-
1
require 'corundum/tasklib'
-
1
require 'yard'
-
-
1
module Corundum
-
1
class YARDoc < TaskLib
-
1
default_namespace :documentation
-
-
1
setting :gemspec
-
1
setting :options, nil
-
1
setting :browser
-
1
setting :yardoc_index, nil
-
-
1
setting(:target_dir, "yardoc")
-
1
setting(:readme, nil)
-
1
setting(:files, nested(:code => [], :docs => []))
-
1
setting(:extra_files, [])
-
-
1
def default_configuration(toolkit)
-
1
self.gemspec = toolkit.gemspec
-
1
toolkit.files.copy_settings_to(self.files)
-
1
self.browser = toolkit.browser
-
end
-
-
1
def resolve_configuration
-
1
self.options ||= gemspec.rdoc_options
-
1
self.options += [ "--output-dir", target_dir]
-
1
self.options += [ "--readme", readme ] if readme
-
1
self.options += files.code
-
1
unless files.docs.empty? and extra_files.empty?
-
1
self.options += [ "-" ] + files.docs + extra_files
-
end
-
1
self.yardoc_index ||= File::join(target_dir, "index.html")
-
end
-
-
1
def define
-
1
directory target_dir
-
-
1
in_namespace do
-
file yardoc_index =>
-
1
FileList["README*"] + files.code + files.docs + extra_files do
-
YARD::CLI::Yardoc.run( *(options) )
-
end
-
-
1
desc "Open up a browser to view your documentation"
-
1
BrowserTask.new(self) do |t|
-
1
t.index_html = yardoc_index
-
end
-
end
-
-
1
desc "Generate documentation based on code using YARD"
-
1
task root_task => yardoc_index
-
end
-
end
-
end