diff --git a/Rakefile b/Rakefile index 05136dc2..4f7c3dac 100644 --- a/Rakefile +++ b/Rakefile @@ -1,138 +1,138 @@ -require 'open-uri' - namespace :book do - def exec_or_raise(command) - puts `#{command}` - if (! $?.success?) - raise "[ERROR] '#{command}' failed" - end - end - - def generate_contributors_list(column_size) - # Generating preformatted contributors list... - `git shortlog -s HEAD | grep -v -E "(Straub|Chacon|dependabot)" | cut -f 2- | column -c #{column_size} > book/contributors.txt` - end - - def download_locale(locale_file) - locale_file_url = "https://raw.githubusercontent.com/asciidoctor/asciidoctor/master/data/locale/#{locale_file}" - if not File.exist?(locale_file) - puts "Downloading locale attributes file..." - l10n_text = URI.open(locale_file_url).read - File.open(locale_file, 'w') { |file| file.puts l10n_text } - puts " -- Saved at #{locale_file}" - else - puts "Use existing file with locale attributes #{locale_file}" - end - end # Variables referenced for build - lang = 'ru' - locale_file = "attributes-#{lang}.adoc" - date_string = Time.now.strftime('%d.%m.%Y') - - version_string = `git describe --tags`.chomp + version_string = `git describe --tags --abbrev=0`.chomp if version_string.empty? version_string = '0' + else + versions = version_string.split('.') + version_string = versions[0] + '.' + versions[1] + '.' + versions[2].to_i.next.to_s + end + date_string = Time.now.strftime('%Y-%m-%d') + params = "--attribute revnumber='#{version_string}' --attribute revdate='#{date_string}'" + header_hash = `git rev-parse --short HEAD`.strip + + # Check contributors list + # This checks commit hash stored in the header of list against current HEAD + def check_contrib + if File.exist?('book/contributors.txt') + current_head_hash = `git rev-parse --short HEAD`.strip + header = `head -n 1 book/contributors.txt`.strip + # Match regex, then coerce resulting array to string by join + header_hash = header.scan(/[a-f0-9]{7,}/).join + + if header_hash == current_head_hash + puts "Hash on header of contributors list (#{header_hash}) matches the current HEAD (#{current_head_hash})" + else + puts "Hash on header of contributors list (#{header_hash}) does not match the current HEAD (#{current_head_hash}), refreshing" + sh "rm book/contributors.txt" + # Reenable and invoke task again + Rake::Task['book/contributors.txt'].reenable + Rake::Task['book/contributors.txt'].invoke + end + end end - params = "--attribute revnumber='#{version_string}' --attribute revdate='#{date_string}' --attribute lang=#{lang} " - ignore_urls = "'https://developer.github.com','https://developer.github.com/webhooks/','https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent','https://mvnrepository.com/artifact/org.eclipse.jgit/org.eclipse.jgit','https://www.mercurial-scm.org/'" - # Tasks list desc 'build basic book formats' task :build => [:build_html, :build_epub, :build_fb2, :build_mobi, :build_pdf] do begin - puts 'Validating generated files...' - Rake::Task['book:check'].invoke + # Run check + Rake::Task['book:check'].invoke + + # Rescue to ignore checking errors + rescue => e + puts e.message + puts 'Error when checking books (ignored)' end end - desc 'prepare necessary data to start build' - task :prebuild, [:column_size] do |t, args| - args.with_defaults(:column_size => 72) + desc 'build basic book formats (for ci)' + task :ci => [:build_html, :build_epub, :build_fb2, :build_mobi, :build_pdf] do + # Run check, but don't ignore any errors + Rake::Task['book:check'].invoke + end - download_locale(locale_file) - generate_contributors_list(args.column_size) + desc 'generate contributors list' + file 'book/contributors.txt' do + puts 'Generating contributors list' + sh "echo 'Contributors as of #{header_hash}:\n' > book/contributors.txt" + sh "git shortlog -s HEAD | grep -v -E '(Straub|Chacon|dependabot)' | cut -f 2- | sort | column -c 120 >> book/contributors.txt" end desc 'build HTML format' - task :build_html do - Rake::Task['book:prebuild'].invoke(72) + task :build_html => 'book/contributors.txt' do + check_contrib() + + puts 'Converting to HTML...' + sh "bundle exec asciidoctor #{params} -a data-uri progit.asc" + puts ' -- HTML output at progit.html' - puts 'Converting to HTML...' - `bundle exec asciidoctor #{params} -a data-uri progit.asc` - puts ' -- HTML output at progit.html' end - desc 'build EPUB format' - task :build_epub do - Rake::Task['book:prebuild'].invoke(48) + desc 'build Epub format' + task :build_epub => 'book/contributors.txt' do + check_contrib() + + puts 'Converting to EPub...' + sh "bundle exec asciidoctor-epub3 #{params} progit.asc" + puts ' -- Epub output at progit.epub' - puts 'Converting to EPUB...' - `bundle exec asciidoctor-epub3 #{params} progit.asc` - puts ' -- EPUB output at progit.epub' end desc 'build FB2 format' - task :build_fb2 do - Rake::Task['book:prebuild'].invoke(48) + task :build_fb2 => 'book/contributors.txt' do + check_contrib() + + puts 'Converting to FB2...' + sh "bundle exec asciidoctor-fb2 #{params} progit.asc" + puts ' -- FB2 output at progit.fb2.zip' - puts 'Converting to FB2...' - `bundle exec asciidoctor-fb2 #{params} progit.asc --trace --verbose` - puts ' -- FB2 output at progit.fb2.zip' end desc 'build Mobi format' - task :build_mobi do - Rake::Task['book:prebuild'].invoke(48) + task :build_mobi => 'book/contributors.txt' do + check_contrib() - puts 'Converting to Mobi (kf8)...' - `bundle exec asciidoctor-epub3 #{params} -a ebook-format=kf8 progit.asc` - puts ' -- Mobi output at progit.mobi' + puts "Converting to Mobi (kf8)..." + sh "bundle exec asciidoctor-epub3 #{params} -a ebook-format=kf8 progit.asc" + puts " -- Mobi output at progit.mobi" end desc 'build PDF format' - task :build_pdf do - Rake::Task['book:prebuild'].invoke(72) - - puts 'Converting to PDF... (this one takes a while)' - `bundle exec asciidoctor-pdf #{params} progit.asc 2>/dev/null` - puts ' -- PDF output at progit.pdf' - end + task :build_pdf => 'book/contributors.txt' do + check_contrib() - desc 'check HTML book' - task :check_html do - if not File.exist?('progit.html') - Rake::Task['book:build_html'].invoke - end - - puts ' -- Validate HTML file progit.html' - exec_or_raise("bundle exec htmlproofer --url-ignore #{ignore_urls} --check-html progit.html") + puts 'Converting to PDF... (this one takes a while)' + sh "bundle exec asciidoctor-pdf #{params} progit.asc 2>/dev/null" + puts ' -- PDF output at progit.pdf' end - desc 'check EPUB book' - task :check_epub do - if not File.exist?('progit.epub') - Rake::Task['book:build_epub'].invoke - end + desc 'Check generated books' + task :check => [:build_html, :build_epub] do + puts 'Checking generated books' - puts ' -- Validate EPUB output file progit.epub' - exec_or_raise('bundle exec epubcheck progit.epub') + sh "htmlproofer progit.html" + sh "epubcheck progit.epub" end - desc 'check generated books' - task :check => [:check_html, :check_epub] - - desc 'clean all generated files' + desc 'Clean all generated files' task :clean do begin - puts 'Removing downloaded and generated files' - - FileList[locale_file, 'book/contributors.txt', 'progit.html', 'progit.epub', 'progit.fb2.zip', 'progit.pdf', 'progit.mobi'].each do |file| - rm file - rescue Errno::ENOENT - end + puts 'Removing generated files' + + FileList['book/contributors.txt', 'progit.html', 'progit-kf8.epub', 'progit.epub', 'progit.fb2.zip', 'progit.mobi', 'progit.pdf'].each do |file| + rm file + + # Rescue if file not found + rescue Errno::ENOENT => e + begin + puts e.message + puts 'Error removing files (ignored)' + end + end end end + end task :default => "book:build"