task/gemgem.rb in request-replay-0.5.0 vs task/gemgem.rb in request-replay-0.6.0

- old
+ new

@@ -1,203 +1,213 @@ -require 'pathname' - module Gemgem class << self - attr_accessor :dir, :spec + attr_accessor :dir, :spec, :spec_create end module_function + def gem_tag ; "#{spec.name}-#{spec.version}" ; end + def gem_path ; "#{pkg_dir}/#{gem_tag}.gem" ; end + def spec_path ; "#{dir}/#{spec.name}.gemspec" ; end + def pkg_dir ; "#{dir}/pkg" ; end + def escaped_dir; @escaped_dir ||= Regexp.escape(dir); end + + def init dir, &block + self.dir = dir + $LOAD_PATH.unshift("#{dir}/lib") + ENV['RUBYLIB'] = "#{dir}/lib:#{ENV['RUBYLIB']}" + ENV['PATH'] = "#{dir}/bin:#{ENV['PATH']}" + self.spec_create = block + end + def create - yield(spec = Gem::Specification.new{ |s| + spec = Gem::Specification.new do |s| s.authors = ['Lin Jen-Shin (godfat)'] s.email = ['godfat (XD) godfat.org'] s.description = description.join s.summary = description.first s.license = readme['LICENSE'].sub(/.+\n\n/, '').lines.first.strip - s.rubygems_version = Gem::VERSION - s.date = Time.now.strftime('%Y-%m-%d') - s.files = gem_files - s.test_files = gem_files.grep(%r{^test/(.+?/)*test_.+?\.rb$}) - s.executables = Dir['bin/*'].map{ |f| File.basename(f) } - s.require_paths = %w[lib] - }) - spec.homepage ||= "https://github.com/godfat/#{spec.name}" - spec + s.date = Time.now.strftime('%Y-%m-%d') + s.files = gem_files + s.test_files = test_files + s.executables = bin_files + end + spec_create.call(spec) + spec.homepage = "https://github.com/godfat/#{spec.name}" + self.spec = spec end - def readme - path = %w[README.md README].find{ |name| - File.exist?("#{Gemgem.dir}/#{name}") - } - @readme ||= - if path - ps = "##{File.read(path)}". - scan(/((#+)[^\n]+\n\n.+?(?=(\n\n\2[^#\n]+\n)|\Z))/m).map(&:first) - ps.inject('HEADER' => ps.first){ |r, s, i| - r[s[/\w+/]] = s - r - } + def write + File.open(spec_path, 'w'){ |f| f << split_lines(spec.to_ruby) } + end + + def split_lines ruby + ruby.gsub(/(.+?)\s*=\s*\[(.+?)\]/){ |s| + if $2.index(',') + "#{$1} = [\n #{$2.split(',').map(&:strip).join(",\n ")}]" else - {} + s end + } end - def description - @description ||= (readme['DESCRIPTION']||'').sub(/.+\n\n/, '').lines + def strip_path path + strip_home_path(strip_cwd_path(path)) end - def changes - path = %w[CHANGES.md CHANGES].find{ |name| - File.exist?("#{Gemgem.dir}/#{name}") - } - @changes ||= - if path - date = '\d+{4}\-\d+{2}\-\d{2}' - File.read(path).match( - /([^\n]+#{date}\n\n(.+?))(?=\n\n[^\n]+#{date}\n|\Z)/m)[1] - else - '' - end + def strip_home_path path + path.sub(ENV['HOME'], '~') end - def ann_md - "#{readme['HEADER'].sub(/([\w\-]+)/, "[\\1](#{spec.homepage})")}\n\n" \ - "##{readme['DESCRIPTION'][/[^\n]+\n\n[^\n]+/]}\n\n" \ - "### CHANGES:\n\n" \ - "###{changes}\n\n" \ - "##{readme['INSTALLATION']}\n\n" + - if readme['SYNOPSIS'] then "##{readme['SYNOPSIS'][/[^\n]+\n\n[^\n]+/]}" - else '' end + def strip_cwd_path path + path.sub(Dir.pwd, '.') end - def ann_html - gem 'nokogiri' - gem 'kramdown' - - IO.popen('kramdown', 'r+') do |md| - md.puts Gemgem.ann_md - md.close_write - require 'nokogiri' - html = Nokogiri::XML.parse("<gemgem>#{md.read}</gemgem>") - html.css('*').each{ |n| n.delete('id') } - html.root.children.to_html - end + def git *args + `git --git-dir=#{dir}/.git #{args.join(' ')}` end - def ann_email - "#{readme['HEADER'].sub(/([\w\-]+)/, "\\1 <#{spec.homepage}>")}\n\n" \ - "#{readme['DESCRIPTION']}\n\n" \ - "#{readme['INSTALLATION']}\n\n" + - if readme['SYNOPSIS'] then "##{readme['SYNOPSIS']}\n\n" else '' end + - "## CHANGES:\n\n" \ - "##{changes}\n\n" + def sh_git *args + Rake.sh('git', "--git-dir=#{dir}/.git", *args) end - def gem_tag - "#{spec.name}-#{spec.version}" + def sh_gem *args + Rake.sh(Gem.ruby, '-S', 'gem', *args) end - def write - File.open("#{dir}/#{spec.name}.gemspec", 'w'){ |f| - f << split_lines(spec.to_ruby) } + def glob path=dir + Dir.glob("#{path}/**/*", File::FNM_DOTMATCH) end - def split_lines ruby - ruby.gsub(/(.+?)\s*=\s*\[(.+?)\]/){ |s| - if $2.index(',') - "#{$1} = [\n #{$2.split(',').map(&:strip).join(",\n ")}]" + def readme + @readme ||= + if (path = "#{Gemgem.dir}/README.md") && File.exist?(path) + ps = "##{File.read(path)}". + scan(/((#+)[^\n]+\n\n.+?(?=(\n\n\2[^#\n]+\n)|\Z))/m).map(&:first) + ps.inject('HEADER' => ps.first){ |r, s, i| + r[s[/\w+/]] = s + r + } else - s + {} end - } end + def description + # JRuby String#lines is returning an enumerator + @description ||= (readme['DESCRIPTION']||'').sub(/.+\n\n/, '').lines.to_a + end + def all_files - @all_files ||= find_files(Pathname.new(dir)).map{ |file| - if file.to_s =~ %r{\.git/|\.git$} - nil + @all_files ||= fold_files(glob).sort + end + + def fold_files files + files.inject([]){ |r, path| + if File.file?(path) && path !~ %r{/\.git(/|$)} && + (rpath = path[%r{^#{escaped_dir}/(.*$)}, 1]) + r << rpath + elsif File.symlink?(path) # walk into symlinks... + r.concat(fold_files(glob(File.expand_path(path, + File.readlink(path))))) else - file.to_s + r end - }.compact.sort + } end def gem_files - @gem_files ||= all_files - ignored_files + @gem_files ||= all_files.reject{ |f| + f =~ ignored_pattern && !git_files.include?(f) + } end - def ignored_files - @ignored_file ||= all_files.select{ |path| ignore_patterns.find{ |ignore| - path =~ ignore && !git_files.include?(path)}} + def test_files + @test_files ||= gem_files.grep(%r{^test/(.+?/)*test_.+?\.rb$}) end + def bin_files + @bin_files ||= gem_files.grep(%r{^bin/}).map{ |f| File.basename(f) } + end + def git_files @git_files ||= if File.exist?("#{dir}/.git") - `git ls-files`.split("\n") + git('ls-files').split("\n") else [] end end - # protected - def find_files path - path.children.select(&:file?).map{|file| file.to_s[(dir.size+1)..-1]} + - path.children.select(&:directory?).map{|dir| find_files(dir)}.flatten + def ignored_files + @ignored_files ||= all_files.grep(ignored_pattern) end - def ignore_patterns - @ignore_files ||= expand_patterns( - gitignore.split("\n").reject{ |pattern| - pattern.strip == '' - }).map{ |pattern| %r{^([^/]+/)*?#{Regexp.escape(pattern)}(/[^/]+)*?$} } + def ignored_pattern + @ignored_pattern ||= Regexp.new(expand_patterns(gitignore).join('|')) end def expand_patterns pathes - pathes.map{ |path| - if path !~ /\*/ - path - else - expand_patterns( - Dir[path] + - Pathname.new(File.dirname(path)).children.select(&:directory?). - map{ |prefix| "#{prefix}/#{File.basename(path)}" }) + # http://git-scm.com/docs/gitignore + pathes.flat_map{ |path| + case path + when %r{\*} + Regexp.escape(path).gsub(/\\\*/, '[^/]*') + when %r{^/} + "^#{Regexp.escape(path[1..-1])}" + else # we didn't implement negative pattern for now + Regexp.escape(path) end - }.flatten + } end def gitignore - if File.exist?(path = "#{dir}/.gitignore") - File.read(path) - else - '' - end + @gitignore ||= if File.exist?(path = "#{dir}/.gitignore") + File.read(path).lines. + reject{ |l| l == /^\s*(#|\s+$)/ }.map(&:strip) + else + [] + end end end namespace :gem do desc 'Install gem' task :install => [:build] do - sh("#{Gem.ruby} -S gem install pkg/#{Gemgem.gem_tag}.gem") + Gemgem.sh_gem('install', Gemgem.gem_path) end desc 'Build gem' task :build => [:spec] do - sh("#{Gem.ruby} -S gem build #{Gemgem.spec.name}.gemspec") - sh("mkdir -p pkg") - sh("mv #{Gemgem.gem_tag}.gem pkg/") + require 'fileutils' + require 'rubygems/package' + gem = nil + Dir.chdir(Gemgem.dir) do + gem = Gem::Package.build(Gem::Specification.load(Gemgem.spec_path)) + FileUtils.mkdir_p(Gemgem.pkg_dir) + FileUtils.mv(gem, Gemgem.pkg_dir) # gem is relative path, but might be ok + end + puts "\e[35mGem built: \e[33m" \ + "#{Gemgem.strip_path("#{Gemgem.pkg_dir}/#{gem}")}\e[0m" end +desc 'Generate gemspec' +task :spec do + Gemgem.create + Gemgem.write +end + desc 'Release gem' task :release => [:spec, :check, :build] do - sh("git tag #{Gemgem.gem_tag}") - sh("git push") - sh("git push --tags") - sh("#{Gem.ruby} -S gem push pkg/#{Gemgem.gem_tag}.gem") + Gemgem.module_eval do + sh_git('tag', Gemgem.gem_tag) + sh_git('push') + sh_git('push', '--tags') + sh_gem('push', Gemgem.gem_path) + end end task :check do ver = Gemgem.spec.version.to_s @@ -216,53 +226,39 @@ end # of gem namespace desc 'Run tests in memory' task :test do + next if Gemgem.test_files.empty? + require 'bacon' Bacon.extend(Bacon::TestUnitOutput) Bacon.summary_on_exit - $LOAD_PATH.unshift('lib') - Dir['./test/**/test_*.rb'].each{ |file| require file[0..-4] } + Gemgem.test_files.each{ |file| require "#{Gemgem.dir}/#{file[0..-4]}" } end -desc 'Run tests with shell' -task 'test:shell', :RUBY_OPTS do |t, args| - files = Dir['test/**/test_*.rb'].join(' ') +desc 'Remove ignored files' +task :clean => ['gem:spec'] do + next if Gemgem.ignored_files.empty? - cmd = [Gem.ruby, args[:RUBY_OPTS], - '-I', 'lib', '-S', 'bacon', '--quiet', files] + require 'fileutils' + trash = File.expand_path("~/.Trash/#{Gemgem.spec.name}") + puts "Move the following files into:" \ + " \e[35m#{Gemgem.strip_path(trash)}\e[33m" - sh(cmd.compact.join(' ')) -end + Gemgem.ignored_files.each do |file| + from = "#{Gemgem.dir}/#{file}" + to = "#{trash}/#{File.dirname(file)}" + puts Gemgem.strip_path(from) -desc 'Generate ann markdown' -task 'ann:md' => ['gem:spec'] do - puts Gemgem.ann_md -end + FileUtils.mkdir_p(to) + FileUtils.mv(from, to) + end -desc 'Generate ann html' -task 'ann:html' => ['gem:spec'] do - puts Gemgem.ann_html + print "\e[0m" end -desc 'Generate ann email' -task 'ann:email' => ['gem:spec'] do - puts Gemgem.ann_email -end - -desc 'Generate rdoc' -task :doc => ['gem:spec'] do - sh("yardoc -o rdoc --main README.md" \ - " --files #{Gemgem.spec.extra_rdoc_files.join(',')}") -end - -desc 'Remove ignored files' -task :clean => ['gem:spec'] do - trash = "~/.Trash/#{Gemgem.spec.name}/" - sh "mkdir -p #{trash}" unless File.exist?(File.expand_path(trash)) - Gemgem.ignored_files.each{ |file| sh "mv #{file} #{trash}" } -end - task :default do - puts `#{Gem.ruby} -S #{$PROGRAM_NAME} -T` + # Is there a reliable way to do this in the current process? + # It failed miserably before between Rake versions... + exec "#{Gem.ruby} -S #{$PROGRAM_NAME} -f #{Rake.application.rakefile} -T" end