Rework ruby gems
svn path=/nixpkgs/trunk/; revision=25654
This commit is contained in:
parent
404f669852
commit
9e22c7f8ab
6 changed files with 155 additions and 1410 deletions
18
pkgs/development/interpreters/ruby/gem_hook.patch
Normal file
18
pkgs/development/interpreters/ruby/gem_hook.patch
Normal file
|
@ -0,0 +1,18 @@
|
|||
diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb
|
||||
index d1ef3cb..bf15652 100755
|
||||
--- a/lib/rubygems/installer.rb
|
||||
+++ b/lib/rubygems/installer.rb
|
||||
@@ -545,6 +545,13 @@ Results logged to #{File.join(Dir.pwd, 'gem_make.out')}
|
||||
|
||||
say path if Gem.configuration.really_verbose
|
||||
end
|
||||
+
|
||||
+ if !ENV['NIX_POST_EXTRACT_FILES_HOOK'].nil?
|
||||
+ print "\nrunning NIX_POST_EXTRACT_FILES_HOOK #{ENV['NIX_POST_EXTRACT_FILES_HOOK']} #{@gem_dir}\n"
|
||||
+ print `#{ENV['NIX_POST_EXTRACT_FILES_HOOK']} #{@gem_dir}`
|
||||
+ print "\nrunning NIX_POST_EXTRACT_FILES_HOOK done\n"
|
||||
+ end
|
||||
+
|
||||
end
|
||||
|
||||
##
|
|
@ -1,266 +0,0 @@
|
|||
diff --git a/lib/rubygems/command_manager.rb b/lib/rubygems/command_manager.rb
|
||||
index 0a19016..ef66d30 100755
|
||||
--- a/lib/rubygems/command_manager.rb
|
||||
+++ b/lib/rubygems/command_manager.rb
|
||||
@@ -70,6 +70,7 @@ class Gem::CommandManager
|
||||
register_command :unpack
|
||||
register_command :update
|
||||
register_command :which
|
||||
+ register_command :nix
|
||||
end
|
||||
|
||||
##
|
||||
|
||||
diff --git a/lib/rubygems/commands/nix_command.rb b/lib/rubygems/commands/nix_command.rb
|
||||
new file mode 100644
|
||||
index 0000000..24f3479
|
||||
--- /dev/null
|
||||
+++ b/lib/rubygems/commands/nix_command.rb
|
||||
@@ -0,0 +1,228 @@
|
||||
+require 'net/http'
|
||||
+require 'rubygems/command'
|
||||
+require 'rubygems/doc_manager'
|
||||
+require 'rubygems/install_update_options'
|
||||
+require 'rubygems/dependency_installer'
|
||||
+require 'rubygems/local_remote_options'
|
||||
+require 'rubygems/validator'
|
||||
+require 'rubygems/exceptions'
|
||||
+require 'rubygems/version_option'
|
||||
+require 'rubygems/version'
|
||||
+require 'open3'
|
||||
+
|
||||
+
|
||||
+def nixname(gem)
|
||||
+ s = "#{gem}" == gem ? gem : gem.full_name
|
||||
+ s.gsub(/[.-]/,'_')
|
||||
+end
|
||||
+
|
||||
+def nixdescription(spec)
|
||||
+ desc_from_spec = spec.description
|
||||
+ desc = desc_from_spec.sub(/[.].*/,'') # only keep first sentence
|
||||
+ desc = desc.length > 120 \
|
||||
+ ? "description = ''#{ desc[0..120] }''; # cut to 120 chars" \
|
||||
+ : "description = ''#{ desc }'';"
|
||||
+ desc = desc.sub(/'';$/,"[...]'';") if desc != desc_from_spec
|
||||
+ desc.gsub("\n"," ") # no \ns in description
|
||||
+end
|
||||
+
|
||||
+##
|
||||
+# tool creating nix expression to install gems (from ruby forge etc)
|
||||
+#
|
||||
+# this is work in progress
|
||||
+
|
||||
+class Gem::Commands::NixCommand < Gem::Command
|
||||
+
|
||||
+ include Gem::VersionOption
|
||||
+ include Gem::LocalRemoteOptions
|
||||
+ include Gem::InstallUpdateOptions
|
||||
+
|
||||
+ def initialize
|
||||
+ defaults = Gem::DependencyInstaller::DEFAULT_OPTIONS.merge({
|
||||
+ })
|
||||
+ super 'nix', 'create a nix file containing expressions of the gems', defaults
|
||||
+ end
|
||||
+
|
||||
+ def description # :nodoc:
|
||||
+ <<-EOF
|
||||
+ create a nix file containing expressions of the gems
|
||||
+ There are many gems. So it's best to only specify some target gems and
|
||||
+ take them into acocunt with their deps
|
||||
+ TODO more details
|
||||
+ EOF
|
||||
+ end
|
||||
+
|
||||
+ def usage # :nodoc:
|
||||
+ "#{program_name} GEMNAME [GEMNAME ...] [options] -- --build-flags"
|
||||
+ end
|
||||
+
|
||||
+ def arguments # :nodoc:
|
||||
+ "GEMNAME name of gem to be added to the expressions file"
|
||||
+ end
|
||||
+
|
||||
+ def defaults_str # :nodoc:
|
||||
+ # what to put in here ? TODO (probably nothing is ok)
|
||||
+ ""
|
||||
+ end
|
||||
+
|
||||
+ def execute
|
||||
+
|
||||
+ begin
|
||||
+ @prerelease = false;
|
||||
+
|
||||
+ args = options[:args];
|
||||
+
|
||||
+ @gems_with_deps = {}
|
||||
+ @seen = {}
|
||||
+
|
||||
+ # args to dep informations
|
||||
+ args.map { |arg|
|
||||
+ if arg =~ /(.+)-?(.*)?/ then
|
||||
+ gem_name = $1
|
||||
+ version = $2.empty? ? Gem::Requirement.default : Gem::Version.new($2)
|
||||
+ else
|
||||
+ raise Gem::CommandLineError, "could'nt parse arg. expected: name or name-version"
|
||||
+ end
|
||||
+
|
||||
+ warn "adding #{gem_name}\n"
|
||||
+
|
||||
+ adddep(Gem::Dependency.new gem_name, version)
|
||||
+ }
|
||||
+
|
||||
+ warn " total: #{@gems_with_deps.length}"
|
||||
+
|
||||
+
|
||||
+ out = "
|
||||
+ # WARNING: automatically generated CODE
|
||||
+ # This section has been generated by gem nix #{args.join(" ")}
|
||||
+ # the gem nix command has been added by a nix patch to ruby gems
|
||||
+ "
|
||||
+ # define aliases
|
||||
+ aliases = {}
|
||||
+ @gems_with_deps.each{ |key, (spec, src, deps)|
|
||||
+ aliases[spec.name] = spec \
|
||||
+ if aliases[spec.name].nil? || aliases[spec.name].version < spec.version
|
||||
+
|
||||
+ src_url = "http://gems.rubyforge.org/gems/#{spec.full_name}.gem"
|
||||
+
|
||||
+ # [> get true mirror url reading redirect contents
|
||||
+ # h = Net::HTTP.new('gems.rubyforge.org', 80)
|
||||
+ # resp, data = h.get("/gems/#{spec.full_name}.gem", nil)
|
||||
+ # if resp.code == "200" then
|
||||
+ # src_url = "http://gems.rubyforge.org/gems/#{spec.full_name}.gem"
|
||||
+ # else if resp.code == "302" then
|
||||
+ # src_url = resp['location']
|
||||
+ # print "redirection: http://gems.rubyforge.org/gems/#{spec.full_name}.gem -> #{src_url}\n"
|
||||
+ # else
|
||||
+ # raise Gem::DependencyError.new("unkown http return code #{resp} #{data}")
|
||||
+ # end
|
||||
+ # end
|
||||
+
|
||||
+ #raise Gem::DependencyError("src_url is nil, 302 redirection failed?") if src_url.nil?
|
||||
+
|
||||
+ out += "
|
||||
+ #{nixname spec} = rubyDerivation {
|
||||
+ name = \"ruby-#{spec.full_name}\"; # full_name
|
||||
+ nameNoVersion = \"#{nixname spec.name}\";
|
||||
+ propagatedBuildInputs = [ #{deps.map {|n| n.nil? ? "" : (nixname n) }.join(" ")} ];
|
||||
+ src = fetchurl {
|
||||
+ url = \"#{src_url}\";
|
||||
+ sha256 = \"#{nixhashof src_url}\";
|
||||
+ };
|
||||
+ meta = {
|
||||
+ homepage = \"#{spec.homepage}\";
|
||||
+ license = [#{spec.licenses.map{|l| "\"#{l}\""}.join(" ") }]; # one of ?
|
||||
+ #{nixdescription spec}
|
||||
+ longDescription = ''#{ spec.description }'';
|
||||
+ };
|
||||
+ };\n"
|
||||
+ }
|
||||
+
|
||||
+ out += "\n# aliases\n"
|
||||
+ aliases.each { |key, spec |
|
||||
+ out += "#{nixname key}=#{nixname spec};\n"
|
||||
+ }
|
||||
+
|
||||
+ print out
|
||||
+ exit_code = 0
|
||||
+
|
||||
+ rescue => e
|
||||
+ puts e.inspect
|
||||
+ puts e.backtrace
|
||||
+ end
|
||||
+
|
||||
+
|
||||
+ end
|
||||
+
|
||||
+ # helper funtions ================
|
||||
+
|
||||
+ def adddep(dep)
|
||||
+ gem = find_gem_with_source(dep)
|
||||
+ raise Gem::CommandLineError, "couldn't find #{dep}" if gem.nil?
|
||||
+ full_name = gem[0].full_name
|
||||
+
|
||||
+ return if @seen[full_name]
|
||||
+ @seen[full_name] = true # there maybe circular dependencies. thus mark this gem seen as early as possible
|
||||
+
|
||||
+ # development deps can't be found. Some are old. Thus only add rutime dependencies
|
||||
+ deps = gem[0].dependencies.find_all { |d| d.type == :runtime }
|
||||
+
|
||||
+ warn " total deps of #{full_name}: #{deps.length}"
|
||||
+
|
||||
+ dep_specs = []
|
||||
+ # recurse while collecting deps
|
||||
+ deps.each {|dep_var| dep_specs.push(adddep(dep_var)) }
|
||||
+
|
||||
+
|
||||
+ @gems_with_deps[full_name] = [
|
||||
+ gem[0], # spec
|
||||
+ gem[1], # src
|
||||
+ dep_specs # deps
|
||||
+ ]
|
||||
+ gem[0] # only return spec, no source for dep list
|
||||
+ end
|
||||
+
|
||||
+
|
||||
+ # copied from dependency_installer, stripped
|
||||
+ def find_gem_with_source(dep)
|
||||
+ gems_and_sources = []
|
||||
+
|
||||
+ # no local
|
||||
+
|
||||
+ requirements = dep.version_requirements.requirements.map do |req, ver|
|
||||
+ req
|
||||
+ end
|
||||
+
|
||||
+ all = true
|
||||
+ found = Gem::SpecFetcher.fetcher.fetch dep, all, true, @prerelease
|
||||
+ found.reverse[0]
|
||||
+ end
|
||||
+
|
||||
+
|
||||
+ def nixhashof(src)
|
||||
+ cashfile="#{ENV['HOME']}/.nix-ruby-gems-cache"
|
||||
+ cash = {}
|
||||
+ if FileTest.exists?(cashfile)
|
||||
+ File.open(cashfile,'r') do |f| Marshal.load(f) end
|
||||
+ end
|
||||
+
|
||||
+ if cash[src].nil? then
|
||||
+ tmp="/tmp/ruby-gems-nix-tmp-file"
|
||||
+ system("nix-prefetch-url #{src.gsub(/([:= `$;])/,'\\\\\1')} > #{tmp} 2>/dev/null")
|
||||
+ if $? == 0
|
||||
+ file = File.new(tmp)
|
||||
+ hash = file.readlines().first().split("\n")[0] # remove trailing \n
|
||||
+ file.close()
|
||||
+ File.delete(tmp)
|
||||
+ cash[src] = hash
|
||||
+ else
|
||||
+ cash[src] = "no hash"
|
||||
+ end
|
||||
+
|
||||
+ File.open(cashfile, "w+") do |f| Marshal.dump(cash, f) end
|
||||
+ end
|
||||
+
|
||||
+ return cash[src]
|
||||
+ end
|
||||
+
|
||||
+end
|
||||
|
||||
diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb
|
||||
index d1ef3cb..bf15652 100755
|
||||
--- a/lib/rubygems/installer.rb
|
||||
+++ b/lib/rubygems/installer.rb
|
||||
@@ -545,6 +545,13 @@ Results logged to #{File.join(Dir.pwd, 'gem_make.out')}
|
||||
|
||||
say path if Gem.configuration.really_verbose
|
||||
end
|
||||
+
|
||||
+ if !ENV['NIX_POST_EXTRACT_FILES_HOOK'].nil?
|
||||
+ print "\nrunning NIX_POST_EXTRACT_FILES_HOOK #{ENV['NIX_POST_EXTRACT_FILES_HOOK']} #{@gem_dir}\n"
|
||||
+ print `#{ENV['NIX_POST_EXTRACT_FILES_HOOK']} #{@gem_dir}`
|
||||
+ print "\nrunning NIX_POST_EXTRACT_FILES_HOOK done\n"
|
||||
+ end
|
||||
+
|
||||
end
|
||||
|
||||
##
|
34
pkgs/development/interpreters/ruby/gems-generated.nix
Normal file
34
pkgs/development/interpreters/ruby/gems-generated.nix
Normal file
|
@ -0,0 +1,34 @@
|
|||
# WARNING: automatically generated file
|
||||
# Generated by 'gem nix' command that comes from 'nix' gem
|
||||
g: # Get dependencies from patched gems
|
||||
{
|
||||
aliases = {
|
||||
nix = g.nix_0_1;
|
||||
rake = g.rake_0_8_7;
|
||||
};
|
||||
gem_nix_args = [ ''nix'' ''rake'' ];
|
||||
gems = {
|
||||
nix_0_1 = {
|
||||
basename = ''nix'';
|
||||
meta = {
|
||||
description = ''Nix package manager interface'';
|
||||
homepage = ''http://gitorious.org/ruby-nix'';
|
||||
longDescription = ''Adds 'gem nix' command that dumps given set of gems to format suitable for Nix package manager'';
|
||||
};
|
||||
name = ''nix-0.1'';
|
||||
requiredGems = [ ];
|
||||
sha256 = ''16lc3yfjcsm1s5jjfazlwia1vhy6x401f0mam79r2qkcic70xnap'';
|
||||
};
|
||||
rake_0_8_7 = {
|
||||
basename = ''rake'';
|
||||
meta = {
|
||||
description = ''Ruby based make-like utility.'';
|
||||
homepage = ''http://rake.rubyforge.org'';
|
||||
longDescription = ''Rake is a Make-like program implemented in Ruby. Tasks and dependencies are specified in standard Ruby syntax.'';
|
||||
};
|
||||
name = ''rake-0.8.7'';
|
||||
requiredGems = [ ];
|
||||
sha256 = ''03z1zm7xwl2r9v945ambwbd9sn2smbi34xldmac7qjcmsvd7pcqh'';
|
||||
};
|
||||
};
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -43,5 +43,5 @@ rec {
|
|||
|
||||
# TODO don't resolve 302 redirects but make nix resolve in fetchurl and
|
||||
# nix-prefetch-url. This should be done on stdenv-updates.
|
||||
patches = [ ./gem_nix_command.patch /* see longDescription above */ ];
|
||||
patches = [ ./gem_hook.patch /* see longDescription above */ ];
|
||||
}
|
|
@ -2348,9 +2348,7 @@ let
|
|||
#ruby19 = import ../development/interpreters/ruby/ruby-19.nix { inherit ruby18 fetchurl; };
|
||||
ruby = ruby18;
|
||||
|
||||
rubyLibs = recurseIntoAttrs (import ../development/interpreters/ruby/libs.nix {
|
||||
inherit pkgs stdenv;
|
||||
});
|
||||
rubyLibs = recurseIntoAttrs (callPackage ../development/interpreters/ruby/libs.nix { });
|
||||
|
||||
rake = callPackage ../development/ruby-modules/rake { };
|
||||
|
||||
|
@ -2360,7 +2358,7 @@ let
|
|||
withBioconductor = getConfig ["rLang" "withBioconductor"] false;
|
||||
};
|
||||
|
||||
rubygemsFun = ruby: builderDefsPackage (import ../development/interpreters/ruby/gems.nix) {
|
||||
rubygemsFun = ruby: builderDefsPackage (import ../development/interpreters/ruby/rubygems.nix) {
|
||||
inherit ruby makeWrapper;
|
||||
};
|
||||
rubygems = rubygemsFun ruby;
|
||||
|
|
Loading…
Reference in a new issue