| SVN-S4 documentation | Contained in the SVN-S4 distribution. |
SVN::S4::FixProp - Fix svn:ignore and svn:keywords properties
Shell: s4 fixprop {files_or_directories}
Scripts: use SVN::S4::FixProp; $svns4_object->fixprop(filename=>filename);
SVN::S4::FixProp provides utilities for changing properties on a file-by-file basis.
Return true if the filename contains a SVN metacomment.
Return true if the filename has a name which shouldn't be recursed on.
The following methods extend to the global SVN::S4 class.
Recurse the specified files, searching for .cvsignore, .gitignore or keywords that need repair.
The latest version is available from CPAN and from http://www.veripool.org/.
Copyright 2005-2011 by Wilson Snyder. This package is free software; you can redistribute it and/or modify it under the terms of either the GNU Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
Wilson Snyder <wsnyder@wsnyder.org>
| SVN-S4 documentation | Contained in the SVN-S4 distribution. |
# See copyright, etc in below POD section. ###################################################################### package SVN::S4::FixProp; require 5.006_001; use SVN::S4; use SVN::S4::Debug qw (DEBUG is_debug); use strict; use Carp; use IO::Dir; use IO::File; use Cwd; use vars qw($AUTOLOAD); use SVN::S4::Path; our $VERSION = '1.053'; # Basenames we should ignore, because they contain large files of no relevance our %_SkipBasenames = ( CVS => 1, '.git' => 1, '.svn' => 1, blib => 1, ); ####################################################################### # Methods sub skip_filename { my $filename = shift; (my $basename = $filename) =~ s!.*/!!; return $_SkipBasenames{$basename} } sub file_has_keywords { my $filename = shift; # Return true if there's a svn metacomment in $filename return undef if readlink $filename; my $fh = IO::File->new("<$filename") or return undef; my $lineno = 0; while (defined(my $line = $fh->getline)) { $lineno++; last if $lineno>1000; if ($line =~ /[\001\002\003\004\005\006]/) { # Binary file. $fh->close; return 0; } if ($line =~ /\$(LastChangedDate|Date|LastChangedRevision|Revision|Rev|LastChangedBy|Author|HeadURL|URL|Id)[: \$]/) { $fh->close; return 1; } if ($lineno==1 && $line =~ /^SVN-fs-dump-format/) { return 0; } } $fh->close; return 0; } ####################################################################### ####################################################################### ####################################################################### ####################################################################### # OVERLOADS of S4 object package SVN::S4; use Cwd qw(getcwd); use SVN::S4::Debug qw (DEBUG is_debug); sub fixprops { my $self = shift; my %params = (#filename=>, keyword_propval => 'author date id revision', recurse => 1, personal => undef, @_); my $filename = $params{filename}; $filename = getcwd()."/".$filename if $filename !~ m%^/%; _fixprops_recurse($self,\%params,$filename); } sub _fixprops_recurse { my $self = shift; my $param = shift; my $filename = shift; if (-d $filename) { my $dir = $filename; DEBUG "In $dir\n" if $self->debug; if (!-r "$dir/.svn") { # silently ignore a non a subversion directory } else { my $dh = new IO::Dir $dir or die "s4: %Error: Could not directory $dir.\n"; while (defined (my $basefile = $dh->read)) { next if $basefile eq '.' || $basefile eq '..'; my $file = $dir."/".$basefile; next if SVN::S4::FixProp::skip_filename($file); if (-d $file) { if ($param->{recurse} && !readlink $file) { _fixprops_recurse($self,$param,$file); } } else { if ($param->{recurse} || $file =~ m!/(\.cvsignore|\.gitignore)$!) { # If not recursing, we did a dir with -N; process the dir's ignore _fixprops_recurse($self,$param,$file); } } } $dh->close(); } } else { # File if ($filename =~ m!^(.*)/(\.cvsignore|\.gitignore)$!) { my $dir = $1; DEBUG ".cvsignore check $dir\n" if $self->debug; if ($self->file_url(filename=>$dir)) { $self->_fixprops_add_ignore($dir); } } elsif (SVN::S4::FixProp::file_has_keywords($filename)) { if ($self->file_url(filename=>$filename) && !defined ($self->propget_string(filename=>$filename, propname=>"svn:keywords")) && (!$param->{personal} || $self->is_file_personal(filename=>$filename))) { $self->propset_string(filename=>$filename, propname=>"svn:keywords", propval=>$param->{keyword_propval}); } } } } sub _fixprops_add_ignore { my $self = shift; my $dir = shift; my $ignores = (SVN::S4::Path::wholefile("$dir/.cvsignore") || SVN::S4::Path::wholefile("$dir/.gitignore")); if (defined $ignores) { # else not found $ignores .= "\n"; $ignores =~ s/[ \t\n\r\f]+/\n/g; $self->propset_string(filename=>$dir, propname=>"svn:ignore", propval=>$ignores); } } ###################################################################### ### Package return package SVN::S4::FixProp; 1; __END__