vss_deleted_files.rb #4

  • //
  • guest/
  • robert_cowham/
  • perforce/
  • utils/
  • vss_deleted_files.rb
  • View
  • Commits
  • Open Download .zip Download (5 KB)
#!/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

# Change User Description Committed
#4 5177 Robert Cowham Working and linked to docs.
#3 5172 Robert Cowham Tidied.
#2 5171 Robert Cowham Tidied up with parameters etc.
#1 5170 Robert Cowham Ruby version