Files
textmate/bin/upload
Allan Odgaard d737efd7e1 Generalize bin/upload
It now takes key path and destination (github repostiory) as arguments. The generated build.ninja assumes the user local build.ninja sets these variables.
2012-08-20 15:44:47 +02:00

101 lines
3.2 KiB
Ruby
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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