mirror of
https://github.com/zhigang1992/RubyMotion.git
synced 2026-04-04 22:58:19 +08:00
This changing will introduce: 1. When run 'rake clean', the object files of gem is not removed. To reduce the time when rebuild the project. 2. Across multiple projects that use the same gem, this changing will share the object files. 3. When update RubyMotion with 'motion update', it will remove the object files to clean up disk space.
284 lines
8.0 KiB
Ruby
284 lines
8.0 KiB
Ruby
#!/usr/bin/ruby
|
|
# Copyright (C) 2012, HipByte SPRL. All Rights Reserved.
|
|
#
|
|
# This file is subject to the terms and conditions of the End User License
|
|
# Agreement accompanying the package this file is a part of.
|
|
|
|
require 'fileutils'
|
|
require 'uri'
|
|
|
|
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/RubyMotion/lib'
|
|
$:.unshift($motion_libdir)
|
|
require 'motion/version'
|
|
require 'motion/project/app.rb'
|
|
require 'motion/project/builder.rb'
|
|
|
|
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
|
|
|
|
def read_license_key
|
|
unless File.exist?(LicensePath)
|
|
die "License file not present. Please activate RubyMotion with `motion activate' and try again."
|
|
end
|
|
File.read(LicensePath).strip
|
|
end
|
|
|
|
def guess_email_address
|
|
# Guess the default email address from git.
|
|
URI.escape(`git config --get user.email`.strip)
|
|
end
|
|
end
|
|
end
|
|
|
|
class CreateCommand < Command
|
|
self.name = 'create'
|
|
self.help = 'Create a new project'
|
|
|
|
def self.run(args)
|
|
if args.size < 1 || args.size > 2
|
|
end
|
|
|
|
app_name = nil
|
|
template_name = 'ios'
|
|
args.each do |a|
|
|
case a
|
|
when /--([^=]+)=(.+)/
|
|
opt_name = $1.to_s.strip
|
|
opt_val = $2.to_s.strip
|
|
case opt_name
|
|
when 'template'
|
|
template_name = opt_val
|
|
else
|
|
die "Incorrect option `#{opt_name}'"
|
|
end
|
|
else
|
|
if app_name
|
|
app_name = nil
|
|
break
|
|
else
|
|
app_name = a
|
|
end
|
|
end
|
|
end
|
|
|
|
unless app_name
|
|
die "Usage: motion create [--template=<template_name>] <app-name>"
|
|
end
|
|
|
|
Motion::Project::App.create(app_name, template_name)
|
|
end
|
|
end
|
|
|
|
LicensePath = '/Library/RubyMotion/license.key'
|
|
|
|
class ActivateCommand < Command
|
|
self.name = 'activate'
|
|
self.help = 'Activate the software license'
|
|
|
|
def self.run(args)
|
|
if File.exist?(LicensePath)
|
|
die "Product is already activated. Delete the license file `#{LicensePath}' if you want to activate a new license."
|
|
end
|
|
|
|
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
|
|
|
|
need_root
|
|
File.open(LicensePath, 'w') { |io| io.write license_key }
|
|
puts "Product activated. Thanks for purchasing RubyMotion :-)"
|
|
end
|
|
end
|
|
|
|
class AccountCommand < Command
|
|
self.name = 'account'
|
|
self.help = 'Access the software license account'
|
|
|
|
def self.run(args)
|
|
unless args.empty?
|
|
die "Usage: motion account"
|
|
end
|
|
|
|
license_key = read_license_key
|
|
email = guess_email_address
|
|
|
|
system("open \"https://secure.rubymotion.com/account?license_key=#{license_key}&email=#{email}\"")
|
|
end
|
|
end
|
|
|
|
class SupportCommand < Command
|
|
self.name = 'support'
|
|
self.help = 'Create a support ticket'
|
|
|
|
def self.run(args)
|
|
unless args.empty?
|
|
die "Usage: motion support"
|
|
end
|
|
|
|
license_key = read_license_key
|
|
email = guess_email_address
|
|
|
|
# Collect details about the environment.
|
|
osx_vers = `/usr/bin/sw_vers -productVersion`.strip
|
|
rm_vers = Motion::Version
|
|
xcode_vers = begin
|
|
xcodebuild = `which xcodebuild`.strip
|
|
xcodebuild = '/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild' if xcodebuild.empty?
|
|
vers = ''
|
|
if File.exist?(xcodebuild)
|
|
vers = `#{xcodebuild} -version`.strip.scan(/Xcode\s(.+)$/).flatten[0].to_s
|
|
end
|
|
vers = 'unknown' if vers.empty?
|
|
vers
|
|
end
|
|
|
|
environment = URI.escape("OSX #{osx_vers}, RubyMotion #{rm_vers}, Xcode #{xcode_vers}")
|
|
|
|
system("open \"https://secure.rubymotion.com/new_support_ticket?license_key=#{license_key}&email=#{email}&environment=#{environment}\"")
|
|
end
|
|
end
|
|
|
|
class UpdateCommand < Command
|
|
self.name = 'update'
|
|
self.help = 'Update the software'
|
|
|
|
def self.curl(cmd)
|
|
resp = `/usr/bin/curl --connect-timeout 60 #{cmd}`
|
|
if $?.exitstatus != 0
|
|
die "Error when connecting to the server. Check your Internet connection and try again."
|
|
end
|
|
resp
|
|
end
|
|
|
|
def self.run(args)
|
|
check_mode = false
|
|
wanted_software_version = ''
|
|
args.each do |a|
|
|
case a
|
|
when '--check'
|
|
check_mode = true
|
|
when /--force-version=(.+)/
|
|
wanted_software_version = $1.to_s
|
|
else
|
|
die "Usage: motion update [--force-version=X]"
|
|
end
|
|
end
|
|
|
|
product_version = Motion::Version
|
|
if check_mode
|
|
update_check_file = File.join(ENV['TMPDIR'] || '/tmp', '.motion-update-check')
|
|
if !File.exist?(update_check_file) or (Time.now - File.mtime(update_check_file) > 60 * 60 * 24)
|
|
resp = curl("-s -d \"product=rubymotion\" -d \"current_software_version=#{product_version}\" http://secure.rubymotion.com/latest_software_version")
|
|
exit 1 unless resp.match(/^\d+\.\d+/)
|
|
File.open(update_check_file, 'w') { |io| io.write(resp) }
|
|
end
|
|
exit File.read(update_check_file) > product_version ? 2 : 0
|
|
end
|
|
|
|
unless File.exist?(LicensePath)
|
|
die "License file not present. Please activate RubyMotion with `motion activate' and try again."
|
|
end
|
|
|
|
need_root
|
|
license_key = File.read(LicensePath).strip
|
|
|
|
$stderr.puts "Connecting to the server..."
|
|
resp = curl("-s -d \"product=rubymotion\" -d \"current_software_version=#{product_version}\" -d \"wanted_software_version=#{wanted_software_version}\" -d \"license_key=#{license_key}\" https://secure.rubymotion.com/update_software")
|
|
unless resp.match(/^http:/)
|
|
die resp
|
|
end
|
|
|
|
$stderr.puts "Downloading software update..."
|
|
url = resp
|
|
tmp_dest = '/tmp/_rubymotion_su.pkg'
|
|
curl("-# \"#{url}\" -o #{tmp_dest}")
|
|
|
|
$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/RubyMotion/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/RubyMotion/NEWS' file for all changes.)"
|
|
|
|
FileUtils.rm_rf Motion::Project::Builder.common_build_dir
|
|
end
|
|
end
|
|
|
|
class RICommand < Command
|
|
self.name = 'ri'
|
|
self.help = 'Display API reference'
|
|
|
|
def self.run(args)
|
|
if args.size <= 0
|
|
die "Usage: motion ri <API-name>"
|
|
end
|
|
|
|
system("/Library/RubyMotion/lib/yard/bin/yri --db /Library/RubyMotion/doc/yardoc #{args[0]}")
|
|
end
|
|
end
|
|
|
|
class MotionMainCommand
|
|
Commands = [CreateCommand, ActivateCommand, UpdateCommand, RICommand, SupportCommand, AccountCommand]
|
|
|
|
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)
|