SVN-S4
view release on metacpan or search on metacpan
lib/SVN/S4/FixProp.pm view on Meta::CPAN
sub fixprops {
my $self = shift;
my %params = (#filename=>,
keyword_propval => 'author date id revision',
personal => undef,
autoprops => 1,
ignores => 1,
keywords => 1,
recurse => 1,
@_);
DEBUG "fixprops (filename=>$params{filename})\n" if $self->debug;
my $filename = $params{filename};
$filename = getcwd()."/".$filename if $filename !~ m%^/%;
$filename = $self->abs_filename($filename);
_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 (!$self->dir_uses_svn($dir)) {
# silently ignore a non a subversion directory
} else {
if ($param->{ignores}) {
$self->_fixprops_add_ignore($dir);
}
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 ($param->{keywords}
&& 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});
}
}
if ($param->{autoprops}
&& $self->file_url(filename=>$filename, assert_exists=>0)) {
$self->_fixprops_autoprops($filename);
}
}
}
sub _fixprops_add_ignore {
my $self = shift;
my $dir = shift;
$dir =~ s!/\.$!!;
my $ignores = "";
my $went_up;
for (my $updir = $dir; 1;) {
$ignores .= $self->_fixprops_read_ignore($updir, $went_up++);
$updir =~ m!(.*)/([^/]+)$! or last;
$updir = $1;
$self->dir_uses_svn($updir) or last;
}
if ($ignores && $ignores !~ /^\s*$/) { # else not found
$ignores .= "\n";
$ignores =~ s/[ \t\n\r\f]+/\n/g;
$ignores =~ s/^\n+//g;
$ignores =~ s/\n\n+/\n/g;
$ignores =~ s!^/!!g; $ignores =~ s!\n/!\n!g; # gitignore prepends / to mean current dir
$self->propset_string(filename=>$dir, propname=>"svn:ignore", propval=>$ignores);
}
}
sub _fixprops_read_ignore {
my $self = shift;
my $dir = shift;
my $recursive_only = shift;
my $val = $self->{_fixprops_read_ignore_cache}{$dir};
if (!defined $val) {
$val = (SVN::S4::Path::wholefile("$dir/.cvsignore")
|| SVN::S4::Path::wholefile("$dir/.gitignore"));
$val = "" if !defined $val;
$self->{_fixprops_read_ignore_cache}{$dir} = $val;
}
if ($recursive_only) {
if ($val =~ /\[recursive\]/) {
$val =~ s/.*\[recursive\]//g;
} else {
$val = "";
}
} else {
$val =~ s/\[recursive\]//g;
}
return $val;
}
sub _fixprops_autoprops {
my $self = shift;
my $filename = shift;
my $val;
for (my $updir = $filename; 1;) {
$updir =~ m!(.*)/([^/]+)$! or last; $updir=$1;
$self->dir_uses_svn($updir) or last;
$val = $self->_fixprops_read_autoprops($updir);
last if $val ne "";
}
return if !$val || $val eq '';
foreach my $line (split /\n/, $val) {
next if $line =~ /^\s*$/;
if ($line =~ /^\s*([^= \t]*)\s*=\s*(.*)/) {
my $re = quotemeta($1); my $props = $2;
$re =~ s/\\\*/.*/g; # Convert glob regexp to perl regexp
$re =~ s/\\\?/?/g;
if ($filename =~ /$re/) {
while ($props =~ /([^;=]*)=([^;=]*)/g) {
my $prop=$1; my $val=$2;
DEBUG "autoprop: '$re' : '$prop'='$val'\n" if $self->debug;
if (!$self->propget_string(filename=>$filename, propname=>$prop)) {
$self->propset_string(filename=>$filename, propname=>$prop, propval=>$val);
}
}
}
}
}
}
sub _fixprops_read_autoprops {
my $self = shift;
my $dir = shift;
my $val = $self->{_fixprops_read_autoprops_cache}{$dir};
if (!defined $val) {
$val = $self->propget_string(filename=>$dir, propname=>"tsvn:autoprops");
$val = "" if !defined $val;
$self->{_fixprops_read_autoprops_cache}{$dir} = $val;
DEBUG "_fixprops_autoprops($dir) => $val\n" if $self->debug;
}
return $val;
}
######################################################################
### Package return
package SVN::S4::FixProp;
1;
__END__
=pod
=head1 NAME
SVN::S4::FixProp - Fix svn:ignore and svn:keywords properties
=head1 SYNOPSIS
Shell:
s4 fixprop {files_or_directories}
Scripts:
use SVN::S4::FixProp;
$svns4_object->fixprop(filename=>I<filename>);
=head1 DESCRIPTION
SVN::S4::FixProp provides utilities for changing properties on a file-by-file basis.
=head1 METHODS
=over 4
=item file_has_keywords(I<filename>)
Return true if the filename contains a SVN metacomment.
=item skip_filename(I<filename>)
Return true if the filename has a name which shouldn't be recursed on.
=back
=head1 METHODS ADDED TO SVN::S4
( run in 0.511 second using v1.01-cache-2.11-cpan-71847e10f99 )