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