]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/commitdiff
make gettext tasks only update a file with new msg/msgid, normalize po/pot files
authorYaohan Chen <yaohan.chen@gmail.com>
Sat, 28 Jun 2008 21:58:04 +0000 (17:58 -0400)
committerGiuseppe Bilotta <giuseppe.bilotta@gmail.com>
Mon, 30 Jun 2008 08:51:20 +0000 (10:51 +0200)
Rakefile

index 6b321fdc166d400fafa8911e802bdc92a885b292..be00f4ed61b726f73f23ddb972cf76ff641915f8 100644 (file)
--- a/Rakefile
+++ b/Rakefile
@@ -35,34 +35,92 @@ Rake::GemPackageTask.new(spec) do |pkg|
   pkg.need_tar = true
 end
 
+# normalize a po/pot file
+def normalize_po(fn)
+  content = File.read(fn)
+
+  # replace project-id-version placholder
+  modified = content.sub!(/^("Project-Id-Version: )PACKAGE VERSION(\\n")$/) {
+    "#{$1}rbot#{$2}"
+  }
+
+  # sort the messages by file location
+  if MSGCAT
+    sorted = `#{MSGCAT} --width=79 --sort-by-file #{fn}`
+    if sorted != content
+      content = sorted
+      modified = true
+    end
+  end
+
+  if modified
+    File.open(fn, 'w') {|f| f.write content}
+  end
+end
+
 PLUGIN_FILES = FileList['data/rbot/plugins/**/*.rb']
 NON_PLUGIN_FILES = FileList["{lib,bin,data}/**/*.{rb,rhtml}"] - PLUGIN_FILES
-rgettext_proc = proc do |t|
-  require 'gettext/utils'
-  source_files, pot_file = t.prerequisites, t.name
-  puts "#{source_files.join(', ')} => #{pot_file}"
-  GetText.rgettext(source_files, pot_file)
-end
 
-# generate pot file for non-plugin files
-file('po/rbot.pot' => NON_PLUGIN_FILES, &rgettext_proc)
-
-# generate pot files for plugin files
-rule(%r'^po/.+\.pot$' => proc {|fn|
-  PLUGIN_FILES.select {|f| f.pathmap('rbot-%n') == fn.pathmap('%n')}
-}, &rgettext_proc)
-
-# update po files
-# ruby-gettext treats empty output from msgmerge as error, causing this task to
-# fail. we provide a wrapper to work around it. see bin/msgmerge-wrapper.rb for
-# details
-ENV['REAL_MSGMERGE_PATH'] = ENV['MSGMERGE_PATH']
-ENV['MSGMERGE_PATH'] = ENV['MSGMERGE_WRAPPER_PATH'] || 'ruby msgmerge-wrapper.rb'
-rule(%r'^po/.+/.+\.po$' => proc {|fn| fn.pathmap '%{^po/.+/,po/}X.pot'}) do |t|
-  require 'gettext/utils'
-  po_file, pot_file = t.name, t.source
-  puts "#{pot_file} => #{po_file}"
-  GetText.msgmerge po_file, pot_file, 'rbot'
+# this task defines how po files and pot files are made. those rules are not defined
+# normally because po and pot files should be only updated in the updatepo task,
+# but po files are also prereqs for makemo
+task :define_po_rules do
+  # generate pot file from rb files
+  rgettext_proc = proc do |t|
+    require 'gettext/utils'
+    source_files, pot_file = t.prerequisites, t.name
+    new_pot_file = "#{pot_file}.new"
+    puts "#{source_files.join(', ')} => #{pot_file}"
+    GetText.rgettext(source_files, new_pot_file)
+
+    # only use the new pot file if it contains unique messages
+    if MSGCOMM && `#{MSGCOMM} --unique #{pot_file} #{new_pot_file}`.empty?
+      rm new_pot_file
+    else
+      mv new_pot_file, pot_file
+    end
+
+    normalize_po(pot_file)
+    
+    # save all this work until rb files are updated again
+    touch pot_file
+  end
+
+  # generate pot file for non-plugin files
+  file('po/rbot.pot' => NON_PLUGIN_FILES, &rgettext_proc)
+
+  # generate pot files for plugin files
+  rule(%r'^po/.+\.pot$' => proc {|fn|
+    PLUGIN_FILES.select {|f| f.pathmap('rbot-%n') == fn.pathmap('%n')}
+  }, &rgettext_proc)
+
+  # map the po file to its source pot file
+  pot_for_po = proc {|fn| fn.pathmap '%{^po/.+/,po/}X.pot'}
+
+  # update po file from pot file
+  msgmerge_proc = proc do |t|
+    require 'gettext/utils'
+    po_file, pot_file = t.name, t.source
+    puts "#{pot_file} => #{po_file}"
+    sh "#{MSGMERGE} --backup=off --update #{po_file} #{pot_file}"
+    normalize_po(po_file)
+    touch po_file
+  end
+
+  # generate English po files
+  file(%r'^po/en_US/.+\.po$' => pot_for_po) do |t|
+    po_file, pot_file = t.name, t.source
+    if MSGEN
+      sh "#{MSGEN} --output-file=#{po_file} #{pot_file}"
+      normalize_po(po_file)
+      touch po_file
+    else
+      msgmerge_proc.call t
+    end
+  end
+
+  # update po files
+  rule(%r'^po/.+/.+\.po$' => pot_for_po, &msgmerge_proc)
 end
 
 # generate mo files
@@ -77,6 +135,35 @@ rule(%r'^data/locale/.+/LC_MESSAGES/.+\.mo$' => proc {|fn|
   GetText.rmsgfmt po_file, mo_file
 end
 
+task :check_po_tools do
+  have = {}
+
+  po_tools = {
+    'msgmerge' => {
+      :options => %w[--backup= --update],
+      :message => 'Cannot update po files' },
+    'msgcomm' => {
+      :options => %w[--unique],
+      :message => 'Pot files may be modified even without message change' },
+    'msgen' => {
+      :options => %w[--output-file],
+      :message => 'English po files will not be generated' },
+    'msgcat' => {
+      :options => %w[--width= --sort-by-file],
+      :message => 'Pot files will not be normalized' }
+  }
+
+  po_tools.each_pair do |command, value|
+    path = ENV["#{command.upcase}_PATH"] || command
+    have_it = have[command] = value[:options].all? do |option|
+      `#{path} --help`.include? option
+    end
+    Object.const_set(command.upcase, have_it ? path : false)
+    warn "#{command} not found. #{value[:message]}" unless have_it
+  end
+  abort unless MSGMERGE
+end
+
 PLUGIN_BASENAMES = PLUGIN_FILES.map {|f| f.pathmap('%n')}
 LOCALES = FileList['po/*/'].map {|d| d.pathmap('%n')}
 
@@ -85,7 +172,7 @@ LOCALES.each do |l|
 end
 
 desc 'Update po files'
-task :updatepo => LOCALES.map {|l|
+task :updatepo => [:define_po_rules, :check_po_tools] + LOCALES.map {|l|
   ["po/#{l}/rbot.po"] +
   PLUGIN_BASENAMES.map {|n| "po/#{l}/rbot-#{n}.po"}
 }.flatten