translator: fix undefined variable
[rbot] / Rakefile
1 require 'rubygems'
2 require 'rake'
3 require 'rake/gempackagetask'
4
5 task :default => [:buildext]
6
7 SPECFILE = 'rbot.gemspec'
8 # The Rakefile is also used after installing the gem, to build
9 # the .mo files. Since in this case the SPECFILE is not available,
10 # we must (and can) skip defining the gem packaging tasks.
11 if File.exist? SPECFILE
12   spec = eval(File.read(SPECFILE), nil, SPECFILE)
13   Rake::GemPackageTask.new(spec) do |pkg|
14     pkg.need_zip = true
15     pkg.need_tar = true
16   end
17 end
18
19 # normalize a po/pot file
20 def normalize_po(fn)
21   content = File.read(fn)
22
23   # sort the messages by file location
24   if MSGCAT
25     sorted = `#{MSGCAT} --width=79 --sort-by-file #{fn}`
26     if sorted != content
27       content = sorted
28       modified = true
29     end
30   end
31
32   # replace project-id-version placholder
33   modified |= content.sub!(/^("Project-Id-Version: )PACKAGE VERSION(\\n")$/) {
34     "#{$1}rbot#{$2}"
35   }
36
37   if modified
38     File.open(fn, 'w') {|f| f.write content}
39   end
40 end
41
42 PLUGIN_FILES = FileList['data/rbot/plugins/**/*.rb']
43 NON_PLUGIN_FILES = FileList["{lib,bin,data}/**/*.{rb,rhtml}"] - PLUGIN_FILES
44
45 # this task defines how po files and pot files are made. those rules are not defined
46 # normally because po and pot files should be only updated in the updatepo task,
47 # but po files are also prereqs for makemo
48 task :define_po_rules do
49   # generate pot file from rb files
50   rgettext_proc = proc do |t|
51     require 'gettext/utils'
52     source_files, pot_file = t.prerequisites, t.name
53     new_pot_file = "#{pot_file}.new"
54     puts "#{source_files.join(', ')} => #{pot_file}"
55     GetText.rgettext(source_files, new_pot_file)
56
57     # only use the new pot file if it contains unique messages
58     if File.exists?(pot_file) && MSGCOMM && `#{MSGCOMM} --unique #{pot_file} #{new_pot_file}`.empty?
59       rm new_pot_file
60     else
61       mv new_pot_file, pot_file
62     end
63
64     normalize_po(pot_file)
65     
66     # save all this work until rb files are updated again
67     touch pot_file
68   end
69
70   # generate pot file for non-plugin files
71   file('po/rbot.pot' => NON_PLUGIN_FILES, &rgettext_proc)
72
73   # generate pot files for plugin files
74   rule(%r'^po/.+\.pot$' => proc {|fn|
75     PLUGIN_FILES.select {|f| f.pathmap('rbot-%n') == fn.pathmap('%n')}
76   }, &rgettext_proc)
77
78   # map the po file to its source pot file
79   pot_for_po = proc {|fn| fn.pathmap '%{^po/.+/,po/}X.pot'}
80
81   # update po file from pot file
82   msgmerge_proc = proc do |t|
83     require 'gettext/utils'
84     po_file, pot_file = t.name, t.source
85     puts "#{pot_file} => #{po_file}"
86     if File.exists? po_file
87       sh "#{MSGMERGE} --backup=off --update #{po_file} #{pot_file}"
88     elsif MSGINIT
89       locale = po_file[%r'^po/(.+)/.+\.po$', 1]
90       sh "#{MSGINIT} --locale=#{locale} --no-translator --input=#{pot_file} --output-file=#{po_file}"
91     else
92       warn "#{po_file} is missing and cannot be generated without msginit"
93       next
94     end
95     normalize_po(po_file)
96     touch po_file
97   end
98
99   # generate English po files
100   file(%r'^po/en_US/.+\.po$' => pot_for_po) do |t|
101     po_file, pot_file = t.name, t.source
102     if MSGEN
103       sh "#{MSGEN} --output-file=#{po_file} #{pot_file}"
104       normalize_po(po_file)
105       touch po_file
106     else
107       msgmerge_proc.call t
108     end
109   end
110
111   # update po files
112   rule(%r'^po/.+/.+\.po$' => pot_for_po, &msgmerge_proc)
113 end
114
115 # generate mo files
116 rule(%r'^data/locale/.+/LC_MESSAGES/.+\.mo$' => proc {|fn|
117   [ fn.pathmap('%{^data/locale,po;LC_MESSAGES/,}X.po'), 
118     # the directory is created if not existing
119     fn.pathmap('%d') ]
120 }) do |t|
121   po_file, mo_file = t.source, t.name
122   puts "#{po_file} => #{mo_file}"
123   require 'gettext/utils'
124   GetText.rmsgfmt po_file, mo_file
125 end
126
127 task :check_po_tools do
128   have = {}
129
130   po_tools = {
131     'msgmerge' => {
132       :options => %w[--backup= --update],
133       :message => 'Cannot update po files' },
134     'msginit' => {
135       :options => %w[--locale= --no-translator --input= --output-file=],
136       :message => 'Cannot generate missing po files' },
137     'msgcomm' => {
138       :options => %w[--unique],
139       :message => 'Pot files may be modified even without message change' },
140     'msgen' => {
141       :options => %w[--output-file],
142       :message => 'English po files will not be generated' },
143     'msgcat' => {
144       :options => %w[--width= --sort-by-file],
145       :message => 'Pot files will not be normalized' }
146   }
147
148   po_tools.each_pair do |command, value|
149     path = ENV["#{command.upcase}_PATH"] || command
150     have_it = have[command] = value[:options].all? do |option|
151       `#{path} --help`.include? option
152     end
153     Object.const_set(command.upcase, have_it ? path : false)
154     warn "#{command} not found. #{value[:message]}" unless have_it
155   end
156   abort unless MSGMERGE
157 end
158
159 PLUGIN_BASENAMES = PLUGIN_FILES.map {|f| f.pathmap('%n')}
160 LOCALES = FileList['po/*/'].map {|d| d.pathmap('%n')}
161
162 LOCALES.each do |l|
163   directory "data/locale/#{l}/LC_MESSAGES"
164 end
165
166 desc 'Update po files'
167 task :updatepo => [:define_po_rules, :check_po_tools] + LOCALES.map {|l|
168   ["po/#{l}/rbot.po"] +
169   PLUGIN_BASENAMES.map {|n| "po/#{l}/rbot-#{n}.po"}
170 }.flatten
171
172 desc 'Normalize po files'
173 task :normalizepo => :check_po_tools do
174   FileList['po/*/*.po'].each {|fn| normalize_po(fn)}
175 end
176
177 # this task invokes makemo if ruby-gettext is available, but otherwise succeeds
178 # with a warning instead of failing. it is to be used by Gem's extension builder
179 # to make installation not fail because of lack of ruby-gettext
180 task :buildext do
181   begin
182     require 'gettext/utils'
183     Rake::Task[:makemo].invoke
184   rescue LoadError
185     warn 'Ruby-gettext cannot be located, so mo files cannot be built and installed' 
186   end
187 end
188
189 desc 'Generate mo files'
190 task :makemo =>
191   FileList['po/*/*.po'].pathmap('%{^po,data/locale}d/LC_MESSAGES/%n.mo')
192
193