[Bps-public-commit] r14596 - in Pushmi/trunk: . lib/Pushmi lib/Pushmi/Command
clkao at bestpractical.com
clkao at bestpractical.com
Tue Jul 29 12:14:47 EDT 2008
Author: clkao
Date: Tue Jul 29 12:14:47 2008
New Revision: 14596
Added:
Pushmi/trunk/lib/Pushmi/Command/Runlock.pm
Pushmi/trunk/lib/Pushmi/Command/Rununlock.pm
Pushmi/trunk/t/lock.t
Modified:
Pushmi/trunk/ (props changed)
Pushmi/trunk/MANIFEST
Pushmi/trunk/lib/Pushmi/Command.pm
Pushmi/trunk/lib/Pushmi/Command/Runhook.pm
Pushmi/trunk/lib/Pushmi/Mirror.pm
Pushmi/trunk/lib/Pushmi/Test.pm
Log:
- Merge /bps/mirror/Pushmi/branches/lock to /bps/mirror/Pushmi/trunk
Modified: Pushmi/trunk/MANIFEST
==============================================================================
--- Pushmi/trunk/MANIFEST (original)
+++ Pushmi/trunk/MANIFEST Tue Jul 29 12:14:47 2008
@@ -21,9 +21,11 @@
lib/Pushmi/Command/Help.pm
lib/Pushmi/Command/Mirror.pm
lib/Pushmi/Command/Runhook.pm
+lib/Pushmi/Command/Runlock.pm
lib/Pushmi/Command/Sync.pm
lib/Pushmi/Command/Tryauth.pm
lib/Pushmi/Command/Unlock.pm
+lib/Pushmi/Command/Ununlock.pm
lib/Pushmi/Command/Verify.pm
lib/Pushmi/Config.pm
lib/Pushmi/Editor/Locker.pm
Modified: Pushmi/trunk/lib/Pushmi/Command.pm
==============================================================================
--- Pushmi/trunk/lib/Pushmi/Command.pm (original)
+++ Pushmi/trunk/lib/Pushmi/Command.pm Tue Jul 29 12:14:47 2008
@@ -103,6 +103,10 @@
return $SVN::_Core::SVN_NO_ERROR;
}
+sub requires_svn_version {
+ my ($self, $version, $message) = @_;
+ die $message."\n" if $SVN::Core::VERSION lt $version;
+}
1;
Modified: Pushmi/trunk/lib/Pushmi/Command/Runhook.pm
==============================================================================
--- Pushmi/trunk/lib/Pushmi/Command/Runhook.pm (original)
+++ Pushmi/trunk/lib/Pushmi/Command/Runhook.pm Tue Jul 29 12:14:47 2008
@@ -3,6 +3,7 @@
use warnings;
use base 'Pushmi::Command';
use SVK::Editor::MapRev;
+use SVK::I18N;
our $AUTHOR;
my $logger = Pushmi::Config->logger('pushmi.runhook');
@@ -29,6 +30,26 @@
my $t = $pushmi->root_svkpath;
$pushmi->ensure_consistency;
+ my $locks;
+ if (!eof(\*STDIN)) {
+ if ((scalar <STDIN>) =~ m'^LOCKS-TOKENS:') {
+ while (<STDIN>) {
+ chomp;
+ last unless $_;
+ my ($path, $token) = split('\|', $_, 2);
+ $locks->{$path} = $token;
+ }
+
+ # turn lock path into relative
+ $locks = { map { my $token = $locks->{$_};
+ substr($_, 0, 1, '');
+ $_ => $token; } keys %$locks};
+ }
+ }
+
+ $self->requires_svn_version('1.6.0', loc("Commit with locks requires svn 1.6.0 on replica."))
+ if $locks;
+
# XXX: if we reentrant, the mirror will be in deadlock.
$AUTHOR = $txn->prop('svn:author');
$logger->info("[$repospath] committing from txn $self->{txnname} by $AUTHOR");
@@ -38,6 +59,7 @@
my ($editor, $inspector, %arg) = $t->get_editor(notee => 1,
callback => sub {},
caller => '',
+ lock_tokens => $locks,
message => $txn->prop('svn:log'));
my $mirror = $pushmi->master;
Added: Pushmi/trunk/lib/Pushmi/Command/Runlock.pm
==============================================================================
--- (empty file)
+++ Pushmi/trunk/lib/Pushmi/Command/Runlock.pm Tue Jul 29 12:14:47 2008
@@ -0,0 +1,57 @@
+package Pushmi::Command::Runlock;
+use strict;
+use warnings;
+use base 'Pushmi::Command';
+use SVK::I18N;
+my $logger = Pushmi::Config->logger('pushmi.runlock');
+
+sub options {
+ ( 'path=s' => 'path',
+ 'user=s' => 'user',
+ 'comment=s' => 'comment',
+ 'steal' => 'steal' );
+}
+
+sub run {
+ my ($self, $repospath) = @_;
+ die "repospath required" unless $repospath;
+
+ $self->requires_svn_version('1.6.0', loc("locking requires svn 1.6.0 on replica."));
+
+ my $pushmi = Pushmi::Mirror->new( path => $repospath );
+ $pushmi->ensure_consistency;
+
+ my $t = $pushmi->root_svkpath;
+
+ my ($mirror) = $t->is_mirrored;
+ my $ra = $mirror->_backend->_new_ra;
+ my $lock_path = substr($self->{path}, 1);
+ $ra->lock({ $lock_path => -1 }, $self->{comment}, $self->{steal},
+ sub { my ($path, $locked, $lock, $err, $pool) = @_;
+ die $err->expanded_message."\n" if $err;
+ print $lock->token if $lock;
+ });
+ exit 0;
+}
+
+=head1 NAME
+
+Pushmi::Command::Runlock - svn lock preprocessing
+
+=head1 SYNOPSIS
+
+ runlock
+
+=head1 OPTIONS
+
+
+=head1 DESCRIPTION
+
+The command tries to lock the master and output the token on success
+to be used by the replica.
+
+This is not intended to be invoked manually.
+
+=cut
+
+1;
Added: Pushmi/trunk/lib/Pushmi/Command/Rununlock.pm
==============================================================================
--- (empty file)
+++ Pushmi/trunk/lib/Pushmi/Command/Rununlock.pm Tue Jul 29 12:14:47 2008
@@ -0,0 +1,56 @@
+package Pushmi::Command::Rununlock;
+use strict;
+use warnings;
+use base 'Pushmi::Command';
+use SVK::I18N;
+my $logger = Pushmi::Config->logger('pushmi.runlock');
+
+sub options {
+ ( 'path=s' => 'path',
+ 'user=s' => 'user',
+ 'token=s' => 'token',
+ 'break' => 'break' );
+}
+
+sub run {
+ my ($self, $repospath) = @_;
+ die "repospath required" unless $repospath;
+
+ $self->requires_svn_version('1.6.0', loc("locking requires svn 1.6.0 on replica."));
+
+ my $pushmi = Pushmi::Mirror->new( path => $repospath );
+ $pushmi->ensure_consistency;
+
+ my $t = $pushmi->root_svkpath;
+
+ my ($mirror) = $t->is_mirrored;
+ my $ra = $mirror->_backend->_new_ra;
+ my $lock_path = substr($self->{path}, 1);
+ $ra->unlock({ $lock_path => $self->{token} }, $self->{break},
+ sub { my ($path, $locked, $lock, $err, $pool) = @_;
+ die $err->expanded_message."\n" if $err;
+ });
+ exit 0;
+}
+
+=head1 NAME
+
+Pushmi::Command::Rununlock - svn lock preprocessing
+
+=head1 SYNOPSIS
+
+ runlock
+
+=head1 OPTIONS
+
+
+=head1 DESCRIPTION
+
+The command tries to lock the master and output the token on success
+to be used by the replica.
+
+This is not intended to be invoked manually.
+
+=cut
+
+1;
Modified: Pushmi/trunk/lib/Pushmi/Mirror.pm
==============================================================================
--- Pushmi/trunk/lib/Pushmi/Mirror.pm (original)
+++ Pushmi/trunk/lib/Pushmi/Mirror.pm Tue Jul 29 12:14:47 2008
@@ -119,6 +119,28 @@
END
+ _install_hook( $self->path, 'pre-lock', << "END");
+#!/bin/sh
+export SVKNOSVNCONFIG=1
+export PUSHMI_CONFIG=$ENV{PUSHMI_CONFIG}
+export LD_LIBRARY_PATH=$ENV{LD_LIBRARY_PATH}
+export DYLD_LIBRARY_PATH=$ENV{DYLD_LIBRARY_PATH}
+export PATH=$ENV{PATH}
+$perl $pushmi runlock "\$1" --path "\$2" --user "\$3" --comment "\$4" --steal "\$5"
+
+END
+
+ _install_hook( $self->path, 'pre-unlock', << "END");
+#!/bin/sh
+export SVKNOSVNCONFIG=1
+export PUSHMI_CONFIG=$ENV{PUSHMI_CONFIG}
+export LD_LIBRARY_PATH=$ENV{LD_LIBRARY_PATH}
+export DYLD_LIBRARY_PATH=$ENV{DYLD_LIBRARY_PATH}
+export PATH=$ENV{PATH}
+$perl $pushmi rununlock "\$1" --path "\$2" --user "\$3" --token "\$4" --break "\$5"
+
+END
+
}
sub _install_hook {
Modified: Pushmi/trunk/lib/Pushmi/Test.pm
==============================================================================
--- Pushmi/trunk/lib/Pushmi/Test.pm (original)
+++ Pushmi/trunk/lib/Pushmi/Test.pm Tue Jul 29 12:14:47 2008
@@ -48,15 +48,28 @@
}
}
+sub svn_cmd {
+ return $ENV{PUSHMI_SVN_COMMAND} if $ENV{PUSHMI_SVN_COMMAND};
+ return qw(arch -i386 /usr/local/bin/svn) if $^O eq 'darwin';
+ return 'svn';
+}
+
sub is_svn_output {
my ($arg, $exp_stdout, $exp_stderr) = @_;
my $stdout_err = [];
$exp_stderr ||= [];
- my $ret = run3 ['svn', ($SVN::Core::VERSION ge '1.5.0'
+
+ my $ret = run3 [svn_cmd(), ($SVN::Core::VERSION ge '1.5.0'
? '--non-interactive' : ()),
@$arg], undef,
_mk_cmp_closure($exp_stdout, $stdout_err), # stdout
_mk_cmp_closure($exp_stderr, $stdout_err); # stderr
+
+ unless ($ret) {
+ diag("Exit value: $?");
+ @_ = (0, join(' ', 'svn', @$arg));
+ }
+
if (@$stdout_err) {
@_ = (0, join(' ', 'svn', @$arg));
diag("Different in line: ".join(',', @$stdout_err));
Added: Pushmi/trunk/t/lock.t
==============================================================================
--- (empty file)
+++ Pushmi/trunk/t/lock.t Tue Jul 29 12:14:47 2008
@@ -0,0 +1,72 @@
+#!/usr/bin/perl -w
+use strict;
+use Test::More;
+use SVK::Test;
+use Pushmi::Test;
+use Pushmi::Mirror;
+use FindBin;
+
+plan skip_all => 'requires 1.6.0 for lock'
+ if $SVN::Core::VERSION lt '1.6.0';
+
+plan tests => 21;
+
+my $user = $ENV{USER};
+
+my ($svk,
+ $uri, $srepos, undef, undef, $scorpath,
+ $muri, $repos, undef, $copath, undef ) = build_basic_test_ok();
+
+is_svn_output(['co', $muri, $copath],
+ ['A t/checkout/basic-svn/A',
+ 'Checked out revision 1.']);
+chdir($copath);
+overwrite_file("fromsvn.txt", "orz\n");
+is_svn_output(['add', 'fromsvn.txt'],
+ ['A fromsvn.txt']);
+is_svn_output(['ci', -m => 'add fromsvn'],
+ ['Adding fromsvn.txt',
+ 'Transmitting file data .',
+ 'Committed revision 2.']);
+is($srepos->fs->youngest_rev, 2, 'committed via hook');
+
+is_svn_output(['lock', -m => 'lock from slave', 'fromsvn.txt'],
+ ["'fromsvn.txt' locked by user '$user'."]);
+my $lock = $repos->fs->get_lock('/fromsvn.txt');
+$lock = $lock->token if $lock;
+ok($lock, 'has lock on slave');
+my $lock2 = $srepos->fs->get_lock('/fromsvn.txt');
+is($lock && $lock2->comment, 'lock from slave');
+$lock2 = $lock2->token if $lock;
+ok($lock2, 'has lock on master');
+
+is($lock, $lock2, 'lock token are identical');
+
+is_svn_output(['unlock', 'fromsvn.txt'],
+ ["'fromsvn.txt' unlocked."]);
+
+ok(!$repos->fs->get_lock('/fromsvn.txt'), 'unlocked for slave');
+ok(!$srepos->fs->get_lock('/fromsvn.txt'), 'unlocked for msater');
+
+# lock from url
+is_svn_output(['lock', -m => 'lock from slave', $muri.'/fromsvn.txt'],
+ ["'fromsvn.txt' locked by user '$user'."]);
+
+is_svn_output(['lock', -m => 'lock from slave', $uri.'/fromsvn.txt'],[],
+ [qr{svn: warning: Path '/fromsvn.txt' is already locked by user '$user' in filesystem}]);
+
+is_svn_output(['lock', -m => 'lock from slave', 'fromsvn.txt'], [],
+ [qr{svn: warning: Path '/fromsvn.txt' is already locked by user '$user' in filesystem}]);
+
+is_svn_output(['lock', -m => 'lock from slave', '--force', 'fromsvn.txt'],
+ ["'fromsvn.txt' locked by user '$user'."]);
+
+is($repos->fs->get_lock('/fromsvn.txt')->token, $srepos->fs->get_lock('/fromsvn.txt')->token, 'lock identical after stealing');
+
+is_svn_output(['lock', '--force', -m => 'lock from again', 'fromsvn.txt'],
+ ["'fromsvn.txt' locked by user '$user'."]);
+append_file('fromsvn.txt', "more content\n");
+is_svn_output(['ci', -m => 'yatta'],
+ ['Sending fromsvn.txt',
+ 'Transmitting file data .',
+ 'Committed revision 3.' ], 'commit through slave holding lock, verified by master');
More information about the Bps-public-commit
mailing list