g-gem 0.1.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.
- data/bin/g-gem +15 -0
- data/lib/g-gem.rb +12 -0
- data/lib/g-gem/command.rb +150 -0
- data/lib/g-gem/core_extensions.rb +39 -0
- data/lib/g-gem/ebuild.rb +292 -0
- data/lib/g-gem/gems_commands_with_portage.rb +70 -0
- data/lib/g-gem/gems_extensions.rb +133 -0
- data/lib/g-gem/portage_commands.rb +78 -0
- data/lib/g-gem/spec_fetcher.rb +77 -0
- data/lib/g-gem/utils.rb +85 -0
- metadata +51 -0
data/bin/g-gem
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
begin
|
|
3
|
+
require 'g-gem'
|
|
4
|
+
rescue LoadError
|
|
5
|
+
require 'rubygems'
|
|
6
|
+
require_gem 'g-gem'
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
Gem.manage_gems
|
|
10
|
+
Gem::CommandManager.wave_all_with_portage
|
|
11
|
+
load %w{
|
|
12
|
+
/bin/gem
|
|
13
|
+
/usr/bin/gem
|
|
14
|
+
/usr/local/bin/gem
|
|
15
|
+
}.find { |f| File.executable?(f) }
|
data/lib/g-gem.rb
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
module Gem::Portage
|
|
2
|
+
class Command < Gem::Command
|
|
3
|
+
|
|
4
|
+
def initialize(command, summary=nil, defaults=nil)
|
|
5
|
+
super(command, summary, defaults || {})
|
|
6
|
+
options_defaults = {}
|
|
7
|
+
class_command_options.each_pair do |k, option|
|
|
8
|
+
add_option(*option.optparse_args, &option.handler)
|
|
9
|
+
options_defaults[option.opt_id] = option.default unless option.default.nil?
|
|
10
|
+
extend option.module
|
|
11
|
+
end
|
|
12
|
+
self.defaults = options_defaults unless defaults
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def defaults_str
|
|
16
|
+
defaults.keys.inject("") do |str, opt|
|
|
17
|
+
str + " " + class_command_options[opt].to_s
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def register
|
|
22
|
+
command_manager.register_command self
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def class_command_options(*args, &prc)
|
|
26
|
+
self.class.class_command_options(*args, &prc)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class << self
|
|
30
|
+
def has_option(id, *getopt_args, &handler)
|
|
31
|
+
option = Option.new(id, *getopt_args, &handler)
|
|
32
|
+
class_command_options[option.opt_id] = option
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def has_options_from(other, *opts)
|
|
36
|
+
defaults = Hash === opts.last ? opts.pop : {}
|
|
37
|
+
borrowed = opts.empty? ? other.class_command_options.keys : opts + defaults.keys
|
|
38
|
+
borrowed.each do |key|
|
|
39
|
+
next unless key
|
|
40
|
+
opt = other.class_command_options[key].dup
|
|
41
|
+
opt.default = defaults[key] if defaults.has_key? key
|
|
42
|
+
class_command_options[opt.opt_id] = opt
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def register
|
|
47
|
+
new.register
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def class_command_options
|
|
51
|
+
@command_options ||= if superclass.respond_to?(:class_command_options)
|
|
52
|
+
superclass.class_command_options.dup
|
|
53
|
+
else
|
|
54
|
+
{}
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
end # class Command
|
|
60
|
+
|
|
61
|
+
class Command::Option
|
|
62
|
+
def initialize(sym, *optparse, &handler)
|
|
63
|
+
/[?=]?$/ === sym.to_s
|
|
64
|
+
@id = $`.to_sym
|
|
65
|
+
@opt_id = $`.to_sym # $`.gsub('_','-').to_sym
|
|
66
|
+
@type = $&[0] if $&
|
|
67
|
+
@opts = Hash === optparse.last ? optparse.pop : {}
|
|
68
|
+
@optparse_args = optparse
|
|
69
|
+
long
|
|
70
|
+
@handler ||= lambda {|v, h| h[@opt_id] = v}
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
attr_reader :id, :opt_id, :handler
|
|
74
|
+
def boolean?
|
|
75
|
+
@type == ?? || default == true || default == false || !@opts[:boolean].nil?
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def has_arg?
|
|
79
|
+
@type == ?= || !arg_name.nil?
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def arg_name
|
|
83
|
+
@opts[:arg_name]
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def default
|
|
87
|
+
return @default if not @default.nil?
|
|
88
|
+
def_name = @opts.keys.detect { |k| /^default(_(\S+))?/ === k.to_s }
|
|
89
|
+
@opts[:arg_name] = $2.upcase if $2 && arg_name.nil?
|
|
90
|
+
@default = @opts[def_name]
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def long
|
|
94
|
+
return @long if @long
|
|
95
|
+
re = /^--(\[no-\])?(\S+)(\s+\[?([^\]\s]+))?/
|
|
96
|
+
long = @optparse_args.detect(@opts[:long]) { |a| re === a }
|
|
97
|
+
if long.to_s =~ re
|
|
98
|
+
@opt_id = $2.to_sym
|
|
99
|
+
@opts[:boolean] = true if $1
|
|
100
|
+
@opts[:arg_name] = $4 if $4
|
|
101
|
+
@long = long
|
|
102
|
+
else
|
|
103
|
+
@long = "--"
|
|
104
|
+
@long << "[no-]" if boolean?
|
|
105
|
+
@long << @opt_id.to_s
|
|
106
|
+
@long << " "+arg_name.to_s if has_arg?
|
|
107
|
+
@long
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def optparse_args
|
|
112
|
+
([long] + @optparse_args).uniq.reject { |o| o.nil? }
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def to_s
|
|
116
|
+
str = "--"
|
|
117
|
+
str << "no-" if boolean? and not default
|
|
118
|
+
str << opt_id.to_s
|
|
119
|
+
str << case default
|
|
120
|
+
when TrueClass, FalseClass; ""
|
|
121
|
+
when Array; " "+default.join(",").inspect
|
|
122
|
+
when String; " "+default.inspect
|
|
123
|
+
end
|
|
124
|
+
str
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def module
|
|
128
|
+
src = <<-READER
|
|
129
|
+
def #{id}
|
|
130
|
+
options["#{opt_id}".intern]
|
|
131
|
+
end
|
|
132
|
+
READER
|
|
133
|
+
src << <<-QUESTION if boolean?
|
|
134
|
+
def #{id}?
|
|
135
|
+
return false if options["#{opt_id}".intern] == false
|
|
136
|
+
not options["#{opt_id}".intern].nil?
|
|
137
|
+
end
|
|
138
|
+
QUESTION
|
|
139
|
+
src << <<-WRITER if has_arg?
|
|
140
|
+
def #{id}=(value)
|
|
141
|
+
options["#{opt_id}".intern] = value
|
|
142
|
+
end
|
|
143
|
+
WRITER
|
|
144
|
+
Module.new do
|
|
145
|
+
module_eval src
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
end # class Command::Option
|
|
150
|
+
end # module Gem::Portage
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
class << ENV
|
|
2
|
+
def with(hash)
|
|
3
|
+
oldenv = {}
|
|
4
|
+
hash.each_pair do |key, val|
|
|
5
|
+
oldenv[key.to_sym], ENV[key.to_s] = ENV[key.to_s], val
|
|
6
|
+
end
|
|
7
|
+
yield
|
|
8
|
+
oldenv.each_pair do |key, val|
|
|
9
|
+
ENV[key.to_s] = val
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class Object
|
|
15
|
+
def singleton_class
|
|
16
|
+
class << self; self; end
|
|
17
|
+
end
|
|
18
|
+
def singleton_eval(code=nil, filename=nil, lineno=nil, &block)
|
|
19
|
+
if code
|
|
20
|
+
singleton_class.module_eval(code,
|
|
21
|
+
*[filename, lineno].reject{ |n| n.nil? })
|
|
22
|
+
else
|
|
23
|
+
singleton_class.module_eval(&block)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
class Class
|
|
29
|
+
def superclass
|
|
30
|
+
ancestors[1..-1].find {|a| Class === a}
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
class String
|
|
35
|
+
def head_indented
|
|
36
|
+
return self unless self =~ /^\s+/
|
|
37
|
+
self.gsub(/^\s{0,#{$&.length}}/, '')
|
|
38
|
+
end
|
|
39
|
+
end
|
data/lib/g-gem/ebuild.rb
ADDED
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
module Gem::Portage
|
|
2
|
+
class Ebuild
|
|
3
|
+
portdir = Gem::Portage::Utils::ConfigFile.new[:RUBYGEMS_PORTDIR] ||
|
|
4
|
+
Gem::Portage::Utils::ConfigFile.new[:PORTDIR_OVERLAY]
|
|
5
|
+
if portdir and not (portdir = portdir.split(/\s+/)).empty?
|
|
6
|
+
portdir = portdir.detect { |s| s =~ /gems/ } || portdir.first
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
DEFAULT_PORTDIR = portdir || "/usr/local/portage"
|
|
10
|
+
DEFAULT_CATEGORY = Gem::Portage::Utils::ConfigFile.new[:RUBYGEMS_CATEGORY] || "dev-ruby"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class Ebuild
|
|
14
|
+
|
|
15
|
+
DEFAULT_INSTALL_DIR = ::Gem.dir
|
|
16
|
+
|
|
17
|
+
EXTENSION = ".ebuild"
|
|
18
|
+
|
|
19
|
+
COMMANDS = %w(help setup clean fetch digest unpack compile test
|
|
20
|
+
preinst install postinst qmerge merge unmerge
|
|
21
|
+
prerm postrm config package rpm generate)
|
|
22
|
+
|
|
23
|
+
class << self
|
|
24
|
+
alias_method :for, :new
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
require 'forwardable'
|
|
28
|
+
extend Forwardable
|
|
29
|
+
|
|
30
|
+
def_delegators :@spec, :name, :version, :date, :summary, :email,
|
|
31
|
+
:homepage, :rubyforge_project, :description, :local?, :remote?
|
|
32
|
+
|
|
33
|
+
attr_reader :spec, :file_path
|
|
34
|
+
attr_accessor :install_dir, :license, :portdir, :category
|
|
35
|
+
|
|
36
|
+
def initialize(spec, portdir=nil, category=nil)
|
|
37
|
+
@portdir = DEFAULT_PORTDIR
|
|
38
|
+
@category = DEFAULT_CATEGORY
|
|
39
|
+
@spec = spec
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def file_path
|
|
43
|
+
File.expand_path(File.join(portdir, category, spec.name,
|
|
44
|
+
"#{spec.full_name}#{EXTENSION}"))
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def dirname
|
|
48
|
+
File.dirname(file_path)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def basename(include_extension=true)
|
|
52
|
+
File.basename(file_path, (EXTENSION unless include_extension) )
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def exists?
|
|
56
|
+
File.exists? file_path
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def write
|
|
60
|
+
require 'fileutils'
|
|
61
|
+
dir = File.dirname(file_path)
|
|
62
|
+
FileUtils.mkdir_p(dir) unless File.directory?(dir)
|
|
63
|
+
File.open(file_path, 'w') { |f| f.write(content) }
|
|
64
|
+
end
|
|
65
|
+
alias_method :generate, :write
|
|
66
|
+
|
|
67
|
+
def local_fetch_command
|
|
68
|
+
"cp -Lvgf --target-directory \${DISTDIR} \${URI}"
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def local_gentoo_mirror
|
|
72
|
+
File.dirname(spec.fetched_from) if spec.local?
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def execute(*commands)
|
|
76
|
+
raise "Invalid emerge command" unless (commands - COMMANDS).empty?
|
|
77
|
+
callcc do |c|
|
|
78
|
+
if spec.local?
|
|
79
|
+
ENV.with(:FETCHCOMMAND => local_fetch_command,
|
|
80
|
+
:GENTOO_MIRRORS => local_gentoo_mirror) do
|
|
81
|
+
c.call
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
generate if commands.delete('generate')
|
|
86
|
+
raise "Missing #{file_path}" unless exists?
|
|
87
|
+
system("ebuild #{file_path} #{commands.join(' ')}") unless commands.empty?
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def digest_file
|
|
91
|
+
File.join(dirname, "files", "digest-#{basename(false)}")
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def src_uri
|
|
95
|
+
uri = spec.fetched_from if spec.respond_to? :fetched_from
|
|
96
|
+
case uri
|
|
97
|
+
when /gems.rubyforge.org/
|
|
98
|
+
"#{uri}/gems/#{spec.full_name}.gem"
|
|
99
|
+
else; uri
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def gem_src
|
|
104
|
+
return spec.fetched_from if spec.local?
|
|
105
|
+
"${DISTDIR}/${P}"
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def license
|
|
109
|
+
"Ruby | BSD | GPL-2"
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def install_dir
|
|
113
|
+
@install_dir || DEFAULT_INSTALL_DIR
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def keywords
|
|
117
|
+
Gem::Portage::Utils::ConfigFile[:ARCH]
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def iuse
|
|
121
|
+
"#{'doc' if spec.has_rdoc}"
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def enable_test_phase
|
|
125
|
+
@test_phase = true
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def disable_test_phase
|
|
129
|
+
@test_phase = false
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def test_phase_enabled?
|
|
133
|
+
@test_phase
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def gem_command_args
|
|
137
|
+
args = [] # %w(--no-portage)
|
|
138
|
+
args << "--test" if test_phase_enabled?
|
|
139
|
+
args.join(' ')
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def depend
|
|
143
|
+
spec.dependencies.inject("virtual/ruby\ndev-ruby/rubygems") do |s, d|
|
|
144
|
+
s + "\n" + DependencyAtom.from_gem_dependency(d, category).to_s
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def content
|
|
149
|
+
require 'date'
|
|
150
|
+
doc = (<<-EBUILD).head_indented
|
|
151
|
+
# Copyright 1999-#{Date.today.year} Gentoo Foundation
|
|
152
|
+
# Distributed under the terms of the GNU General Public License v2
|
|
153
|
+
#
|
|
154
|
+
# #{spec.full_name}.ebuild was auto-generated on #{Date.today}
|
|
155
|
+
# by g-gem and rubygems using a gemspec dated #{spec.date.to_s} from
|
|
156
|
+
# #{spec.fetched_from}
|
|
157
|
+
#
|
|
158
|
+
inherit ruby gems
|
|
159
|
+
|
|
160
|
+
DESCRIPTION=#{description.inspect}
|
|
161
|
+
|
|
162
|
+
HOMEPAGE=#{homepage.inspect}
|
|
163
|
+
|
|
164
|
+
USERUBY="ruby18"
|
|
165
|
+
|
|
166
|
+
SLOT="0"
|
|
167
|
+
|
|
168
|
+
# Please see the homepage for licensing issues
|
|
169
|
+
# at it's current state g-gem cannot detect gemspec's license
|
|
170
|
+
LICENSE=#{license.inspect}
|
|
171
|
+
# Auto detected architecture keyword
|
|
172
|
+
# Modify this if you intend to distribute this ebuild to other architectures
|
|
173
|
+
KEYWORDS=#{keywords.inspect}
|
|
174
|
+
|
|
175
|
+
IUSE=#{iuse.inspect}
|
|
176
|
+
# Dependencies obtained from the gemspec (only other gems)
|
|
177
|
+
DEPEND=#{depend.inspect.gsub('\n', "\n")}
|
|
178
|
+
|
|
179
|
+
#{"# FETCHCOMMAND="+local_fetch_command.inspect if local?}
|
|
180
|
+
SRC_URI=#{src_uri.inspect}
|
|
181
|
+
|
|
182
|
+
GEMSARGS=#{gem_command_args.inspect}
|
|
183
|
+
|
|
184
|
+
gems_location() {
|
|
185
|
+
# Installation directory from the gem command
|
|
186
|
+
export GEMSDIR=#{install_dir.inspect}
|
|
187
|
+
# Actually gems.eclass unconditionally searches the gem in ${DISTDIR}
|
|
188
|
+
export GEM_SRC=#{gem_src.inspect}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
# TODO: support gems_src_compile for have-to-be-compiled gems
|
|
192
|
+
# TODO: support test stage for gems
|
|
193
|
+
|
|
194
|
+
gems_src_install() {
|
|
195
|
+
gems_location
|
|
196
|
+
dodir ${GEMSDIR}
|
|
197
|
+
gem install ${GEM_SRC} -v ${PV} -l -i ${D}/${GEMSDIR} ${GEMSARGS} || die "gem install failed"
|
|
198
|
+
if [ -d ${D}/${GEMSDIR}/bin ] ; then
|
|
199
|
+
exeinto /usr/bin
|
|
200
|
+
for exe in ${D}/${GEMSDIR}/bin/* ; do
|
|
201
|
+
doexe ${exe}
|
|
202
|
+
done
|
|
203
|
+
fi
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
EBUILD
|
|
207
|
+
end
|
|
208
|
+
end # class Ebuild
|
|
209
|
+
end # module Gem::Portage
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
module Gem::Portage
|
|
213
|
+
class DependencyAtom
|
|
214
|
+
|
|
215
|
+
PREFIX_EXT_RE = /[!~]/
|
|
216
|
+
PREFIX_RE = /(>=|<=|<|>|=)/
|
|
217
|
+
CATEGORY_RE = /\w+-\w+/
|
|
218
|
+
POSTFIX_RE = /\*/
|
|
219
|
+
VERSION_RE = /(\d+(\.\d+)*)+/
|
|
220
|
+
VERSION_EXT_RE = /[a-z]?(_(alpha|beta|pre|rc|p)\d+)?/
|
|
221
|
+
PACKAGE_NAME_RE = /[a-zA-Z0-9_-]+/
|
|
222
|
+
|
|
223
|
+
attr_reader :package_name, :version, :version_ext,
|
|
224
|
+
:prefix, :prefix_ext, :postfix, :origin
|
|
225
|
+
|
|
226
|
+
def initialize(str)
|
|
227
|
+
@origin = str
|
|
228
|
+
@prefix_ext, str = $&, $' if /^#{PREFIX_EXT_RE}/ === str
|
|
229
|
+
@prefix, str = $&, $' if /^#{PREFIX_RE}/ === str
|
|
230
|
+
@category, str = $1, $' if /^(#{CATEGORY_RE})\// === str
|
|
231
|
+
@postfix, str = $&, $` if /#{POSTFIX_RE}$/ === str
|
|
232
|
+
@version, @version_ext, str = $1, $3, $` if /-#{VERSION_RE}(#{VERSION_EXT_RE})/ === str
|
|
233
|
+
raise "Invalid atom: #{@origin}" unless /^#{PACKAGE_NAME_RE}$/ === str
|
|
234
|
+
@package_name = $&
|
|
235
|
+
end
|
|
236
|
+
private :initialize
|
|
237
|
+
|
|
238
|
+
alias_method :name, :package_name
|
|
239
|
+
attr_accessor :category
|
|
240
|
+
|
|
241
|
+
def category
|
|
242
|
+
@category or Gem::Portage::Ebuild::DEFAULT_CATEGORY
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
##
|
|
246
|
+
# FIXME: support other gentoo atom prefixes
|
|
247
|
+
##
|
|
248
|
+
def gem_requirement
|
|
249
|
+
return Gem::Version::Requirement.default unless version
|
|
250
|
+
full_prefix = "#{prefix_ext}#{prefix}"
|
|
251
|
+
gem_prefix = if /^(~>|>|>=|=|!=|<=|<)$/ === full_prefix
|
|
252
|
+
full_prefix
|
|
253
|
+
elsif not prefix
|
|
254
|
+
"="
|
|
255
|
+
end
|
|
256
|
+
Gem::Version::Requirement.create(["#{gem_prefix} #{version}"])
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
def gem_dependency
|
|
260
|
+
Gem::Dependency.new(package_name, [gem_requirement.to_s])
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def to_s
|
|
264
|
+
"#{prefix_ext}#{(prefix or "=") if version}#{category+"/" if category}#{package_name}"+
|
|
265
|
+
"#{"-"+version+version_ext if version}#{postfix}"
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
class << self
|
|
269
|
+
def from_s(str)
|
|
270
|
+
if str =~ /(.*\/)?(\S+)\.gem$/ # From gem file
|
|
271
|
+
atom = from_s($2)
|
|
272
|
+
atom.instance_eval { @origin = str }
|
|
273
|
+
atom
|
|
274
|
+
else
|
|
275
|
+
new(str)
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
alias_method :parse, :from_s
|
|
280
|
+
|
|
281
|
+
def parse_list(list)
|
|
282
|
+
list.map { |str| parse(str) }
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
def from_gem_dependency(dep, category)
|
|
286
|
+
# fixme:
|
|
287
|
+
prefix, version = *dep.version_requirements.instance_eval { @requirements.first }
|
|
288
|
+
new("#{prefix}#{category}/#{dep.name}-#{version}")
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
end # class DependencyAtom
|
|
292
|
+
end # module Gem::Portage
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
module Gem::Portage
|
|
2
|
+
module InstallWithPortage
|
|
3
|
+
include Gem::Command::WithPortage(:execute)
|
|
4
|
+
include Gem::Portage::GemSpecFetcher
|
|
5
|
+
|
|
6
|
+
def default_portage_args
|
|
7
|
+
%w(--verbose)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def execute_with_portage
|
|
11
|
+
fail (<<-EOE).head_indented if options[:args].empty?
|
|
12
|
+
Please specify a gem name on the command line (e.g. gem #{command} GEMNAME)
|
|
13
|
+
As with the ebuild command you can also specify a portage dependency-atom.
|
|
14
|
+
(see ebuild(5) under 'DEPEND Atoms' for more info)
|
|
15
|
+
|
|
16
|
+
Note that everything after the '--portage' option is ignored by this
|
|
17
|
+
command and is used as arguments for the emerge program.
|
|
18
|
+
EOE
|
|
19
|
+
ecmd = Gem::Portage::EbuildCommand.new :command => %w(generate digest),
|
|
20
|
+
:overwrite => false,
|
|
21
|
+
:force => false,
|
|
22
|
+
:test_phase => options[:test],
|
|
23
|
+
:install_dir => options[:install_dir],
|
|
24
|
+
:domain => options[:domain],
|
|
25
|
+
:dependencies => options[:include_dependencies]
|
|
26
|
+
self.portage_args += %w(--nodeps) if options[:ignore_dependencies]
|
|
27
|
+
ENV['USE'] = "#{ENV['USE']} doc" if options[:generate_rdoc]
|
|
28
|
+
ENV['FEATURES'] = "#{ENV['FEATURES']} test" if options[:test]
|
|
29
|
+
atoms = Gem::Portage::DependencyAtom.parse_list(options[:args])
|
|
30
|
+
ecmd.execute_on(atoms)
|
|
31
|
+
atoms_s = atoms.inject("") { |s, a| s + " " + a.to_s }
|
|
32
|
+
system("emerge #{portage_args_s} #{atoms_s}")
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
end # module InstallWithPortage
|
|
36
|
+
end # module Gem::Portage
|
|
37
|
+
|
|
38
|
+
module Gem::Portage
|
|
39
|
+
module UpdateWithPortage
|
|
40
|
+
include Gem::Command::WithPortage(:execute)
|
|
41
|
+
include Gem::Portage::GemSpecFetcher
|
|
42
|
+
|
|
43
|
+
def execute_with_portage
|
|
44
|
+
p "Unimplemented"
|
|
45
|
+
exit 0
|
|
46
|
+
end
|
|
47
|
+
end # module InstallWithPortage
|
|
48
|
+
end # module Gem::Portage
|
|
49
|
+
|
|
50
|
+
class Gem::CommandManager
|
|
51
|
+
WITH_PORTAGE_COMMANDS = {
|
|
52
|
+
:install => Gem::Portage::InstallWithPortage,
|
|
53
|
+
:update => Gem::Portage::UpdateWithPortage
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
def with_portage(name)
|
|
57
|
+
return self.class.instance[name] unless
|
|
58
|
+
WITH_PORTAGE_COMMANDS.has_key?(name.to_sym)
|
|
59
|
+
Gem::Command::WithPortage.wave_with_portage(self.class.instance[name],
|
|
60
|
+
WITH_PORTAGE_COMMANDS[name.to_sym])
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
class << self
|
|
64
|
+
def wave_all_with_portage
|
|
65
|
+
WITH_PORTAGE_COMMANDS.each_key do |name|
|
|
66
|
+
self.instance.with_portage(name.to_s)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
Gem.manage_gems
|
|
3
|
+
|
|
4
|
+
class Gem::DependencyList
|
|
5
|
+
class << self
|
|
6
|
+
def from_atoms(fetcher, atoms)
|
|
7
|
+
deps = self.new
|
|
8
|
+
atoms.each do |atom|
|
|
9
|
+
dep = atom.gem_dependency
|
|
10
|
+
if atom.origin =~ /^(.*\/)/
|
|
11
|
+
dep.singleton_eval do
|
|
12
|
+
define_method(:origin_dir) { $1 }
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
deps.add(fetcher[dep])
|
|
16
|
+
end
|
|
17
|
+
deps
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def satisfied?(dependency)
|
|
22
|
+
@specs.any? { |s| s.satisfies_requirement?(dependency) }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def include_dependencies(fetcher)
|
|
26
|
+
return self if ok?
|
|
27
|
+
size = @specs.size
|
|
28
|
+
@specs.each do |spec|
|
|
29
|
+
spec.dependencies.each do |dep|
|
|
30
|
+
next if satisfied?(dep)
|
|
31
|
+
add fetcher[dep]
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
@specs.size != size ? include_dependencies(fetcher) : self
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def each_spec
|
|
38
|
+
@specs.each do |spec| yield spec ; end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end # class Gem::DependencyList
|
|
42
|
+
|
|
43
|
+
class Gem::Command
|
|
44
|
+
def handle_options_with_portage(args)
|
|
45
|
+
port_arg = args.index('--portage')
|
|
46
|
+
port_arg = args.slice!(port_arg.succ .. -1) if port_arg
|
|
47
|
+
handle_options_without_portage(args)
|
|
48
|
+
@options[:portage_args] = port_arg if port_arg
|
|
49
|
+
@options[:args]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
alias_method :handle_options_without_portage, :handle_options
|
|
53
|
+
alias_method :handle_options, :handle_options_with_portage
|
|
54
|
+
|
|
55
|
+
module WithPortage
|
|
56
|
+
DEFAULT_PORTAGE_ARGS = %w(--verbose --ask)
|
|
57
|
+
|
|
58
|
+
def default_portage_args
|
|
59
|
+
DEFAULT_PORTAGE_ARGS
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def portage_args
|
|
63
|
+
@portage_args || default_portage_args + @options[:portage_args].to_a
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def portage_args=(arr)
|
|
67
|
+
@portage_args = arr
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def portage_args_s
|
|
71
|
+
portage_args.join(' ')
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def with_portage?
|
|
75
|
+
return false if options[:with_portage] == false
|
|
76
|
+
options[:with_portage] || Process.euid == 0
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def waved_with_portage?
|
|
80
|
+
true
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
class << self
|
|
84
|
+
def wave_with_portage(cmd, with_portage_module)
|
|
85
|
+
cmd.extend with_portage_module
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
end # module WithPortage
|
|
90
|
+
|
|
91
|
+
def self.WithPortage(methname, &block)
|
|
92
|
+
Module.new do
|
|
93
|
+
include WithPortage
|
|
94
|
+
|
|
95
|
+
if block
|
|
96
|
+
define_method("maybe_#{methname}_with_portage".intern, &block)
|
|
97
|
+
else
|
|
98
|
+
module_eval <<-MAYBE
|
|
99
|
+
def maybe_#{methname}_with_portage(*args, &prc)
|
|
100
|
+
if with_portage?
|
|
101
|
+
#{methname}_with_portage(*args, &prc)
|
|
102
|
+
else
|
|
103
|
+
#{methname}_without_portage(*args, &prc)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
MAYBE
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
singleton_eval do # class << self
|
|
110
|
+
define_method(:append_features) do |mod|
|
|
111
|
+
super
|
|
112
|
+
mod.singleton_eval do # class << mod
|
|
113
|
+
define_method(:extend_object) do |obj|
|
|
114
|
+
super
|
|
115
|
+
obj.singleton_eval <<-ALIAS # class << obj
|
|
116
|
+
alias_method :#{methname}_without_portage, :#{methname}
|
|
117
|
+
alias_method :#{methname}, :maybe_#{methname}_with_portage
|
|
118
|
+
ALIAS
|
|
119
|
+
obj.instance_eval do
|
|
120
|
+
add_option '--[no-]portage',
|
|
121
|
+
"#{command.capitalize} using the portage system" do |v, h|
|
|
122
|
+
h[:with_portage] = v
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
obj.instance_eval &block if block
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end # WithPortage anon module
|
|
131
|
+
end
|
|
132
|
+
end # class Gem::Command
|
|
133
|
+
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
require 'g-gem/ebuild'
|
|
2
|
+
|
|
3
|
+
module Gem::Portage
|
|
4
|
+
class PortageCommand < Command
|
|
5
|
+
has_option :category, 'Portage category for the gems ebuilds',
|
|
6
|
+
:default_category => Gem::Portage::Ebuild::DEFAULT_CATEGORY
|
|
7
|
+
end # class PortageCommand
|
|
8
|
+
|
|
9
|
+
class EbuildCommand < PortageCommand
|
|
10
|
+
include Gem::LocalRemoteOptions
|
|
11
|
+
include GemSpecFetcher
|
|
12
|
+
|
|
13
|
+
has_option :overwrite, 'Whether to overwrite existing ebuilds or not',
|
|
14
|
+
:default => false
|
|
15
|
+
has_option :force, 'Execute actions even if the ebuild file was not generated by this command',
|
|
16
|
+
:default => true
|
|
17
|
+
has_option :dependencies, 'Execute actions for dependent gems also',
|
|
18
|
+
:default => true
|
|
19
|
+
has_option :portdir, 'Set the portage directory',
|
|
20
|
+
:default_dir => Gem::Portage::Ebuild::DEFAULT_PORTDIR
|
|
21
|
+
has_option :test_phase, 'Whether to generate ebuilds with test phase',
|
|
22
|
+
:default => true
|
|
23
|
+
has_option :install_dir, 'Target installation directory for the ebuild',
|
|
24
|
+
:default_dir => Gem::Portage::Ebuild::DEFAULT_INSTALL_DIR
|
|
25
|
+
has_option :ebuild_command, '--command x,y,z', Array, "The 'list' of ebuild(1) commands to execute or 'generate'",
|
|
26
|
+
:default => %w(generate digest)
|
|
27
|
+
|
|
28
|
+
def initialize(defaults=nil)
|
|
29
|
+
super('ebuild', 'Generate portage ebuilds from gem specification', defaults)
|
|
30
|
+
add_local_remote_options
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def usage
|
|
34
|
+
"#{program_name} GEM_NAME"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def arguments
|
|
38
|
+
return <<-ARGUMENTS
|
|
39
|
+
GEMNAME
|
|
40
|
+
ARGUMENTS
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def execute
|
|
44
|
+
fail Gem::CommandLineError, show_help if options[:args].empty?
|
|
45
|
+
fail <<-EOE unless (ebuild_command - Gem::Portage::Ebuild::COMMANDS).empty?
|
|
46
|
+
Invalid ebuild commands: #{ebuild_command.inspect}
|
|
47
|
+
|
|
48
|
+
Valid values are those listed on ebuild(1) and 'generate'
|
|
49
|
+
EOE
|
|
50
|
+
atoms = DependencyAtom.parse_list(options[:args])
|
|
51
|
+
execute_on(atoms)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def execute_on(atoms)
|
|
55
|
+
specs = Gem::DependencyList.from_atoms(spec_fetcher, atoms)
|
|
56
|
+
specs.include_dependencies(spec_fetcher) if dependencies?
|
|
57
|
+
create = ebuild_command.delete('generate')
|
|
58
|
+
specs.each_spec do |spec|
|
|
59
|
+
ebuild = Ebuild.for(spec, portdir, category)
|
|
60
|
+
if create and (overwrite? or not ebuild.exists?)
|
|
61
|
+
say "Generating #{ebuild.file_path} ..."
|
|
62
|
+
begin
|
|
63
|
+
File.delete(ebuild.digest_file)
|
|
64
|
+
rescue
|
|
65
|
+
end
|
|
66
|
+
ebuild.install_dir = File.expand_path(install_dir, Dir.pwd)
|
|
67
|
+
ebuild.enable_test_phase if test_phase?
|
|
68
|
+
ebuild.generate
|
|
69
|
+
ebuild.execute(*ebuild_command)
|
|
70
|
+
elsif force?
|
|
71
|
+
ebuild.execute(*ebuild_command)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
register
|
|
77
|
+
end # class EbuildCommand
|
|
78
|
+
end # module Gem::Portage
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
module Gem::Portage
|
|
2
|
+
module GemSpecFetcher
|
|
3
|
+
class << self
|
|
4
|
+
def LocalOrRemote(domain)
|
|
5
|
+
Module.new do
|
|
6
|
+
define_method(:local?) do
|
|
7
|
+
domain == :local || domain == :both
|
|
8
|
+
end
|
|
9
|
+
define_method(:remote?) do
|
|
10
|
+
domain == :remote || domain == :both
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def LocalOrRemote(domain)
|
|
17
|
+
GemSpecFetcher.LocalOrRemote(domain)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def fetch_local(dependency)
|
|
21
|
+
dir = dependency.respond_to?(:origin_dir) ? dependency.origin_dir : Dir.pwd
|
|
22
|
+
file = Gem::Portage::Utils::gem_file_for(dependency, dir)
|
|
23
|
+
raise "Gem for #{dependency} not found" unless file
|
|
24
|
+
spec = Gem::Format.from_file_by_path(file).spec
|
|
25
|
+
spec.singleton_eval do
|
|
26
|
+
define_method(:fetched_from) { file }
|
|
27
|
+
end
|
|
28
|
+
spec.extend LocalOrRemote(:local)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def fetch_remote(dependency)
|
|
32
|
+
remote_installer = Gem::RemoteInstaller.new
|
|
33
|
+
remote_source_index = remote_installer.source_index_hash
|
|
34
|
+
fetcher_proc = lambda do |dep|
|
|
35
|
+
spec, uri = remote_installer.find_gem_to_install(dep.name,
|
|
36
|
+
dep.version_requirements,
|
|
37
|
+
remote_source_index)
|
|
38
|
+
spec.singleton_eval do
|
|
39
|
+
define_method(:fetched_from) { uri }
|
|
40
|
+
end
|
|
41
|
+
spec.extend LocalOrRemote(:remote)
|
|
42
|
+
end
|
|
43
|
+
singleton_eval do
|
|
44
|
+
define_method(:fetch_remote, &fetcher_proc)
|
|
45
|
+
end
|
|
46
|
+
fetch_remote(dependency)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def local_fetcher
|
|
50
|
+
method(:fetch_local).extend LocalOrRemote(:local)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def remote_fetcher
|
|
54
|
+
method(:fetch_remote).extend LocalOrRemote(:remote)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def spec_fetcher(domain=nil)
|
|
58
|
+
domain = domain ? Object.new.extend(LocalOrRemote(domain)) : self
|
|
59
|
+
if domain.local? ^ domain.remote?
|
|
60
|
+
domain.local? ? local_fetcher : remote_fetcher
|
|
61
|
+
else
|
|
62
|
+
lambda do |dependency|
|
|
63
|
+
begin
|
|
64
|
+
local_fetcher[dependency]
|
|
65
|
+
rescue
|
|
66
|
+
remote_fetcher[dependency]
|
|
67
|
+
end
|
|
68
|
+
end.extend LocalOrRemote(:both)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def fetch_spec(dependency)
|
|
73
|
+
spec_fetcher[dependency]
|
|
74
|
+
end
|
|
75
|
+
end # class GemFetcher
|
|
76
|
+
|
|
77
|
+
end # module Gem::Portage
|
data/lib/g-gem/utils.rb
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
module Gem::Portage; end
|
|
2
|
+
module Gem::Portage::Utils
|
|
3
|
+
GEMFILE_VERSION_RE = /-(\d+(\.\d+)*)\.gem$/
|
|
4
|
+
class << self
|
|
5
|
+
def gem_file_for(dependency, dir=nil)
|
|
6
|
+
dir ||= Dir.pwd
|
|
7
|
+
dir = File.expand_path(dir, Dir.pwd)
|
|
8
|
+
entries = Dir.glob(File.join(dir, "#{dependency.name}-*.gem"))
|
|
9
|
+
entries.find do |f|
|
|
10
|
+
next unless f =~ GEMFILE_VERSION_RE
|
|
11
|
+
dependency.version_requirements.satisfied_by?(Gem::Version.create($1))
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
class ConfigFile
|
|
17
|
+
def initialize(path="/etc/make.conf")
|
|
18
|
+
@path = path
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def to_s
|
|
22
|
+
@path
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def exists?
|
|
26
|
+
File.exists?(@path)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def readable?
|
|
30
|
+
File.readable?(@path)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def cache
|
|
34
|
+
@@cache ||= {}
|
|
35
|
+
end
|
|
36
|
+
private :cache
|
|
37
|
+
|
|
38
|
+
def succ
|
|
39
|
+
res = case @path
|
|
40
|
+
when "/etc/make.conf"
|
|
41
|
+
ConfigFile.new("/etc/profile/make.defaults")
|
|
42
|
+
when "/etc/profile/make.defaults"
|
|
43
|
+
ConfigFile.new(File.join(File.expand_path(File.readlink("/etc/make.profile"), "/etc"), "make.defaults"))
|
|
44
|
+
else
|
|
45
|
+
parent = @path.sub(/make.defaults$/, 'parent')
|
|
46
|
+
if File.readable?(parent)
|
|
47
|
+
File.open(parent, 'r') do |f|
|
|
48
|
+
f.each_line do |line|
|
|
49
|
+
next if /^\s*$|^\s*#.*$/ === line
|
|
50
|
+
parent = line.chomp
|
|
51
|
+
break
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
parent = File.expand_path(parent, File.dirname(@path))
|
|
55
|
+
ConfigFile.new(File.join(parent, "make.defaults"))
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
res.exists? ? res : res.succ unless res.nil?
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def [](var)
|
|
62
|
+
var = var.to_sym
|
|
63
|
+
cache[var] or \
|
|
64
|
+
if readable? && !File.read(@path).scan(/^\s*#{var.to_s}\s*=\s*(.+)/).empty?
|
|
65
|
+
cache[var] = $1.gsub(/^"|"$/, '') unless $1.nil?
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def search(var)
|
|
70
|
+
self[var] or \
|
|
71
|
+
begin
|
|
72
|
+
succ_conf = self.succ
|
|
73
|
+
succ_conf.search(var) if succ_conf
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
class << self
|
|
78
|
+
def [](var)
|
|
79
|
+
new.search(var)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
end # class ConfigFile
|
|
84
|
+
|
|
85
|
+
end # module Gem::Portage::Utils
|
metadata
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
!ruby/object:Gem::Specification
|
|
2
|
+
rubygems_version: 0.8.10
|
|
3
|
+
specification_version: 1
|
|
4
|
+
name: g-gem
|
|
5
|
+
version: !ruby/object:Gem::Version
|
|
6
|
+
version: 0.1.0
|
|
7
|
+
date: 2005-10-10
|
|
8
|
+
summary: g-gem is a plugin for rubygems for integration with the gentoo's portage system
|
|
9
|
+
require_paths:
|
|
10
|
+
- lib
|
|
11
|
+
email: vhborja@gmail.com
|
|
12
|
+
homepage: http://www.rubyforge.org/projects/g-gem
|
|
13
|
+
rubyforge_project:
|
|
14
|
+
description:
|
|
15
|
+
autorequire: g-gem
|
|
16
|
+
default_executable: g-gem
|
|
17
|
+
bindir: bin
|
|
18
|
+
has_rdoc: false
|
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
|
20
|
+
requirements:
|
|
21
|
+
- - ">"
|
|
22
|
+
- !ruby/object:Gem::Version
|
|
23
|
+
version: 0.0.0
|
|
24
|
+
version:
|
|
25
|
+
platform: ruby
|
|
26
|
+
authors:
|
|
27
|
+
- Victor Borja
|
|
28
|
+
files:
|
|
29
|
+
- lib/g-gem.rb
|
|
30
|
+
- lib/g-gem/core_extensions.rb
|
|
31
|
+
- lib/g-gem/portage_commands.rb
|
|
32
|
+
- lib/g-gem/gems_commands_with_portage.rb
|
|
33
|
+
- lib/g-gem/gems_extensions.rb
|
|
34
|
+
- lib/g-gem/ebuild.rb
|
|
35
|
+
- lib/g-gem/command.rb
|
|
36
|
+
- lib/g-gem/spec_fetcher.rb
|
|
37
|
+
- lib/g-gem/utils.rb
|
|
38
|
+
test_files: []
|
|
39
|
+
|
|
40
|
+
rdoc_options: []
|
|
41
|
+
|
|
42
|
+
extra_rdoc_files: []
|
|
43
|
+
|
|
44
|
+
executables:
|
|
45
|
+
- g-gem
|
|
46
|
+
extensions: []
|
|
47
|
+
|
|
48
|
+
requirements: []
|
|
49
|
+
|
|
50
|
+
dependencies: []
|
|
51
|
+
|