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
|
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
module Gem
##
# The Builder class processes RubyGem specification files
# to produce a .gem file.
#
class Builder
include UserInteraction
##
# Constructs a builder instance for the provided specification
#
# spec:: [Gem::Specification] The specification instance
#
def initialize(spec)
require "yaml"
require "rubygems/package"
require "rubygems/security"
@spec = spec
end
##
# Builds the gem from the specification. Returns the name of the file
# written.
#
def build
@spec.mark_version
@spec.validate
@signer = sign
write_package
say success
@spec.file_name
end
def success
<<-EOM
Successfully built RubyGem
Name: #{@spec.name}
Version: #{@spec.version}
File: #{@spec.full_name+'.gem'}
EOM
end
private
def sign
# if the signing key was specified, then load the file, and swap
# to the public key (TODO: we should probably just omit the
# signing key in favor of the signing certificate, but that's for
# the future, also the signature algorithm should be configurable)
signer = nil
if @spec.respond_to?(:signing_key) && @spec.signing_key
signer = Gem::Security::Signer.new(@spec.signing_key, @spec.cert_chain)
@spec.signing_key = nil
@spec.cert_chain = signer.cert_chain.map { |cert| cert.to_s }
end
signer
end
def write_package
open @spec.file_name, 'wb' do |gem_io|
Gem::Package.open gem_io, 'w', @signer do |pkg|
pkg.metadata = @spec.to_yaml
@spec.files.each do |file|
next if File.directory? file
stat = File.stat file
mode = stat.mode & 0777
size = stat.size
pkg.add_file_simple file, mode, size do |tar_io|
tar_io.write open(file, "rb") { |f| f.read }
end
end
end
end
end
end
end
|