nix 0.0.1
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.
- data/.gitignore +3 -0
- data/Gemfile +4 -0
- data/Rakefile +2 -0
- data/lib/nix.rb +3 -0
- data/lib/nix/convert.rb +40 -0
- data/lib/nix/gem-nix-command.rb +196 -0
- data/lib/nix/version.rb +3 -0
- data/lib/rubygems_plugin.rb +38 -0
- data/nix.gemspec +19 -0
- metadata +76 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
data/lib/nix.rb
ADDED
data/lib/nix/convert.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
module Nix
|
2
|
+
INDENT_STRING=" "
|
3
|
+
end
|
4
|
+
|
5
|
+
class Symbol
|
6
|
+
def to_nix(indent = 0)
|
7
|
+
to_s
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class NilClass
|
12
|
+
def to_nix(indent = 0)
|
13
|
+
"null"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Hash
|
18
|
+
def to_nix(indent = 0)
|
19
|
+
"{\n" +
|
20
|
+
sort {|a, b| a[0].to_s <=> b[0].to_s}.map do |key, value|
|
21
|
+
raise "Key must be a Symbol, not #{key.class}" unless key.is_a?(Symbol)
|
22
|
+
Nix::INDENT_STRING * (indent + 1)+ key.to_nix +
|
23
|
+
" = " + value.to_nix(indent + 1) + ";"
|
24
|
+
end.join("\n") + "\n" +
|
25
|
+
Nix::INDENT_STRING * indent + "}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class Array
|
30
|
+
def to_nix(indent = 0)
|
31
|
+
"[ " + map(&:to_nix).join(" ") + " ]"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class String
|
36
|
+
def to_nix(indent = 0)
|
37
|
+
# TODO: escape ${var} in string
|
38
|
+
"''#{self}''"
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,196 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'rubygems/command'
|
3
|
+
require 'rubygems/doc_manager'
|
4
|
+
require 'rubygems/install_update_options'
|
5
|
+
require 'rubygems/dependency_installer'
|
6
|
+
require 'rubygems/local_remote_options'
|
7
|
+
require 'rubygems/validator'
|
8
|
+
require 'rubygems/exceptions'
|
9
|
+
require 'rubygems/version_option'
|
10
|
+
require 'rubygems/version'
|
11
|
+
require 'open3'
|
12
|
+
|
13
|
+
require 'nix/convert'
|
14
|
+
|
15
|
+
class Gem::Specification
|
16
|
+
def nix_name(mode = :symbol)
|
17
|
+
case mode
|
18
|
+
when :symbol
|
19
|
+
full_name.gsub(/[.-]/, '_').to_sym
|
20
|
+
when :short
|
21
|
+
name.gsub(/[.-]/, '_')
|
22
|
+
when :short_sym
|
23
|
+
nix_name(:short).to_sym
|
24
|
+
when :rhs_sym
|
25
|
+
("g." + nix_name(:symbol).to_s).to_sym
|
26
|
+
else
|
27
|
+
raise "Unknown mode #{mode} passed to nix_name"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def nix_meta
|
32
|
+
{
|
33
|
+
:homepage => homepage,
|
34
|
+
:description => nix_description(false),
|
35
|
+
:longDescription => nix_description(true),
|
36
|
+
:license => licenses
|
37
|
+
}.reject { |k, v| v.nil? or (v.respond_to?(:empty?) and v.empty?) }
|
38
|
+
end
|
39
|
+
|
40
|
+
def nix_description(long)
|
41
|
+
return nil if description.nil? or description.empty?
|
42
|
+
desc = description.dup
|
43
|
+
if not long then
|
44
|
+
desc.sub!(/\A[[:space:]]*([^.\n]*[^.\n[:space:]]).*\z/,'\1')
|
45
|
+
desc.sub!(/ +/, ' ')
|
46
|
+
desc.sub!(/(.{120}).+/, '\1[...]') # Trim to 120 chars
|
47
|
+
end
|
48
|
+
desc
|
49
|
+
end
|
50
|
+
|
51
|
+
def nix_hash
|
52
|
+
src = "http://rubygems.org/downloads/#{full_name}.gem"
|
53
|
+
cashfile="#{ENV['HOME']}/.nix-ruby-gems-cache"
|
54
|
+
cash = {}
|
55
|
+
if FileTest.exists?(cashfile)
|
56
|
+
File.open(cashfile,'r') do |f| Marshal.load(f) end
|
57
|
+
end
|
58
|
+
|
59
|
+
if cash[src].nil? then
|
60
|
+
tmp="/tmp/ruby-gems-nix-tmp-file"
|
61
|
+
system("nix-prefetch-url #{src.gsub(/([:= `$;])/,'\\\\\1')} > #{tmp} 2>/dev/null")
|
62
|
+
if $? == 0
|
63
|
+
file = File.new(tmp)
|
64
|
+
hash = file.readlines().first().split("\n")[0] # remove trailing \n
|
65
|
+
file.close()
|
66
|
+
File.delete(tmp)
|
67
|
+
cash[src] = hash
|
68
|
+
else
|
69
|
+
cash[src] = "no hash"
|
70
|
+
end
|
71
|
+
|
72
|
+
File.open(cashfile, "w+") do |f| Marshal.dump(cash, f) end
|
73
|
+
end
|
74
|
+
|
75
|
+
return cash[src]
|
76
|
+
end
|
77
|
+
|
78
|
+
def nix_derivation
|
79
|
+
{
|
80
|
+
:name => full_name,
|
81
|
+
:basename => nix_name(:short),
|
82
|
+
:sha256 => nix_hash,
|
83
|
+
:meta => nix_meta
|
84
|
+
}
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
class Gem::Commands::NixCommand < Gem::Command
|
89
|
+
include Gem::VersionOption
|
90
|
+
include Gem::LocalRemoteOptions
|
91
|
+
include Gem::InstallUpdateOptions
|
92
|
+
|
93
|
+
def exec
|
94
|
+
begin
|
95
|
+
@prerelease = false;
|
96
|
+
|
97
|
+
args = options[:args];
|
98
|
+
|
99
|
+
@gems_with_deps = {}
|
100
|
+
@seen = {}
|
101
|
+
|
102
|
+
# args to dep informations
|
103
|
+
args.map { |arg|
|
104
|
+
if arg =~ /(.+)-?(.*)?/ then
|
105
|
+
gem_name = $1
|
106
|
+
version = $2.empty? ? Gem::Requirement.default : Gem::Version.new($2)
|
107
|
+
else
|
108
|
+
raise Gem::CommandLineError, "couldn't parse arg. expected: name or name-version"
|
109
|
+
end
|
110
|
+
|
111
|
+
warn "adding #{gem_name}\n"
|
112
|
+
|
113
|
+
adddep(Gem::Dependency.new gem_name, version)
|
114
|
+
}
|
115
|
+
|
116
|
+
warn " total: #{@gems_with_deps.length}"
|
117
|
+
|
118
|
+
print <<-EOF
|
119
|
+
# WARNING: automatically generated file
|
120
|
+
# the gem nix command comes from 'nix' gem
|
121
|
+
g: # Get dependencies from patched gems
|
122
|
+
EOF
|
123
|
+
# define aliases
|
124
|
+
aliases = {}
|
125
|
+
output_gems = {}
|
126
|
+
|
127
|
+
@gems_with_deps.each_value do |(spec, src, deps)|
|
128
|
+
if !aliases.key?(spec.name) or aliases[spec.name].version < spec.version
|
129
|
+
aliases[spec.name] = spec
|
130
|
+
end
|
131
|
+
|
132
|
+
output_gems[spec.nix_name(:symbol)] = spec.nix_derivation.merge({
|
133
|
+
:requiredGems => deps.compact.map { |d| d.nix_name(:rhs_sym) }
|
134
|
+
})
|
135
|
+
end
|
136
|
+
|
137
|
+
print ({
|
138
|
+
:gem_nix_args => args,
|
139
|
+
:gems => output_gems,
|
140
|
+
:aliases => aliases.values.inject({}) do |h, s|
|
141
|
+
h[s.nix_name(:short_sym)] = s.nix_name(:rhs_sym)
|
142
|
+
h
|
143
|
+
end
|
144
|
+
}.to_nix)
|
145
|
+
exit_code = 0
|
146
|
+
|
147
|
+
rescue => e
|
148
|
+
puts e.inspect
|
149
|
+
puts e.backtrace
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# helper funtions ================
|
154
|
+
|
155
|
+
def adddep(dep)
|
156
|
+
gem = find_gem_with_source(dep)
|
157
|
+
raise Gem::CommandLineError, "couldn't find #{dep}" if gem.nil?
|
158
|
+
full_name = gem[0].full_name
|
159
|
+
|
160
|
+
return if @seen[full_name]
|
161
|
+
@seen[full_name] = true # there maybe circular dependencies. thus mark this gem seen as early as possible
|
162
|
+
|
163
|
+
# development deps can't be found. Some are old. Thus only add rutime dependencies
|
164
|
+
deps = gem[0].dependencies.find_all { |d| d.type == :runtime }
|
165
|
+
|
166
|
+
warn " total deps of #{full_name}: #{deps.length}"
|
167
|
+
|
168
|
+
dep_specs = []
|
169
|
+
# recurse while collecting deps
|
170
|
+
deps.each {|dep_var| dep_specs.push(adddep(dep_var)) }
|
171
|
+
|
172
|
+
|
173
|
+
@gems_with_deps[full_name] = [
|
174
|
+
gem[0], # spec
|
175
|
+
gem[1], # src
|
176
|
+
dep_specs # deps
|
177
|
+
]
|
178
|
+
gem[0] # only return spec, no source for dep list
|
179
|
+
end
|
180
|
+
|
181
|
+
|
182
|
+
# copied from dependency_installer, stripped
|
183
|
+
def find_gem_with_source(dep)
|
184
|
+
gems_and_sources = []
|
185
|
+
|
186
|
+
# no local
|
187
|
+
|
188
|
+
requirements = dep.requirement.requirements.map do |req, ver|
|
189
|
+
req
|
190
|
+
end
|
191
|
+
|
192
|
+
all = true
|
193
|
+
found = Gem::SpecFetcher.fetcher.fetch dep, all, true, @prerelease
|
194
|
+
found.reverse[0]
|
195
|
+
end
|
196
|
+
end
|
data/lib/nix/version.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'rubygems/command_manager'
|
2
|
+
require 'rubygems/dependency_installer'
|
3
|
+
|
4
|
+
class Gem::Commands::NixCommand < Gem::Command
|
5
|
+
def initialize
|
6
|
+
defaults = Gem::DependencyInstaller::DEFAULT_OPTIONS.merge({ })
|
7
|
+
super 'nix', 'Create a nix file containing expressions of the gems', defaults
|
8
|
+
end
|
9
|
+
|
10
|
+
def description # :nodoc:
|
11
|
+
<<-EOF
|
12
|
+
create a nix file containing expressions of the gems
|
13
|
+
There are many gems. So it's best to only specify some target gems and
|
14
|
+
take them into acocunt with their deps
|
15
|
+
TODO more details
|
16
|
+
EOF
|
17
|
+
end
|
18
|
+
|
19
|
+
def usage # :nodoc:
|
20
|
+
"#{program_name} GEMNAME [GEMNAME ...] [options] -- --build-flags"
|
21
|
+
end
|
22
|
+
|
23
|
+
def arguments # :nodoc:
|
24
|
+
"GEMNAME name of gem to be added to the expressions file"
|
25
|
+
end
|
26
|
+
|
27
|
+
def defaults_str # :nodoc:
|
28
|
+
# what to put in here ? TODO (probably nothing is ok)
|
29
|
+
""
|
30
|
+
end
|
31
|
+
|
32
|
+
def execute
|
33
|
+
require 'nix/gem-nix-command' unless respond_to? :exec
|
34
|
+
exec
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
Gem::CommandManager.instance.register_command :nix
|
data/nix.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "nix/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "nix"
|
7
|
+
s.version = Nix::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Yury G. Kudryashov"]
|
10
|
+
s.email = ["urkud@ya.ru"]
|
11
|
+
s.homepage = "http://gitorious.org/ruby-nix"
|
12
|
+
s.summary = %q{Nix package manager interface}
|
13
|
+
s.description = %q{See http://www.nixos.org}
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nix
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Yury G. Kudryashov
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-01-16 00:00:00 +03:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: See http://www.nixos.org
|
23
|
+
email:
|
24
|
+
- urkud@ya.ru
|
25
|
+
executables: []
|
26
|
+
|
27
|
+
extensions: []
|
28
|
+
|
29
|
+
extra_rdoc_files: []
|
30
|
+
|
31
|
+
files:
|
32
|
+
- .gitignore
|
33
|
+
- Gemfile
|
34
|
+
- Rakefile
|
35
|
+
- lib/nix.rb
|
36
|
+
- lib/nix/convert.rb
|
37
|
+
- lib/nix/gem-nix-command.rb
|
38
|
+
- lib/nix/version.rb
|
39
|
+
- lib/rubygems_plugin.rb
|
40
|
+
- nix.gemspec
|
41
|
+
has_rdoc: true
|
42
|
+
homepage: http://gitorious.org/ruby-nix
|
43
|
+
licenses: []
|
44
|
+
|
45
|
+
post_install_message:
|
46
|
+
rdoc_options: []
|
47
|
+
|
48
|
+
require_paths:
|
49
|
+
- lib
|
50
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
hash: 3
|
56
|
+
segments:
|
57
|
+
- 0
|
58
|
+
version: "0"
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
hash: 3
|
65
|
+
segments:
|
66
|
+
- 0
|
67
|
+
version: "0"
|
68
|
+
requirements: []
|
69
|
+
|
70
|
+
rubyforge_project:
|
71
|
+
rubygems_version: 1.4.1
|
72
|
+
signing_key:
|
73
|
+
specification_version: 3
|
74
|
+
summary: Nix package manager interface
|
75
|
+
test_files: []
|
76
|
+
|