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