require 'shoulda/matchers/version' require 'erb' module Shoulda module Matchers module DocumentationTasks extend Rake::DSL def self.create # rubocop:disable Metrics/MethodLength publisher = DocumentationPublisher.new namespace :docs do file DocumentationPublisher.gh_pages_dir do publisher.create_reference_to_gh_pages_branch end file DocumentationPublisher.docs_dir => DocumentationPublisher.gh_pages_dir task setup: DocumentationPublisher.docs_dir do publisher.reset_repo_directory end desc 'Generate docs for a particular version' task :generate, [:version, :latest_version] => :setup do |_t, args| unless args.version raise ArgumentError, 'Missing version' end unless args.latest_version raise ArgumentError, 'Missing latest_version' end publisher.generate_docs_for( args.version, latest_version: args.latest_version, ) end desc 'Watch source files for this project for changes and'\ ' autogenerate docs accordingly' task :autogenerate do require 'fssm' project_directory = File.expand_path("#{File.dirname(__FILE__)}/..") regenerate_docs = proc do print 'Regenerating docs... ' if system('bundle exec yard doc &>/dev/null') puts 'done!' else print "\nCould not regenerate docs!!" end end regenerate_docs.call puts 'Waiting for documentation files to change...' FSSM.monitor do path project_directory do glob '{README.md,CHANGELOG.md,.yardopts,docs/**/*.md,'\ 'doc_config/yard/**/*.{rb,js,css,erb},lib/**/*.rb}' create(®enerate_docs) update(®enerate_docs) end end end desc 'Generate docs for a particular version and push them to GitHub' task :publish, [:version, :latest_version] => :setup do |_t, args| unless args.version raise ArgumentError, 'Missing version' end unless args.latest_version raise ArgumentError, 'Missing latest_version' end publisher.generate_docs_for( args.version, latest_version: args.latest_version, ) publisher.publish_docs_for( args.version, latest_version: args.latest_version, ) end desc 'Generate docs for version'\ " #{DocumentationPublisher.current_version} and push them to GitHub" task publish_latest: :setup do publisher.publish_latest_version end end end end class DocumentationPublisher CURRENT_VERSION = Shoulda::Matchers::VERSION GITHUB_USERNAME = 'thoughtbot'.freeze # GITHUB_USERNAME = 'mcmire' GH_PAGES_DIR = ".#{GITHUB_USERNAME}-gh-pages".freeze DOCS_DIR = "#{GH_PAGES_DIR}/docs".freeze def self.current_version CURRENT_VERSION end def self.gh_pages_dir GH_PAGES_DIR end def self.docs_dir DOCS_DIR end def create_reference_to_gh_pages_branch system "git clone git@github.com:#{GITHUB_USERNAME}"\ "/shoulda-matchers.git #{GH_PAGES_DIR} --branch gh-pages" end def reset_repo_directory within_gh_pages_dir do system 'git fetch origin' system 'git reset --hard origin/gh-pages' end end def generate_docs_for(version, options = {}) ref = determine_ref_from(version) system "rm -rf #{DOCS_DIR}/#{ref}" system "bundle exec yard -o #{DOCS_DIR}/#{ref}" add_version_to_index_page_for(ref, version) within_docs_dir do system "git add #{ref}" end if options[:latest_version] generate_file_that_redirects_to_latest_version( options[:latest_version], ) end end def publish_docs_for(version, _options = {}) message = build_commit_message(version) within_gh_pages_dir do system 'git clean -f' system "git commit -m '#{message}'" system 'git push origin gh-pages' end end def publish_latest_version version = Gem::Version.new(CURRENT_VERSION) options = {} unless version.prerelease? options[:latest_version] = version.to_s end generate_docs_for(CURRENT_VERSION, options) publish_docs_for(CURRENT_VERSION, options) end private def add_version_to_index_page_for(ref, version) within_docs_dir do filename = "#{ref}/index.html" content = File.read(filename) content.sub!( %r{

shoulda-matchers.+

}, "

shoulda-matchers (#{version})

", ) File.open(filename, 'w') {|f| f.write(content) } end end def generate_file_that_redirects_to_latest_version(version) ref = determine_ref_from(version) locals = { ref: ref, github_username: GITHUB_USERNAME } erb = ERB.new(File.read('doc_config/gh-pages/index.html.erb')) within_docs_dir do File.open('index.html', 'w') { |f| f.write(erb.result(binding)) } system 'git add index.html' end end def determine_ref_from(version) if version =~ /^\d+\.\d+\.\d+/ "v#{version}" else version end end def build_commit_message(version) "Regenerated docs for version #{version}" end def within_gh_pages_dir(&block) Dir.chdir(GH_PAGES_DIR, &block) end def within_docs_dir(&block) Dir.chdir(DOCS_DIR, &block) end end end end