Files
RubyMotion/bin/motion
2012-02-18 12:36:15 +01:00

212 lines
5.5 KiB
Ruby

#!/usr/bin/ruby
require 'fileutils'
relative_libdir = File.expand_path(File.join(File.dirname(File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__), '../lib'))
$motion_libdir = File.exist?(File.join(relative_libdir, 'motion')) ? relative_libdir : '/Library/Motion/lib'
$:.unshift($motion_libdir)
require 'motion/version'
class Command
class << self
attr_accessor :name
attr_accessor :help
def die(*msg)
$stderr.puts msg
exit 1
end
def need_root
if Process.uid != 0
die "You need to be root to run this command."
end
end
end
end
class CreateCommand < Command
self.name = 'create'
self.help = 'Create a new project'
def self.run(args)
if args.size != 1
die "Usage: motion create <appname>"
end
app_name = args.shift
unless app_name.match(/^[a-zA-Z\d\s]+$/)
die "Invalid app name"
end
if File.exist?(app_name)
die "Directory `#{app_name}' already exists"
end
Dir.mkdir(app_name)
Dir.chdir(app_name) do
File.open('Rakefile', 'w') do |io|
io.puts <<EOS
$:.unshift(\"#{$motion_libdir}\")
require 'motion/project'
Motion::Project::App.setup do |app|
# Use `rake config' to see complete project settings.
app.name = '#{app_name}'
end
EOS
end
Dir.mkdir('app')
File.open('app/main.rb', 'w') do |io|
io.puts <<EOS
class AppDelegate
def application(application, didFinishLaunchingWithOptions:launchOptions)
puts "Hello World!"
return true
end
end
EOS
end
Dir.mkdir('resources')
Dir.mkdir('spec')
File.open('spec/main_spec.rb', 'w') do |io|
io.puts <<EOS
describe "Application '#{app_name}'" do
before do
@app = UIApplication.sharedApplication
end
it "has one window" do
@app.windows.size.should == 1
end
end
EOS
end
end
end
end
LicensePath = '/Library/Motion/license.key'
class ActivateCommand < Command
self.name = 'activate'
self.help = 'Activate the software license'
def self.run(args)
if args.size != 1
die "Usage: motion activate <license-key>"
end
license_key = args[0]
unless license_key.match(/^[a-f0-9]{40}$/)
die "Given license key `#{license_key}' seems invalid. It should be a string of 40 hexadecimal characters. Check the mail you received after the order, or contact us if you need any help: info@hipbyte.com"
end
if File.exist?(LicensePath)
die "Product is already activated. Delete the license file `#{LicensePath}' if you want to activate a new license."
end
need_root
File.open(LicensePath, 'w') { |io| io.write license_key }
puts "Product activated. Thanks for purchasing RubyMotion :-)"
end
end
class UpdateCommand < Command
self.name = 'update'
self.help = 'Update the software'
def self.run(args)
check_mode = args.delete('--check')
unless args.empty?
die "Usage: motion update [--check]"
end
product_version = Motion::Version
if check_mode
curl = "/usr/bin/curl -s -d \"product=rubymotion\" -d \"current_software_version=#{product_version}\" http://data.hipbyte.com/latest_software_version"
resp = `#{curl}`
unless resp.match(/^\d+\.\d+/)
die resp
end
exit resp > product_version ? 1 : 0
end
unless File.exist?(LicensePath)
die "The product has not been activated yet. Please purchase RubyMotion, then use the `motion activate' command."
end
need_root
license_key = File.read(LicensePath)
$stderr.puts "Connecting to the server..."
curl = "/usr/bin/curl -s -d \"product=rubymotion\" -d \"current_software_version=#{product_version}\" -d \"license_key=#{license_key}\" http://data.hipbyte.com/update_software"
resp = `#{curl}`
unless resp.match(/^http:/)
die resp
end
$stderr.puts "Downloading software update..."
url = resp
tmp_dest = '/tmp/_rubymotion_su.pkg'
curl = "/usr/bin/curl -# \"#{url}\" -o #{tmp_dest}"
unless system(curl)
die "An error happened when downloading the software update."
end
$stderr.puts "Installing software update..."
installer = "/usr/sbin/installer -pkg \"#{tmp_dest}\" -target / >& /tmp/installer.stderr"
unless system(installer)
die "An error happened when installing the software update: #{File.read('/tmp/installer.stderr')}"
end
FileUtils.rm_f tmp_dest
$stderr.puts "Software update installed.\n\n"
news = File.read('/Library/Motion/NEWS')
news.lines.each do |line|
if md = line.match(/^=\s+RubyMotion\s+(.+)\s+=$/)
break if md[1] <= product_version
end
$stderr.puts line
end
$stderr.puts "(See the `/Library/Motion/NEWS' file for all changes.)"
end
end
class MotionMainCommand
Commands = [CreateCommand, ActivateCommand, UpdateCommand]
def initialize(args)
arg = args.shift
case arg
when '-h', '--help'
usage
when '-v', '--version'
$stdout.puts Motion::Version
exit 1
when /^-/
$stderr.puts "Unknown option: #{arg}"
exit 1
end
command = Commands.find { |command| command.name == arg }
usage unless command
command.run(args)
end
def usage
$stderr.puts 'Usage:'
$stderr.puts " #{File.basename(__FILE__)} [-h, --help]"
$stderr.puts " #{File.basename(__FILE__)} [-v, --version]"
$stderr.puts " #{File.basename(__FILE__)} <command> [<args...>]"
$stderr.puts ''
$stderr.puts 'Commands:'
Commands.each do |command|
$stderr.puts " #{command.name}".ljust(15) + command.help
end
exit 1
end
end
MotionMainCommand.new(ARGV)