Call set_source in GGem#mass_generate to have proper SRC_URI
[g-gem.git] / g-gem.rb
blob9ad812210fc572ba56d8ac8b335eeaef3737c28d
1 require 'portage'
2 require 'depatom'
3 require 'ebuild'
5 module GGem
6   @@gri = nil
7   @@sources = nil
9   SHORTMAP = {
10     'p' => :prepend,
11     'h' => :help,
12     'v' => :verbose,
13   }
14   
15   LONGMAP = {
16     'prepend' => :prepend,
17     'verbose' => :verbose,
18     'help' => :help,
19     'generate' => :generate,
20     'madgen' => :mass_generate,
21   }
23   class << self
25     attr_accessor :options
27     def main
28       @options, packages = parse_opts(ARGV)
29       Portage.setup_overlay(options[:prepend])
31       mass_generate and return if @options[:mass_generate] == true
33       spec_groups = packages.map {|pkg| get_specs(pkg)}
34       all_specs = spec_groups.flatten
36       ebuilds = []
37       for spec in all_specs
38         puts "Create ebuild for #{spec.full_name}" if options[:verbose]
39         gem_ebuild = Ebuild.new(spec)
40         gem_ebuild.write
41         ebuilds << gem_ebuild
42       end
43       # No prepend, digest the ebuilds
44       if options[:prepend] == false
45         ebuilds.each {|ebuild| ebuild.execute('digest')}
46       end
47       # don't specify --generate, continue digest and emerge
48       if options[:generate] == false 
49         system('emerge '+ARGV.join(' ')) 
50       else
51         puts "Ebuilds are in #{Portage.rubydev_overlay}"
52       end
54       # don't clean up if --generate because overlay may be /tmp/*
55       Portage.cleanup unless options[:generate] == true
56     end
58     def get_specs(pkg)
59       specs = []
60       navigate(pkg.package_name,pkg.gem_requirement) { |spec| specs << spec }
61       specs.reverse
62     end
64     def navigate(gem_name,gem_version = nil,&block)
65       if Portage.ebuild_exists(gem_name,gem_version)
66         puts "Ebuild for #{gem_name} exists" if options[:verbose]
67         return true 
68       end
69       # cache source_index_hash, no need to recheck it everytime
70       @@gri = Gem::RemoteInstaller.new if @@gri.nil?
71       @@sources = @@gri.source_index_hash if @@sources.nil?
72       version_requirement = gem_version.is_a?(Gem::Version::Requirement) ? gem_version : Gem::Version::Requirement.new(gem_version || ">= 0")
73       gem_spec = nil
74       for source_name,source in @@sources
75         specs = source.find_name(gem_name, version_requirement)
76         next if specs.nil? or specs.empty?
77         # ignore mswin32 platform
78         satisfied_specs = specs.find_all do |spec|
79           spec.platform == 'ruby' and
80             version_requirement.satisfied_by?(spec.version)
81         end
82         gem_spec = satisfied_specs[-1]
83         class << gem_spec
84           def local?() false; end
85           def set_source(source)
86             @source = source
87           end
88           def fetched_from
89             @source
90           end
91         end
92         gem_spec.set_source(source_name)
93         break
94       end
95       if gem_spec.nil?
96         puts "#{gem_name} not found"
97         return false
98       end
99       yield(gem_spec)
100       for dep in gem_spec.dependencies
101         navigate(dep.name, dep.requirement_list, &block)
102       end
103       true
104     end
106     def parse_opts(argv)
107       opts = {
108         :prepend => false,
109         :generate => false,
110         :help => false,
111         :verbose => false,
112         :mass_generate => false
113       }
114       packages = []
115     
116       for arg in argv
117         if arg =~ /^-[^-]/
118           for i in 1..arg.length-1
119             if SHORTMAP.key? arg[i..i]
120               opts[SHORTMAP[arg[i..i]]] = true
121             else
122               puts "Unknown option '-#{arg[i..i]}'"
123             end
124           end
125         elsif arg =~ /^--/
126           if LONGMAP.key? arg[2..-1]
127             opts[LONGMAP[arg[2..-1]]] = true
128           else
129             puts "Unknown option '#{arg}'"
130           end
131         else
132           packages << DependencyAtom.new(arg)
133         end
134       end
135       return opts, packages
136     end
138     def mass_generate
139       @@gri = Gem::RemoteInstaller.new if @@gri.nil?
140       @@sources = @@gri.source_index_hash if @@sources.nil?
141       for source_name,source in @@sources
142         source.each do |full_name,spec|
143           if spec.platform == 'ruby'
144             puts full_name
145             class << spec
146               def local?() false; end
147               def set_source(source) @source = source end
148               def fetched_from() @source end
149             end
150             spec.set_source(source_name)
151             e = Ebuild.new(spec)
152             e.write
153           end
154         end
155       end
156     end
157   end