gem-dependencies 0.2.4 → 0.3.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/README.md +53 -26
- data/gem-dependencies.gemspec +1 -1
- data/lib/rubygems/gem_dependencies.rb +32 -13
- data.tar.gz.sig +0 -0
- metadata +4 -4
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ae07b23b2801b2e63733fa1a73f82299a6af6e21
|
4
|
+
data.tar.gz: 4a702611f1812fdd358d6125eac64db223dcb0a4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f2baad6f32b9ccbe869adc28d73dd8bf28a959c290bc96017eb589884446c8840df51d0e78fc6cf08c3411a2db7111bb3bbd93977ce89d069bdfb560fb70cffe
|
7
|
+
data.tar.gz: 0d36fe6bd2ce0373d246b2808ed536171fc2ab2fe45d68736f4dda0ecbbe5dd77377a37dfea0defa25c52e4d9b487da9832a63e7e9fb231b1f1eaa365dcf3c65
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/README.md
CHANGED
@@ -1,46 +1,70 @@
|
|
1
1
|
# gem-dependencies
|
2
2
|
|
3
|
-
A RubyGems plugin
|
3
|
+
A RubyGems plugin that simplifies working with gems that have binary extensions. It does this through the use of a succinct dependency index file. For development systems, this file specifies build dependencies and arguments necessary to compile and create a tarball with a gem's binary extensions. For runtime systems, which are lightweight and might not have access to a compiler, the dependency index file provides a list of runtime dependencies that must first be installed and also specifies the tarball which contains the pre-built binary extension files.
|
4
|
+
|
5
|
+
Think of ```gem-dependencies``` as a helper that allows lightweight machines, such as docker containers, to be able to use native rubygems without having a compiler installed. At the moment that ```gem install``` would normally try to compile a binary extension, ```gem-dependencies``` will lookup the gem in it's dependency index and, if a matching version is found, install any required runtime packages and then download and extract any pre-compiled binary extensions. Everything works seamlessly and efficiently.
|
4
6
|
|
5
7
|
## Usage
|
6
8
|
|
7
9
|
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
10
|
|
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
11
|
## Dependency index
|
20
12
|
|
21
|
-
The dependency index is a YAML file that contains information necessary to
|
13
|
+
The dependency index is a YAML file that contains information necessary to compile gems on a development system or install them on a runtime system. An example dependency file looks like:
|
22
14
|
|
23
15
|
```yaml
|
24
16
|
gems:
|
25
17
|
"*":
|
26
|
-
command:
|
18
|
+
command: apk --update add ${packages}
|
27
19
|
bcrypt:
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
20
|
+
mysql2: "* mariadb-libs"
|
21
|
+
nokogiri: "* libxml2 libxslt +libxml2-dev +libxslt -- --use-system-libraries"
|
22
|
+
pokogiri:
|
23
|
+
- "*"
|
24
|
+
- libxml2
|
25
|
+
- libxslt
|
26
|
+
- +libxml2-dev
|
27
|
+
- +libxslt
|
28
|
+
- --
|
29
|
+
- --use-system-libraries
|
30
|
+
unf_ext:
|
31
|
+
"~> 0.0.7.1": "* libstdc++"
|
32
|
+
">= 0.0.4, < 0.0.7": "*/old-gems/* libstdc++"
|
33
|
+
"< 0.0.4": "s3://foo:bar@s3.amazon.com/baz/* one two three"
|
34
|
+
```
|
35
|
+
|
36
|
+
The format of this file is quite flexible. Keys in the above hash represent gems that have binary extensions. The hash values can be:
|
37
|
+
|
38
|
+
* ```nil``` (like ```bcrypt``` above)
|
39
|
+
* ```String``` (like ```mysql``` above)
|
40
|
+
* ```Array``` (like ```pokogiri``` above)
|
41
|
+
* ```Hash``` (like ```unf_ext``` above)
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
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. As an additional help, all urls that begin with ```https://github.com/``` will be automatically suffixed with ```?raw=true```.
|
46
|
+
|
47
|
+
There are several naming shortcuts that can be used for extension tarballs. In the common case, when there is one tarball with binary extensions for a gem and no package dependencies, you can simply leave the hash value empty (as shown in the case of ```bcrypt``` above). This will cause ```gem-dependencies``` to download and extract a file named ```bcrypt-3.1.10.tar.gz``` (or whatever gem name and version you are installing) from the base path of the ```GEM_DEPENDENCIES``` environment variable. If, as in the case of ```mysql2``` above, you do have some platform dependencies, then use the ```*``` to indicate the 'default' extension tarball and then list the package dependencies. If a ```*``` character is found anywhere else, it will be interpreted as the value ```{gemname}-{version}.tar.gz```. You can combine wildcards such as the case of ```nokogiri``` above, where ```*/old-gems/*``` will give ```https://github.com/shreeve/gemdeps-alpine-3.2-x86_64-2.2.0/blob/master/old-gems/nokogiri-1.4.4.tar.gz```. These shortcuts are much easier to type and they will dynamically use the proper gem versions.
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
## Development system
|
53
|
+
|
54
|
+
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:
|
55
|
+
|
56
|
+
```shell
|
57
|
+
$ GEM_DEPENDENCIES=1 gem install bcrypt
|
34
58
|
```
|
35
59
|
|
36
|
-
|
60
|
+
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```).
|
37
61
|
|
38
62
|
## Runtime system
|
39
63
|
|
40
64
|
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:
|
41
65
|
|
42
66
|
```shell
|
43
|
-
export GEM_DEPENDENCIES="https://github.com/shreeve/
|
67
|
+
export GEM_DEPENDENCIES="https://github.com/shreeve/gemdeps-alpine-3.2-x86_64-2.2.0/blob/master/INDEX.yaml"
|
44
68
|
gem install bcrypt
|
45
69
|
```
|
46
70
|
|
@@ -54,7 +78,10 @@ The dependency index will be downloaded and searched for the requested gem and v
|
|
54
78
|
Note that a version requirement can also be specified in the ```gem install``` command. For example, the following are all valid:
|
55
79
|
|
56
80
|
```shell
|
57
|
-
|
81
|
+
gem install bcrypt
|
82
|
+
gem install bcrypt:3.1.4
|
83
|
+
gem install "bcrypt:~>3.1.8"
|
84
|
+
gem install "bcrypt > 3.1.4, ~> 3.2, < 3.8"
|
58
85
|
```
|
59
86
|
|
60
87
|
Using this approach, a runtime system can quickly and efficiently install dependencies and extensions without the need to compile them locally.
|
@@ -69,11 +96,11 @@ alias bundle='RUBYOPT="-rrubygems/gem_dependencies" bundle'
|
|
69
96
|
|
70
97
|
## Todos
|
71
98
|
|
72
|
-
* Allow both compiler and runtime package dependencies in the dependency index file
|
73
|
-
* Allow the use of flags (such as ```--use-system-libraries```) for packages
|
74
|
-
* Make sure everything works seamlessly with ```bundler```
|
75
|
-
* Document the various formats supported in the dependency index file
|
76
99
|
* Document how to create a platform repository (e.g. on GitHub)
|
100
|
+
* ~~Allow both compiler and runtime package dependencies in the dependency index file~~
|
101
|
+
* ~~Allow the use of flags (such as ```--use-system-libraries```) for packages~~
|
102
|
+
* ~~Document the various formats supported in the dependency index file~~
|
103
|
+
* ~~Make sure everything works seamlessly with ```bundler```~~
|
77
104
|
|
78
105
|
## License
|
79
106
|
|
data/gem-dependencies.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "gem-dependencies"
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.3.0.rc1"
|
6
6
|
s.summary = "RubyGems plugin to simplify installing binary gems on runtime systems."
|
7
7
|
s.description = "This gem makes it easy to install binary gems on systems without a compiler."
|
8
8
|
s.homepage = "https://github.com/shreeve/gem-dependencies"
|
@@ -21,27 +21,35 @@ module Gem
|
|
21
21
|
module Dependencies
|
22
22
|
require 'rubygems/user_interaction'
|
23
23
|
include Gem::UserInteraction
|
24
|
-
|
24
|
+
|
25
|
+
REGEXP_SCHEMA = %r|\A[a-z][a-z\d]{1,5}://|i
|
26
|
+
REGEXP_DEVPKG = %r|^\+|
|
27
|
+
REGEXP_DEVARG = %r|^(?=-)|
|
25
28
|
|
26
29
|
def build_extensions
|
27
|
-
if
|
28
|
-
|
29
|
-
path = "#{spec.full_name}.tar.gz"
|
30
|
-
File.binwrite(path, gzip(tar(spec.extension_dir)))
|
31
|
-
say "Extensions packaged as #{path}"
|
32
|
-
elsif deps = find_dependencies(env)
|
33
|
-
pkgs, exts = deps
|
30
|
+
if deps = find_dependencies(ENV["GEM_DEPENDENCIES"])
|
31
|
+
pkgs, exts, args = deps
|
34
32
|
install_os_packages(*pkgs) if pkgs.any?
|
33
|
+
if args
|
34
|
+
@build_args.concat(args)
|
35
|
+
super
|
36
|
+
path = "#{spec.full_name}.tar.gz"
|
37
|
+
File.binwrite(path, gzip(tar(spec.extension_dir)))
|
38
|
+
say "Extensions packaged as #{path}"
|
39
|
+
end
|
35
40
|
copy_gem_extensions(*exts) if exts.any?
|
36
41
|
end
|
37
42
|
true
|
38
43
|
end
|
39
44
|
|
40
|
-
# return a gem's packages and
|
45
|
+
# return a gem's packages, extensions, and arguments
|
41
46
|
def find_dependencies(env)
|
47
|
+
args = [] if (env = env.dup).sub!(REGEXP_DEVPKG,'') # are we in compile mode?
|
48
|
+
return [[], [], args] if args && env.empty?
|
49
|
+
|
42
50
|
require 'rubygems/remote_fetcher'
|
43
51
|
@@deps = YAML.load(fetch(env))['gems'] unless defined?(@@deps)
|
44
|
-
@@deps.key?(spec.name) or return
|
52
|
+
@@deps.key?(spec.name) or return(args ? [[], [], args] : nil)
|
45
53
|
|
46
54
|
# find dependencies
|
47
55
|
case deps = @@deps[spec.name]
|
@@ -63,8 +71,19 @@ module Gem
|
|
63
71
|
benv = File.dirname(env.split(/[?;#]/,2).first)
|
64
72
|
name = "#{spec.full_name}.tar.gz"
|
65
73
|
|
66
|
-
#
|
67
|
-
|
74
|
+
# grok dependencies
|
75
|
+
pkgs, exts = [], []
|
76
|
+
deps.each do |item|
|
77
|
+
if item.include?("*") || item =~ REGEXP_SCHEMA || item.include?(".tar.gz")
|
78
|
+
exts << item unless args
|
79
|
+
elsif item =~ REGEXP_DEVPKG
|
80
|
+
pkgs << $' if args
|
81
|
+
elsif item =~ REGEXP_DEVARG
|
82
|
+
args << $' if args
|
83
|
+
else
|
84
|
+
pkgs << item unless args
|
85
|
+
end
|
86
|
+
end
|
68
87
|
exts.map! do |item|
|
69
88
|
case item
|
70
89
|
when "*" then item = File.join(benv, name) # use complete default tarball name
|
@@ -73,7 +92,7 @@ module Gem
|
|
73
92
|
end
|
74
93
|
item.gsub("*", name) # swap inline wildcards with default tarball name
|
75
94
|
end
|
76
|
-
[pkgs, exts]
|
95
|
+
[pkgs, exts, args]
|
77
96
|
end
|
78
97
|
|
79
98
|
def install_os_packages(*args)
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gem-dependencies
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steve Shreeve
|
@@ -30,7 +30,7 @@ cert_chain:
|
|
30
30
|
4PkbTeqnzZJmSZjUBwvnQFNhXY08hPUs7aASHu9deACBbOBY+Hg6tiSOdfw50uYS
|
31
31
|
ksjokeQosImFuxgjMrlyoRcpbZmyfQ33yImqtLH6FMWF3hpoxJq9wPk=
|
32
32
|
-----END CERTIFICATE-----
|
33
|
-
date: 2015-06-
|
33
|
+
date: 2015-06-17 00:00:00.000000000 Z
|
34
34
|
dependencies: []
|
35
35
|
description: This gem makes it easy to install binary gems on systems without a compiler.
|
36
36
|
email: steve.shreeve@gmail.com
|
@@ -59,9 +59,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
59
59
|
version: '0'
|
60
60
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
61
|
requirements:
|
62
|
-
- - "
|
62
|
+
- - ">"
|
63
63
|
- !ruby/object:Gem::Version
|
64
|
-
version:
|
64
|
+
version: 1.3.1
|
65
65
|
requirements: []
|
66
66
|
rubyforge_project:
|
67
67
|
rubygems_version: 2.4.7
|
metadata.gz.sig
CHANGED
Binary file
|