view release on metacpan or search on metacpan
* SVN::S4 1.050 2010-10-04
*** 's4 add' no longer does fixprop by default. Use a configuration file
to enable this behavior.
* SVN::S4 1.040 2010-09-30
** Add 's4 workpropdel, workpropget, workpropset, workproplist'.
*** Viewspecs now allow ^ to refer to repo root.
* SVN::S4 1.034 2010-07-09
** Support SVN 1.6.6.
* SVN::S4 1.033 2010-02-25
bryce-notes.txt view on Meta::CPAN
cd /local/denney/svn114branch/subversion/tests/clients/cmdline/working_copies/s4_tests-7.wc2
It is ok to be over conservative (e.g. never remove any switchpoints)
but it is not okay to make things disappear when they should not.
- (DONE) BUG: s4 does not undo void switchpoints that were created on the way to a real switchpoint.
Really it should.
- (DONE) What happens if two view lines map the same switchpoint? Illegal, or one overrides the other?
Now, one overrides the other.
- (DONE) if the URL is outside of the repository:
- (DONE) test UUID
- (DONE) print an error that it's not supported
- or, make an svn external (svn propset . and then svn co [-r] URL PATH)
but wait until there's a need.
- (DONE) Integrate complete_patch as "s4 snapshot"
- (DONE) Integrate strong_revert as "s4 scrub --force"
To decide:
- How to make a tag when the view is an important part of the tag?
svn cp trunk tags/1.1
Then you can check out the tag of trunk and you know that it's static.
lib/SVN/S4.pm view on Meta::CPAN
# $ctx->import($path, $url, $nonrecursive, $pool);
# $ctx->log($targets, $start, $end, $discover_changed_paths, $strict_node_history,
# \&log_receiver, $pool);
# $ctx->ls($target, $revision, $recursive, $pool);
# $ctx->merge($src1, $rev1, $src2, $rev2, $target_wcpath, $recursive, $ignore_ancestry,
# $force, $dry_run, $pool);
# $ctx->mkdir($targets, $pool);
# $ctx->move($src_path, $src_revision, $dst_path, $force, $pool);
# $ctx->propget($propname, $target, $revision, $recursive, $pool);
# $ctx->proplist($target, $revision, $recursive, $pool);
# $ctx->propset($propname, $propval, $target, $recursive, $pool);
# $ctx->relocate($dir, $from, $to, $recursive, $pool);
# $ctx->resolved($path, $recursive, $pool);
# $ctx->revert($paths, $recursive, $pool);
# $ctx->revprop_get($propname, $url, $revision, $pool);
# $ctx->revprop_list($url, $revision, $pool);
# $ctx->revprop_set($propname, $propval, $url, $revision, $force, $pool);
# $ctx->status($path, $revision, \&status_func, $recursive, $get_all, $update, $no_ignore, $pool);
# $ctx->switch($path, $url, $revision, $recursive, $pool);
# $ctx->update($path, $revision, $recursive, $pool)
# $ctx->url_from_path($target, $pool); or SVN::Client::url_from_path($target, $pool);
lib/SVN/S4.pm view on Meta::CPAN
$self->client_reopen();
my $pl = $self->client->proplist($filename, undef, 0);
return undef if !$pl;
foreach my $propitem (@{$pl}) {
my $propval = $propitem->prop_hash->{$params{propname}};
return $propval if defined $propval;
}
return undef;
}
sub propset_string {
my $self = shift;
my %params = (#filename =>
#propname =>
#propval =>
dryrun => $self->{dryrun},
quiet => $self->{quiet},
@_);
# Set property name, only if not set yet
my $filename = $self->clean_filename($params{filename});
$self->open();
my $stored = $self->propget_string(%params);
if (!defined $stored || (($stored ne $params{propval})
&& "$stored\n" ne $params{propval})) {
print " svn propset $params{propname} $filename\n" if !$params{quiet};
$self->client_reopen();
$self->client->propset($params{propname}, $params{propval}, $params{filename}, 0) if !$params{dryrun};
}
}
######################################################################
#### Package return
1;
=pod
=head1 NAME
lib/SVN/S4.pm view on Meta::CPAN
=over 4
=item $self->client
Return the SVN::Client object.
=item $self->propget_string(filename=>I<file>, propname=>I<prop>)
Return the string value of the property, or undef if not set or bad file.
=item $self->propset_string(filename=>I<file>, propname=>I<prop>, propval=>I<val>)
Set the string value of the property.
=item new (I<params>)
Create a new SVN::S4 object.
=back
=head1 DISTRIBUTION
lib/SVN/S4/FixProp.pm view on Meta::CPAN
}
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);
}
}
}
lib/SVN/S4/FixProp.pm view on Meta::CPAN
$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")
lib/SVN/S4/FixProp.pm view on Meta::CPAN
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;
lib/SVN/S4/Getopt.pm view on Meta::CPAN
'mv' => 'move',
'pd' => 'propdel',
'pdel' => 'propdel',
'pe' => 'propedit',
'pedit' => 'propedit',
'pg' => 'propget',
'pget' => 'propget',
'pl' => 'proplist',
'plist' => 'proplist',
'praise' => 'blame',
'ps' => 'propset',
'pset' => 'propset',
'remove' => 'delete',
'ren' => 'move',
'rename' => 'move',
'rm' => 'delete',
'snap' => 'snapshot',
'st' => 'status',
'stat' => 'status',
'sw' => 'switch',
'up' => 'update',
# S4 additions
lib/SVN/S4/Getopt.pm view on Meta::CPAN
.' [-v|--verbose]'
#
.' [--username USER]'
.' [--password PASS]'
.' [--no-auth-cache]'
.' [--non-interactive]'
.' [--trust-server-cert]' # 1.6
.' [--config-dir DIR]'
.' [--config-option ARG]' # 1.6
.' PROPNAME [PATHORURL@PATHORURLREV...]')},
'propset' => {
args => (''#'propset PROPNAME [PROPVAL | -F VALFILE] PATH...'
#'propset PROPNAME --revprop -r REV [PROPVAL | -F VALFILE] [URL]'
.' [--changelist ARG]'
.' [--depth ARG]' # 1.6
.' [--encoding ENC]'
.' [--force]'
.' [--revprop]'
.' [--targets FILENAME]'
.' [-F|--file FILE]'
.' [-R|--recursive]'
.' [-q|--quiet]'
.' [-r|--revision REV]'
lib/SVN/S4/Getopt.pm view on Meta::CPAN
.' PROPNAME')},
'workpropget' => {
s4_addition => 1,
args => (''
.' PROPNAME')},
'workproplist' => {
s4_addition => 1,
args => (''
.' [--xml]'
.' [-v|--verbose]')},
'workpropset' => {
s4_addition => 1,
args => (''
.' PROPNAME PROPVAL')},
);
#######################################################################
#######################################################################
#######################################################################
sub new {
lib/SVN/S4/Snapshot.pm view on Meta::CPAN
my $out = _emit_propclear ($relpath); # emit code to clear properties
return $out if !defined $proplist->[0]; # there are no properties. done!
my $prophash = $proplist->[0]->prop_hash;
if ($self->debug) {
DEBUG "path=", $proplist->[0]->node_name, "\n";
DEBUG Dumper($prophash) if $self->debug;
}
foreach my $name (keys %$prophash) {
my $value = $prophash->{$name};
DEBUG "name=$name, value=$value\n" if $self->debug;
$out .= _emit_propset($relpath, $name, $value);
}
return $out;
}
sub _emit_propclear {
my ($path) = @_;
my $out = $Propclear_bash_func;
$Propclear_bash_func = ""; # so that it's only printed once into the patch
return $out . "propclear $path\n";
}
sub _emit_propset {
my ($path, $name, $value) = @_;
# name or esp. value could conceivably be things that are impossible to quote.
if (single_quotable($name) && single_quotable($value)) {
return "svn propset ".single_quote($name)." ".single_quote($value)." $path\n";
} else {
warn "%Error: property name($name) or value($value) has strange characters in $path\n";
}
}
sub single_quotable {
my ($v) = @_;
return 0 if $v =~ /\'/;
# all chars ascii 0x20 through 0x7e (space through tilde)
return 1 if $v =~ /^[ -~\t\n\r]*$/;
lib/SVN/S4/WorkProp.pm view on Meta::CPAN
sub workpropdel {
my $self = shift;
my %params = (propname=>undef,
@_);
$self->_workprop_read;
delete $self->{_workcfg}{workprops}{$params{propname}};
$self->_workprop_write;
}
sub workpropset {
my $self = shift;
my %params = (propname=>undef,
value=>undef,
@_);
$params{propname} =~ /$_Prop_Regexp/
or die "s4: %Error: workprop name has illegal characters; non [a-zA-Z0-9_-+,/]: $params{propname}\n";
$params{value} =~ /$_Prop_Regexp/
or die "s4: %Error: workprop value has illegal characters; non [a-zA-Z0-9_-+,/]: $params{propname}\n";
$self->_workprop_read;
$self->{_workcfg}{workprops}{$params{propname}} = $params{value};
lib/SVN/S4/WorkProp.pm view on Meta::CPAN
=head1 NAME
SVN::S4::WorkProp - Work area properties
=head1 SYNOPSIS
Shell:
s4 workpropdel PROPNAME
s4 workpropget PROPNAME
s4 workproplist [-v --xml]
s4 workpropset PROPNAME PROPVAL
Scripts:
use SVN::S4;
# See below
=head1 DESCRIPTION
SVN::S4::WorkProp provides utilities for work area properties.
=head1 METHODS
lib/SVN/S4/WorkProp.pm view on Meta::CPAN
=over 4
=item workpropdel(name=>I<name>)
Delete the property.
=item workpropget(name=>I<name>, print=>1)
Return or print value of given property.
=item workpropset(name=>I<name>, value=>I<value>)
Set the property.
=item workproplist(verbose=>1, xml=>1)
Return value of given property.
=back
=head1 METHODS ADDED TO SVN::S4
} elsif ($Opt_Cmd eq "switch") {
cmd_switch();
} elsif ($Opt_Cmd eq "update") {
cmd_update();
} elsif ($Opt_Cmd eq "workpropdel") {
cmd_workpropdel();
} elsif ($Opt_Cmd eq "workpropget") {
cmd_workpropget();
} elsif ($Opt_Cmd eq "workproplist") {
cmd_workproplist();
} elsif ($Opt_Cmd eq "workpropset") {
cmd_workpropset();
} else {
cmd_svn();
}
#----------------------------------------------------------------------
sub usage {
print "Version $VERSION\n";
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT, -noperldoc=>1);
exit (1);
sub cmd_workproplist {
DEBUG "cmd_workpropget ",join(' ',@Opt_CmdParams),"\n" if is_debug;
!$opts{unknown} or die "%Error: s4 workpropget: Unknown argument: $opts{unknown}[0]\n";
#DEBUG "opts=",Dumper(\%opts), "\n" if is_debug;
$s4->workproplist (print=>1,
verbose=>$opts{'-v'},
xml=>$opts{'--xml'});
}
sub cmd_workpropset {
DEBUG "cmd_workpropset ",join(' ',@Opt_CmdParams),"\n" if is_debug;
!$opts{unknown} or die "%Error: s4 workpropset: Unknown argument: $opts{unknown}[0]\n";
#DEBUG "opts=",Dumper(\%opts), "\n" if is_debug;
my $propname = $opts{propname}[0];
my $propval = $opts{propval}[0];
(defined $propname) or die "%Error: s4 workpropset requires the property name\n";
(defined $propval) or die "%Error: s4 workpropset requires the property value\n";
$s4->workpropset (propname=>$propname, value=>$propval);
}
sub cmd_help {
my $cmd;
if ($opts{subcommand}) {
$cmd = $opts{subcommand}[0];
$cmd = $SvnOpt->dealias($cmd);
my $needdash;
if ($SvnOpt->command_s4_addition($cmd)
|| $SvnOpt->command_s4_changed($cmd)) {
=head2 workpropget I<propname>
s4 workpropget returns a work-area property of the given name, if it
exists, otherwise "".
=head2 workproplist [--xml]
s4 workproplist lists all work area properties, with their values.
=head2 workpropset I<propname> I<propvalue>
s4 workpropset sets a work-area property of the given name to the given
value. Work area properties are associated and unique to a given work
area, and stored in the top level .svn directory.
=head1 ARGUMENTS
=over 4
=item --help
Displays this message and program version and exits.
t/20_getopt.t view on Meta::CPAN
ck('list --revision REV --verbose --recursive --incremental --xml --username USER --password PASS --no-auth-cache --non-interactive --config-dir DIR PATH');
ck('lock --targets FILENAME --message TEXT --file FILE --force-log --encoding ENC --username USER --password PASS --no-auth-cache --non-interactive --config-dir DIR --force PATH');
ck('log --revision REV --quiet --verbose --targets FILENAME --stop-on-copy --incremental --limit NUM --xml --username USER --password PASS --no-auth-cache --non-interactive --config-dir DIR PATHORURL PATH');
ck('merge --revision REV --non-recursive --quiet --force --dry-run --diff3-cmd CMD --ignore-ancestry --username USER --password PASS --no-auth-cache --non-interactive --config-dir DIR --extensions ARGS --change REV PATHORURL');
ck('mkdir --message TEXT --file FILE --quiet --username USER --password PASS --no-auth-cache --non-interactive --editor-cmd EDITOR --encoding ENC --force-log --config-dir DIR PATHORURL');
ck('move --message TEXT --file FILE --revision REV --quiet --force --username USER --password PASS --no-auth-cache --non-interactive --editor-cmd EDITOR --encoding ENC --force-log --config-dir DIR SRC DST');
ck('propdel --quiet --recursive --revision REV --revprop --username USER --password PASS --no-auth-cache --non-interactive --config-dir DIR PROPNAME PATHORURL');
ck('propedit --revision REV --revprop --username USER --password PASS --no-auth-cache --non-interactive --encoding ENC --editor-cmd EDITOR --config-dir DIR PROPNAME PATHORURL');
ck('propget --recursive --revision REV --revprop --strict --username USER --password PASS --no-auth-cache --non-interactive --config-dir DIR PROPNAME PATHORURL');
ck('proplist --verbose --recursive --revision REV --quiet --revprop --username USER --password PASS --no-auth-cache --non-interactive --config-dir DIR PROPNAME PATHORURL');
ck('propset --file FILE --quiet --revision REV --targets FILENAME --recursive --revprop --username USER --password PASS --no-auth-cache --non-interactive --encoding ENC --force --config-dir DIR PROPNAME PATHORURL');
ck('resolved --targets FILENAME --recursive --quiet --config-dir DIR PATH');
ck('revert --targets FILENAME --recursive --quiet --config-dir DIR PATH');
ck('status --show-updates --verbose --non-recursive --quiet --no-ignore --username USER --password PASS --no-auth-cache --non-interactive --config-dir DIR --ignore-externals PATH');
ck('switch --relocate --revision REV --non-recursive --quiet --diff3-cmd CMD --relocate FROM TO --username USER --password PASS --no-auth-cache --non-interactive --config-dir DIR PATH');
ck('unlock --targets FILENAME --username USER --password PASS --no-auth-cache --non-interactive --config-dir DIR --force PATH');
ck('update --revision REV --non-recursive --quiet --diff3-cmd CMD --username USER --password PASS --no-auth-cache --non-interactive --config-dir DIR --ignore-externals PATH');
ck_deep('co -N --username USER url@12345 PATH',
{'--non-recursive' => 1,
'--username' => 1,
t/84_s4_workprop.t view on Meta::CPAN
use Test::More;
use Cwd;
BEGIN { plan tests => 6 }
BEGIN { require "./t/test_utils.pl"; }
our $S4 = "${PERL} ../../s4";
chdir "test_dir/trunk";
like_cmd("${S4} workpropset testprop value",
qr/^$/);
like_cmd("${S4} workpropget testprop",
qr/value/);
like_cmd("${S4} workproplist -v",
qr/testprop\n\s+value/);
like_cmd("${S4} workproplist --xml -v",
qr/name=/);