SVN-S4

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN



* 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

s4  view on Meta::CPAN

} 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);

s4  view on Meta::CPAN


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)) {

s4  view on Meta::CPAN


=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=/);



( run in 0.747 second using v1.01-cache-2.11-cpan-71847e10f99 )