gem-dependencies 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 339fb3eb77cc83c5a1c9acfcd13608f76a78fda5
4
+ data.tar.gz: 0cfe64435be447d265dd7a9a2bc7f3d08098d2df
5
+ SHA512:
6
+ metadata.gz: f4d8a34ec0b2bee8c6a97cdc373b228b7b22d8333b8cc67ff39b60a67bc0e8c6a75713a946220c4dc257b663be0a3a0077eea9166fa19d1217176bb98f497900
7
+ data.tar.gz: bd60113473d8b779bf5bd49b6e43028036e914894e79c334ef686d6da10c5c42872a1c2f988574a18056ded372f07f5aa595ae8e581a422c3aacf46611e137a9
checksums.yaml.gz.sig ADDED
Binary file
data.tar.gz.sig ADDED
@@ -0,0 +1 @@
1
+ (���h!A� F�63�����ט0���0?S��o{�C�L�Ku�҃m���3ae I��K*{HXW��bL�}f#�-�@�x��V���#]{�H�
data/MIT ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2015 Steve Shreeve <steve.shreeve@gmail.com>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,77 @@
1
+ # gem-dependencies
2
+
3
+ A RubyGems plugin to simplify installing binary gems on runtime systems. Runtime system are usually lightweight and might not even have a compiler. This is accomplished by using a development machine to determine these dependencies and to create tarballs of compiled extensions. Through the use of a dependency index file, these dependencies and extensions can be clearly specified and shared.
4
+
5
+ ## Usage
6
+
7
+ You don't need to do anything special, just use ```gem install``` as normal. The resulting behavior is controlled by the value of the ```GEM_DEPENDENCIES``` environment variable. If this environment variable is not set, then this gem has no effect and is simply ignored.
8
+
9
+ ## Development system
10
+
11
+ Make sure you have a development system with the same architecture as your runtime system. On the development system, make a note of all of the package dependencies needed to install the desired gem. Finally, run:
12
+
13
+ ```shell
14
+ $ GEM_DEPENDENCIES=1 gem install bcrypt
15
+ ```
16
+
17
+ This will perform a normal install, but it will also create a tarball in the current directory with the compiled extensions for the given gem. The naming scheme is straightforward and based on the gem's name and version (e.g. ```bcrypt-3.1.10.tar.gz```).
18
+
19
+ ## Dependency index
20
+
21
+ The dependency index is a YAML file that contains information necessary to install gems on the runtime system. An example dependency file looks like:
22
+
23
+ ```yaml
24
+ gems:
25
+ "*":
26
+ command: sudo apk --update add ${packages}
27
+ bcrypt:
28
+ "~> 2.0, <= 3.1":
29
+ - bcrypt-2.1
30
+ - libxml2-3.4
31
+ - libyagni-1.0c
32
+ "~> 3.1.5": "bcrypt-3.1.10.tar.gz tree"
33
+ nokogiri:
34
+ "~> 2.0, <= 3.1":
35
+ - bcrypt-2.1
36
+ - libxml2-3.4
37
+ - libyagni-1.0c
38
+ "~> 3.1.5": "s3://one:two@s3.amazon.com/three/bcrypt-3.1.10.tar.gz tree"
39
+ ```
40
+
41
+ After determining the runtime dependencies and creating a compiled extensions tarball, edit the dependency index to add a key with the name of the new gem and sub-keys to indicate the version requirements. The values of these sub-key are either an array of package dependencies and extension tarballs or a space-delimited string of the same. All items ending in ```.tar.gz``` are considered to be extension tarballs and everything else is considered to be a package dependency. Extension tarballs can also be given as a file system path or an http, https, git, or s3 url.
42
+
43
+ ## Runtime system
44
+
45
+ If ```GEM_DEPENDENCIES``` is set to a file system path or an http, https, git, or s3 url, then this value will be used to fetch the dependency index. Suppose the following command is run from the runtime system:
46
+
47
+ ```shell
48
+ export GEM_DEPENDENCIES="https://dist.foo.com/gemdeps/alpine-3.2-x86_64/index.yaml"
49
+ gem install bcrypt
50
+ ```
51
+
52
+ The dependency index will be downloaded and searched for the requested gem and version. If a match is found, then the order of installation is as follows:
53
+
54
+ * package dependencies will be installed (uses the value from the ```command``` key),
55
+ * the 'normal' gem files will be installed
56
+ * the 'normal' build_extensions step will be skipped, and
57
+ * compiled extension tarballs will be downloaded and installed
58
+
59
+ Note that a version requirement can also be specified in the ```gem install``` command. For example, the following are all valid:
60
+
61
+ ```shell
62
+ bcrypt, bcrypt:3.1.4, "bcrypt:~>3.1.8", "bcrypt > 3.1.4, ~3.2, < 3.8"
63
+ ```
64
+
65
+ Using this approach, a runtime system can quickly and efficiently install dependencies and extensions without the need to compile them locally.
66
+
67
+ ## Using bundler
68
+
69
+ To make bundler to use this gem as well, you need to load the rubygems_plugin before. The easiest way is to make an alias in your `~/.bashrc`, such as:
70
+
71
+ ```
72
+ alias bundle='RUBYOPT="-rrubygems/gem_dependencies" bundle'
73
+ ```
74
+
75
+ ## License
76
+
77
+ This software is licensed under terms of the MIT License.
data/certs/shreeve.pem ADDED
@@ -0,0 +1,21 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDhTCCAm2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMRYwFAYDVQQDDA1zdGV2
3
+ ZS5zaHJlZXZlMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZ
4
+ FgNjb20wHhcNMTUwNjEyMDMyMjM4WhcNMTYwNjExMDMyMjM4WjBEMRYwFAYDVQQD
5
+ DA1zdGV2ZS5zaHJlZXZlMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJ
6
+ k/IsZAEZFgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCoT0lD
7
+ XoRFhnjFAtJ79NonyJxzMwq2s4TSnqrY25ElM2NoTcboCJ3eTgoeV/F1WSxGfEHs
8
+ xM00/ok/fMqFAZMIA8eV5+aaWze2q6/vE+/u+EI1dI9bogtGxu3FFuYUpVy5wha9
9
+ 87U4HXPwXUbKS7bGQuTeJ07jO2okGCufbb+HNXABf+EEZCLk5fH9j1TGgu8fxq/X
10
+ vmVRKF/YpFEFM5TVv0dOO17vU/wOyBynjQ33AW8NHily163YjgIZR7mE042Hh9+G
11
+ w3Uq4L5ytgSoVDIs+owm5NLt0G13EjmsZUBszVErJ+byg62VjiAjSL4DQJSrlCsU
12
+ UuTSvTtx7Ez1nvKtAgMBAAGjgYEwfzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAd
13
+ BgNVHQ4EFgQU41cP4dVdL49Hzswd3/gCzX3+z3swIgYDVR0RBBswGYEXc3RldmUu
14
+ c2hyZWV2ZUBnbWFpbC5jb20wIgYDVR0SBBswGYEXc3RldmUuc2hyZWV2ZUBnbWFp
15
+ bC5jb20wDQYJKoZIhvcNAQEFBQADggEBAIaDzT/cGpJJT9eyhovk1ScwTA1jocDR
16
+ bIs/mNbQN6XlkipOtxCcx9XvVuwEZtP8/UeX+SKBHAtTnFf4Dez7vjSQAaVLZQe7
17
+ uXuX+S4LFTTf0oFVznQaMQ7PbqKqCmtof+1MqNpDTPTayxrlNUTPl3SpkW6bv4qi
18
+ hWz+RgGCWYc9TQ+JigLPbsfJpok31sHXrCztMb/KMbTozGTGswljbpuSq7Lzs9rp
19
+ 4PkbTeqnzZJmSZjUBwvnQFNhXY08hPUs7aASHu9deACBbOBY+Hg6tiSOdfw50uYS
20
+ ksjokeQosImFuxgjMrlyoRcpbZmyfQ33yImqtLH6FMWF3hpoxJq9wPk=
21
+ -----END CERTIFICATE-----
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "gem-dependencies"
5
+ s.version = "0.1.3"
6
+ s.summary = "RubyGems plugin to simplify installing binary gems on runtime systems."
7
+ s.description = "This gem makes it easy to install binary gems on machines without a compiler."
8
+ s.homepage = "https://github.com/shreeve/gem-dependencies"
9
+ s.authors = ["Steve Shreeve"]
10
+ s.email = "steve.shreeve@gmail.com"
11
+ s.license = "MIT"
12
+ s.files = `git ls-files`.split("\n") - %w[.gitignore]
13
+ s.cert_chain = ["certs/shreeve.pem"]
14
+ s.signing_key = File.expand_path("~/.ssh/gem-private_key.pem") if $0 =~ /gem\z/
15
+ end
@@ -0,0 +1,142 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # =============================================================================
4
+ # gem_dependencies.rb: Simplifies installing binary gems on runtime systems
5
+ #
6
+ # Author: Steve Shreeve <steve.shreeve@gmail.com>
7
+ # Date: June 11, 2015
8
+ # Legal: MIT License
9
+ # =============================================================================
10
+
11
+ require "yaml"
12
+
13
+ module Gem
14
+ if ENV["GEM_DEPENDENCIES"]
15
+ pre_install do |gem|
16
+ if gem.spec.extensions.any?
17
+ gem.extend Gem::Installer::Dependencies
18
+ end
19
+ end
20
+ end
21
+
22
+ class Installer
23
+ module Dependencies
24
+ require 'rubygems/user_interaction'
25
+ include Gem::UserInteraction
26
+ REGEXP_SCHEMA = %r|\A[a-z][a-z\d]{1,5}://|io
27
+
28
+ def build_extensions
29
+ if (env = ENV["GEM_DEPENDENCIES"]) == "1"
30
+ super
31
+ path = "#{spec.full_name}.tar.gz"
32
+ File.binwrite(path, gzip(tar(spec.extension_dir)))
33
+ say "Extensions packaged as #{path}"
34
+ elsif deps = find_dependencies(env)
35
+ pkgs, exts = deps
36
+ install_os_packages(*pkgs) if pkgs.any?
37
+ copy_gem_extensions(*exts) if exts.any?
38
+ end
39
+ true
40
+ end
41
+
42
+ # locate a match and return [pkgs, exts]
43
+ def find_dependencies(env)
44
+ require 'rubygems/remote_fetcher'
45
+ @@deps = YAML.load(fetch(env))['gems'] unless defined?(@@deps)
46
+
47
+ case deps = @@deps[spec.name]
48
+ when String
49
+ when Array
50
+ when Hash
51
+ reqs, deps = deps.find do |reqs, info|
52
+ Gem::Requirement.new(reqs.split(',')).satisfied_by?(spec.version)
53
+ end
54
+ end
55
+ deps or return
56
+ deps = deps.strip.split(/\s+/) if deps.is_a?(String)
57
+ deps.compact.uniq.partition {|item| item =~ REGEXP_SCHEMA || item.end_with?(".tar.gz")}.reverse
58
+ end
59
+
60
+ def install_os_packages(*args)
61
+ args.each do |item|
62
+ say "* Installing '#{item}' dependency"
63
+ end
64
+ cmds = @@deps["*"]["command"].strip.split(/\s+/).flat_map {|item| item == '${packages}' ? args : item}
65
+ Gem::Util.silent_system(*cmds)
66
+ true # success/error?
67
+ end
68
+
69
+ def copy_gem_extensions(*args)
70
+ require 'rubygems/remote_fetcher'
71
+
72
+ root = spec.extension_dir
73
+ args.each do |item|
74
+ say "* Extracting '#{item}' to '#{root}'"
75
+ untar(gunzip(fetch(item)), root)
76
+ end
77
+ true # success/error?
78
+ end
79
+
80
+ def fetch(item)
81
+ tool = Gem::RemoteFetcher.fetcher
82
+ item =~ REGEXP_SCHEMA ? tool.fetch_path(item) : File.binread(item)
83
+ end
84
+
85
+ # The tar/gz code below is based on MIT licensed code by Colin MacKenzie IV
86
+
87
+ def tar(dir, ext=nil)
88
+ path = File.expand_path(dir)
89
+ skip = path.size + 1
90
+ tar_io = StringIO.new
91
+ Gem::Package::TarWriter.new(tar_io) do |tar|
92
+ Dir[File.join(path, "**/*#{'.' + ext if ext}")].each do |file|
93
+ stat = File.stat(file)
94
+ name = file[skip..-1]
95
+ if stat.file?
96
+ tar.add_file_simple(name, stat.mode, stat.size) do |tf|
97
+ tf.write(File.binread(file))
98
+ end
99
+ elsif stat.directory?
100
+ tar.mkdir(name, mode)
101
+ end
102
+ end
103
+ end
104
+ tar_io.string
105
+ end
106
+
107
+ def gzip(str)
108
+ gz_io = StringIO.new
109
+ z = Zlib::GzipWriter.new(gz_io)
110
+ z.write(str)
111
+ z.close
112
+ gz_io.string
113
+ end
114
+
115
+ def gunzip(str)
116
+ gz_io = StringIO.new(str)
117
+ z = Zlib::GzipReader.new(gz_io)
118
+ str = z.read
119
+ z.close
120
+ str
121
+ end
122
+
123
+ def untar(str, dir)
124
+ tar_io = StringIO.new(str)
125
+ root = File.expand_path(dir)
126
+ Gem::Package::TarReader.new(tar_io) do |tar|
127
+ tar.each do |file|
128
+ path = File.join(root, file.full_name)
129
+ mode = file.header.mode
130
+ if file.directory?
131
+ FileUtils.mkdir_p(path, mode)
132
+ else
133
+ FileUtils.mkdir_p(File.dirname(path))
134
+ File.binwrite(path, file.read)
135
+ FileUtils.chmod(mode, path)
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1 @@
1
+ require "rubygems/gem_dependencies"
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gem-dependencies
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.3
5
+ platform: ruby
6
+ authors:
7
+ - Steve Shreeve
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIDhTCCAm2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMRYwFAYDVQQDDA1zdGV2
14
+ ZS5zaHJlZXZlMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZ
15
+ FgNjb20wHhcNMTUwNjEyMDMyMjM4WhcNMTYwNjExMDMyMjM4WjBEMRYwFAYDVQQD
16
+ DA1zdGV2ZS5zaHJlZXZlMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJ
17
+ k/IsZAEZFgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCoT0lD
18
+ XoRFhnjFAtJ79NonyJxzMwq2s4TSnqrY25ElM2NoTcboCJ3eTgoeV/F1WSxGfEHs
19
+ xM00/ok/fMqFAZMIA8eV5+aaWze2q6/vE+/u+EI1dI9bogtGxu3FFuYUpVy5wha9
20
+ 87U4HXPwXUbKS7bGQuTeJ07jO2okGCufbb+HNXABf+EEZCLk5fH9j1TGgu8fxq/X
21
+ vmVRKF/YpFEFM5TVv0dOO17vU/wOyBynjQ33AW8NHily163YjgIZR7mE042Hh9+G
22
+ w3Uq4L5ytgSoVDIs+owm5NLt0G13EjmsZUBszVErJ+byg62VjiAjSL4DQJSrlCsU
23
+ UuTSvTtx7Ez1nvKtAgMBAAGjgYEwfzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAd
24
+ BgNVHQ4EFgQU41cP4dVdL49Hzswd3/gCzX3+z3swIgYDVR0RBBswGYEXc3RldmUu
25
+ c2hyZWV2ZUBnbWFpbC5jb20wIgYDVR0SBBswGYEXc3RldmUuc2hyZWV2ZUBnbWFp
26
+ bC5jb20wDQYJKoZIhvcNAQEFBQADggEBAIaDzT/cGpJJT9eyhovk1ScwTA1jocDR
27
+ bIs/mNbQN6XlkipOtxCcx9XvVuwEZtP8/UeX+SKBHAtTnFf4Dez7vjSQAaVLZQe7
28
+ uXuX+S4LFTTf0oFVznQaMQ7PbqKqCmtof+1MqNpDTPTayxrlNUTPl3SpkW6bv4qi
29
+ hWz+RgGCWYc9TQ+JigLPbsfJpok31sHXrCztMb/KMbTozGTGswljbpuSq7Lzs9rp
30
+ 4PkbTeqnzZJmSZjUBwvnQFNhXY08hPUs7aASHu9deACBbOBY+Hg6tiSOdfw50uYS
31
+ ksjokeQosImFuxgjMrlyoRcpbZmyfQ33yImqtLH6FMWF3hpoxJq9wPk=
32
+ -----END CERTIFICATE-----
33
+ date: 2015-06-12 00:00:00.000000000 Z
34
+ dependencies: []
35
+ description: This gem makes it easy to install binary gems on machines without a compiler.
36
+ email: steve.shreeve@gmail.com
37
+ executables: []
38
+ extensions: []
39
+ extra_rdoc_files: []
40
+ files:
41
+ - MIT
42
+ - README.md
43
+ - certs/shreeve.pem
44
+ - gem-dependencies.gemspec
45
+ - lib/rubygems/gem_dependencies.rb
46
+ - lib/rubygems_plugin.rb
47
+ homepage: https://github.com/shreeve/gem-dependencies
48
+ licenses:
49
+ - MIT
50
+ metadata: {}
51
+ post_install_message:
52
+ rdoc_options: []
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ requirements: []
66
+ rubyforge_project:
67
+ rubygems_version: 2.4.7
68
+ signing_key:
69
+ specification_version: 4
70
+ summary: RubyGems plugin to simplify installing binary gems on runtime systems.
71
+ test_files: []
metadata.gz.sig ADDED
@@ -0,0 +1,3 @@
1
+ �����O !�=�#�x����Ӧ
2
+ �Vs-Z��ގz
3
+ kS��H��%�\o�v�B�d�,S�g]a�\�����o����J