1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
|
#!/usr/bin/env ruby
require 'erb'
require 'fileutils'
require 'tmpdir'
require 'optparse'
File.umask(0022)
SOURCE_DIR = File.absolute_path(File.join(__dir__, '..', '..'))
RUBY_VERSION_FILE = File.join('gitaly', 'version.rb')
def parse_options
options = {}
option_parser = OptionParser.new do |opts|
opts.banner = "Usage: build-proto-gem [options]"
opts.on_tail("--skip-verify-tag", "Skip verification that this is run for a tagged Gitaly commit") do
options[:skip_verify_tag] = true
end
opts.on("-o", "--output PATH", "output path for the gem") do |path|
options[:output_path] = File.absolute_path(path)
end
end
option_parser.parse!
if options[:output_path].nil?
puts option_parser.help
exit 1
end
return options
end
def main(options)
version = File.read(File.join(SOURCE_DIR, 'VERSION')).strip
unless version.match?(/\d+\.\d+\.\d+(-rc\d+)?/)
abort "Version string #{version.inspect} does not look like a Gitaly Release tag (e.g. \"v1.0.2\"). Aborting."
end
if !options[:skip_verify_tag]
ref = capture!(%w[git describe --tag]).chomp
if ref != "v#{version}"
abort "Checkout tag v#{version} to publish.\n\t git checkout v#{version}"
end
end
puts 'Testing for changed files'
run!(%w[git diff --quiet --exit-code])
puts 'Testing for staged changes'
run!(%w[git diff --quiet --cached --exit-code])
Dir.mktmpdir do |output_dir|
generate_sources(output_dir, version)
build_gem(output_dir, options[:output_path])
end
end
def generate_sources(output_dir, version)
proto_output_dir = File.absolute_path(File.join(output_dir, 'ruby', 'proto', 'gitaly'))
FileUtils.mkdir_p(proto_output_dir)
proto_dir = File.join(SOURCE_DIR, 'proto')
proto_files = Dir[File.join(proto_dir, '*.proto')].sort
run!(
%W[bundle exec grpc_tools_ruby_protoc -I #{proto_dir} --ruby_out=#{proto_output_dir} --grpc_out=#{proto_output_dir}] + proto_files,
File.join(SOURCE_DIR, 'tools', 'protogem')
)
write_version_file(output_dir, version)
write_ruby_requires(output_dir)
end
def build_gem(output_dir, output_path)
gemspec = <<~EOT
# coding: utf-8
prefix = 'ruby/proto'
$LOAD_PATH.unshift(File.expand_path(File.join(prefix), __dir__))
require 'gitaly/version'
Gem::Specification.new do |spec|
spec.name = "gitaly"
spec.version = Gitaly::VERSION
spec.authors = ["Jacob Vosmaer"]
spec.email = ["jacob@gitlab.com"]
spec.summary = %q{Auto-generated gRPC client for gitaly}
spec.description = %q{Auto-generated gRPC client for gitaly.}
spec.homepage = "https://gitlab.com/gitlab-org/gitaly"
spec.license = "MIT"
spec.files = Dir['**/*.rb']
spec.require_paths = [prefix]
spec.add_dependency "grpc", "~> 1.0"
end
EOT
gemspec_path = File.join(output_dir, 'gitaly.gemspec')
open(gemspec_path, 'w') { |f| f.write(gemspec) }
run!(['gem', 'build', gemspec_path, '--output', output_path], output_dir)
abort "gem not found" unless File.exist?(output_path)
end
def write_version_file(output_dir, version)
path = File.join(output_dir, 'ruby', 'proto', RUBY_VERSION_FILE)
content = <<~EOF
# This file is generated by #{File.basename($0)}. Do not edit.
module Gitaly
VERSION = '#{version}'
end
EOF
open(path, 'w') { |f| f.write(content) }
end
def write_ruby_requires(output_dir)
requires = Dir.glob(File.join('gitaly', '*_services_pb.rb'), base: File.join(output_dir, 'ruby', 'proto')).sort
abort "No auto-generated Ruby service files found" if requires.empty?
requires.unshift(RUBY_VERSION_FILE)
gem_root = File.join(output_dir, 'ruby', 'proto', 'gitaly.rb')
gem_root_template = ERB.new <<~EOT
# This file is generated by #{File.basename($0)}. Do not edit.
$:.unshift(File.expand_path('../gitaly', __FILE__))
<% requires.each do |f| %>
require '<%= f.sub(/\.rb$/, '') %>'
<% end %>
EOT
open(gem_root, 'w') { |f| f.write(gem_root_template.result(binding)) }
end
def run!(cmd, chdir='.')
GitalySupport.print_cmd(cmd)
unless system(*cmd, chdir: chdir)
GitalySupport.fail_cmd!(cmd)
end
end
def capture!(cmd, chdir='.')
GitalySupport.print_cmd(cmd)
output = IO.popen(cmd, chdir: chdir) { |io| io.read }
GitalySupport.fail_cmd!(cmd) unless $?.success?
output
end
module GitalySupport
class << self
def print_cmd(cmd)
puts '-> ' + printable_cmd(cmd)
end
def fail_cmd!(cmd)
abort "command failed: #{printable_cmd(cmd)}"
end
def printable_cmd(cmd)
cmd.join(' ')
end
end
end
main(parse_options)
|