Add scripts to build releases. These are generic ruby scripts partly based on

the work of Harald Sitter for Amarok. They are not specific to partition
manager in any way.

svn path=/trunk/extragear/sysadmin/partitionmanager/; revision=889829
This commit is contained in:
Volker Lanz 2008-11-27 19:35:38 +00:00
parent cc3f80ad71
commit da03905187
6 changed files with 976 additions and 0 deletions

View File

@ -0,0 +1,238 @@
=begin
***************************************************************************
* Copyright (C) 2008 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
Apps = {
'Amarok' => [ 'amarok2', 'extragear', 'multimedia' ],
'Digikam' => [ 'digikam', 'extragear', 'graphics' ],
'Partition Manager' => [ 'partitionmanager', 'extragear', 'sysadmin' ]
}
require 'tagger.rb'
require 'translationstatsbuilder.rb'
require 'fileutils'
require 'getoptlong'
class ReleaseBuilder
def initialize(workingDir, repository, component, section, appName, version)
@workingDir = workingDir
@repository = repository
@component = component
@section = section
@appName = appName
@version = version
@outputDir = "#{@appName}-#{@version}"
FileUtils.rm_rf @outputDir
FileUtils.rm_rf "#{@outputDir}.tar.bz2"
end
def run(protocol, user, createTarball, getTranslations, getDocs, createTag)
checkoutSource
translations = checkoutTranslations if getTranslations
docs = checkoutDocumentation if getDocs
if createTag
repositoryTags = ReleaseBuilder.repository(@appName, protocol, user, @version)
tagger = Tagger.new(@repository, repositoryTags, @component, @section, @appName, @version)
tagger.tagSource
tagger.tagTranslations(translations)
tagger.tagDocumentation(docs)
end
self.createTarball if createTarball
end
def checkoutSource
Dir.chdir @workingDir
svnDir = "#{@component}/#{@section}/#{@appName}"
puts "Checking out source from #{@repository}/#{svnDir}..."
system "svn co #{@repository}/#{svnDir} #{@outputDir} >/dev/null 2>&1"
end
def checkoutTranslations
Dir.chdir "#{@workingDir}/#{@outputDir}"
FileUtils.rm_rf 'l10n'
FileUtils.rm_rf 'po'
Dir.mkdir 'l10n'
Dir.mkdir 'po'
subdirs = `svn cat #{@repository}/l10n-kde4/subdirs 2>/dev/null`.chomp!
translations = []
subdirs.each do |lang|
lang.chomp!
next if lang == 'x-test'
FileUtils.rm_rf 'l10n'
system "svn co #{@repository}/l10n-kde4/#{lang}/messages/#{@component}-#{@section} l10n >/dev/null 2>&1"
next unless FileTest.exists? "l10n/#{@appName}.po"
puts "Adding translations for #{lang}..."
dest = "po/#{lang}"
Dir.mkdir dest
FileUtils.mv("l10n/#{@appName}.po", dest)
FileUtils.mv('l10n/.svn', dest)
File.open("#{dest}/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
system "svn add #{dest}/CMakeLists.txt >/dev/null 2>&1"
translations += [lang]
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(@appName, @version, @workingDir, @outputDir).run
else
FileUtils.rm_rf 'po'
end
FileUtils.rm_rf 'l10n'
return translations
end
def checkoutDocumentation
Dir.chdir "#{@workingDir}/#{@outputDir}"
system "svn co #{@repository}/#{@component}/#{@section}/doc/#{@appName} doc/en_US >/dev/null 2>&1"
if not File.exists? 'doc/en_US/index.docbook'
FileUtils.rm_rf 'doc'
return nil
end
File.open("doc/en_US/CMakeLists.txt", File::CREAT | File::RDWR | File::TRUNC) do |f|
f << "kde4_create_handbook(index.docbook INSTALL_DESTINATION \${HTML_INSTALL_DIR}/en_US/ SUBDIR #{@appName})\n"
end
docs = [ "en_US" ]
subdirs = `svn cat #{@repository}/l10n-kde4/subdirs 2>/dev/null`.chomp!
subdirs.each do |lang|
lang.chomp!
FileUtils.rm_rf 'l10n'
system "svn co #{@repository}/l10n-kde4/#{lang}/docs/#{@component}-#{@section}/#{@appName} l10n >/dev/null 2>&1"
next unless FileTest.exists? 'l10n/index.docbook'
puts "Adding documentation for #{lang}..."
dest = "doc/#{lang}"
FileUtils.mv('l10n', dest)
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 #{@appName})\n"
end
system "svn add doc/#{lang}/CMakeLists.txt >/dev/null 2>&1"
docs += [lang]
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
tarFileName = "#{@outputDir}.tar.bz2"
system "find #{@outputDir} -name .svn | xargs rm -rf"
system "tar cfj #{tarFileName} #{@outputDir}"
FileUtils.rm_rf @outputDir
puts "MD5: " + `md5sum #{tarFileName}`.split[0]
puts "SHA1: " + `sha1sum #{tarFileName}`.split[0]
end
def self.repository(appName, protocol, user, tag)
if protocol == 'anonsvn'
protocol = 'svn'
user = 'anon'
else
user += "@"
end
if tag == 'stable'
branch = 'branches/stable'
elsif tag == 'trunk'
branch = 'trunk'
else
branch = "tags/#{appName}/#{tag}"
end
# return "file://localhost/home/vl/tmp/svn/#{branch}"
return "#{protocol}://#{user}svn.kde.org/home/kde/#{branch}"
end
def self.apps
return Apps
end
end

113
scripts/release/releasecmd.rb Executable file
View File

@ -0,0 +1,113 @@
#!/usr/bin/ruby
=begin
***************************************************************************
* Copyright (C) 2008 by Volker Lanz <vl@fidra.de> *
* *
* 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 'releasebuilder.rb'
def usage
puts <<END_OF_TEXT
#{$0} [options]
where options are:
--application-name (-a)*
--version (-v)*
--checkout-from (-c): trunk, stable, tag
--tag (-t): name of tag
--svn-access (-s): (https, svn+ssh, anonsvn)
--get-docs (-d): also get documentation
--get-translations (-r): also get translations
--create-tag (-e): create a new tag
--create-tarball (-b): create a tarball
--help (-h): show this usage
Options with an asterisk are required.
Possible values for application-name:
END_OF_TEXT
ReleaseBuilder.apps.sort.each { |a| puts '"' + a[0] + '"' }
end
opts = GetoptLong.new(
[ '--application-name', '-a', GetoptLong::REQUIRED_ARGUMENT ],
[ '--version', '-v', GetoptLong::REQUIRED_ARGUMENT ],
[ '--checkout-from', '-c', GetoptLong::REQUIRED_ARGUMENT ],
[ '--tag', '-t', GetoptLong::REQUIRED_ARGUMENT ],
[ '--svn-access', '-s', GetoptLong::REQUIRED_ARGUMENT ],
[ '--svn-user', '-u', GetoptLong::REQUIRED_ARGUMENT ],
[ '--get-docs', '-d', GetoptLong::NO_ARGUMENT ],
[ '--get-translations', '-r', GetoptLong::NO_ARGUMENT ],
[ '--create-tag', '-e', GetoptLong::NO_ARGUMENT ],
[ '--create-tarball', '-b', GetoptLong::NO_ARGUMENT ],
[ '--help', '-h', GetoptLong::NO_ARGUMENT ]
)
appName = ''
version = ''
checkoutFrom = 'trunk'
tag = ''
protocol = 'anonsvn'
user = ''
getDocs = false
getTranslations = false
createTag = false
createTarball = false
opts.each do |opt, arg|
case opt
when '--application-name' then appName = arg
when '--version' then version = arg
when '--checkout-from' then checkoutFrom = arg
when '--tag' then tag = arg
when '--svn-access' then protocol = arg
when '--svn-user' then user = arg
when '--get-docs' then getDocs = true
when '--get-translations' then getTranslations = true
when '--create-tag' then createTag = true
when '--create-tarball' then createTarball = true
when '--help' then usage; exit
end
end
if appName.empty? or version.empty?
puts "Application and version can not be empty."
exit
end
if not ReleaseBuilder.apps.key?(appName)
puts "Unknown application '#{appName}'"
exit
end
if protocol != 'anonsvn' and user.empty?
puts "The selected SVN access protocol requires a user name."
exit
end
if checkoutFrom == 'tag' and tag.empty?
puts "Cannot check out from tag dir if tag is empty."
exit
end
component = ReleaseBuilder.apps[appName][1]
section = ReleaseBuilder.apps[appName][2]
repository = ReleaseBuilder.repository(ReleaseBuilder.apps[appName][0], protocol, user, checkoutFrom != 'tag' ? checkoutFrom : tag)
releaseBuilder = ReleaseBuilder.new(Dir.getwd, repository, component, section, ReleaseBuilder.apps[appName][0], version)
releaseBuilder.run(protocol, user, createTarball, getTranslations, getDocs, createTag)

112
scripts/release/releasedialog.rb Executable file
View File

@ -0,0 +1,112 @@
#!/usr/bin/ruby
=begin
***************************************************************************
* Copyright (C) 2008 by Volker Lanz <vl@fidra.de> *
* *
* 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 'Qt4'
if not FileTest.exists?('ui_releasedialog.rb') or File::stat('ui_releasedialog.rb').mtime.to_i < File::stat('releasedialog.ui').mtime.to_i
puts "rebuilding ui_releasedialog.rb..."
system "rbuic4 releasedialog.ui > ui_releasedialog.rb"
end
require 'ui_releasedialog.rb'
require 'releasebuilder.rb'
class ReleaseDialog < Qt::Dialog
slots 'on_comboAccess_currentIndexChanged(int)',
'on_comboCheckout_currentIndexChanged(int)',
'on_comboName_currentIndexChanged(int)'
def initialize
super
@ui = Ui_ReleaseDialog.new()
@ui.setupUi(self)
ReleaseBuilder.apps.sort.each { |key, value| @ui.comboName.addItem(key) }
end
def validate
if @ui.editVersion.text.empty?
Qt::MessageBox.information(self, tr('Missing Information'), tr('The application\'s version can not be empty.'))
return false
end
if @ui.comboAccess.currentIndex != 0 and @ui.editUser.text.empty?
Qt::MessageBox.information(self, tr('Missing Information'), tr('Please provide a user name for the selected SVN access method.'))
return false
end
return true
end
def accept
return if not validate
component = ReleaseBuilder.apps[@ui.comboName.currentText][1]
section = ReleaseBuilder.apps[@ui.comboName.currentText][2]
appName = ReleaseBuilder.apps[@ui.comboName.currentText][0]
version = @ui.editVersion.text
repository = ReleaseBuilder.repository(ReleaseBuilder.apps[@ui.comboName.currentText][0], @ui.comboAccess.currentText, @ui.editUser.text, @ui.comboCheckout.currentText != 'tag' ? @ui.comboCheckout.currentText : @ui.comboTag.currentText)
releaseBuilder = ReleaseBuilder.new(Dir.getwd, repository, component, section, appName, version)
releaseBuilder.run(@ui.comboAccess.currentText, @ui.editUser.text, @ui.checkTarball.isChecked, @ui.checkTranslations.isChecked, @ui.checkDocs.isChecked, @ui.checkTag.isChecked)
super
end
private
def on_comboName_currentIndexChanged(index)
on_comboCheckout_currentIndexChanged(@ui.comboCheckout.currentIndex)
end
def on_comboAccess_currentIndexChanged(index)
@ui.editUser.setEnabled(index > 0)
end
def on_comboCheckout_currentIndexChanged(index)
@ui.comboTag.setEnabled(index == 2)
updateTags or @ui.comboTag.setEnabled(false) if index == 2
end
def updateTags
@ui.comboTag.clear
appName = ReleaseBuilder.apps[@ui.comboName.currentText][0]
# tags = `svn ls file://localhost/home/vl/tmp/svn/tags/#{appName}`.chomp!
tags = `svn ls svn://anonsvn.kde.org/home/kde/tags/#{appName}`.chomp!
return false if not tags or tags.length == 0
tags.sort.each { |t| @ui.comboTag.addItem(t.delete("/\n\r")) }
return true
end
end
if __FILE__ == $0
app = Qt::Application.new(ARGV)
window = ReleaseDialog.new
window.show
app.exec
end

View File

@ -0,0 +1,314 @@
<ui version="4.0" >
<class>ReleaseDialog</class>
<widget class="QDialog" name="ReleaseDialog" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>464</width>
<height>374</height>
</rect>
</property>
<property name="windowTitle" >
<string>KDE Release Builder</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" >
<item>
<widget class="QGroupBox" name="goupApplication" >
<property name="title" >
<string>Application</string>
</property>
<layout class="QGridLayout" name="gridLayout" >
<item row="0" column="0" >
<widget class="QLabel" name="label" >
<property name="text" >
<string>&amp;Name:</string>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<cstring>comboName</cstring>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QComboBox" name="comboName" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="0" column="2" >
<widget class="QLabel" name="label_4" >
<property name="text" >
<string>&amp;Version:</string>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<cstring>editVersion</cstring>
</property>
</widget>
</item>
<item row="0" column="3" >
<widget class="QLineEdit" name="editVersion" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox" >
<property name="title" >
<string>Repository and Revision</string>
</property>
<layout class="QGridLayout" name="gridLayout_3" >
<item row="0" column="0" >
<widget class="QLabel" name="label_2" >
<property name="text" >
<string>&amp;Checkout From:</string>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<cstring>comboCheckout</cstring>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QComboBox" name="comboCheckout" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text" >
<string>trunk</string>
</property>
</item>
<item>
<property name="text" >
<string>stable</string>
</property>
</item>
<item>
<property name="text" >
<string>tag</string>
</property>
</item>
</widget>
</item>
<item row="0" column="2" >
<widget class="QLabel" name="label_6" >
<property name="text" >
<string>Ta&amp;g:</string>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<cstring>comboCheckout</cstring>
</property>
</widget>
</item>
<item row="0" column="3" >
<widget class="QComboBox" name="comboTag" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QLabel" name="label_3" >
<property name="text" >
<string>&amp;SVN Access:</string>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<cstring>comboAccess</cstring>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QComboBox" name="comboAccess" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text" >
<string>anonsvn</string>
</property>
</item>
<item>
<property name="text" >
<string>https</string>
</property>
</item>
<item>
<property name="text" >
<string>svn+ssh</string>
</property>
</item>
</widget>
</item>
<item row="1" column="2" >
<widget class="QLabel" name="label_5" >
<property name="text" >
<string>&amp;User:</string>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<cstring>editUser</cstring>
</property>
</widget>
</item>
<item row="1" column="3" >
<widget class="QLineEdit" name="editUser" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupOptions" >
<property name="title" >
<string>Options</string>
</property>
<layout class="QGridLayout" name="gridLayout_2" >
<item row="1" column="0" >
<widget class="QCheckBox" name="checkDocs" >
<property name="text" >
<string>Get &amp;Documentation</string>
</property>
<property name="checked" >
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="1" >
<widget class="QCheckBox" name="checkTarball" >
<property name="text" >
<string>Create Tar&amp;ball</string>
</property>
<property name="checked" >
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QCheckBox" name="checkTranslations" >
<property name="text" >
<string>Get &amp;Translations</string>
</property>
<property name="checked" >
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0" >
<widget class="QCheckBox" name="checkTag" >
<property name="text" >
<string>C&amp;reate Tag</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons" >
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>comboName</tabstop>
<tabstop>editVersion</tabstop>
<tabstop>comboCheckout</tabstop>
<tabstop>comboTag</tabstop>
<tabstop>comboAccess</tabstop>
<tabstop>editUser</tabstop>
<tabstop>checkDocs</tabstop>
<tabstop>checkTranslations</tabstop>
<tabstop>checkTag</tabstop>
<tabstop>checkTarball</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>ReleaseDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel" >
<x>222</x>
<y>311</y>
</hint>
<hint type="destinationlabel" >
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>ReleaseDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel" >
<x>290</x>
<y>317</y>
</hint>
<hint type="destinationlabel" >
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

79
scripts/release/tagger.rb Normal file
View File

@ -0,0 +1,79 @@
=begin
***************************************************************************
* Copyright (C) 2008 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 'fileutils'
class Tagger
def initialize(repositorySource, repositoryTag, component, section, appName, version)
@appName = appName
@version = version
@repositorySource = "#{repositorySource}/#{component}/#{section}/#{@appName}"
@repositoryTag = repositoryTag
@tmpDirName = 'tagging_dir'
end
def tagSource
puts "Tagging source files..."
system "svn mkdir --parents -m 'Directory for tag #{@version}' #{@repositoryTag} >/dev/null 2>&1"
system "svn cp -m 'Tag #{@version}' #{@repositorySource} #{@repositoryTag} >/dev/null 2>&1"
puts "Done tagging source files."
end
def tagTranslations(translations)
return if translations == nil or translations.length == 0
puts "Tagging translations..."
system "svn co --depth immediates #{@repositoryTag} #{@tmpDirName} >/dev/null 2>&1"
system "svn mkdir --parents -m 'Translations for #{@version}' #{@repositoryTag}/po >/dev/null 2>&1"
system "svn up #{@tmpDirName}/po >/dev/null 2>&1"
translations.each do |trans|
system "svn mkdir #{@tmpDirName}/po/#{trans} >/dev/null 2>&1 >/dev/null 2>&1"
system "svn cp po/#{trans}/#{@appName}.po #{@tmpDirName}/po/#{trans}/ >/dev/null 2>&1"
end
system "svn ci -m 'Tag translations for #{@version}' #{@tmpDirName}/po >/dev/null 2>&1"
FileUtils.rm_rf @tmpDirName
puts "Done tagging translations."
end
def tagDocumentation(docs)
return if docs == nil or docs.length == 0
puts "Tagging documentation..."
system "svn co --depth immediates #{@repositoryTag} #{@tmpDirName} >/dev/null 2>&1"
system "svn mkdir --parents -m 'Documentation for #{@version}' #{@repositoryTag}/doc >/dev/null 2>&1"
system "svn up #{@tmpDirName}/doc >/dev/null 2>&1"
docs.each { |doc| system "svn cp doc/#{doc} #{@tmpDirName}/doc/ >/dev/null 2>&1" }
system "svn ci -m 'Tag documentation for #{@version}' #{@tmpDirName}/doc >/dev/null 2>&1"
FileUtils.rm_rf @tmpDirName
puts "Done tagging documentation."
end
end

View File

@ -0,0 +1,120 @@
=begin
***************************************************************************
* Copyright (C) 2008 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
class TranslationStatsBuilder
def initialize(appName, version, workingDir, outputDir)
@appName = appName
@version = version
@workingDir = workingDir
@outputDir = outputDir
end
def run
Dir.chdir "#{@workingDir}/#{@outputDir}"
file = File.new("../#{@appName}-#{@version}-l10n-stats.html", File::CREAT | File::RDWR | File::TRUNC)
statsHeader(file)
numLanguages = 0
translatedPercent = 0
Dir.entries('po').sort.each do |lang|
next if lang == '.' or lang == '..' or lang == 'CMakeLists.txt'
numLanguages, translatedPercent = statsLine(file, lang, numLanguages, translatedPercent)
end
statsFooter(file, numLanguages, translatedPercent)
file.close
end
private
def statsHeader(file)
file.print <<END_OF_TEXT
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>#{@appName} #{@version} translation statistics</title>
<style>
.th { color: #196aff; font-weight: bold; height: 12px; }
</style>
</head>
<body>
<h1>#{@appName} #{@version} translation statistics</h1>
<br>
<table border="1" cellspacing="0">
<tr>
<th>Language</th>
<th>Fuzzy</th>
<th>Untranslated</th>
<th>Total Missing</th>
<th>Complete</th>
</tr>
END_OF_TEXT
end
def statsFooter(file, numLanguages, translatedPercent)
file.print <<END_OF_TEXT
<tr>
<th>#{numLanguages}</th>
<th></th>
<th></th>
<th></th>
<th>#{translatedPercent.to_s + " %"}</th>
</tr>
</table>
</body>
</html>
END_OF_TEXT
end
def statsLine(file, langName, numLanguages, translatedPercent)
values = `msgfmt --statistics po/#{langName}/#{@appName}.po -o /dev/null 2>&1`.scan /[\d]+/
missing = values[1].to_i + values[2].to_i
total = values[0].to_i + values[1].to_i + values[2].to_i
percentage = (total - missing) * 100 / total
textColor = case percentage
when 0...70 then 'red'
when 70...100 then 'orange'
else 'green'
end
file.print <<END_OF_TEXT
<tr>
<td style="text-align: left; color: #{textColor}">#{langName}</td>
<td style="text-align: center; color: #{textColor}">#{values[1].to_i}</td>
<td style="text-align: center; color: #{textColor}">#{values[2].to_i}</td>
<td style="text-align: center; color: #{textColor}">#{missing.to_i}</td>
<td style="text-align: center; color: #{textColor}">#{percentage.to_s + " %"}</td>
</tr>
END_OF_TEXT
numLanguages += 1
translatedPercent = translatedPercent.to_i != 0 ? (translatedPercent + percentage) / 2 : percentage
return numLanguages, translatedPercent
end
end