Created
December 21, 2009 17:22
-
-
Save vicalejuri/261082 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# Owner: frangossauro | |
# | |
# Build your patota project without using the TextMate bundle. | |
# Very useful with Vim | |
# | |
require 'pathname' | |
require 'ftools' | |
require 'logger' | |
require 'colored' | |
require 'yaml' | |
namespace :build do | |
@build_yaml = nil | |
@should_run = nil | |
@project = File.dirname( __FILE__ ) | |
@fcshd = File.join( @project , "bin/fcshd.py" ) | |
@growl = File.join( @project, "bin/growl.rb") | |
def self.init | |
# Create a log | |
@log = Logger.new( STDOUT ) | |
@log.level = Logger::INFO | |
@log.datetime_format = '' | |
end | |
def self.destroy | |
@log.close | |
end | |
def self.build_file | |
build_file_path = File.join(@project , "build.yaml") | |
if !file = File.open(build_file_path) rescue nil | |
@log.fatal "Hey, we could not find the build file at %s".red.bold % build_file_path | |
exit(1) | |
exit | |
end | |
@build_yaml = YAML::load(file) rescue nil | |
if !@build_yaml | |
@log.fatal "Something wron when parsing YAML file".red.bold | |
exit(1) | |
end | |
@build_yaml | |
end | |
def self.get_path_list(attr_name) | |
dirs = [] | |
if build_file.has_key?(attr_name) | |
build_file.fetch(attr_name).each do |path| | |
dirs.push path | |
end | |
end | |
dirs | |
end | |
def self.definitions(paths, relative_path_from=nil) | |
classes = {} | |
paths.each do |path| | |
source_path = Pathname.new(File.join(@project,path)) | |
Find.find(source_path.to_s) do |f| | |
if f =~ /.as$/ | |
if !relative_path_from | |
clean_path = Pathname.new(f).relative_path_from(source_path).to_s | |
else | |
clean_path = Pathname.new(f).relative_path_from(Pathname.new(File.join(@project, relative_path_from))).to_s | |
end | |
classes[f.to_s] = clean_path.gsub("/", ".").gsub(".as", "") | |
end | |
end | |
end | |
classes | |
end | |
def self.source_path_list | |
get_path_list("source-path") | |
end | |
def self.libray_path_list | |
get_path_list("library-path") | |
end | |
def self.mxmlc_source_path | |
paths = source_path_list | |
source_path = [] | |
paths.each do |path| | |
source_path.push "-sp+="+File.join(@project, path) | |
end | |
source_path.join(" ") | |
end | |
def self.mxmlc_library_path | |
paths = libray_path_list | |
library_path = [] | |
paths.each do |path| | |
library_path.push "-library-path+="+File.join(@project, path) | |
end | |
library_path.join(" ") | |
end | |
def self.mxmlc_default_extra | |
build_file.fetch("default")[0].fetch("extra") rescue "" | |
end | |
def self.mxmlc_default_debug | |
build_file.fetch("default")[0].fetch("debug") rescue "false" | |
end | |
def self.default_run_file | |
build_file.fetch("default")[0].fetch("open") rescue "" | |
end | |
def self.mxmlc_applications | |
apps = [] | |
if build_file.has_key?("applications") | |
build_file.fetch("applications").each do |app| | |
if app && app.has_key?("class") && app.has_key?("output") | |
debug = app.fetch("debug") rescue mxmlc_default_debug | |
extra = app.fetch("extra") rescue mxmlc_default_extra | |
klass = File.join(@project, app.fetch("class")) | |
output = File.join(@project, app.fetch("output")) | |
library_path = mxmlc_library_path rescue "" | |
source_path = mxmlc_source_path rescue "" | |
app_obj = {"klass"=>app.fetch("class")} | |
if output =~ /.swc$/ | |
require 'pathname' | |
require 'find' | |
app_obj["mxmlc"] = "compc -include-classes=#{definitions(source_path_list)[klass]} -o=#{output} #{library_path} #{source_path} #{extra}" | |
else | |
app_obj["mxmlc"] = "mxmlc #{klass} -o=#{output} -debug=#{debug} #{library_path} #{source_path} #{extra}" | |
end | |
apps.push(app_obj) | |
end | |
end | |
end | |
apps | |
end | |
desc "Compile (and run) your patota project" | |
task :compile, :run do |t,args| | |
self.init() | |
files_compiled = 0 | |
should_run = args.run || @should_run | |
if should_run | |
Dir.mkdir('/tmp/fcshd') if !File.exist?('/tmp/fcshd') | |
`echo '' > /tmp/fcshd/failed` | |
`ruby '#{@growl}' 'Buiding' ''` | |
end | |
server() | |
mxmlc_applications.each do |app| | |
printf("\n" + ("-"*75) + "\n") | |
@log.info "Compiling ".green.bold + "%s".magenta % app["klass"] | |
# TODO: Make and external app like textmate to pretty output this shit.. | |
result = system(" | |
'#{@fcshd}' '#{app["mxmlc"]}' 2>&1 | grep -v 'Loading' | grep -v '(fcsh)' | grep -v 'affected' | grep -v 'Reason' | grep -v 'Recompile' | grep -v 'Skip' | |
if [ ${PIPESTATUS[0]} -eq 0 ] | |
then | |
exit 0; | |
else | |
echo 'true' > /tmp/fcshd/failed | |
exit 1; | |
fi | |
") | |
if result | |
files_compiled = files_compiled + 1 | |
#growl notifications (only in build and run) | |
`ruby '#{@growl}' 'Success' '#{app["klass"]}'` if should_run | |
#run if in Build and Run and all apps compiled | |
run() if files_compiled == mxmlc_applications.length && should_run | |
end | |
end | |
#Check if everything was ok | |
if `cat /tmp/fcshd/failed` == "true" | |
return false | |
end | |
@log.info "Done".green.bold | |
end | |
def self.server() | |
system("python '#{@fcshd}' --start-server") | |
end | |
def self.run() | |
if default_run_file != "" | |
#checking if the default_run_file is local or remote | |
if default_run_file.include?("://") #oh man, we have a protocol (http://, https://, ftp://) | |
system("open #{default_run_file}") | |
end | |
system("open #{File.join(@project, default_run_file)}") | |
end | |
end | |
end | |
namespace :locale do | |
@src_path = 'source/classes/' | |
@out_path = 'public/' | |
@exclude = '.xml' | |
@allowed_ext = 'as' | |
def self.init | |
# Create a log | |
@log = Logger.new( STDOUT ) | |
@log.level = Logger::INFO | |
@log.datetime_format = '' | |
end | |
def self.destroy | |
@log.close | |
end | |
# Generate PO files. | |
def generate_po( indexFile, outFile ) | |
@log.warn "Generating MAIN PO File: ".white + "#{outFile}".magenta | |
system("xgettext --extract-all --force-po --from-code=utf-8 --language=Python --no-wrap --output=%s --files-from=%s"%[outFile, indexFile]) | |
end | |
# Because importing pot is so expensive, | |
# we are cultivating our own shit. Let's get High | |
def generate_pot( lang , out_path) | |
inFile = out_path + 'locale/messages.po' | |
outFile = out_path + 'locale/'+lang+'/LC_MESSAGES/messages.pot' | |
system("msginit --no-wrap --input=%s --output=%s" % [inFile, outFile ]) | |
end | |
# Compile (compress) the pot files in .mo files | |
def generate_mo( out_path ) | |
Dir[out_path + 'locale/**/messages.pot'].each { |file| | |
outFile = File.dirname( file ) + '/messages.mo' | |
system( "msgfmt --strict --use-fuzzy --output=%s %s" % [outFile , file]) | |
} | |
end | |
# Update the POT files (merging with the old ones) | |
def update_trans_pot( out_path ) | |
if not File.exist? out_path + 'locale/messages.po' | |
@log.fatal "Hey, did you already runned an update? Some files are missing...".red.bold | |
exit(1) | |
end | |
Dir[out_path + 'locale/*/LC_MESSAGES/'].each{ |path| | |
outFile = path + 'messages.pot' | |
srcFile = out_path + 'locale/messages.po' | |
if not File.exists? outFile | |
generate_pot( path.match( /.*?\/locale\/([a-zA-Z_]{2})\/.*/ )[1] , out_path ) | |
end | |
# Merge the changes | |
system("msgmerge --force-po --update --backup=numbered --backup=off --no-wrap %s %s"%[outFile, srcFile]) | |
} | |
end | |
def generate_trans_dir(lang, out_path) | |
if File.exist? out_path + "locale/"+lang | |
@log.fatal "Translation for language '%s' exists already!".red.bold % lang | |
exit(1) | |
end | |
if not File.exist? out_path + 'locale/messages.po' | |
@log.fatal "Hey, did you already runned an update? Some files are missing...".red.bold | |
exit(1) | |
end | |
create_dir( out_path + 'locale/' + lang ) | |
create_dir( out_path + 'locale/' + lang + '/LC_MESSAGES' ) | |
generate_pot( lang, out_path ) | |
end | |
# Create a index file, with the source of every | |
# file that gettext utility have to parse. | |
def create_index_file( filtered_src_files , out_path ) | |
indexFile = File.new( out_path + 'indexLocale.list' , 'w') | |
tmpFiles = filtered_src_files | |
tmpFiles.each { |file| | |
@log.warn "#{file}".magenta + " has translations... ADDING TO INDEX FILE".green | |
indexFile.puts file | |
} | |
indexFile.close | |
return out_path + 'indexLocale.list' | |
end | |
def clean_tmp_files( filtered_src_files , path ) | |
File.delete path + 'indexLocale.list' | |
filtered_src_files.each { |file| | |
File.delete file | |
} | |
end | |
# For every file, filter the translatable strings | |
# and generate new files from it (*.pox) | |
def filter_src_files( src_files_array ) | |
tmpFiles = [] | |
src_files_array.each{ |file| | |
infile = File.new( file , 'r') | |
trans_str = filter_translatable_strings( infile ) | |
if(trans_str != "") | |
tmpFiles.push file + '.pox' | |
outFile = File.new( file + '.pox','w') | |
outFile.puts trans_str | |
outFile.close | |
end | |
} | |
return tmpFiles | |
end | |
# Filter the translatable strings,you know, the | |
# ones with the form _("STRING") | |
def filter_translatable_strings(full_as_file) | |
trans_strs = "" | |
full_as_file.each { |line| | |
if line =~ /(_\(.*?\))/ | |
trans_strs += $~[1]+"\n" | |
end | |
} | |
return trans_strs | |
end | |
# Create a dir, if not exists! | |
def create_dir( dir_name ) | |
if not File.exist? dir_name | |
Dir.mkdir dir_name | |
end | |
end | |
desc "Run all over your source code, catching all translatable strings and generating the locale files for them. Sweeet!" | |
task :update, :src_path, :out_path, :exclude do |t,args| | |
self.init() | |
src_path = args.src_path || @src_path | |
out_path = args.out_path || @out_path | |
exclude = args.exclude || @exclude | |
@log.info "Parsing folder ".green.bold + "#{src_path}".magenta | |
# Get all as files, excluding what user wanna | |
src_files = FileList.new( src_path + '**/*.' + @allowed_ext ) | |
# Parse all files, generate a index file | |
filtered_src_files = filter_src_files( src_files ) | |
index_file = create_index_file( filtered_src_files , out_path ) | |
# oooook, now generate our hot trans! I mean, translations... | |
@log.info "Generating BASE translations from source files ".white + ' ...' | |
generate_po( index_file, out_path + 'locale/messages.po' ) | |
@log.info "DONE".green.bold | |
# Calvin: I Order you to clean this mess, Hobbes! | |
clean_tmp_files( filtered_src_files , out_path ) | |
# Ok, now update every language pot files | |
update_trans_pot( out_path ) | |
end | |
desc "Create the structure of locales (folders and default files)" | |
task :init , :project_path do |t,args| | |
self.init() | |
path = args.project_path || @out_path | |
create_dir path + 'locale' | |
@log.info "Done".green.bold | |
end | |
desc "Create a new localized language." | |
task :add, :localeCountry, :out_path do |t,args| | |
self.init() | |
if not args.localeCountry | |
@log.fatal "You ".red.bold + "MUST".red.underline + " specify a country!".red.bold | |
exit(1) | |
end | |
out_path = args.out_path || @out_path | |
@log.info "Creating files and folder for localization ".white + "#{args.localeCountry}".magenta.bold | |
generate_trans_dir( args.localeCountry, out_path ) | |
@log.info "DONE".green.bold | |
end | |
desc "Compress all .pot files to the deploy files .mo" | |
task :compile,:out_path do |t,args| | |
self.init() | |
out_path = args.out_path || @out_path | |
@log.info "Compiling pofiles ".white | |
generate_mo( out_path ) | |
@log.info "DONE".green.bold | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment