#!/usr/bin/env ruby
#
# $Id: //guest/robert_cowham/perforce/utils/vss_deleted_files.rb#4 $
#
# Author: Robert Cowham
# Copyright (c) 2005 Robert Cowham
#
# =DESCRIPTION
# Script to print out "deleted" files in VSS
#
# Uses VSS OLE Automation
# Documentation on VSS Object Model can be found at:
# http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvss/html/msdn_vssole.asp
#
# Usual disclaimers apply!
require 'win32ole'
require 'getoptlong'
# Module for constants to be loaded into
module VSS_CONST
end
class DeletedFiles
attr_reader :count, :deleted_count, :deleted_dirs_count
def initialize(vssdb)
@vssdb = vssdb
@count = 0
@deleted_count = 0
@deleted_dirs_count = 0
end
# Recurse down the list of VSS directories looking for deleted files
def vss_dir_tree(rt)
begin
root = @vssdb.VSSItem(rt, 1)
@deleted_dirs_count += 1
print "\'#{rt}\'\n"
rescue
root = @vssdb.VSSItem(rt, 0)
end
items = root.Items(1)
items.each{|item|
if (item.Type == VSS_CONST::VSSITEM_PROJECT)
dir = item.Name
vss_dir_tree("#{rt}/#{dir}")
else
check_deleted("#{rt}/#{item.Name}")
end
}
end
def check_deleted(file)
@count += 1
begin
item = @vssdb.VSSItem(file, 1)
rescue
return
end
if item.Deleted
@deleted_count += 1
print "'#{file}'\n"
end
end
end
#
# Main application class
#
class App
VERSION = "$Revision: #4 $"
REVISION_DATE = "$Date: 2005/10/31 $"
AUTHOR = "Robert Cowham"
#
# Returns a version string similar to:
# <app_name>: Version: 1.2 Created on: 2002/05/08 by Jim Freeze
# The version number is maintained by CVS.
# The date is the last checkin date of this file.
#
def version
"Version: #{VERSION.split[1]} Created on: " +
"#{REVISION_DATE.split[1]} by #{AUTHOR}"
end
def initialize
@debug = false
@verbose = false
@user = nil
@password = nil
@srcsafeini = nil
if 0 == ARGV.size
STDERR.puts usage
exit 1
end
get_options
rescue => err
STDERR.puts err
STDERR.puts usage
exit 1
end
#
# Returns usage string
#
def usage
<<-USAGE
Usage: #{File.basename $0} -u <user> -p <password> -s <srcsafeini> [-v] file_or_dir
-v|--verbose print intermediate steps to STDERR
-u|--user SourceSafe user
-p|--password SourceSafe password
-s|--srcsafeini Full path to srcsafe.ini file
USAGE
end
#
# Processes command line arguments
#
def get_options
opts = GetoptLong.new(
[ '--verbose', '-v', GetoptLong::OPTIONAL_ARGUMENT],
[ '--user', '-u', GetoptLong::REQUIRED_ARGUMENT],
[ '--password', '-p', GetoptLong::REQUIRED_ARGUMENT],
[ '--srcsafeini', '-s', GetoptLong::REQUIRED_ARGUMENT],
[ '--help', '-h', GetoptLong::REQUIRED_ARGUMENT]
)
opts.each do |opt, arg|
case opt
when "--verbose"
@verbose = true
when "--user"
@user = arg
when "--password"
@password = arg
when "--srcsafeini"
@srcsafeini = arg
when "--help"
puts usage
else
raise "Invalid option '#{opt}'."
end
end
if ARGV.size != 1
puts usage
raise "VSS Path argument required: [vssdir]\ne.g.\n \"\$/Project 1/subdir\"\n"
end
@root = ARGV[0]
rescue NameError => err
STDERR.puts "ERROR: #{err}"
exit 1
rescue => err
STDERR.puts "ERROR: #{err}"
exit 1
end
#
# Launches the application
# App.new.run
#
def run
# Load up VSS Ole Automation
vssdb = WIN32OLE.new('SourceSafe')
WIN32OLE.const_load(vssdb, VSS_CONST)
vssdb.Open(@srcsafeini, @user, @password)
print "Deleted VSS files in '#{@root}':\n"
df = DeletedFiles.new(vssdb)
df.vss_dir_tree(@root)
print "\n#{df.deleted_count} deleted files out of #{df.count} files in total.\n"
print "#{df.deleted_dirs_count} deleted directories.\n"
end#run
end#App
app = App.new.run