Skip to content
This repository
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 203 lines (172 sloc) 6.295 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
require 'rake/clean'
require 'rake/testtask'
require 'fileutils'
require 'date'

# CI Reporter is only needed for the CI
begin
  require 'ci/reporter/rake/test_unit'
rescue LoadError
end

task :default => :test
task :spec => :test

CLEAN.include "**/*.rbc"

def source_version
  @source_version ||= begin
    line = File.read('lib/sinatra/base.rb')[/^\s*VERSION = .*/]
    line.match(/.*VERSION = '(.*)'/)[1]
  end
end

def prev_feature
  source_version.gsub(/^(\d\.)(\d+)\..*$/) { $1 + ($2.to_i - 1).to_s }
end

def prev_version
  return prev_feature + '.0' if source_version.end_with? '.0'
  source_version.gsub(/\d+$/) { |s| s.to_i - 1 }
end

# SPECS ===============================================================

task :test do
  ENV['LANG'] = 'C'
  ENV.delete 'LC_CTYPE'
end

Rake::TestTask.new(:test) do |t|
  t.test_files = FileList['test/*_test.rb']
  t.ruby_opts = ['-rubygems'] if defined? Gem
  t.ruby_opts << '-I.'
end

Rake::TestTask.new(:"test:core") do |t|
  core_tests = %w[base delegator encoding extensions filter
helpers mapped_error middleware radius rdoc
readme request response result route_added_hook
routing server settings sinatra static templates]
  t.test_files = core_tests.map {|n| "test/#{n}_test.rb"}
  t.ruby_opts = ["-rubygems"] if defined? Gem
  t.ruby_opts << "-I."
end

# Rcov ================================================================

namespace :test do
  desc 'Mesures test coverage'
  task :coverage do
    rm_f "coverage"
    sh "rcov -Ilib test/*_test.rb"
  end
end

# Website =============================================================

desc 'Generate RDoc under doc/api'
task 'doc' => ['doc:api']
task('doc:api') { sh "yardoc -o doc/api" }
CLEAN.include 'doc/api'

# README ===============================================================

task :add_template, [:name] do |t, args|
  Dir.glob('README.*') do |file|
    code = File.read(file)
    if code =~ /^===.*#{args.name.capitalize}/
      puts "Already covered in #{file}"
    else
      template = code[/===[^\n]*Liquid.*index\.liquid<\/tt>[^\n]*/m]
      if !template
        puts "Liquid not found in #{file}"
      else
        puts "Adding section to #{file}"
        template = template.gsub(/Liquid/, args.name.capitalize).gsub(/liquid/, args.name.downcase)
        code.gsub! /^(\s*===.*CoffeeScript)/, "\n" << template << "\n\\1"
        File.open(file, "w") { |f| f << code }
      end
    end
  end
end

# Thanks in announcement ===============================================

team = ["Ryan Tomayko", "Blake Mizerany", "Simon Rozet", "Konstantin Haase"]
desc "list of contributors"
task :thanks, [:release,:backports] do |t, a|
  a.with_defaults :release => "#{prev_version}..HEAD",
    :backports => "#{prev_feature}.0..#{prev_feature}.x"
  included = `git log --format=format:"%aN\t%s" #{a.release}`.lines.to_a
  excluded = `git log --format=format:"%aN\t%s" #{a.backports}`.lines.to_a
  commits = (included - excluded).group_by { |c| c[/^[^\t]+/] }
  authors = commits.keys.sort_by { |n| - commits[n].size } - team
  puts authors[0..-2].join(', ') << " and " << authors.last,
    "(based on commits included in #{a.release}, but not in #{a.backports})"
end

desc "list of authors"
task :authors, [:commit_range, :format, :sep] do |t, a|
  a.with_defaults :format => "%s (%d)", :sep => ", ", :commit_range => '--all'
  authors = Hash.new { |h,k| h[k] = 0 }
  blake = "Blake Mizerany"
  overall = 0
  mapping = {
    "blake.mizerany@gmail.com" => blake, "bmizerany" => blake,
    "a_user@mac.com" => blake, "ichverstehe" => "Harry Vangberg",
    "Wu Jiang (nouse)" => "Wu Jiang" }
  `git shortlog -s #{a.commit_range}`.lines.map do |line|
    num, name = line.split("\t", 2).map(&:strip)
    authors[mapping[name] || name] += num.to_i
    overall += num.to_i
  end
  puts "#{overall} commits by #{authors.count} authors:"
  puts authors.sort_by { |n,c| -c }.map { |e| a.format % e }.join(a.sep)
end

# PACKAGING ============================================================

if defined?(Gem)
  # Load the gemspec using the same limitations as github
  def spec
    require 'rubygems' unless defined? Gem::Specification
    @spec ||= eval(File.read('sinatra.gemspec'))
  end

  def package(ext='')
    "pkg/sinatra-#{spec.version}" + ext
  end

  desc 'Build packages'
  task :package => %w[.gem .tar.gz].map {|e| package(e)}

  desc 'Build and install as local gem'
  task :install => package('.gem') do
    sh "gem install #{package('.gem')}"
  end

  directory 'pkg/'
  CLOBBER.include('pkg')

  file package('.gem') => %w[pkg/ sinatra.gemspec] + spec.files do |f|
    sh "gem build sinatra.gemspec"
    mv File.basename(f.name), f.name
  end

  file package('.tar.gz') => %w[pkg/] + spec.files do |f|
    sh <<-SH
git archive \
--prefix=sinatra-#{source_version}/ \
--format=tar \
HEAD | gzip > #{f.name}
SH
  end

  task 'sinatra.gemspec' => FileList['{lib,test,compat}/**','Rakefile','CHANGES','*.rdoc'] do |f|
    # read spec file and split out manifest section
    spec = File.read(f.name)
    head, manifest, tail = spec.split(" # = MANIFEST =\n")
    # replace version
    head.sub!(/\.version = '.*'/, ".version = '#{source_version}'")
    # determine file list from git ls-files
    files = `git ls-files`.
      split("\n").
      sort.
      reject{ |file| file =~ /^\./ }.
      reject { |file| file =~ /^doc/ }.
      map{ |file| " #{file}" }.
      join("\n")
    # piece file back together and write...
    manifest = " s.files = %w[\n#{files}\n ]\n"
    spec = [head,manifest,tail].join(" # = MANIFEST =\n")
    File.open(f.name, 'w') { |io| io.write(spec) }
    puts "updated #{f.name}"
  end

  task 'release' => ['test', package('.gem')] do
    if File.read("CHANGES") =~ /= \d\.\d\.\d . not yet released$/i
      fail 'please update changes first'
    end

    sh <<-SH
gem install #{package('.gem')} --local &&
gem push #{package('.gem')} &&
git commit --allow-empty -a -m '#{source_version} release' &&
git tag -s v#{source_version} -m '#{source_version} release' &&
git tag -s #{source_version} -m '#{source_version} release' &&
git push && (git push sinatra || true) &&
git push --tags && (git push sinatra --tags || true)
SH
  end
end
Something went wrong with that request. Please try again.