fatgem 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/bin/fatgem +171 -0
  3. metadata +45 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 74b326838076701fc449b32973365e409769a3ef
4
+ data.tar.gz: c40e5edbeb89a115f526ec7281cd484b7349f7f7
5
+ SHA512:
6
+ metadata.gz: 1066b8d1b6dd3fdbaf098b803d404b80702babb1c3f1dbe0153b40985886d57e5fe3b1b2e736f66b80b39b9df6f35dff8bdc8c83eee979ccd8d5268b9b1401b9
7
+ data.tar.gz: ac70111cf30a46a2cecd179b7bc0bf42d2303f5974aa4342176bf5f98911abc4082eceff5a8558f2417d26915735796ab26a7b5760a2346f865cf69fa58a5b1e
@@ -0,0 +1,171 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems/package'
4
+ require 'yaml'
5
+ require 'digest/sha1'
6
+ require 'tmpdir'
7
+ require 'open-uri'
8
+
9
+ class FatGem
10
+ class Error < StandardError; end
11
+
12
+ def self.tmp
13
+ Dir.mktmpdir do |dir|
14
+ yield new(dir)
15
+ end
16
+ end
17
+
18
+ attr_reader :directory
19
+
20
+ def initialize(directory)
21
+ @directory = directory
22
+ @files = Hash.new { |h, k| h[k] = {} }
23
+ @versions = {}
24
+ @specs = []
25
+ end
26
+
27
+ def open_tar(io, &blk)
28
+ Gem::Package::TarReader.new(io) do |reader|
29
+ reader.each(&blk)
30
+ end
31
+ end
32
+
33
+ def open_tar_gz(io, &blk)
34
+ Zlib::GzipReader.wrap io do |gzio|
35
+ open_tar(gzio, &blk)
36
+ end
37
+ end
38
+
39
+ def add_gem(path, ruby_version)
40
+
41
+ if @versions.has_key?(ruby_version)
42
+ version_str = ruby_version ? "Ruby v#{ruby_version}" : "all Ruby versions"
43
+ fail Error, ["Found two gems with same Ruby version:",
44
+ "- #{path} matches #{version_str}",
45
+ "- #{@versions[ruby_version]} also matches #{version_str}"].join("\n")
46
+ end
47
+
48
+ @versions[ruby_version] = path
49
+
50
+ yaml_metadata = nil
51
+
52
+ open_tar(open(path)) do |entry|
53
+ case entry.full_name
54
+ when "metadata.gz"
55
+ yaml_metadata = Gem.gunzip(entry.read)
56
+ when "metadata"
57
+ yaml_metadata = entry.read
58
+ when "data.tar.gz"
59
+ open_tar_gz(entry) do |data|
60
+ write_version(ruby_version, data.full_name, data.read)
61
+ end
62
+ end
63
+ end
64
+
65
+ fail Error, "#{path} does not contain a gemspec" if yaml_metadata.nil?
66
+
67
+ write_version(ruby_version, "metadata.yml", yaml_metadata)
68
+
69
+ spec = YAML.load(yaml_metadata)
70
+ @versions[spec] = path
71
+ @specs << spec
72
+ end
73
+
74
+ def write_version(version, path, content)
75
+ hash = Digest::SHA1.hexdigest(content)
76
+ blobpath = "data/#{hash}"
77
+ write(blobpath, content)
78
+ @files[version][path] = blobpath
79
+ end
80
+
81
+ def write(name, data)
82
+ path = File.join(@directory, name)
83
+ FileUtils.mkdir_p(File.dirname(path))
84
+ File.write(path, data)
85
+ end
86
+
87
+ RAKEFILE = <<-'EOF'
88
+ require 'yaml'
89
+ require 'rubygems/ext'
90
+
91
+ task :default do
92
+ versions = YAML.load_file("data/index")
93
+ ruby_main = RUBY_VERSION.split(".")[0,2].join(".")
94
+ files = versions[ruby_main] || versions[nil]
95
+
96
+ if files.nil?
97
+ $stderr.puts "ERROR: This gem can not be installed on #{RUBY_VERSION}"
98
+ exit 1
99
+ end
100
+
101
+ files.each do |name, hash|
102
+ dir = File.dirname(name)
103
+ FileUtils.mkdir_p(dir)
104
+ FileUtils.cp(hash, name)
105
+ end
106
+
107
+ FileUtils.rm_rf("data")
108
+
109
+ version_spec = YAML.load(File.read("metadata.yml"))
110
+ builder = Gem::Ext::Builder.new(version_spec)
111
+ builder.build_extensions
112
+ end
113
+ EOF
114
+
115
+ def assert_unique(type, specs = @specs)
116
+ values = specs.uniq(&type)
117
+ if values.size != 1
118
+ errors = values.map { |s| "- #{@versions[s]} has #{type} = #{s.send(type)}" }
119
+ if errors.empty?
120
+ errors << "- There's no gem with a specific platform"
121
+ end
122
+ fail Error, ["Can only fatten gems with same '#{type}'.", *errors].join("\n")
123
+ end
124
+ end
125
+
126
+ def finalize
127
+ platform_specs = @specs.select { |s| s.platform != "ruby" }
128
+
129
+ assert_unique :name
130
+ assert_unique :version
131
+ assert_unique :platform, platform_specs
132
+
133
+ main_spec = platform_specs[0]
134
+
135
+ write("data/index", @files.to_yaml)
136
+ write("Rakefile", RAKEFILE)
137
+
138
+ result = nil
139
+
140
+ Dir.chdir(@directory) do
141
+ main_spec.files = Dir["**/*"]
142
+ main_spec.extensions = ["Rakefile"]
143
+
144
+ file_name = Gem::Package.build(main_spec)
145
+ result = File.expand_path(file_name)
146
+ end
147
+
148
+ result
149
+ end
150
+ end
151
+
152
+ if ARGV.empty?
153
+ puts "usage: fatgem GEM1 GEM2 ..."
154
+ exit
155
+ end
156
+
157
+ begin
158
+ FatGem.tmp do |fat|
159
+ ARGV.each do |path|
160
+ version = path[/ruby(\d.\d)/, 1]
161
+ fat.add_gem(path, version)
162
+ end
163
+
164
+ path = fat.finalize
165
+ FileUtils.cp(path, File.basename(path))
166
+ end
167
+ rescue FatGem::Error => e
168
+ puts "ERROR: #{e.message}"
169
+ exit 1
170
+ end
171
+
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fatgem
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Magnus Holm
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-01-18 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email: judofyr@gmail.com
15
+ executables:
16
+ - fatgem
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - bin/fatgem
21
+ homepage: https://github.com/judofyr/fatgem
22
+ licenses:
23
+ - MIT
24
+ metadata: {}
25
+ post_install_message:
26
+ rdoc_options: []
27
+ require_paths:
28
+ - lib
29
+ required_ruby_version: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.9.3
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ requirements: []
40
+ rubyforge_project:
41
+ rubygems_version: 2.4.5.1
42
+ signing_key:
43
+ specification_version: 4
44
+ summary: Combine gems for multiple Ruby versions
45
+ test_files: []