325 lines
9.9 KiB
Ruby
325 lines
9.9 KiB
Ruby
=begin
|
|
***************************************************************************
|
|
* Copyright (C) 2008,2009,2010 by Volker Lanz <vl@fidra.de> *
|
|
* Copyright (C) 2007-2008 by Harald Sitter <harald@getamarok.com> *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program; if not, write to the *
|
|
* Free Software Foundation, Inc., *
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
|
|
***************************************************************************
|
|
=end
|
|
|
|
require 'application.rb'
|
|
require 'tagger.rb'
|
|
require 'translationstatsbuilder.rb'
|
|
require 'fileutils'
|
|
require 'getoptlong'
|
|
|
|
class ReleaseBuilder
|
|
|
|
public
|
|
def initialize(checkoutFrom, checkoutTag, app, workingDir, protocol, user, version)
|
|
@checkoutFrom = checkoutFrom
|
|
@checkoutTag = checkoutTag
|
|
@app = app
|
|
@workingDir = workingDir
|
|
@protocol = protocol
|
|
@user = user
|
|
@version = version
|
|
|
|
@outputDir = "#{@app.name}-#{@version}"
|
|
|
|
FileUtils.rm_rf @outputDir
|
|
FileUtils.rm_rf "#{@outputDir}.tar.bz2"
|
|
FileUtils.rm_rf "#{@outputDir}.tar.gz"
|
|
FileUtils.rm_rf "#{@outputDir}-l10n-stats.html"
|
|
end
|
|
|
|
def run(createTarball, getTranslations, skipBelow, getDocs, createTag, applyFixes)
|
|
checkoutSource
|
|
translations = checkoutTranslations(skipBelow) if getTranslations
|
|
docs = checkoutDocumentation if getDocs
|
|
|
|
if createTag
|
|
Dir.chdir "#{@workingDir}/#{@outputDir}"
|
|
tagger = Tagger.new(@checkoutFrom, @checkoutTag, @app, @protocol, @user, @version)
|
|
tagger.tagSource
|
|
tagger.tagTranslations(translations) if getTranslations
|
|
tagger.tagDocumentation(docs) if getDocs
|
|
end
|
|
|
|
@app.applyFixes(@workingDir, @outputDir) if applyFixes
|
|
|
|
self.createTarball if createTarball
|
|
end
|
|
|
|
def checkoutSource
|
|
Dir.chdir @workingDir
|
|
|
|
repository = ReleaseBuilder.repositoryRoot(@protocol, @user) + ReleaseBuilder.repositoryPath('src', @app, @checkoutFrom, @checkoutTag)
|
|
`svn co #{repository} #{@outputDir}`
|
|
end
|
|
|
|
def createCmakeListsTranslations(lang)
|
|
File.open("po/#{lang}/CMakeLists.txt", File::CREAT | File::RDWR | File::TRUNC) do |f|
|
|
f.print <<END_OF_TEXT
|
|
file(GLOB _po_files *.po)
|
|
GETTEXT_PROCESS_PO_FILES(#{lang} ALL INSTALL_DESTINATION ${LOCALE_INSTALL_DIR} ${_po_files})
|
|
END_OF_TEXT
|
|
end
|
|
end
|
|
|
|
def checkTranslation(lang, translationDir, skipBelow)
|
|
if skipBelow > 0
|
|
fuzzy, untranslated, per = TranslationStatsBuilder.fileStats("#{translationDir}/#{@app.name}.po")
|
|
puts "Language #{lang} is #{per}% complete."
|
|
if per < skipBelow
|
|
FileUtils.rm_rf translationDir
|
|
return false
|
|
end
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
def checkoutTranslations(skipBelow)
|
|
Dir.chdir "#{@workingDir}/#{@outputDir}"
|
|
|
|
FileUtils.rm_rf 'l10n'
|
|
FileUtils.rm_rf 'po'
|
|
|
|
repository = ReleaseBuilder.repositoryRoot(@protocol, @user) + ReleaseBuilder.repositoryPath('i18n', @app, @checkoutFrom, @checkoutTag)
|
|
|
|
translations = []
|
|
|
|
if @checkoutFrom == 'trunk'
|
|
Dir.mkdir 'po'
|
|
|
|
subdirs = `svn cat #{repository}/subdirs 2>/dev/null`.chomp!
|
|
|
|
subdirs.each do |lang|
|
|
lang.chomp!
|
|
next if lang == 'x-test'
|
|
|
|
FileUtils.rm_rf 'l10n'
|
|
`svn co #{repository}/#{lang}/messages/#{@app.component}-#{@app.section} l10n >/dev/null 2>&1`
|
|
next unless FileTest.exists? "l10n/#{@app.name}.po"
|
|
next unless checkTranslation(lang, "l10n", skipBelow)
|
|
|
|
puts "Adding translations for #{lang}..."
|
|
|
|
dest = "po/#{lang}"
|
|
Dir.mkdir dest
|
|
|
|
FileUtils.mv("l10n/#{@app.name}.po", dest)
|
|
FileUtils.mv('l10n/.svn', dest)
|
|
|
|
createCmakeListsTranslations(lang)
|
|
|
|
`svn add #{dest}/CMakeLists.txt >/dev/null 2>&1`
|
|
translations << lang
|
|
end
|
|
else
|
|
`svn co #{repository} >/dev/null 2>&1`
|
|
Dir.entries('po').sort.each do |lang|
|
|
next if lang == 'CMakeLists.txt' or lang == '.' or lang == '..' or lang == '.svn'
|
|
next unless checkTranslation(lang, "po/#{lang}", skipBelow)
|
|
|
|
createCmakeListsTranslations(lang)
|
|
|
|
translations << lang
|
|
end
|
|
end
|
|
|
|
if translations.length > 0
|
|
File.open('po/CMakeLists.txt', File::CREAT | File::RDWR | File::TRUNC) do |f|
|
|
f.print <<END_OF_TEXT
|
|
|
|
find_package(Gettext REQUIRED)
|
|
|
|
if (NOT GETTEXT_MSGMERGE_EXECUTABLE)
|
|
message(FATAL_ERROR "Please install the msgmerge program from the gettext package.")
|
|
endif (NOT GETTEXT_MSGMERGE_EXECUTABLE)
|
|
|
|
if (NOT GETTEXT_MSGFMT_EXECUTABLE)
|
|
message(FATAL_ERROR "Please install the msgfmt program from the gettext package.")
|
|
endif (NOT GETTEXT_MSGFMT_EXECUTABLE)
|
|
|
|
END_OF_TEXT
|
|
|
|
translations.each { |lang| f.print "add_subdirectory(#{lang})\n" }
|
|
end
|
|
|
|
File.open('CMakeLists.txt', File::APPEND | File::RDWR) do |f|
|
|
f.print <<END_OF_TEXT
|
|
include(MacroOptionalAddSubdirectory)
|
|
macro_optional_add_subdirectory(po)
|
|
END_OF_TEXT
|
|
end
|
|
|
|
TranslationStatsBuilder.new(@app.name, @version, @workingDir, @outputDir).run
|
|
else
|
|
FileUtils.rm_rf 'po'
|
|
end
|
|
|
|
FileUtils.rm_rf 'l10n'
|
|
|
|
return translations
|
|
end
|
|
|
|
def createCmakeListsDoc(lang)
|
|
File.open("doc/#{lang}/CMakeLists.txt", File::CREAT | File::RDWR | File::TRUNC) do |f|
|
|
f << "kde4_create_handbook(index.docbook INSTALL_DESTINATION \${HTML_INSTALL_DIR}/#{lang}/ SUBDIR #{@app.name})\n"
|
|
end
|
|
end
|
|
|
|
def checkoutDocumentation
|
|
Dir.chdir "#{@workingDir}/#{@outputDir}"
|
|
|
|
docs = [ ]
|
|
repository = ReleaseBuilder.repositoryRoot(@protocol, @user) + ReleaseBuilder.repositoryPath('doc', @app, @checkoutFrom, @checkoutTag)
|
|
|
|
if @checkoutFrom == 'trunk'
|
|
# the english docs are the super-extra-exception: they reside near, but not with, the code
|
|
usDocsRepo = ReleaseBuilder.repositoryRoot(@protocol, @user) + "trunk"
|
|
|
|
`svn co #{usDocsRepo}/#{@app.component}/#{@app.section}/doc/#{@app.name} doc/en_US >/dev/null 2>&1`
|
|
|
|
if not File.exists? 'doc/en_US/index.docbook'
|
|
FileUtils.rm_rf 'doc'
|
|
return nil
|
|
end
|
|
|
|
createCmakeListsDoc("en_US")
|
|
docs << 'en_US'
|
|
|
|
# now, the rest of the docs are localized, so reside somewhere else
|
|
subdirs = `svn cat #{repository}/subdirs 2>/dev/null`.chomp!
|
|
|
|
subdirs.each do |lang|
|
|
lang.chomp!
|
|
|
|
FileUtils.rm_rf 'l10n'
|
|
`svn co #{repository}/#{lang}/docs/#{@app.component}-#{@app.section}/#{@app.name} l10n >/dev/null 2>&1`
|
|
next unless FileTest.exists? 'l10n/index.docbook'
|
|
|
|
puts "Adding documentation for #{lang}..."
|
|
|
|
dest = "doc/#{lang}"
|
|
FileUtils.mv('l10n', dest)
|
|
|
|
createCmakeListsDoc(lang)
|
|
|
|
`svn add doc/#{lang}/CMakeLists.txt >/dev/null 2>&1`
|
|
docs << lang
|
|
end
|
|
else
|
|
`svn co #{repository} >/dev/null 2>&1`
|
|
return nil if not FileTest.exists? 'doc'
|
|
Dir.entries('doc').sort.each do |lang|
|
|
next if lang == 'CMakeLists.txt' or lang == '.' or lang == '..' or lang == '.svn'
|
|
createCmakeListsDoc(lang)
|
|
docs << lang
|
|
end
|
|
end
|
|
|
|
File.open('doc/CMakeLists.txt', File::CREAT | File::RDWR | File::TRUNC) do |f|
|
|
docs.each { |lang| f << "add_subdirectory(#{lang})\n" }
|
|
end
|
|
|
|
File.open('CMakeLists.txt', File::APPEND | File::RDWR) do |f|
|
|
f << "include(MacroOptionalAddSubdirectory)\n" unless File.exists? 'po'
|
|
f << "macro_optional_add_subdirectory(doc)\n"
|
|
end
|
|
|
|
FileUtils.rm_rf 'l10n'
|
|
|
|
return docs
|
|
end
|
|
|
|
def createTarball
|
|
Dir.chdir @workingDir
|
|
|
|
tarBzFileName = "#{@outputDir}.tar.bz2"
|
|
tarGzFileName = "#{@outputDir}.tar.gz"
|
|
|
|
`find #{@outputDir} -name .svn | xargs rm -rf`
|
|
`tar cfj #{tarBzFileName} #{@outputDir}`
|
|
`tar cfz #{tarGzFileName} #{@outputDir}`
|
|
`rm -rf #{@outputDir}`
|
|
|
|
puts "bz2 MD5: " + `md5sum #{tarBzFileName}`.split[0]
|
|
puts "bz2 SHA1: " + `sha1sum #{tarBzFileName}`.split[0]
|
|
|
|
puts "gz MD5: " + `md5sum #{tarGzFileName}`.split[0]
|
|
puts "gz SHA1: " + `sha1sum #{tarGzFileName}`.split[0]
|
|
end
|
|
|
|
def self.repositoryRoot(protocol, user)
|
|
if protocol == 'anonsvn'
|
|
protocol = 'svn'
|
|
user = 'anon'
|
|
else
|
|
user += "@"
|
|
end
|
|
|
|
return "#{protocol}://#{user}svn.kde.org/home/kde/"
|
|
end
|
|
|
|
def self.repositoryPath(type, app, checkoutFrom, tag)
|
|
|
|
if type == 'src'
|
|
|
|
rval = case checkoutFrom
|
|
when 'trunk' then "trunk/#{app.component}/#{app.section}/#{app.name}"
|
|
when 'branches' then "branches/#{app.name}/#{tag}/#{app.name}"
|
|
when 'tags' then "tags/#{app.name}/#{tag}/#{app.name}"
|
|
else "### invalid checkout source: #{checkoutFrom} ###"
|
|
end
|
|
|
|
elsif type == 'i18n'
|
|
|
|
rval = case checkoutFrom
|
|
when 'trunk' then "trunk/l10n-kde4/" # followed by $lang/messages/#{app.component}-#{app.section}/#{app.name}.po, but the code has to deal with that
|
|
when 'branches' then "branches/#{app.name}/#{tag}/po"
|
|
when 'tags' then "tags/#{app.name}/#{tag}/po"
|
|
else "### invalid checkout source: #{checkoutFrom} ###"
|
|
end
|
|
|
|
elsif type == 'doc'
|
|
|
|
rval = case checkoutFrom
|
|
when 'trunk' then "trunk/l10n-kde4/" # see above
|
|
when 'branches' then "branches/#{app.name}/#{tag}/doc"
|
|
when 'tags' then "tags/#{app.name}/#{tag}/doc"
|
|
else "### invalid checkout source: #{checkoutFrom} ###"
|
|
end
|
|
|
|
else
|
|
# this is to get the root directory for tags and branches. it doesn't make any
|
|
# sense for trunk.
|
|
rval = case checkoutFrom
|
|
when 'trunk' then "### invalid checkout type / source combo: #{type} - #{checkoutFrom} ###"
|
|
when 'branches' then "branches/#{app.name}/#{tag}"
|
|
when 'tags' then "tags/#{app.name}/#{tag}"
|
|
else "### invalid checkout source: #{checkoutFrom} ###"
|
|
end
|
|
|
|
end
|
|
|
|
return rval
|
|
end
|
|
end
|
|
|