Ruby script for performing checkout in Subversion
This is my first Ruby program.
1 2 #!/usr/bin/env ruby 3 4 require 'optparse' 5 require 'ostruct' 6 require 'uri' 7 require 'pathname' 8 require 'fileutils' 9 require 'svn/repos' 10 11 class Checkout 12 attr_accessor :url, :pathname, :revision 13 14 def initialize(url,pathname, revision=nil) 15 @url = url 16 @pathname = pathname 17 @revision = revision 18 end 19 20 def perform(ctx) 21 ctx.checkout @url, @pathname.to_s, @revision, nil, true, true 22 proppy = (ctx.propget "svn:externals", @url)[@url] 23 24 if proppy==nil 25 proppy=[] 26 else 27 lines = proppy.split "\n" 28 29 lines.map { |line| 30 splitted = line.split " " 31 sub_path= Pathname.new(splitted.shift) 32 sub_url= splitted.pop 33 sub_revision= nil 34 35 if !splitted.empty? 36 revnumber_string = splitted.shift.scan(/[0-9]+/).shift 37 sub_revision = revnumber_string.to_i 38 end 39 40 Checkout.new(sub_url,@pathname.join(sub_path),sub_revision) 41 } 42 end 43 end 44 end 45 46 def parse_args(args) 47 options = OpenStruct.new 48 49 options.revision = nil; 50 51 opts = OptionParser.new do |opts| 52 opts.banner = "Usage: example.rb URL [PATH]" 53 54 opts.separator "" 55 opts.separator "Valid options:" 56 57 # Mandatory argument. 58 opts.on("-r", "--revision arg","Revision number") do |rev| 59 options.revision = rev.to_i 60 end 61 62 opts.on_tail("-h", "--help", "Show this message") do 63 puts opts 64 exit 65 end 66 end 67 68 opts.parse!(args) 69 70 if args.empty? 71 print "Repository URL needed", "\n" 72 exit 73 end 74 75 options.url = args.shift 76 77 if !args.empty? 78 options.pathname = Pathname.new(args.shift) 79 else 80 uri = URI.parse(options.url) 81 options.pathname = Pathname.new(uri.path).basename 82 end 83 84 if !args.empty? 85 print "Too many arguments", "\n" 86 exit 87 end 88 89 Checkout.new(options.url,options.pathname,options.revision) 90 end 91 92 93 # we parse the args 94 initial_checkout = parse_args(ARGV) 95 96 # we create a client context 97 ctx = Svn::Client::Context.new 98 ctx.add_simple_provider 99 homedir=ENV['HOME'] 100 ctx.auth_baton[Svn::Core::AUTH_PARAM_CONFIG_DIR] = "#{homedir}/.subversion" 101 # ctx.auth_baton[Svn::Core::AUTH_PARAM_DEFAULT_USERNAME] = "foouser" 102 # ctx.auth_baton[Svn::Core::AUTH_PARAM_DEFAULT_PASSWORD] = "foopasswd" 103 104 # we initialize the data structures 105 checkout_queue = [initial_checkout] 106 pathname_cache = {} 107 108 # we traverse the tree 109 while !checkout_queue.empty? 110 checkout = checkout_queue.shift 111 112 cached_path = pathname_cache[checkout.url] 113 114 if cached_path==nil 115 colist = checkout.perform ctx 116 colist.each { |co| checkout_queue.push co } 117 pathname_cache[checkout.url] = checkout.pathname 118 119 puts "check out #{checkout.url} -> #{checkout.pathname}" 120 else 121 relative_path=cached_path.relative_path_from(checkout.pathname.dirname) 122 FileUtils.ln_sf(relative_path, checkout.pathname) 123 124 puts "link #{cached_path} -> #{checkout.pathname}" 125 end 126 end