Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Ruby script for performing checkout in Subversion (See related posts)

This Ruby script checkouts Subversion repositories. If during checkout it encounters two or more externals that point to the same directory, that directory is only downloaded once and symbolic links are created where appropriate, avoiding duplication. It requires the Ruby Subversion bindings.

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

You need to create an account or log in to post comments to this site.


Click here to browse all 5137 code snippets

Related Posts