mirror of
https://github.com/textmate/textmate.git
synced 2026-01-21 04:38:13 -05:00
It now takes key path and destination (github repostiory) as arguments. The generated build.ninja assumes the user local build.ninja sets these variables.
101 lines
3.2 KiB
Ruby
Executable File
101 lines
3.2 KiB
Ruby
Executable File
#!/usr/bin/env ruby -wKU
|
||
# == Synopsis
|
||
#
|
||
# upload [-k «keyfile»] [-d «destination»] «file»
|
||
#
|
||
# == Usage
|
||
#
|
||
# --help:
|
||
# show help.
|
||
#
|
||
# --keyfile/-k:
|
||
# Keyfile used for signing.
|
||
#
|
||
# --destination/-d:
|
||
# Which GitHub ‘«user»/«repository»’ we should upload to.
|
||
#
|
||
require 'getoptlong'
|
||
require "rubygems"
|
||
require "net/netrc"
|
||
require "json"
|
||
require 'base64'
|
||
require 'openssl'
|
||
require 'digest/sha1'
|
||
|
||
def sign_file(path, keyfile, password)
|
||
# %x{openssl dgst -dss1 -sign '#{keyfile}' -passin 'pass:#{password}' '#{path}'|openssl enc -base64}.chomp
|
||
|
||
key = OpenSSL::PKey::DSA.new(File.read(keyfile), password) or abort "*** error reading keyfile: ‘#{keyfile}’."
|
||
digest = Digest::SHA1.digest(File.read(path))
|
||
signature = key.syssign(digest)
|
||
Base64.encode64(signature).gsub("\n", '')
|
||
end
|
||
|
||
def aws_upload(path, url, key, acl, filename, content_type, access_key, policy, signature)
|
||
rc = %x{curl -sw'%{http_code}' --show-error -o/dev/null \
|
||
-F "key=#{key}" \
|
||
-F "acl=#{acl}" \
|
||
-F "success_action_status=201" \
|
||
-F "Filename=#{filename}" \
|
||
-F "Content-Type=#{content_type}" \
|
||
-F "AWSAccessKeyId=#{access_key}" \
|
||
-F "Policy=#{policy}" \
|
||
-F "Signature=#{signature}" \
|
||
-F "file=@#{path}" \
|
||
#{url}
|
||
}
|
||
abort "aws error: #{rc}" unless rc == '201'
|
||
end
|
||
|
||
def create_download(path, repository, name, description, content_type)
|
||
payload = { 'name' => name || File::basename(path), 'size' => File::size(path), 'content_type' => content_type || 'application/octet-stream' }
|
||
payload['description'] = description unless description.nil?
|
||
|
||
open("|curl -snd '#{payload.to_json}' https://api.github.com/repos/#{repository}/downloads") do |io|
|
||
github = JSON.parse(io.read)
|
||
abort "github error: #{github['errors'].inspect} for #{repository}" if github.include?('errors')
|
||
abort "github unexpected response: #{github.inspect} for #{repository}" unless github.include?('html_url')
|
||
aws_upload(path, github['s3_url'], github['path'], github['acl'], payload['name'], payload['content_type'], github['accesskeyid'], github['policy'], github['signature'])
|
||
return github['html_url']
|
||
end
|
||
nil
|
||
end
|
||
|
||
if __FILE__ == $PROGRAM_NAME
|
||
opts = GetoptLong.new(
|
||
[ '--help', '-h', GetoptLong::NO_ARGUMENT ],
|
||
[ '--keyfile', '-k', GetoptLong::REQUIRED_ARGUMENT ],
|
||
[ '--destination', '-d', GetoptLong::REQUIRED_ARGUMENT ]
|
||
)
|
||
|
||
keyfile = nil
|
||
destination = 'textmate/textmate'
|
||
netinfo = Net::Netrc.locate("sign.textmate.org") or abort "*** missing passphrase in ~/.netrc."
|
||
|
||
opts.each do |opt, arg|
|
||
case opt
|
||
when '--help' then RDoc::usage
|
||
when '--keyfile' then keyfile = arg
|
||
when '--destination' then destination = arg
|
||
end
|
||
end
|
||
|
||
abort 'No signing key provided' if keyfile.nil?
|
||
|
||
if path = ARGV.shift
|
||
if File.basename(path) =~ /(.+)_r(\d+)\.tbz$/
|
||
base, name, version = $&, $1, $2
|
||
description = ''
|
||
|
||
info = {
|
||
'url' => create_download(path, destination, base, description, 'application/x-bzip2'),
|
||
'version' => version,
|
||
'signature' => sign_file(path, keyfile, netinfo.password),
|
||
'signee' => netinfo.login
|
||
}
|
||
|
||
STDOUT << info.to_json
|
||
end
|
||
end
|
||
end
|