This is my first Ruby program.
#!/usr/bin/env ruby require 'optparse' require 'ostruct' require 'uri' require 'pathname' require 'fileutils' require 'svn/repos' class Checkout attr_accessor :url, :pathname, :revision def initialize(url,pathname, revision=nil) @url = url @pathname = pathname @revision = revision end def perform(ctx) ctx.checkout @url, @pathname.to_s, @revision, nil, true, true proppy = (ctx.propget "svn:externals", @url)[@url] if proppy==nil proppy=[] else lines = proppy.split "\n" lines.map { |line| splitted = line.split " " sub_path= Pathname.new(splitted.shift) sub_url= splitted.pop sub_revision= nil if !splitted.empty? revnumber_string = splitted.shift.scan(/[0-9]+/).shift sub_revision = revnumber_string.to_i end Checkout.new(sub_url,@pathname.join(sub_path),sub_revision) } end end end def parse_args(args) options = OpenStruct.new options.revision = nil; opts = OptionParser.new do |opts| opts.banner = "Usage: example.rb URL [PATH]" opts.separator "" opts.separator "Valid options:" # Mandatory argument. opts.on("-r", "--revision arg","Revision number") do |rev| options.revision = rev.to_i end opts.on_tail("-h", "--help", "Show this message") do puts opts exit end end opts.parse!(args) if args.empty? print "Repository URL needed", "\n" exit end options.url = args.shift if !args.empty? options.pathname = Pathname.new(args.shift) else uri = URI.parse(options.url) options.pathname = Pathname.new(uri.path).basename end if !args.empty? print "Too many arguments", "\n" exit end Checkout.new(options.url,options.pathname,options.revision) end # we parse the args initial_checkout = parse_args(ARGV) # we create a client context ctx = Svn::Client::Context.new ctx.add_simple_provider homedir=ENV['HOME'] ctx.auth_baton[Svn::Core::AUTH_PARAM_CONFIG_DIR] = "#{homedir}/.subversion" # ctx.auth_baton[Svn::Core::AUTH_PARAM_DEFAULT_USERNAME] = "foouser" # ctx.auth_baton[Svn::Core::AUTH_PARAM_DEFAULT_PASSWORD] = "foopasswd" # we initialize the data structures checkout_queue = [initial_checkout] pathname_cache = {} # we traverse the tree while !checkout_queue.empty? checkout = checkout_queue.shift cached_path = pathname_cache[checkout.url] if cached_path==nil colist = checkout.perform ctx colist.each { |co| checkout_queue.push co } pathname_cache[checkout.url] = checkout.pathname puts "check out #{checkout.url} -> #{checkout.pathname}" else relative_path=cached_path.relative_path_from(checkout.pathname.dirname) FileUtils.ln_sf(relative_path, checkout.pathname) puts "link #{cached_path} -> #{checkout.pathname}" end end