Skip to content

Instantly share code, notes, and snippets.

@oelmekki
Created June 4, 2009 20:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save oelmekki/123833 to your computer and use it in GitHub Desktop.
Save oelmekki/123833 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
require 'rubygems'
require 'rubygems/gem_runner'
require 'rubygems/exceptions'
require 'readline'
module Gem
class StreamUI
def say( statement = '' )
@@buffer ||= []
@@buffer << statement
end
def self.flush
return @@buffer
end
end
end
module PortageGateway
class Runner
def initialize( provided_file = nil )
@provided = provided_file
check_provided_file
run
register_in_package_provided
end
protected
def check_provided_file
@provided ||= '/etc/portage/profile/package.provided'
unless File.writable? @provided
puts "Error: #{@provided} is not writable. Exiting."
exit 1
end
end
def find_portage_packages
@found ||= {}
@notFound ||= {}
@packages.each do |name,package|
found = %x(eix -C dev-ruby -e #{name}).split("\n")[0]
if found =~ /#{name}/
package[ 'portage' ] = "dev-ruby/#{name}"
@found[ name ] = package
else
@notFound[ name ] = package
end
end
end
def register_in_package_provided
file = File.new( @provided, 'a' )
@found.each do |name,package|
file.puts "#{package[ 'portage' ]}-#{package[ 'version' ]}"
end
file.close
puts "Done."
end
end
class Populater < Runner
protected
def run
get_local_gems
intersect_packages
find_portage_packages
report_and_ask_to_continue
end
def get_local_gems
Gem::GemRunner.new.run %w( list )
@packages ||= {}
@locals = Gem::StreamUI::flush#[0].split( "\n" )
@locals.delete_if { |line| line !~ /^\S+ \(.*\)/ }
@locals = @locals.first.split( "\n" )
@locals.each do |line|
line =~ /^(\S+) \((.*)\)$/
name, versions_string = $1, $2
versions = versions_string.gsub( / +/, '' ).split( ',' )
@packages[ name ] = { 'version' => versions.last }
end
end
def intersect_packages
provided = File.read( @provided ).gsub( / +/, '' ).split( "\n" )
@packages.delete_if { |name,package| provided.include?( "dev-ruby/#{name}-#{package[ 'version' ]}" ) }
end
def report_and_ask_to_continue
puts "Those packages will be added to package.provided : "
@found.each { |name,package| puts "- #{name}-#{package[ 'version' ] }" }
puts
puts "Not found in portage : "
@notFound.each { |name,package| puts "- #{name}" }
puts
puts "Continue? (y/N)"
answer = Readline.readline( '> ' )
if answer != 'y'
exit
end
end
end
class Updater < Runner
protected
def run
find_outdated
parse_packages
find_portage_packages
report_and_ask_to_continue
do_the_update
end
def find_outdated
Gem::GemRunner.new.run %w( outdated )
@outdated = Gem::StreamUI::flush
end
def parse_packages
@packages ||= {}
@outdated.each do |package|
if package =~ /^(\S+) \(\S+ < (\S+)\)/
@packages[ $1 ] = { 'version' => $2 }
else
puts "don't understand : #{package}. Sorry."
end
end
end
def report_and_ask_to_continue
puts "#{@outdated.length} package to update"
puts "Found in portage : "
@found.each { |name,package| puts "- #{name}" }
puts
puts "Not found in portage : "
@notFound.each { |name,package| puts "- #{name}" }
puts
puts "Continue? (y/N)"
answer = Readline.readline( '> ' )
if answer != 'y'
exit
end
end
def do_the_update
Gem::GemRunner.new.run %w( update )
Gem::StreamUI::flush.each do |line|
puts line
end
end
end
end
mode = ARGV[0]
unless %w( update populate ).include?( mode )
app = File.basename($0)
puts "usage: #{app} [update|populate]"
puts
puts " #{app} let portage knows about gem managed packages."
puts " populate: scan locally installed gems and put them in package.provided if they are not yet."
puts " update: run gem update and add new installed packages in package.provided if the same package name exists in dev-ruby"
exit 1
end
case mode
when 'update'
PortageGateway::Updater.new
when 'populate'
PortageGateway::Populater.new
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment