Skip to content

Instantly share code, notes, and snippets.

@vicalejuri
Created December 21, 2009 17:22
Show Gist options
  • Save vicalejuri/261082 to your computer and use it in GitHub Desktop.
Save vicalejuri/261082 to your computer and use it in GitHub Desktop.
#!/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