[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

[PATCH] set-props.pl: recursively set props on a working copy

From: Michael W Thelen <thelenm_at_cs.utah.edu>
Date: 2004-07-21 09:51:10 CEST

Here is a Perl program I've written to recursively set properties on the files
and directories in a working copy, based on the contents of the auto-props
section of a configuration file. This script could be useful for those who
have imported files to version control before enabling auto-props, and now
want to add properties to those files as if auto-props had been enabled in the
first place.

In my particular case, I had purposely imported some third-party packages as
vendor drops with the --no-auto-props flag. I did that because some of the
files in the package contained inconsistent line endings, and you cannot set
svn:eol-style on such files. This script also incorporates the ability to fix
inconsistent line endings while setting the svn:eol-style property, and the
ability to set the svn:executable property for files that are executable.

I've only tested it on Linux. It can probably be made to work on Windows
without too much effort. The program doesn't take advantage of the Perl
bindings; it just calls the command-line "svn propset" to do its work.

Do you think this may be a good script to include under contrib? This patch
adds it as a new script "set-props.pl" under contrib/client-side.

Log:
* contrib/client-side/set-props.pl:
  New client side script. Recursively sets properties on the files and
  directories in a working copy, based on the contents of the auto-props
  section of a configuration file. This script could be useful for those who
  have imported files to version control before enabling auto-props, and now
  want to add properties to those files as if auto-props had been enabled in
  the first place. The script also incorporates the ability to fix
  inconsistent line endings while setting the svn:eol-style property, and the
  ability to set the svn:executable property for files that are executable.

Index: contrib/client-side/set-props.pl
===================================================================
--- contrib/client-side/set-props.pl (revision 0)
+++ contrib/client-side/set-props.pl (revision 0)
@@ -0,0 +1,125 @@
+#!/usr/bin/perl
+
+# set-props.pl
+# Recursively set properties on files and directories in a working copy
+# according to the auto-props section of a configuration file.
+
+use strict;
+use warnings;
+use Config::IniFiles;
+use File::Find;
+use Getopt::Long;
+
+GetOptions('config-file|F=s' => \my $config_file,
+ 'non-recursive|N' => \my $non_recursive,
+ 'set-executable|X' => \my $set_executable,
+ 'fix-line-endings|L' => \my $fix_line_endings,
+ 'help|h' => \my $help,
+ );
+
+usage() if $help;
+
+# Default to $HOME/.subversion/config, then /etc/subversion/config
+unless (defined $config_file) {
+ $config_file = "$ENV{'HOME'}/.subversion/config";
+ $config_file = "/etc/subversion/config" unless -e $config_file;
+}
+usage("Cannot find configuration file") unless -e $config_file;
+
+# Default to . if no paths specified
+my @paths = @ARGV ? @ARGV : ('.');
+
+# Get auto-props from config file
+my %config;
+tie %config, 'Config::IniFiles', (-file => $config_file);
+die "No auto-props section found in $config_file.\n"
+ unless exists $config{'auto-props'};
+
+# Create a structure of auto-props from the configuration file. Change glob
+# patterns into regular expressions. Only change "*" into ".*"; don't worry
+# about [], {}, etc. because Subversion doesn't. To change the globbish
+# pattern into a regular expression, first quote all special chars (including
+# "\", "*", and "?"), then undo the escaping of those three chars, then change
+# instances of "*" to ".*" and change instances of "?" to ".". Only change
+# instances where there is an even number of backslashes before the "*" or
+# "?".
+my %autoprops;
+for my $key (keys %{$config{'auto-props'}}) {
+ my $val = $config{'auto-props'}->{$key};
+ $key = quotemeta $key;
+ $key =~ s/\\([\\*?])/$1/g;
+ $key =~ s/(?<!\\)((?:\\\\)*)\*/$1.*/g;
+ $key =~ s/(?<!\\)((?:\\\\)*)\?/$1./g;
+ my %props;
+ for (split /;/, $val) {
+ my ($prop, $pval) = split /=/, $_;
+ $props{$prop} = defined $pval ? $pval : '';
+ }
+ $autoprops{$key} = \%props;
+}
+
+# Recurse into paths, calling set_props for each file or directory
+find({wanted => \&set_props, no_chdir => 1}, @paths);
+
+sub set_props
+{
+ my $name = $_;
+ $File::Find::prune = 1, return if $name =~ /(?:^|\/).svn\z/;
+
+ # Set svn:executable if the file is executable
+ system 'svn', 'propset', 'svn:executable', '', $name if $set_executable
+ and -f $name and -x _;
+
+ # Look for matching patterns, and apply properties
+ for my $pattern (keys %autoprops) {
+ next unless $name =~ /(?:^|\/)$pattern\z/s;
+ my $props = $autoprops{$pattern};
+ for my $prop (keys %$props) {
+ my $propval = $props->{$prop};
+ if ($fix_line_endings and $prop eq 'svn:eol-style') {
+ fix_line_endings($name, $propval);
+ }
+ system 'svn', 'propset', $prop, $propval, $name;
+ }
+ }
+
+ $File::Find::prune = 1 if $non_recursive;
+}
+
+# Fix inconsistent line endings if setting svn:eol-style. Just change all
+# instances of \r\n or \r to a simple \n. Subversion will take care of the
+# rest.
+sub fix_line_endings
+{
+ my ($file, $style) = (@_);
+ open IN, "$file" or warn "Can't read '$file': $!\n" and return;
+ my ($seen_lf, $seen_crlf, $seen_cr) = (0) x 3;
+ while (<IN>) {
+ $seen_lf = 1 if /(?<!\r)\n/;
+ $seen_crlf = 1 if /\r\n/;
+ $seen_cr = 1 if /\r(?!\n)/;
+ last if ($seen_lf + $seen_crlf + $seen_cr) > 1;
+ }
+ close IN;
+
+ if (($seen_lf + $seen_crlf + $seen_cr) > 1) {
+ print "Fixing line endings for '$file'\n";
+ system qw(perl -pi -e s/\r\n?/\n/g), $file;
+ }
+}
+
+sub usage
+{
+ warn "@_\n" if @_;
+ die <<EOF
+usage: $0 [PATHS...]
+
+Valid options:
+ -h [--help] : display this help screen
+ -N [--non-recursive] : do not operate on subdirectories
+ -F [--config-file] arg : read configuration file ARG
+ -X [--set-executable] : set svn:executable on files that are executable
+ -L [--fix-line-endings] : fix inconsistent line endings for svn:eol-style
+
+EOF
+}

-- Mike

-- 
Michael W. Thelen
I believe there are more instances of the abridgement of the freedom of the
people by gradual and silent encroachments of those in power than by violent
and sudden usurpations.
                -- James Madison

Received on Wed Jul 21 09:53:08 2004

This is an archived mail posted to the Subversion Dev mailing list.