bundix 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/bundix +44 -0
- data/lib/bundix/source.rb +114 -0
- data/lib/bundix.rb +109 -0
- metadata +47 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 463a40e4d1cb3c3f2d3734509fb2c5f71bdbaa1b
|
|
4
|
+
data.tar.gz: 1d38eaad6a27ac93279500dd86ce21477bb73259
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: a2ff4f560cc61af3f388b10677bc660a678b4f12174916e47ed9de050dd2115758e4dcb70bc6f05fd0c33c7a7616de2b14c8eff32677369b7920b108f88a8830
|
|
7
|
+
data.tar.gz: 3eb1c4652f577833e51cc1682a283fb2484d19b6066eb1f9a2a78e84d6514c3f7a85632529982bde640e39d2ae616fbd4b3d23f90e7386270fcd6afbcc8a9797
|
data/bin/bundix
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'optparse'
|
|
4
|
+
|
|
5
|
+
require_relative '../lib/bundix'
|
|
6
|
+
|
|
7
|
+
options = {}
|
|
8
|
+
|
|
9
|
+
op = OptionParser.new do |o|
|
|
10
|
+
o.on '--gemset=gemset.nix', 'path to the gemset.nix' do |value|
|
|
11
|
+
options[:gemset] = File.expand_path(value)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
o.on '--lockfile=Gemfile.lock', 'path to the Gemfile.lock' do |value|
|
|
15
|
+
options[:lockfile] = File.expand_path(value)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
o.on '-d', '--dependencies', 'include gem dependencies' do
|
|
19
|
+
options[:deps] = true
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
o.on '-q', '--quiet', 'only output errors' do
|
|
23
|
+
options[:quiet] = true
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
o.on '-v', '--version', 'show the version of bundix' do
|
|
27
|
+
puts Bundix::VERSION
|
|
28
|
+
exit
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
op.parse!
|
|
33
|
+
$VERBOSE = !options[:quiet]
|
|
34
|
+
gemset = Bundix.new(options).convert
|
|
35
|
+
|
|
36
|
+
tempfile = Tempfile.new('gemset.nix', encoding: 'UTF-8')
|
|
37
|
+
begin
|
|
38
|
+
Bundix.object2nix(gemset, 2, tempfile)
|
|
39
|
+
tempfile.close
|
|
40
|
+
FileUtils.cp(tempfile.path, options[:gemset])
|
|
41
|
+
ensure
|
|
42
|
+
tempfile.close!
|
|
43
|
+
tempfile.unlink
|
|
44
|
+
end
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
class Bundix
|
|
2
|
+
class Source < Struct.new(:spec)
|
|
3
|
+
def convert
|
|
4
|
+
case spec.source
|
|
5
|
+
when Bundler::Source::Rubygems
|
|
6
|
+
convert_rubygems
|
|
7
|
+
when Bundler::Source::Git
|
|
8
|
+
convert_git
|
|
9
|
+
else
|
|
10
|
+
pp spec
|
|
11
|
+
fail 'unkown bundler source'
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def sh(*args)
|
|
16
|
+
Bundix.sh(*args)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def nix_prefetch_url(*args)
|
|
20
|
+
sh(NIX_PREFETCH_URL, '--type', 'sha256', *args)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def nix_prefetch_git(uri, revision)
|
|
24
|
+
home = ENV['HOME']
|
|
25
|
+
ENV['HOME'] = '/homeless-shelter'
|
|
26
|
+
sh(NIX_PREFETCH_GIT, '--url', uri, '--rev', revision, '--hash', 'sha256', '--leave-dotGit')
|
|
27
|
+
ensure
|
|
28
|
+
ENV['HOME'] = home
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def fetch_local_hash(spec)
|
|
32
|
+
spec.source.caches.each do |cache|
|
|
33
|
+
path = File.join(cache, "#{spec.name}-#{spec.version}.gem")
|
|
34
|
+
next unless File.file?(path)
|
|
35
|
+
begin
|
|
36
|
+
return nix_prefetch_url("file://#{path}")[SHA256_32]
|
|
37
|
+
rescue
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
nil
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def fetch_remotes_hash(spec, remotes)
|
|
45
|
+
remotes.each do |remote|
|
|
46
|
+
begin
|
|
47
|
+
return fetch_remote_hash(spec, remote)
|
|
48
|
+
rescue
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
nil
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def fetch_remote_hash(spec, remote)
|
|
56
|
+
hash = nil
|
|
57
|
+
|
|
58
|
+
if URI(remote).host == 'rubygems.org'
|
|
59
|
+
uri = "#{remote}/api/v1/versions/#{spec.name}.json"
|
|
60
|
+
puts "Getting SHA256 from: #{uri}" if $VERBOSE
|
|
61
|
+
open uri do |io|
|
|
62
|
+
versions = JSON.parse(io.read)
|
|
63
|
+
if found_version = versions.find{|obj| obj['number'] == spec.version.to_s }
|
|
64
|
+
hash = found_version['sha']
|
|
65
|
+
break
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
uri = "#{remote}/gems/#{spec.name}-#{spec.version}.gem"
|
|
71
|
+
|
|
72
|
+
if hash
|
|
73
|
+
begin
|
|
74
|
+
nix_prefetch_url(uri, hash)[SHA256_16]
|
|
75
|
+
rescue
|
|
76
|
+
nix_prefetch_url(uri)[SHA256_32]
|
|
77
|
+
end
|
|
78
|
+
else
|
|
79
|
+
nix_prefetch_url(uri)[SHA256_32]
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def convert_rubygems
|
|
84
|
+
remotes = spec.source.remotes.map{|remote| remote.to_s.sub(/\/+$/, '') }
|
|
85
|
+
hash = fetch_local_hash(spec) || fetch_remotes_hash(spec, remotes)
|
|
86
|
+
hash = sh(NIX_HASH, '--type', 'sha256', '--to-base32', hash)[SHA256_32]
|
|
87
|
+
fail "couldn't fetch hash for #{spec.name}-#{spec.version}" unless hash
|
|
88
|
+
puts "#{hash} => #{spec.name}-#{spec.version}.gem" if $VERBOSE
|
|
89
|
+
|
|
90
|
+
{
|
|
91
|
+
type: 'gem',
|
|
92
|
+
remotes: remotes,
|
|
93
|
+
sha256: hash
|
|
94
|
+
}
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def convert_git
|
|
98
|
+
revision = spec.source.options.fetch('revision')
|
|
99
|
+
uri = spec.source.options.fetch('uri')
|
|
100
|
+
hash = nix_prefetch_git(uri, revision)[/^\h{64}$/m]
|
|
101
|
+
hash = sh(NIX_HASH, '--type', 'sha256', '--to-base32', hash)[SHA256_32]
|
|
102
|
+
fail "couldn't fetch hash for #{spec.name}-#{spec.version}" unless hash
|
|
103
|
+
puts "#{hash} => #{uri}" if $VERBOSE
|
|
104
|
+
|
|
105
|
+
{
|
|
106
|
+
type: 'git',
|
|
107
|
+
url: uri.to_s,
|
|
108
|
+
rev: revision,
|
|
109
|
+
sha256: hash,
|
|
110
|
+
fetchSubmodules: false
|
|
111
|
+
}
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
data/lib/bundix.rb
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
require 'bundler'
|
|
2
|
+
require 'json'
|
|
3
|
+
require 'open-uri'
|
|
4
|
+
require 'open3'
|
|
5
|
+
require 'pp'
|
|
6
|
+
|
|
7
|
+
require_relative 'bundix/source'
|
|
8
|
+
|
|
9
|
+
class Bundix
|
|
10
|
+
VERSION = '2.0.0'
|
|
11
|
+
|
|
12
|
+
NIX_INSTANTIATE = 'nix-instantiate'
|
|
13
|
+
NIX_PREFETCH_URL = 'nix-prefetch-url'
|
|
14
|
+
NIX_PREFETCH_GIT = 'nix-prefetch-git'
|
|
15
|
+
NIX_HASH = 'nix-hash'
|
|
16
|
+
|
|
17
|
+
SHA256_32 = %r(^[a-z0-9]{52}$)
|
|
18
|
+
SHA256_16 = %r(^[a-f0-9]{64}$)
|
|
19
|
+
|
|
20
|
+
attr_reader :options
|
|
21
|
+
|
|
22
|
+
def initialize(options)
|
|
23
|
+
@options = {
|
|
24
|
+
gemset: './gemset.nix',
|
|
25
|
+
lockfile: './Gemfile.lock',
|
|
26
|
+
quiet: false,
|
|
27
|
+
tempfile: nil,
|
|
28
|
+
deps: false
|
|
29
|
+
}.merge(options)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def convert
|
|
33
|
+
cache = parse_gemset
|
|
34
|
+
lock = parse_lockfile
|
|
35
|
+
|
|
36
|
+
# reverse so git comes last
|
|
37
|
+
lock.specs.reverse_each.with_object({}) do |spec, gems|
|
|
38
|
+
name, cached = cache.find{|k, v|
|
|
39
|
+
k == spec.name &&
|
|
40
|
+
v['version'] == spec.version.to_s &&
|
|
41
|
+
v.dig('source', 'sha256').to_s.size == 52
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if cached
|
|
45
|
+
gems[name] = cached
|
|
46
|
+
next
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
gems[spec.name] = {
|
|
50
|
+
version: spec.version.to_s,
|
|
51
|
+
source: Source.new(spec).convert
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if options[:deps] && spec.dependencies.any?
|
|
55
|
+
gems[spec.name][:dependencies] = spec.dependencies.map(&:name) - ['bundler']
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def parse_gemset
|
|
61
|
+
return {} unless File.file?(options[:gemset])
|
|
62
|
+
json = Bundix.sh(
|
|
63
|
+
NIX_INSTANTIATE, '--eval', '-E', "builtins.toJSON(import #{options[:gemset]})")
|
|
64
|
+
JSON.parse(json.strip.gsub(/\\"/, '"')[1..-2])
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def parse_lockfile
|
|
68
|
+
Bundler::LockfileParser.new(File.read(options[:lockfile]))
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def self.object2nix(obj, level = 2, out = '')
|
|
72
|
+
case obj
|
|
73
|
+
when Hash
|
|
74
|
+
out << "{\n"
|
|
75
|
+
obj.each do |k, v|
|
|
76
|
+
out << ' ' * level
|
|
77
|
+
if k.to_s =~ /^[a-zA-Z_-]+[a-zA-Z0-9_-]*$/
|
|
78
|
+
out << k.to_s
|
|
79
|
+
else
|
|
80
|
+
object2nix(k, level + 2, out)
|
|
81
|
+
end
|
|
82
|
+
out << ' = '
|
|
83
|
+
object2nix(v, level + 2, out)
|
|
84
|
+
out << (v.is_a?(Hash) ? "\n" : ";\n")
|
|
85
|
+
end
|
|
86
|
+
out << (' ' * (level - 2)) << (level == 2 ? '}' : '};')
|
|
87
|
+
when Array
|
|
88
|
+
out << '[' << obj.map{|o| o.to_str.dump }.join(' ') << ']'
|
|
89
|
+
when String
|
|
90
|
+
out << obj.dump
|
|
91
|
+
when Symbol
|
|
92
|
+
out << obj.to_s.dump
|
|
93
|
+
when true, false
|
|
94
|
+
out << obj.to_s
|
|
95
|
+
else
|
|
96
|
+
fail obj.inspect
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def self.sh(*args)
|
|
101
|
+
out, status = Open3.capture2e(*args)
|
|
102
|
+
unless status.success?
|
|
103
|
+
puts "$ #{args.join(' ')}" if $VERBOSE
|
|
104
|
+
puts out if $VERBOSE
|
|
105
|
+
fail "command execution failed: #{status}"
|
|
106
|
+
end
|
|
107
|
+
out
|
|
108
|
+
end
|
|
109
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: bundix
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 2.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Michael 'manveru' Fellinger
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2016-01-27 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: Creates Nix packages from Gemfiles.
|
|
14
|
+
email:
|
|
15
|
+
executables:
|
|
16
|
+
- bundix
|
|
17
|
+
extensions: []
|
|
18
|
+
extra_rdoc_files: []
|
|
19
|
+
files:
|
|
20
|
+
- bin/bundix
|
|
21
|
+
- lib/bundix.rb
|
|
22
|
+
- lib/bundix/source.rb
|
|
23
|
+
homepage: https://github.com/manveru/bundix
|
|
24
|
+
licenses:
|
|
25
|
+
- MIT
|
|
26
|
+
metadata: {}
|
|
27
|
+
post_install_message:
|
|
28
|
+
rdoc_options: []
|
|
29
|
+
require_paths:
|
|
30
|
+
- lib
|
|
31
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
32
|
+
requirements:
|
|
33
|
+
- - ">="
|
|
34
|
+
- !ruby/object:Gem::Version
|
|
35
|
+
version: '0'
|
|
36
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
requirements: []
|
|
42
|
+
rubyforge_project:
|
|
43
|
+
rubygems_version: 2.5.1
|
|
44
|
+
signing_key:
|
|
45
|
+
specification_version: 4
|
|
46
|
+
summary: Creates Nix packages from Gemfiles.
|
|
47
|
+
test_files: []
|