Skip to content

Instantly share code, notes, and snippets.

@robertwahler
Last active December 13, 2015 21:48
Show Gist options
  • Save robertwahler/4979833 to your computer and use it in GitHub Desktop.
Save robertwahler/4979833 to your computer and use it in GitHub Desktop.
Thor tasks to run MOAI binaries independent of OS.
require 'pathname'
require 'rbconfig'
require 'fileutils'
module BasicMoai
ROOT_FOLDER = File.expand_path(File.join(File.dirname(__FILE__), ".."))
SRC_FOLDER = File.join(ROOT_FOLDER, "src")
VENDOR_FOLDER = File.join(ROOT_FOLDER, "vendor")
TMP_FOLDER = File.join(ROOT_FOLDER, "tmp")
BIN_FOLDER = File.join(ROOT_FOLDER, "bin")
HOSTS_FOLDER = File.join(ROOT_FOLDER, "hosts")
BUILD_FOLDER = File.join(ROOT_FOLDER, "build")
PKG_FOLDER = File.join(ROOT_FOLDER, 'pkg')
STAGING_FOLDER = File.join(TMP_FOLDER, 'game')
module BasicMoaiHelper
# @return [Symbol] OS specific ID
def os
@os ||= (
require "rbconfig"
host_os = RbConfig::CONFIG['host_os'].downcase
case host_os
when /linux/
:linux
when /darwin|mac os/
:macosx
when /mswin|msys|mingw32/
:windows
when /cygwin/
:cygwin
when /solaris/
:solaris
when /bsd/
:bsd
else
raise Error, "unknown os: #{host_os.inspect}"
end
)
end
# @return [Boolean] true if POSIX system
def posix?
!windows?
end
# @return [Boolean] true if JRuby platform
def jruby?
platform == :jruby
end
# @return [Boolean] true if Mac OSX
def mac?
os == :macosx
end
# @return [Boolean] true if any version of Windows
def windows?
os == :windows
end
# @return [Symbol] OS symbol or :jruby if java platform
def platform
if RUBY_PLATFORM == "java"
:jruby
else
os
end
end
# cache a file to the cache folder
def cache_file(source, cache_folder)
raise ArgumentError, "expected cache_folder param" unless cache_folder
destination = File.join(cache_folder, File.basename(source))
if File.exists?(destination)
say_status "cached", "#{relative_path(destination)}", :yellow
else
say_status "downloading", "#{source} to #{relative_path(destination)}", :green
get source, destination
end
end
def shell_quote(string)
return "" if string.nil? or string.empty?
if windows?
%{"#{string}"}
else
string.split("'").map{|m| "'#{m}'" }.join("\\'")
end
end
# @return[String] the relative path from the CWD
def relative_path(path)
return unless path
path = Pathname.new(File.expand_path(path, FileUtils.pwd))
cwd = Pathname.new(FileUtils.pwd)
if windows?
# c:/home D:/path/here will faile with ArgumentError: different prefix
return path.to_s if path.to_s.capitalize[0] != cwd.to_s.capitalize[0]
end
path = path.relative_path_from(cwd)
path = "./#{path}" unless path.absolute? || path.to_s.match(/^\./)
path.to_s
end
def runtime
# NOTE: don't try this under VNC or VMWare without 3d, it will fail
binary = File.expand_path(File.join('..', 'bin', os.to_s, 'game'), __FILE__)
#binary = "wine #{File.expand_path(File.join('../hosts/vs2008/moai-untz/Release/', 'moai-untz'), __FILE__)}"
binary
end
# execute a block inside a folder
def in_path(path, &block)
if path
Dir.chdir(path, &block)
else
block.call
end
end
# Contents of the src/VERSION file
#
# Example format: 0.0.1
#
# @return [String] the contents of the version file in #.#.# format
def version
version_info_file = File.join(ROOT_FOLDER, "src", "VERSION")
File.open(version_info_file, "r") do |f|
f.read.strip
end
end
# Contents of the hosts/VERSION file
#
# Example format: 0.0.1
#
# @return [String] the contents of the version file in #.#.# format
def host_version
version_info_file = File.join(ROOT_FOLDER, "hosts", "VERSION")
File.open(version_info_file, "r") do |f|
f.read.strip
end
end
end
end
module BasicMoai
class Package < Thor
namespace :package
class Development < Thor
namespace "package:development"
include Thor::Actions
include BasicMoai::BasicMoaiHelper
# adds :quiet, :skip, :pretent, :force
add_runtime_options!
desc "macosx", "create development/debug distribution package for Mac OS X"
def macosx
say_status :invoke, "Invoking 'package:macosx --development'"
# invoke with --development
invoke("package:macosx", [], :development => true)
end
end
end
class Package < Thor
namespace :package
include Thor::Actions
include BasicMoai::BasicMoaiHelper
# adds :quiet, :skip, :pretent, :force
add_runtime_options!
class_option :development, :aliases => "-d", :desc => "Add development/debug/beta assets to the distribution"
desc "clean", "remove tmp staging folder"
def clean
remove_dir(STAGING_FOLDER)
end
desc "macosx", "create distribution package for Mac OS X"
def macosx
# clean staging folder
invoke("package:clean")
# copy compiled lua source
invoke("build:lua:compile", [], options.merge(:force => true))
stage = options[:development] ? 'development' : 'production'
# Game.app
source = File.join(ROOT_FOLDER, 'tasks', 'templates', 'dist', 'macosx', 'Game.app')
destination = File.join(STAGING_FOLDER, 'Game.app')
say_status :copy, "copying #{source} to '#{destination}'"
directory(source, destination)
# set script to execute
destination = File.join(STAGING_FOLDER, 'Game.app', 'Contents', 'MacOS', 'game.sh')
chmod(destination, 0755)
# common files to root of STAGING_FOLDER/distribution archive
copy_common
if options[:development]
# debug and development files to root of STAGING_FOLDER/distribution archive
copy_debug
# debug and development files to the Application's game folder
source = File.join(ROOT_FOLDER, 'DEBUG.txt')
destination = File.join(STAGING_FOLDER, 'Game.app', 'Contents', 'MacOS', 'game', 'DEBUG.txt')
say_status :copy, "copying #{source} to '#{destination}'"
copy_file(source, destination)
end
# HISTORY to root of DMG
source = File.join(ROOT_FOLDER, 'HISTORY.md')
destination = File.join(STAGING_FOLDER, 'HISTORY.txt')
say_status :copy, "copying #{source} to '#{destination}'"
copy_file(source, destination)
# HISTORY to to the Application's game folder
source = File.join(ROOT_FOLDER, 'HISTORY.md')
destination = File.join(STAGING_FOLDER, 'Game.app', 'Contents', 'MacOS', 'game', 'HISTORY.txt')
say_status :copy, "copying #{source} to '#{destination}'"
copy_file(source, destination)
# common files to the Application's game folder
source = File.join(ROOT_FOLDER, 'tasks', 'templates', 'dist', 'common')
destination = File.join(STAGING_FOLDER, 'Game.app', 'Contents', 'MacOS', 'game')
say_status :copy, "copying #{source} to '#{destination}'"
directory(source, destination)
# copy compiled lua
source = BUILD_FOLDER
destination = File.join(STAGING_FOLDER, 'Game.app', 'Contents', 'MacOS', 'game')
say_status :copy, "copying #{source} to '#{destination}'"
directory(source, destination)
# platform specific distribution config to Application's game
# folder unless this is a development build, then keep the original
unless options[:development]
source = File.join(ROOT_FOLDER, 'tasks', 'templates', 'dist', 'macosx', 'src')
destination = File.join(STAGING_FOLDER, 'Game.app', 'Contents', 'MacOS', 'game')
remove_file(File.join(destination, 'config.lua'))
say_status :copy, "copying #{source} to '#{destination}'"
directory(source, destination)
end
# copy executable
source = File.join(BIN_FOLDER, 'macosx', 'game')
destination = File.join(STAGING_FOLDER, 'Game.app', 'Contents', 'MacOS', 'game', 'game')
say_status :copy, "copying #{source} to '#{destination}'"
copy_file(source, destination)
chmod(destination, 0755)
# create tiff and icns icons
source = File.join(HOSTS_FOLDER, 'icons', stage, '128x128.png')
destination = File.join(STAGING_FOLDER, 'Game.app', 'Contents', 'Resources', 'icon.tiff')
run("sips -s format tiff #{source} --out #{destination} --resampleWidth 128 >& /dev/null")
run("tiff2icns -noLarge #{destination} >& /dev/null")
# create the dmg file
source = STAGING_FOLDER
destination = "#{PKG_FOLDER}/#{package_basename}.#{version}.dmg"
remove_file(destination)
run("hdiutil create #{destination} -volname 'Game' -fs HFS+ -srcfolder #{source}")
end
private
# where to start looking for templates, required by the template methods
# even though we are using absolute paths
def self.source_root
File.dirname(__FILE__)
end
# common files to root of STAGING_FOLDER/distribution archive
def copy_common
source = File.join(ROOT_FOLDER, 'tasks', 'templates', 'dist', 'common')
destination = STAGING_FOLDER
say_status :copy, "copying #{source} to '#{destination}'"
directory(source, destination)
end
# debug and development files to root of STAGING_FOLDER/distribution archive
def copy_debug
source = File.join(ROOT_FOLDER, 'DEBUG.txt')
destination = File.join(STAGING_FOLDER, 'DEBUG.txt')
say_status :copy, "copying #{source} to '#{destination}'"
copy_file(source, destination)
end
def package_basename
if File.exists?(File.join(BUILD_FOLDER, 'BETA'))
"game.beta"
else
"game"
end
end
end
end
module BasicMoai
class Run < Thor
namespace :run
include Thor::Actions
include BasicMoai::BasicMoaiHelper
# adds :quiet, :skip, :pretent, :force
add_runtime_options!
desc "specs [ARGS]", "run all the specs"
def specs(*args)
if args.empty? || (args.length > 1)
targets = '../spec/modules'
else
# busted can only handle one file or a pattern, not multiple args
targets = args.map { |arg| arg.to_s }.join(' ')
end
# determine binary before changing path
binary = runtime
in_path 'src' do spec = File.expand_path(targets.strip)
if File.exists?(spec)
tag_option = ""
#tag_option = "--tags='focus'"
# run using maoi binary, don't use 'lpath', use '-m' so it won't be eaten by the busted shell script's '-l' short option
run("busted #{tag_option} -l #{binary} -m '../spec/?.lua' #{targets}")
# run using system luajit or lua
#run("busted #{tag_option} #{targets}")
else
say "no spec available", :yellow
end
end
end
desc "cli", "run command line app on pc"
def cli
#binary = 'lua'
binary = runtime
in_path 'src' do
command = "#{binary} cli.lua"
run(command)
end
end
desc "android", "run the android app on hardware"
def android
# compile assets
invoke("build:lua:compile", [], :force => true)
in_path 'hosts/ant' do
run("bash run-host.sh")
end
end
desc "hanappe", "run the hanappe sample on pc"
def hanappe
# determine binary before changing path
binary = runtime
in_path 'vendor/hanappe/projects/hanappe-samples/bin/' do
command = "#{binary} main.lua"
run(command)
end
end
desc "flower", "run the flower sample on pc"
def flower
# determine binary before changing path
binary = runtime
in_path 'vendor/hanappe/projects/flower-samples/bin/' do
command = "#{binary} main.lua"
run(command)
end
end
desc "gui", "run GUI app on pc"
def gui
# determine binary before changing path
binary = runtime
in_path 'src' do
command = "#{binary} main.lua"
run(command)
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment