Oct 28, 2009

Default settings of svn:keywords property

Keyword expansion is not the default for files added to an SVN repository.  And it’s done on a per file basis (with CVS we could configure an entire repository to turn on keyword expansion — .)  Some svn tools and plugins allow for defaulting properties when adding new files.  I’ve configured the two I use most often (eclipse and smartsvn) to the svn:keywords property for all new files:

svn:keywords : Date Revision Author URL Id

You can see a file’s properties from the command line with

svn pl -v filename

Some tool (like netbeans) don’t provide for defaulting properties when adding new files.  And there are probably some people (not gonna name names :^) who don’t configure their tools to default the svn:keywords property anyway.  So below is a little script that’ll do it for you.  The script is in ruby ’cause Brian (who first sketched it out a few years ago for a project) wanted to do some ruby scripting.

You can run it from time to time from the command line or better yet, set up a cron job on the build server to do it once or twice a day.  Our cron job does something like this:

cd ~/tmp/scratch-dir
svn checkout https://opi.svn.cvsdude.com/xyzzy
add_svn_keywords.rb
svn commit -m "Added svn:keywords property"

It’s up to you if you want to do a full checkout each time (an update would be faster.)

Here’s the script…

#!/usr/bin/ruby
#
# Adds svn:keywords property to source files.  Default to process the
# current directory.  Note: this does not commit the changes!
#
# Usage:
#   ruby add_svn_keywords.rb [src_dir]
#
# where
#   src_dir (Optional) The directory to process.
#
# for example
#   ruby add_svn_keywords.rb c:/mnscu/hr/code
#
require 'find'
require 'fileutils'
include FileUtils::Verbose
require 'ftools'
require 'optparse'

# -- functions --------------------------------------------------------------

def do_system(command)
    puts command
    system(command) or raise($?)
end

# -- vars -------------------------------------------------------------------

working_dir = "."
keywords = "Date Revision Author URL Id"
usage = "Usage: ruby add_svn_keywords.rb [src_dir]"

# -- options and svn checkout/update ----------------------------------------

opts = OptionParser.new
opts.parse(ARGV) rescue usage

unless ARGV[0].nil?
    working_dir = ARGV[0]
end

# -- svn properties ---------------------------------------------------------

num = 0
Find.find(working_dir) do |path|

    if FileTest.directory?(path)
        if File.basename(path) == '.svn'
            # allways skip the .svn dirs
            Find.prune
        else
            # don't bother setting properties on dirs
            next
        end
    else # must be a file...
        # quote spaces on paths that contain them (so svn wont fail)
        path.gsub!(/ /, ' ')

        # add keywords property to some files...
        if File.file?(path) and path =~ /.(ddl|bat|sh|css|dtd|el|groovy|gsp|html|java|js|jsp|properties|sql|txt|xml)$/
            keywordprop = `svn proplist --verbose #{path}`.to_a.find_all {|line| line.include? keywords  }
            if keywordprop.size == 0
                do_system("svn propset svn:keywords "#{keywords}" #{path}")
                num += 1
            end
        end
    end
end # find

# -- commit and cleanup -----------------------------------------------------

if num > 0
    #do_system("svn commit -m "Added svn:keywords property" #{working_dir}");
    puts "Added svn:keywords property to: #{num} files"
else
    puts "No changes"
end

# -- end of file ------------------------------------------------------------

About the Author

Object Partners profile.
Leave a Reply

Your email address will not be published.

Related Blog Posts
Android Development for iOS Developers
Android development has greatly improved since the early days. Maybe you tried it out when Android development was done in Eclipse, emulators were slow and buggy, and Java was the required language. Things have changed […]
Add a custom object to your Liquibase diff
Adding a custom object to your liquibase diff is a pretty simple two step process. Create an implementation of DatabaseObject Create an implementation of SnapshotGenerator In my case I wanted to add tracking of Stored […]
Keeping Secrets Out of Terraform State
There are many instances where you will want to create resources via Terraform with secrets that you just don’t want anyone to see. These could be IAM credentials, certificates, RDS DB credentials, etc. One problem […]
Validating Terraform Plans using Open Policy Agent
When developing infrastructure as code using terraform, it can be difficult to test and validate changes without executing the code against a real environment. The feedback loop between writing a line of code and understanding […]