Class: Bundix

Inherits:
Object
  • Object
show all
Defined in:
lib/bundix.rb,
lib/bundix/source.rb,
lib/bundix/version.rb

Defined Under Namespace

Classes: Source

Constant Summary collapse

NIX_INSTANTIATE =
'nix-instantiate'
NIX_PREFETCH_URL =
'nix-prefetch-url'
NIX_PREFETCH_GIT =
'nix-prefetch-git'
NIX_HASH =
'nix-hash'
SHA256_32 =
%r(^[a-z0-9]{52}$)
SHA256_16 =
%r(^[a-f0-9]{64}$)
VERSION =
'2.0.7'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ Bundix

Returns a new instance of Bundix.



21
22
23
24
25
26
27
28
29
# File 'lib/bundix.rb', line 21

def initialize(options)
  @options = {
    gemset: './gemset.nix',
    lockfile: './Gemfile.lock',
    quiet: false,
    tempfile: nil,
    deps: false
  }.merge(options)
end

Instance Attribute Details

#optionsObject (readonly)

Returns the value of attribute options.



19
20
21
# File 'lib/bundix.rb', line 19

def options
  @options
end

Class Method Details

.object2nix(obj, level = 2, out = '') ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/bundix.rb', line 85

def self.object2nix(obj, level = 2, out = '')
  case obj
  when Hash
    out << "{\n"
    obj.sort.each do |(k, v)|
      out << ' ' * level
      if k.to_s =~ /^[a-zA-Z_-]+[a-zA-Z0-9_-]*$/
        out << k.to_s
      else
        object2nix(k, level + 2, out)
      end
      out << ' = '
      object2nix(v, level + 2, out)
      out << (v.is_a?(Hash) ? "\n" : ";\n")
    end
    out << (' ' * (level - 2)) << (level == 2 ? '}' : '};')
  when Array
    out << '[' << obj.sort.map{|o| o.to_str.dump }.join(' ') << ']'
  when String
    out << obj.dump
  when Symbol
    out << obj.to_s.dump
  when true, false
    out << obj.to_s
  else
    fail obj.inspect
  end
end

.sh(*args) ⇒ Object



114
115
116
117
118
119
120
121
122
# File 'lib/bundix.rb', line 114

def self.sh(*args)
  out, status = Open3.capture2e(*args)
  unless status.success?
    puts "$ #{args.join(' ')}" if $VERBOSE
    puts out if $VERBOSE
    fail "command execution failed: #{status}"
  end
  out
end

Instance Method Details

#convertObject



31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/bundix.rb', line 31

def convert
  cache = parse_gemset
  lock = parse_lockfile

  # reverse so git comes last
  lock.specs.reverse_each.with_object({}) do |spec, gems|
    gem = find_cached_spec(spec, cache) || convert_spec(spec, cache)
    gems.merge!(gem)

    if options[:deps] && spec.dependencies.any?
      gems[spec.name]['dependencies'] = spec.dependencies.map(&:name) - ['bundler']
    end
  end
end

#convert_spec(spec, cache) ⇒ Object



46
47
48
49
50
51
52
# File 'lib/bundix.rb', line 46

def convert_spec(spec, cache)
  {spec.name => {version: spec.version.to_s, source: Source.new(spec).convert}}
rescue => ex
  warn "Skipping #{spec.name}: #{ex}"
  puts ex.backtrace
  {spec.name => {}}
end

#find_cached_spec(spec, cache) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/bundix.rb', line 54

def find_cached_spec(spec, cache)
  name, cached = cache.find{|k, v|
    next unless k == spec.name
    next unless cached_source = v['source']

    case spec_source = spec.source
    when Bundler::Source::Git
      next unless cached_rev = cached_source['rev']
      next unless spec_rev = spec_source.options['revision']
      spec_rev == cached_rev
    when Bundler::Source::Rubygems
      v['version'] == spec.version.to_s
    end
  }

  {name => cached} if cached
end

#parse_gemsetObject



73
74
75
76
77
78
79
# File 'lib/bundix.rb', line 73

def parse_gemset
  path = File.expand_path(options[:gemset])
  return {} unless File.file?(path)
  json = Bundix.sh(
    NIX_INSTANTIATE, '--eval', '-E', "builtins.toJSON(import #{path})")
  JSON.parse(json.strip.gsub(/\\"/, '"')[1..-2])
end

#parse_lockfileObject



81
82
83
# File 'lib/bundix.rb', line 81

def parse_lockfile
  Bundler::LockfileParser.new(File.read(options[:lockfile]))
end