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.
@@ -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) }
@@ -0,0 +1,12 @@
1
+ require 'rubygems'
2
+ Gem.manage_gems
3
+ %w{
4
+ g-gem/core_extensions
5
+ g-gem/spec_fetcher
6
+ g-gem/utils
7
+ g-gem/ebuild
8
+ g-gem/command
9
+ g-gem/portage_commands
10
+ g-gem/gems_extensions
11
+ g-gem/gems_commands_with_portage
12
+ }.map { |f| require f }
@@ -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
@@ -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
@@ -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
+