mirror of
https://github.com/binaryage/totalterminal.git
synced 2026-01-13 08:18:01 -05:00
447 lines
14 KiB
Plaintext
447 lines
14 KiB
Plaintext
ROOT_DIR = File.expand_path('.')
|
|
TMP_ROOT = '/tmp'
|
|
TMP_DIR = File.join(TMP_ROOT, 'totalterminal')
|
|
BUILD_DIR = File.join(ROOT_DIR, 'build')
|
|
RELEASE_DIR = File.join(ROOT_DIR, 'release')
|
|
INSTALLER_DIR = File.join(ROOT_DIR, 'installer')
|
|
PAYLOADS_DIR = File.join(ROOT_DIR, 'payloads')
|
|
|
|
PARENT_DIR = File.expand_path('..')
|
|
|
|
PLUGIN_BUNDLE = "TotalTerminal.bundle"
|
|
XCODE_WORKSPACE = File.join(ROOT_DIR, 'TotalTerminal.xcworkspace')
|
|
|
|
SPARKLE_DIR = File.join(ROOT_DIR, 'sparkle')
|
|
OSAX_DIR = File.join(PARENT_DIR, 'totalterminal-osax')
|
|
I18N_DIR = File.join(PARENT_DIR, 'totalterminal-i18n')
|
|
|
|
TMP_GIT_MODULES = File.join(TMP_DIR, '.gitmodules')
|
|
TMP_TOTALTERMINAL_RESOURCES = File.join(TMP_DIR, 'totalterminal-i18n', 'plugin')
|
|
TMP_TOTALTERMINAL_DIR = File.join(TMP_DIR, 'totalterminal-plugin')
|
|
TMP_BIN_DIR = File.join(TMP_DIR, 'bin')
|
|
TMP_BIN_TOTALTERMINAL_FRAMEWORKS = File.join(TMP_BIN_DIR, 'TotalTerminal.osax/Contents/Resources/TotalTerminal.bundle/Contents/Frameworks')
|
|
|
|
PLUGIN_INFO_PLIST = File.join(TMP_DIR, 'totalterminal-plugin', 'Info.plist')
|
|
PLUGIN_VISOR_M = File.join(TMP_DIR, 'totalterminal-plugin', 'TotalTerminal.mm')
|
|
PLUGIN_PREFERENCES_MM = File.join(TMP_DIR, 'totalterminal-plugin', 'TotalTerminal+Preferences.mm')
|
|
PLUGIN_VISOR_XIB = File.join(TMP_DIR, 'totalterminal-i18n', 'plugin', 'TotalTerminal.xib')
|
|
OSAX_INFO_PLIST = File.join(TMP_DIR, 'totalterminal-osax', 'Info.plist')
|
|
CRASHWATCHER_INFO_PLIST = File.join(TMP_DIR, 'crashwatcher', 'CrashWatcher-Info.plist')
|
|
|
|
PUBLISH_PREFIX_URL = "http://downloads.binaryage.com"
|
|
CHANGELOG_PREFIX_URL = "http://totalterminal.binaryage.com"
|
|
|
|
################################################################################################
|
|
# dependencies
|
|
|
|
begin
|
|
require 'colored'
|
|
rescue LoadError
|
|
raise 'You must "gem install colored" to use terminal colors'
|
|
end
|
|
|
|
def file_color(text); text.yellow; end
|
|
def dir_color(text); text.blue; end
|
|
def cmd_color(text); text.magenta; end
|
|
|
|
|
|
############################################################################################
|
|
|
|
def die(msg, status=1)
|
|
puts "Error[#{status||$?}]: #{msg}".red
|
|
exit status||$?
|
|
end
|
|
|
|
def version()
|
|
$version = ENV["version"] or die("specify version")
|
|
end
|
|
|
|
def revision()
|
|
$revision = `git rev-parse HEAD`.strip
|
|
$short_revision = $revision[0...7]
|
|
end
|
|
|
|
def dirty_repo_warning()
|
|
is_clean = `git status`.match(/working directory clean/)
|
|
puts "Repository is not clean! You should commit all changes before releasing.".red unless is_clean
|
|
end
|
|
|
|
def patch(path, replacers)
|
|
puts "#{cmd_color('Patching')} #{file_color(path)}"
|
|
lines = []
|
|
File.open(path, "r") do |f|
|
|
f.each do |line|
|
|
replacers.each do |r|
|
|
line.gsub!(r[0], r[1])
|
|
end
|
|
lines << line
|
|
end
|
|
end
|
|
File.open(path, "w") do |f|
|
|
f << lines.join
|
|
end
|
|
end
|
|
|
|
def announce(cmd)
|
|
puts "> " + cmd.yellow
|
|
end
|
|
|
|
def sys(cmd)
|
|
announce(cmd)
|
|
system(cmd)
|
|
end
|
|
|
|
############################################################################################
|
|
|
|
def generate_payload_for_pkg(tmp, pkg)
|
|
tree = ""
|
|
exes = ""
|
|
|
|
tmp2 = File.join(tmp, "payload-extractor")
|
|
sys("rm -rf \"#{tmp2}\"") if File.exist? tmp2
|
|
sys("mkdir -p \"#{tmp2}\"")
|
|
sys("cp \"#{pkg}\" \"#{tmp2}\"")
|
|
|
|
name = File.basename pkg
|
|
|
|
Dir.chdir(tmp2) do
|
|
sys("xar -xf \"#{name}\"")
|
|
|
|
Dir.chdir("TotalTerminal_Plugin.pkg") do
|
|
if (File.exist? "Payload") then
|
|
sys("mv Payload Payload.gz")
|
|
sys("gunzip Payload.gz")
|
|
sys("cpio -id < Payload")
|
|
end
|
|
|
|
tree = `tree --dirsfirst -apsugif`
|
|
exes = ""
|
|
Dir.glob("**/MacOS/*") do |exe|
|
|
exes += `file "#{exe}"` + "\n"
|
|
end
|
|
end
|
|
end
|
|
|
|
res = ""
|
|
res << "\n"
|
|
res << "#{name}\n"
|
|
res << "=======================================================================\n"
|
|
res << tree
|
|
res << "\n"
|
|
res << exes
|
|
res
|
|
end
|
|
|
|
def generate_payload(dmg, out)
|
|
puts "Generating payload for: ".green + dmg.blue
|
|
|
|
volume = "/Volumes/TotalTerminal"
|
|
tmp = File.join(TMP_DIR, "payloads", File.basename(dmg, ".dmg"))
|
|
sys("rm -rf \"#{tmp}\"") if File.exist? tmp
|
|
sys("mkdir -p \"#{tmp}\"")
|
|
|
|
puts dmg
|
|
cmd = "hdiutil attach \"#{dmg}\" | grep Apple_partition_scheme"
|
|
announce(cmd)
|
|
res = `#{cmd}`
|
|
puts res
|
|
disk = res.split("\n")[0].split("\t")[0]
|
|
|
|
die("bad disk") unless disk =~ /\/dev/
|
|
|
|
sys("cp -r #{volume}/* \"#{tmp}\"")
|
|
|
|
tree1 = ""
|
|
Dir.chdir(tmp) do
|
|
tree1 = `tree --dirsfirst -apsugif`
|
|
end
|
|
|
|
pkgs = []
|
|
Dir.glob(File.join(tmp, "**/*.pkg")) do |pkg|
|
|
pkgs << generate_payload_for_pkg(tmp, pkg)
|
|
end
|
|
|
|
|
|
outdir = File.dirname out
|
|
`mkdir -p #{outdir}` unless File.exist? outdir
|
|
File.open(out, "w") do |f|
|
|
f << "BASIC DMG LAYOUT\n"
|
|
f << "================\n"
|
|
f << tree1
|
|
|
|
pkgs.each do |pkg|
|
|
f << pkg
|
|
end
|
|
end
|
|
|
|
puts " -> ".green + out.blue
|
|
|
|
sys("hdiutil detach #{disk}")
|
|
end
|
|
|
|
def retag_submodule(tags, submodule)
|
|
tags.each do |tag|
|
|
x = `git ls-tree #{tag} #{submodule}`
|
|
sha = x.split(" ")[2]
|
|
Dir.chdir(submodule) do
|
|
sha = `git log --reverse`.split("\n")[0].split(" ")[1] unless sha # take first commit in case submodule wasn't defined at this point
|
|
sys("git tag -d #{tag}")
|
|
puts "#{tag} #{sha}"
|
|
sys("git tag #{tag} #{sha}")
|
|
end
|
|
end
|
|
Dir.chdir(submodule) do
|
|
sys("git push --tags")
|
|
end
|
|
end
|
|
|
|
def release_version_from_filename(n) # /Users/darwin/code/totalterminal/payloads/TotalTerminal-0.7.1.txt
|
|
p = File.basename(n, ".txt").split("-")[1]
|
|
n = p.split(".")
|
|
while n.size < 3 do
|
|
n << "0"
|
|
end
|
|
x = (n[0]||"0").to_i
|
|
y = (n[1]||"0").to_i
|
|
z = (n[2]||"0").to_i
|
|
x*1000000 + y*1000 + z
|
|
end
|
|
|
|
def patch_gitmodules
|
|
patch(TMP_GIT_MODULES, [
|
|
['git://github.com/binaryage', ROOT_DIR],
|
|
['.git', '']
|
|
])
|
|
end
|
|
|
|
###################################################################################################################
|
|
|
|
desc "opens XCode project"
|
|
task :open do
|
|
`open "#{XCODE_WORKSPACE}"`
|
|
end
|
|
|
|
desc "prepare stage"
|
|
task :stage do
|
|
puts "#{cmd_color('Cloning sources to stage ...')}"
|
|
`rm -rf "#{TMP_DIR}"`
|
|
`mkdir -p "#{TMP_ROOT}"`
|
|
Dir.chdir(TMP_ROOT) do
|
|
`git clone #{ROOT_DIR}`
|
|
end
|
|
|
|
puts "#{cmd_color('Initializing submodules ...')}"
|
|
Dir.chdir(TMP_DIR) do
|
|
`git reset --hard HEAD`
|
|
patch_gitmodules
|
|
`git submodule update --init --recursive`
|
|
end
|
|
end
|
|
|
|
desc "prepares release build"
|
|
task :release do
|
|
unless File.exists?(TMP_DIR) then die('Doing it for first time? => rake stage') end
|
|
|
|
puts "#{cmd_color('Checking environment ...')}"
|
|
dirty_repo_warning()
|
|
version()
|
|
revision()
|
|
mkdir_p(RELEASE_DIR) unless File.exists? RELEASE_DIR
|
|
|
|
unless ENV["fast"] then
|
|
puts "#{cmd_color('Updating stage ...')}"
|
|
Dir.chdir(TMP_DIR) do
|
|
sys('git clean -fd')
|
|
sys('git reset --hard HEAD^') # use previous commit to make working tree resilient to amends
|
|
sys('git submodule foreach --recursive "git clean -fd"')
|
|
sys('git submodule foreach --recursive "git reset --hard HEAD"')
|
|
sys('git submodule update --recursive --checkout')
|
|
sys('git pull --ff-only')
|
|
|
|
patch_gitmodules
|
|
sys('git submodule update --recursive --checkout')
|
|
end
|
|
|
|
puts "#{cmd_color('Patching version info ...')}"
|
|
patch(PLUGIN_VISOR_XIB, [['##VERSION##', $version], ['##REVISION##', $short_revision]])
|
|
patch(PLUGIN_INFO_PLIST, [['##VERSION##', $version], ['##REVISION##', $short_revision]])
|
|
patch(PLUGIN_VISOR_M, [['##VERSION##', $version], ['##REVISION##', $short_revision], ['##SHA##', $revision]])
|
|
patch(PLUGIN_PREFERENCES_MM, [['##VERSION##', $version], ['##REVISION##', $short_revision], ['##SHA##', $revision]])
|
|
patch(OSAX_INFO_PLIST, [['##VERSION##', $version], ['##REVISION##', $short_revision]])
|
|
patch(OSAX_INFO_PLIST, [['##VERSION##', $version], ['##REVISION##', $short_revision]])
|
|
patch(CRASHWATCHER_INFO_PLIST, [['##VERSION##', $version], ['##REVISION##', $short_revision]])
|
|
|
|
Dir.chdir(TMP_DIR) do
|
|
unless ENV["noclean"] then
|
|
puts "#{cmd_color('Cleaning')} #{file_color(TMP_TOTALTERMINAL_DIR)}"
|
|
sys('xcodebuild -workspace TotalTerminal.xcworkspace -scheme "TotalTerminal Package" -configuration Release clean')
|
|
end
|
|
|
|
puts "#{cmd_color('Building')} #{file_color(TMP_TOTALTERMINAL_DIR)}"
|
|
sys('xcodebuild -workspace TotalTerminal.xcworkspace -scheme "TotalTerminal Package" -configuration Release')
|
|
die("build failed") unless $?==0
|
|
end
|
|
|
|
Dir.glob(File.join(TMP_BIN_TOTALTERMINAL_FRAMEWORKS, "*")) do |framework|
|
|
patch(File.join(framework, 'Resources', 'Info.plist'), [['##VERSION##', $version], ['##REVISION##', $short_revision]])
|
|
end
|
|
end
|
|
|
|
releasedmg = File.join(RELEASE_DIR, "TotalTerminal-#{$version}.dmg")
|
|
sys("rm -rf \"#{releasedmg}\"") if File.exist? releasedmg
|
|
die("build failed") unless $?==0
|
|
|
|
Dir.chdir(File.join(TMP_DIR, "totalterminal-installer")) do
|
|
sys("rake build version=#{$version} products=\"../bin\" release=\"#{RELEASE_DIR}\"")
|
|
die("installer build failed") unless $?==0
|
|
end
|
|
|
|
size = File.size(releasedmg)
|
|
sig = `ruby "sparkle/sign_update.rb" "#{releasedmg}" keys/dsa_priv.pem`.strip
|
|
die("build failed") unless $?==0
|
|
|
|
snippet = "\
|
|
<item>
|
|
<title>Version #{$version}</title>
|
|
<sparkle:releaseNotesLink>#{CHANGELOG_PREFIX_URL}/changelog-beta.html</sparkle:releaseNotesLink>
|
|
<pubDate>#{Time.new}</pubDate>
|
|
<enclosure url=\"#{PUBLISH_PREFIX_URL}/TotalTerminal-#{$version}.dmg\" sparkle:version=\"#{$version}\" length=\"#{size}\" type=\"application/octet-stream\" sparkle:dsaSignature=\"#{sig}\"/>
|
|
<sparkle:minimumSystemVersion>10.6.0</sparkle:minimumSystemVersion>
|
|
</item>"
|
|
|
|
puts snippet
|
|
puts
|
|
puts "Don't forget: ".red
|
|
puts " git tag -a v#{$version} -m \"Release #{$version}\"".green
|
|
puts " test sparkle updating on it via touch ~/.use-test-appcast, see totalterminal-plugin/TotalTerminal+Sparkle.mm"
|
|
puts "#{PUBLISH_PREFIX_URL}/TotalTerminal-#{$version}.dmg".blue
|
|
|
|
# Dir.chdir(ROOT_DIR) do
|
|
# sys("mkdir -p ttdata")
|
|
# sys("mount -t smbfs //guest:@whale/Store/ttdata ttdata")
|
|
# sys("rsync -av --delete release ttdata")
|
|
# sys("umount ttdata")
|
|
# sys("rm -rf ttdata")
|
|
# end
|
|
end
|
|
|
|
desc "removes intermediate build files"
|
|
task :clean do
|
|
puts "#{cmd_color('Removing')} #{dir_color(TMP_DIR)}"
|
|
`rm -rf "#{TMP_DIR}"`
|
|
end
|
|
|
|
desc "removes all release builds"
|
|
task :purge do
|
|
puts "#{cmd_color('Removing')} #{dir_color(RELEASE_DIR)}"
|
|
`rm -rf "#{RELEASE_DIR}"`
|
|
end
|
|
|
|
desc "beautify sources using uncrustify => see uncrustify.cfg"
|
|
task :beautify do
|
|
config = File.join(ROOT_DIR, 'configs', 'uncrustify.cfg')
|
|
what = ENV["filter"] || "*"
|
|
base = File.join(ROOT_DIR, "totalterminal-plugin")
|
|
Dir.glob(File.join(base, "**/#{what}")) do |file|
|
|
next unless file=~/\.(mm|m|c|h|cc|cpp|hpp)$/
|
|
puts file[base.size+1..-1]
|
|
`uncrustify -c "#{config}" --replace --no-backup --mtime "#{file}"`
|
|
end
|
|
end
|
|
|
|
desc "build missing payloads"
|
|
task :payload do
|
|
Dir.chdir(RELEASE_DIR) do
|
|
Dir.glob("*.dmg").each do |file|
|
|
name = File.basename(file, ".dmg")
|
|
dest = File.join(PAYLOADS_DIR, name+".txt")
|
|
unless File.exist? dest then
|
|
generate_payload(file, dest)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
desc "diff two most recent payloads"
|
|
task :paydiff do
|
|
res = `ls -1 "#{PAYLOADS_DIR}"/*.txt`
|
|
res = res.split("\n")
|
|
|
|
res = res.sort do |a, b|
|
|
va = release_version_from_filename a
|
|
vb = release_version_from_filename b
|
|
vb<=>va
|
|
end
|
|
|
|
a = res[1]
|
|
b = res[0]
|
|
`ksdiff "#{a}" "#{b}"`
|
|
end
|
|
|
|
desc "update tags in submodules v1.0+"
|
|
task :retag do
|
|
tags = `git tag`.split("\n").reject {|x| x =~ /^v0/ } # skip v0.x.x
|
|
puts "found #{tags.size} tags..."
|
|
|
|
retag_submodule(tags, "totalterminal-i18n")
|
|
retag_submodule(tags, "totalterminal-installer")
|
|
retag_submodule(tags, "totalterminal-osax")
|
|
# NO! retag_submodule(tags, "crashwatcher") # crashwatcher is shared between TotalTerminal and TotalFinder
|
|
# NO! retag_submodule(tags, "sparkle") # sparkle is shared between TotalTerminal and TotalFinder
|
|
|
|
`git push --tags`
|
|
end
|
|
|
|
desc "pull all"
|
|
task :pull do
|
|
Dir.chdir("totalterminal-i18n") do
|
|
puts "in " + Dir.pwd
|
|
sys("git pull")
|
|
end
|
|
Dir.chdir("totalterminal-installer") do
|
|
puts "in " + Dir.pwd
|
|
sys("git pull")
|
|
end
|
|
Dir.chdir("totalterminal-osax") do
|
|
puts "in " + Dir.pwd
|
|
sys("git pull")
|
|
end
|
|
Dir.chdir("sparkle") do
|
|
puts "in " + Dir.pwd
|
|
sys("git pull")
|
|
end
|
|
Dir.chdir("crashwatcher") do
|
|
puts "in " + Dir.pwd
|
|
sys("git pull")
|
|
end
|
|
puts "in " + Dir.pwd
|
|
sys("git pull")
|
|
end
|
|
|
|
desc "push all"
|
|
task :push do
|
|
Dir.chdir("totalterminal-i18n") do
|
|
puts "in " + Dir.pwd
|
|
sys("git push")
|
|
end
|
|
Dir.chdir("totalterminal-installer") do
|
|
puts "in " + Dir.pwd
|
|
sys("git push")
|
|
end
|
|
Dir.chdir("totalterminal-osax") do
|
|
puts "in " + Dir.pwd
|
|
sys("git push")
|
|
end
|
|
Dir.chdir("sparkle") do
|
|
puts "in " + Dir.pwd
|
|
sys("git push")
|
|
end
|
|
Dir.chdir("crashwatcher") do
|
|
puts "in " + Dir.pwd
|
|
sys("git push")
|
|
end
|
|
puts "in " + Dir.pwd
|
|
sys("git push")
|
|
end
|
|
|
|
task :default => :open |