[Bps-public-commit] Prophet branch, master, updated. aa63e50e604a0b02a4986747e185443a7eadaab8

spang at bestpractical.com spang at bestpractical.com
Thu Jul 16 07:34:55 EDT 2009


The branch, master has been updated
       via  aa63e50e604a0b02a4986747e185443a7eadaab8 (commit)
       via  45c988229186721bce2a8965dcfcccee11f091eb (commit)
       via  617dc57ce837508592cc92b37ecdad6129c2b98f (commit)
       via  d9c6863c9180b02bd75488dba6c098428d9a728b (commit)
       via  3e440f160e934166287e7c73b933b21320be2cf6 (commit)
       via  97b6e2cb558aab2bbbbe97ab371a751e04d9e7cb (commit)
       via  693e171b9bf5cea32c9ac7caabd603ca672c7fe7 (commit)
       via  7ebf0b8ff65788b211112ed622c5e4e2e4537346 (commit)
      from  a04cc4e35583663802c9bfda7e6514b595f86491 (commit)

Summary of changes:
 lib/Prophet/App.pm                 |  106 +++++++++++++++++---------------
 lib/Prophet/CLI/Command.pm         |   44 +++++++++++++
 lib/Prophet/CLI/Command/Clone.pm   |   15 +++-
 lib/Prophet/CLI/Command/Init.pm    |    7 ++
 lib/Prophet/CLI/Command/Merge.pm   |   44 +++++++------
 lib/Prophet/CLI/Command/Publish.pm |   14 ++++-
 lib/Prophet/CLI/Command/Pull.pm    |   56 +++++------------
 lib/Prophet/CLI/Command/Push.pm    |   48 ++++++++++++++
 lib/Prophet/CLI/Dispatcher.pm      |   11 +---
 lib/Prophet/Config.pm              |   33 ++---------
 lib/Prophet/Replica.pm             |   20 +++---
 lib/Prophet/Test/Arena.pm          |    2 +-
 t/config.t                         |    6 +-
 t/publish-pull.t                   |  119 +++++++++++++++++++++++++++++++++++-
 14 files changed, 356 insertions(+), 169 deletions(-)
 create mode 100644 lib/Prophet/CLI/Command/Push.pm

- Log -----------------------------------------------------------------
commit 7ebf0b8ff65788b211112ed622c5e4e2e4537346
Author: Christine Spang <spang at mit.edu>
Date:   Tue Jul 14 16:57:04 2009 +0100

    Fix strange grammar in an error message

diff --git a/lib/Prophet/Replica.pm b/lib/Prophet/Replica.pm
index 5fb62a1..ad496d5 100644
--- a/lib/Prophet/Replica.pm
+++ b/lib/Prophet/Replica.pm
@@ -79,7 +79,7 @@ sub get_handle {
 
     if ( !$new_class ) {
         $class->log_fatal(
-            "I don't know how to deal the replica URL you provided - '@{[ $args{url}]}'"
+            "I don't know how to handle the replica URL you provided - '@{[ $args{url}]}'"
         );
     }
 

commit 693e171b9bf5cea32c9ac7caabd603ca672c7fe7
Author: Christine Spang <spang at mit.edu>
Date:   Wed Jul 15 14:29:36 2009 +0100

    Move over display_name_for_uuid and rename it to display_name_for_replica, move pod to end of file.

diff --git a/lib/Prophet/App.pm b/lib/Prophet/App.pm
index ea8d726..c31e60e 100644
--- a/lib/Prophet/App.pm
+++ b/lib/Prophet/App.pm
@@ -46,53 +46,23 @@ has uuid_generator => (
 
 use constant DEFAULT_REPLICA_TYPE => 'prophet';
 
-=head1 NAME
-
-Prophet::App
-
-=head1 SYNOPSIS
-
-=head1 METHODS
-
-=head2 BUILD
-
-=cut
-
-=head2 default_replica_type
-
-Returns a string of the the default replica type for this application.
-
-=cut
-
 sub default_replica_type {
     my $self = shift;
     return $ENV{'PROPHET_REPLICA_TYPE'} || DEFAULT_REPLICA_TYPE;
 }
 
-=head2 require
-
-=cut
-
 sub require {
     my $self = shift;
     my $class = shift;
     $self->_require(module => $class);
 }
 
-=head2 try_to_require
-
-=cut
-
 sub try_to_require {
     my $self = shift;
     my $class = shift;
     $self->_require(module => $class, quiet => 1);
 }
 
-=head2 _require
-
-=cut
-
 sub _require {
     my $self = shift;
     my %args = ( module => undef, quiet => undef, @_);
@@ -136,12 +106,6 @@ sub _require {
     return 1;
 }
 
-=head2 already_required class
-
-Helper function to test whether a given class has already been require'd.
-
-=cut
-
 sub already_required {
     my ($self, $class) = @_;
 
@@ -191,14 +155,6 @@ sub setting {
 
 sub database_settings {} # XXX wants a better name
 
-
-=head3 log $MSG
-
-Logs the given message to C<STDERR> (but only if the C<PROPHET_DEBUG>
-environmental variable is set).
-
-=cut
-
 sub log_debug {
     my $self = shift;
     return unless ($ENV{'PROPHET_DEBUG'});
@@ -211,12 +167,6 @@ sub log {
     print STDERR $msg."\n";# if ($ENV{'PROPHET_DEBUG'});
 }
 
-=head2 log_fatal $MSG
-
-Logs the given message and dies with a stack trace.
-
-=cut
-
 sub log_fatal {
     my $self = shift;
 
@@ -234,6 +184,62 @@ sub current_user_email {
 
 }
 
+# friendly names are replica subsections in the config file
+sub display_name_for_replica {
+    my $self = shift;
+    my $uuid = shift;
+
+    my %possibilities = $self->config->get_regexp( key => '^replica\..*\.uuid$' );
+    # form a hash of uuid -> name
+    my %sources_by_uuid = map {
+        my $uuid = $possibilities{$_};
+        $_ =~ /^replica\.(.*)\.uuid$/;
+        my $name = $1;
+        ( $uuid => $name );
+    } keys %possibilities;
+    return exists $sources_by_uuid{$uuid} ? $sources_by_uuid{$uuid} : $uuid;
+}
+
 __PACKAGE__->meta->make_immutable;
 no Any::Moose;
+
 1;
+
+__END__
+
+=head1 NAME
+
+Prophet::App
+
+=head1 SYNOPSIS
+
+=head1 METHODS
+
+=head2 BUILD
+
+=head2 default_replica_type
+
+Returns a string of the the default replica type for this application.
+
+=head2 require
+
+=head2 try_to_require
+
+=head2 already_required class
+
+Helper function to test whether a given class has already been require'd.
+
+=head3 log $MSG
+
+Logs the given message to C<STDERR> (but only if the C<PROPHET_DEBUG>
+environmental variable is set).
+
+=head2 log_fatal $MSG
+
+Logs the given message and dies with a stack trace.
+
+=head2 display_name_for_replica UUID
+
+Returns a "friendly" id for the replica with the given uuid. UUIDs are for
+computers, friendly names are for people. If no name is found, the friendly
+name is just the UUID.

commit 97b6e2cb558aab2bbbbe97ab371a751e04d9e7cb
Author: Christine Spang <spang at mit.edu>
Date:   Wed Jul 15 14:41:32 2009 +0100

    kill display_name_for_uuid, generalise sources to allow creating hashes containing any variable rather than just urls

diff --git a/lib/Prophet/Config.pm b/lib/Prophet/Config.pm
index 654b978..6cbfbf0 100644
--- a/lib/Prophet/Config.pm
+++ b/lib/Prophet/Config.pm
@@ -108,19 +108,20 @@ sub aliases {
 }
 
 # grab all the replicas we know of and return a hash of
-# name => url, or url => name if $args{by_url} is true
+# name => variable, or variable => name if $args{by_variable} is true
 sub sources {
     my $self = shift;
     my %args = (
         by_url => undef,
+        variable => 'url',
         @_,
     );
 
-    my %sources = $self->get_regexp( key => '^replica\..*\.url$' );
+    my %sources = $self->get_regexp( key => "^replica\..*\.$args{variable}\$" );
 
     my %new_sources = map {
-        $_ =~ /^replica\.(.*)\.url$/;
-        $args{by_url} ? ( $sources{$_} => $1 ) : ( $1 => $sources{$_} );
+        $_ =~ /^replica\.(.*)\.$args{variable}$/;
+        $args{by_variable} ? ( $sources{$_} => $1 ) : ( $1 => $sources{$_} );
     } keys %sources;
 
     return wantarray ? %new_sources : \%new_sources;
@@ -135,24 +136,6 @@ sub replica_config_file {
     );
 }
 
-# friendly names are replica subsections
-sub display_name_for_uuid {
-    my $self = shift;
-    my $uuid = shift;
-
-    my %possibilities = $self->get_regexp( key => '^replica\..*\.uuid$' );
-    # form a hash of uuid -> name
-    my %sources_by_uuid = map {
-        my $uuid = $possibilities{$_};
-        $_ =~ /^replica\.(.*)\.uuid$/;
-        my $name = $1;
-        ( $uuid => $name );
-    } keys %possibilities;
-    return exists $sources_by_uuid{$uuid} ? $sources_by_uuid{$uuid} : $uuid;
-}
-
-
-
 sub _file_if_exists {
     my $self = shift;
     my $file = shift || ''; # quiet warnings
@@ -225,11 +208,6 @@ A convenience method that gets you a hash (or a hashref, depending on context)
 of all currently defined source replicas, in the format { 'name' =>
 'URL' }, or { 'URL' => 'name' } if the argument C<by_url> is passed in.
 
-=head2 display_name_for_uuid UUID
-
-Returns a "friendly" id for the given uuid. UUIDs are for computers, friendly
-names are for people.
-
 =head1 CONFIG VARIABLES
 
 The following config variables are currently used in various places in

commit 3e440f160e934166287e7c73b933b21320be2cf6
Author: Christine Spang <spang at mit.edu>
Date:   Wed Jul 15 14:42:10 2009 +0100

    update config.t to new display_name_for_replica and sources api

diff --git a/t/config.t b/t/config.t
index 3b353bd..14cb3e6 100644
--- a/t/config.t
+++ b/t/config.t
@@ -59,17 +59,17 @@ is( scalar @keys, 0, 'no config options are set' );
         'automatic reload after set' );
     # test the sources sub
     is( $conf->sources->{sd}, 'http://fsck.com/sd/', 'Got correct alias' );
-    is( $conf->sources( by_url => 1)->{'http://fsck.com/sd/'},
+    is( $conf->sources( by_variable => 1)->{'http://fsck.com/sd/'},
         'sd',
         'Got correct alias',
     );
-    # test the display_name_for_uuid sub
+    # test the display_name_for_replica sub
     $conf->set(
         key => 'replica.sd.uuid',
         value => '32b13934-910a-4792-b5ed-c9977b212245',
         filename => File::Spec->catfile($repo, 'test_app.conf'),
     );
-    is( $conf->display_name_for_uuid('32b13934-910a-4792-b5ed-c9977b212245'),
+    is( $app_handle->display_name_for_replica('32b13934-910a-4792-b5ed-c9977b212245'),
         'sd',
         'Got correct display name'
     );

commit d9c6863c9180b02bd75488dba6c098428d9a728b
Author: Christine Spang <spang at mit.edu>
Date:   Wed Jul 15 22:25:05 2009 +0100

    display_name_for_uuid -> display_name_for_replica

diff --git a/lib/Prophet/Replica.pm b/lib/Prophet/Replica.pm
index ad496d5..7b7f790 100644
--- a/lib/Prophet/Replica.pm
+++ b/lib/Prophet/Replica.pm
@@ -287,7 +287,7 @@ sub integrate_changeset {
 
 
     $self->log_debug("Considering changeset ".$changeset->original_sequence_no .
-        " from " . $self->display_name_for_uuid($changeset->original_source_uuid));
+        " from " . $self->display_name_for_replica($changeset->original_source_uuid));
 
     # when we start to integrate a changeset, we need to do a bit of housekeeping
     # We never want to merge in:
@@ -312,7 +312,7 @@ sub integrate_changeset {
         $self->log_debug( "Integrating conflicting changeset "
                 . $changeset->original_sequence_no
                 . " from "
-                . $self->display_name_for_uuid( $changeset->original_source_uuid ) );
+                . $self->display_name_for_replica( $changeset->original_source_uuid ) );
         $args{conflict_callback}->($conflict) if $args{'conflict_callback'};
         $conflict->resolvers( [ sub { $args{resolver}->(@_) } ] ) if $args{resolver};
         if ( $args{resolver_class} ) {
@@ -347,7 +347,7 @@ sub integrate_changeset {
         return 1;
     } else {
         $self->log_debug("Integrating changeset ".$changeset->original_sequence_no .
-            " from " . $self->display_name_for_uuid($changeset->original_source_uuid));
+            " from " . $self->display_name_for_replica($changeset->original_source_uuid));
         $self->record_changeset_and_integration($changeset);
         $args{'reporting_callback'}->( changeset => $changeset ) if ( $args{'reporting_callback'} );
         return 1;
@@ -408,7 +408,7 @@ sub has_seen_changeset {
     my %args = validate( @_, {source_uuid => 1, sequence_no => 1});
     $self->log_debug("Checking to see if we've ever seen changeset " .
         $args{sequence_no} . " from " .
-        $self->display_name_for_uuid($args{source_uuid}));
+        $self->display_name_for_replica($args{source_uuid}));
 
     # If the changeset originated locally, we never want it
     if ($args{source_uuid} eq $self->uuid ) {
@@ -499,7 +499,7 @@ sub should_accept_changeset {
 
 
     $self->log_debug("Should I accept " .$changeset->original_sequence_no .
-        " from ".$self->display_name_for_uuid($changeset->original_source_uuid));
+        " from ".$self->display_name_for_replica($changeset->original_source_uuid));
     return undef if (! $changeset->has_changes);
     return undef if ( $changeset->is_nullification || $changeset->is_resolution );
     return undef if $self->has_seen_changeset( sequence_no => $changeset->original_sequence_no,  source_uuid => $changeset->original_source_uuid );
@@ -1033,7 +1033,7 @@ sub log {
 sub log_debug { 
     my $self = shift;
     my $msg = shift;
-    $self->app_handle->log_debug($self->display_name_for_uuid.": " .$msg);
+    $self->app_handle->log_debug($self->display_name_for_replica.": " .$msg);
 }
 
 =head2 log_fatal $MSG
@@ -1065,7 +1065,7 @@ sub changeset_creator {
     return $self->app_handle->current_user_email;
 }
 
-=head2 display_name_for_uuid [uuid]
+=head2 display_name_for_replica [uuid]
 
 If the user has a "friendly" name for this replica, then use it. Otherwise,
 display the replica's uuid.
@@ -1074,13 +1074,13 @@ If you pass in a uuid, it will be used instead of the replica's uuid.
 
 =cut
 
-sub display_name_for_uuid {
+sub display_name_for_replica {
     my $self = shift;
     my $uuid = shift || $self->uuid;
 
     return $uuid if !$self->app_handle;
 
-    return $self->app_handle->config->display_name_for_uuid($uuid);
+    return $self->app_handle->display_name_for_replica($uuid);
 }
 
 __PACKAGE__->meta->make_immutable();
diff --git a/lib/Prophet/Test/Arena.pm b/lib/Prophet/Test/Arena.pm
index 7516031..cbb08d4 100644
--- a/lib/Prophet/Test/Arena.pm
+++ b/lib/Prophet/Test/Arena.pm
@@ -38,7 +38,7 @@ sub setup {
 
         as_user($c->name => sub { 
                     my $p = Prophet::CLI->new();
-                    diag($c => $p->handle->display_name_for_uuid);
+                    diag($c => $p->handle->display_name_for_replica);
             });
     }
     

commit 617dc57ce837508592cc92b37ecdad6129c2b98f
Author: Christine Spang <spang at mit.edu>
Date:   Wed Jul 15 22:27:05 2009 +0100

    Allow using friendly names for push/publish too.

diff --git a/lib/Prophet/CLI/Command.pm b/lib/Prophet/CLI/Command.pm
index 18b5437..714d532 100644
--- a/lib/Prophet/CLI/Command.pm
+++ b/lib/Prophet/CLI/Command.pm
@@ -239,6 +239,50 @@ sub prompt_Yn {
     return 0;
 }
 
+# Create a new [replica] config file section for the given replica if
+# it hasn't been seen before (config section doesn't already exist)
+sub record_replica_in_config {
+    my $self = shift;
+    my $replica_url = shift;
+    my $replica_uuid = shift;
+    my $url_variable = shift || 'url';
+
+    my %previous_sources_by_uuid
+        = $self->app_handle->config->sources(
+            by_variable => 1,
+            variable => 'uuid',
+        );
+
+    my $found_prev_replica = $previous_sources_by_uuid{$replica_uuid};
+
+    if ( !$found_prev_replica ) {
+        # replica section doesn't exist at all; create a new one
+        $self->app_handle->config->group_set(
+            $self->app_handle->config->replica_config_file,
+            [
+            {
+                key => "replica.$replica_url.$url_variable",
+                value => $replica_url,
+            },
+            {
+                key => "replica.$replica_url.uuid",
+                value => $replica_uuid,
+            },
+            ],
+        );
+    }
+    elsif ( $found_prev_replica ne $replica_url ) {
+        # We're publishing to a different place than where it was published
+        # to previously--we don't want to end up with a multivalue in the
+        # config file, so just replace the old value.
+        my $name = $self->app_handle->display_name_for_replica($replica_uuid);
+        $self->app_handle->config->set(
+            filename => $self->app_handle->config->replica_config_file,
+            key => "replica.$name.$url_variable",
+            value => $replica_url,
+        );
+    }
+}
 
 __PACKAGE__->meta->make_immutable;
 no Any::Moose;
diff --git a/lib/Prophet/CLI/Command/Clone.pm b/lib/Prophet/CLI/Command/Clone.pm
index 634aa2a..285cf2c 100644
--- a/lib/Prophet/CLI/Command/Clone.pm
+++ b/lib/Prophet/CLI/Command/Clone.pm
@@ -43,10 +43,17 @@ sub run {
 
     $target->initialize(%init_args);
 
-    $self->app_handle->config->set(
-        key => 'replica.'.$self->arg('from').'.url',
-        value => $self->arg('from'),
-        filename => $self->app_handle->config->replica_config_file,
+    # create new config section for this replica
+    $self->app_handle->config->group_set(
+        $self->app_handle->config->replica_config_file,
+        [ {
+            key => 'replica.'.$self->arg('from').'.url',
+            value => $self->arg('from'),
+        },
+        {   key => 'replica.'.$self->arg('from').'.uuid',
+            value => $target->uuid,
+        },
+        ]
     );
 
     if ( $source->can('database_settings') ) {
diff --git a/lib/Prophet/CLI/Command/Init.pm b/lib/Prophet/CLI/Command/Init.pm
index 91c187d..cba2f59 100644
--- a/lib/Prophet/CLI/Command/Init.pm
+++ b/lib/Prophet/CLI/Command/Init.pm
@@ -13,6 +13,13 @@ sub run {
     $self->app_handle->handle->after_initialize( sub { shift->app_handle->set_db_defaults } );
     $self->app_handle->handle->initialize;
     print "Initialized your new Prophet database.\n";
+
+    # create new config section for this replica
+    $self->app_handle->config->set(
+        key => 'replica.'.$self->app_handle->handle->url.'.uuid',
+        value => $self->app_handle->handle->uuid,
+        filename => $self->app_handle->config->replica_config_file,
+    );
 }
 
 
diff --git a/lib/Prophet/CLI/Command/Merge.pm b/lib/Prophet/CLI/Command/Merge.pm
index 8236604..1d23276 100644
--- a/lib/Prophet/CLI/Command/Merge.pm
+++ b/lib/Prophet/CLI/Command/Merge.pm
@@ -4,15 +4,18 @@ extends 'Prophet::CLI::Command';
 with 'Prophet::CLI::ProgressBar';
 with 'Prophet::CLI::MirrorCommand';
 
-has source => ( isa => 'Prophet::Replica', is => 'rw');
-has target => ( isa => 'Prophet::Replica', is => 'rw');
+has source => ( isa => 'Prophet::Replica', is => 'rw' );
+has target => ( isa => 'Prophet::Replica', is => 'rw' );
 
-sub ARG_TRANSLATIONS { shift->SUPER::ARG_TRANSLATIONS(),  f => 'force' , n => 'dry-run' };
+sub ARG_TRANSLATIONS {
+    shift->SUPER::ARG_TRANSLATIONS(),  f => 'force' , n => 'dry-run',
+};
 
 sub run {
     my $self = shift;
 
     Prophet::CLI->end_pager();
+
     $self->source( Prophet::Replica->get_handle(
         url       => $self->arg('from'),
         app_handle => $self->app_handle,
@@ -23,21 +26,23 @@ sub run {
         app_handle => $self->app_handle,
     ));
 
-    
-    return  unless $self->validate_merge_replicas($self->source => $self->target);
-    if ( $self->source->can('read_changeset_index') && $self->target->url eq $self->app_handle->handle->url) {
+    $self->validate_merge_replicas($self->source => $self->target);
+
+    if ( $self->source->can('read_changeset_index')
+            && $self->target->url eq $self->app_handle->handle->url) {
         #   my $original_source = $self->source;
         #   $self->source($self->get_cache_for_source($original_source));
         #   $self->sync_cache_from_source( target=> $self->source, source => $original_source);
     }
+
     $self->target->import_resolutions_from_remote_replica(
         from  => $self->source,
         force => $self->has_arg('force'),
     ) if ($self->source->resolution_db_handle);
-   
+
     my $changesets = $self->_do_merge();
     #Prophet::CLI->start_pager();
-    $self->print_report($changesets) 
+    $self->print_report($changesets);
 }
 
 sub print_report {
@@ -46,12 +51,15 @@ sub print_report {
     if ( $self->has_arg('verbose') ) {
         if ( $changesets == 0 ) {
             print "No new changesets.\n";
-        } elsif ( $changesets == 1 ) {
+        }
+        elsif ( $changesets == 1 ) {
             print "Merged one changeset.\n";
-        } else {
+        }
+        else {
             print "Merged $changesets changesets.\n";
         }
-    } else {
+    }
+    else {
         print "\nDone.\n";
     }
 }
@@ -141,25 +149,22 @@ sub validate_merge_replicas {
     my $target = shift;
 
     if ( ! $target->replica_exists ) {
-       $self->handle->log("The target (".$self->arg('to').") replica doesn't exist"); 
-        return 0;
+       $self->handle->log_fatal("The target (".$self->arg('to').") replica doesn't exist"); 
     }
 
     if ( ! $source->replica_exists ) {
-       $self->handle->log("The source (".$self->arg('from').") replica doesn't exist"); 
-        return 0;
+       $self->handle->log_fatal("The source (".$self->arg('from').") replica doesn't exist"); 
     }
 
 
     if ( $target->uuid eq $source->uuid ) {
-        $self->handle->log( "You appear to be trying to merge two identical replicas. Skipping.");
-        return 0;
+        $self->handle->log_fatal( "You appear to be trying to merge two identical replicas. Skipping.");
     }
 
     if ( !$target->can_write_changesets ) {
-        $self->handle->log( $target->url . " does not accept changesets. Perhaps it's unwritable.");
-        return 0;
+        $self->handle->log_fatal( $target->url . " does not accept changesets. Perhaps it's unwritable.");
     }
+
     return 1;
 }
 
@@ -175,7 +180,6 @@ sub merge_resolver {
     return $resolver;
 }
 
-
 __PACKAGE__->meta->make_immutable;
 no Any::Moose;
 
diff --git a/lib/Prophet/CLI/Command/Publish.pm b/lib/Prophet/CLI/Command/Publish.pm
index 2831631..4bf2526 100644
--- a/lib/Prophet/CLI/Command/Publish.pm
+++ b/lib/Prophet/CLI/Command/Publish.pm
@@ -11,6 +11,14 @@ sub run {
     my $self = shift;
     die "Please specify a --to.\n" unless $self->has_arg('to');
 
+    # substitute publish-url config variable for to arg if possible
+    my %previous_sources_by_name
+        = $self->app_handle->config->sources( variable => 'publish-url' );
+
+    my $to = exists $previous_sources_by_name{$self->arg('to')}
+        ? $previous_sources_by_name{$self->arg('to')}
+        : $self->arg('to');
+
     # set the temp directory where we will do all of our work, which will be
     # published via rsync
     $self->set_arg(path => $self->tempdir);
@@ -34,7 +42,6 @@ sub run {
     } 
 
     my $from = $self->arg('path');
-    my $to   = $self->arg('to');
 
     print "Publishing the exported clone of the replica to $to with rsync\n";
     $self->publish_dir(
@@ -43,6 +50,11 @@ sub run {
     );
 
     print "Publication complete.\n";
+
+    # create new config section for where to publish this replica
+    # if we're using a url rather than a name
+    $self->record_replica_in_config($to, $self->handle->uuid, 'publish-url')
+        if $to eq $self->arg('to');
 }
 
 sub export_html {
diff --git a/lib/Prophet/CLI/Command/Pull.pm b/lib/Prophet/CLI/Command/Pull.pm
index 94017e0..1649795 100644
--- a/lib/Prophet/CLI/Command/Pull.pm
+++ b/lib/Prophet/CLI/Command/Pull.pm
@@ -10,20 +10,31 @@ sub run {
 
     Prophet::CLI->end_pager();
 
-    my %previous_sources_by_name = $self->app_handle->config->sources;
+    # prefer replica.name.pull-url if it exists, otherwise use
+    # replica.name.url
+    my %previous_sources_by_name_pull_url
+        = $self->app_handle->config->sources( variable => 'pull-url' );
+    my %previous_sources_by_name_url = $self->app_handle->config->sources;
 
     my $explicit_from = '';
 
     if ($self->has_arg('from')) {
         # substitute friendly name -> replica url if we can
-        $explicit_from
-            = exists $previous_sources_by_name{$self->arg('from')}
-            ? $previous_sources_by_name{$self->arg('from')}
+        my $url_from_name = exists $previous_sources_by_name_pull_url{$self->arg('from')}
+            ? $previous_sources_by_name_pull_url{$self->arg('from')}
+            : exists $previous_sources_by_name_url{$self->arg('from')}
+            ? $previous_sources_by_name_url{$self->arg('from')}
             : $self->arg('from');
+
+        $explicit_from = $url_from_name;
         push @from, $explicit_from;
     }
     elsif ($self->has_arg('all')){
-        for my $url (values %previous_sources_by_name) {
+        # if a source exists in both hashes, the pull-url version will
+        # override the url version
+        my %sources
+            = (%previous_sources_by_name_url, %previous_sources_by_name_pull_url);
+        for my $url (values %sources) {
             push @from, $url;
         }
     }
@@ -37,40 +48,10 @@ sub run {
         $self->set_arg( from => $from );
         $self->SUPER::run();
         if ($self->source->uuid and ($from eq $explicit_from)) {
-            $self->record_pull_from_source($explicit_from, $self->source->uuid);
+            $self->record_replica_in_config($explicit_from, $self->source->uuid);
         }
         print "\n";
     }
-
-}
-
-# Create a new [replica] config file section for this replica if we haven't
-# pulled from it before.
-sub record_pull_from_source {
-    my $self = shift;
-    my $source = shift;
-    my $from_uuid = shift;
-
-    my %previous_sources_by_url
-        = $self->app_handle->config->sources( by_url => 1 );
-
-    my $found_prev_replica = $previous_sources_by_url{$source};
-
-    if ( !$found_prev_replica ) {
-        $self->app_handle->config->group_set(
-            $self->app_handle->config->replica_config_file,
-            [
-            {
-                key => "replica.$source.url",
-                value => $source,
-            },
-            {
-                key => "replica.$source.uuid",
-                value => $from_uuid,
-            },
-            ],
-        );
-    }
 }
 
 sub validate_args {
@@ -125,7 +106,4 @@ sub find_bonjour_sources {
 __PACKAGE__->meta->make_immutable;
 no Any::Moose;
 
-
-
 1;
-
diff --git a/lib/Prophet/CLI/Command/Push.pm b/lib/Prophet/CLI/Command/Push.pm
new file mode 100644
index 0000000..417a112
--- /dev/null
+++ b/lib/Prophet/CLI/Command/Push.pm
@@ -0,0 +1,48 @@
+package Prophet::CLI::Command::Push;
+use Any::Moose;
+extends 'Prophet::CLI::Command::Merge';
+
+sub run {
+    my $self = shift;
+
+    Prophet::CLI->end_pager();
+
+    $self->validate_args;
+
+    # sub out friendly names for replica URLs if possible
+    my %previous_sources_by_name_push_url
+        = $self->app_handle->config->sources( variable => 'push-url' );
+    my %previous_sources_by_name_url = $self->app_handle->config->sources;
+
+    my $original_to = $self->arg('to');
+    $self->set_arg( 'to' => exists $previous_sources_by_name_push_url{$self->arg('to')}
+        ? $previous_sources_by_name_push_url{$self->arg('to')}
+        : exists $previous_sources_by_name_url{$self->arg('to')}
+        ? $previous_sources_by_name_url{$self->arg('to')}
+        : $self->arg('to')
+    );
+
+    $self->set_arg( from =>  $self->handle->url );
+    $self->set_arg( db_uuid => $self->handle->db_uuid );
+
+    $self->SUPER::run();
+
+    # we want to record only the replica we're pushing TO, and only if we
+    # weren't using a friendly name already
+    $self->record_replica_in_config($self->arg('to'), $self->target->uuid)
+        if $self->arg('to') eq $original_to;
+}
+
+sub validate_args {
+    my $self = shift;
+
+    die "Please specify a --to.\n" unless $self->context->has_arg('to');
+}
+
+__PACKAGE__->meta->make_immutable;
+no Any::Moose;
+
+
+
+1;
+
diff --git a/lib/Prophet/CLI/Dispatcher.pm b/lib/Prophet/CLI/Dispatcher.pm
index 98bd653..51bd345 100644
--- a/lib/Prophet/CLI/Dispatcher.pm
+++ b/lib/Prophet/CLI/Dispatcher.pm
@@ -66,16 +66,7 @@ on log      => run_command("Log");
 on shell    => run_command("Shell");
 on export   => run_command('Export');
 on info     => run_command('Info');
-
-on push => sub {
-    my $self = shift;
-
-    die "Please specify a --to.\n" if !$self->context->has_arg('to');
-
-    $self->context->set_arg(from => $self->cli->handle->url);
-    $self->context->set_arg(db_uuid => $self->cli->handle->db_uuid);
-    run('merge', $self, @_);
-};
+on push     => run_command('Push');
 
 on qr/^(alias(?:es)?|config)?\s+(.*)/ => sub {
     my ( $self ) = @_;
diff --git a/lib/Prophet/Config.pm b/lib/Prophet/Config.pm
index 6cbfbf0..d59e93e 100644
--- a/lib/Prophet/Config.pm
+++ b/lib/Prophet/Config.pm
@@ -117,8 +117,7 @@ sub sources {
         @_,
     );
 
-    my %sources = $self->get_regexp( key => "^replica\..*\.$args{variable}\$" );
-
+    my %sources = $self->get_regexp( key => "^replica[.].*[.]$args{variable}\$" );
     my %new_sources = map {
         $_ =~ /^replica\.(.*)\.$args{variable}$/;
         $args{by_variable} ? ( $sources{$_} => $1 ) : ( $1 => $sources{$_} );

commit 45c988229186721bce2a8965dcfcccee11f091eb
Author: Christine Spang <spang at mit.edu>
Date:   Thu Jul 16 12:24:47 2009 +0100

    Tests for friendly names with commands--init/clone/pull/publish (still need to test push).

diff --git a/t/publish-pull.t b/t/publish-pull.t
index d532fd6..c44ef1b 100644
--- a/t/publish-pull.t
+++ b/t/publish-pull.t
@@ -1,17 +1,35 @@
 #!/usr/bin/perl
 use warnings;
 use strict;
-use Prophet::Test tests => 24;
+use Prophet::Test tests => 33;
 use Test::Exception;
-use File::Temp 'tempdir';
+use File::Temp qw(tempdir tempfile);
 use Params::Validate;
+use Prophet::Util;
+# require Prophet::CLIContext;
 
 my ($bug_uuid, $pullall_uuid);
 
 my $alice_published = tempdir(CLEANUP => ! $ENV{PROPHET_DEBUG});
 
+(undef, my $alice_config) = tempfile( CLEANUP => ! $ENV{PROPHET_DEBUG} );
+(undef, my $bob_config) = tempfile( CLEANUP => ! $ENV{PROPHET_DEBUG} );
+diag "Alice's config file is located at $alice_config";
+diag "Bob's config file is located at $bob_config";
+
 as_alice {
+    $ENV{PROPHET_APP_CONFIG} = $alice_config;
     run_ok('prophet', [qw(init)]);
+
+    # check that new config section has been created with uuid variable
+    my $config_contents = Prophet::Util->slurp($ENV{PROPHET_APP_CONFIG});
+    like($config_contents, qr/
+\[core\]
+	config-format-version = \d+
+\[replica ".*?"\]
+	uuid = $Prophet::CLIContext::ID_REGEX
+/, 'replica section created in config file after init');
+
     run_output_matches( 'prophet',
         [qw(create --type Bug -- --status new --from alice )],
         [qr/Created Bug \d+ \((\S+)\)(?{ $bug_uuid = $1 })/],
@@ -19,15 +37,81 @@ as_alice {
     ok($bug_uuid, "got a uuid for the Bug record");
     run_output_matches( 'prophet', [qw(search --type Bug --regex .)], [qr/new/], [], " Found our record" );
     run_ok( 'prophet', [qw(publish --to), $alice_published] );
+
+    # check that publish-url config key has been created correctly
+    $config_contents = Prophet::Util->slurp($ENV{PROPHET_APP_CONFIG});
+    like($config_contents, qr/
+\[core\]
+	config-format-version = \d+
+\[replica "(.*?)"\]
+	uuid = $Prophet::CLIContext::ID_REGEX
+	publish-url = $alice_published
+/, 'publish-url variable created correctly in config');
+    $config_contents =~ /\[replica "(.*?)"\]/;
+    my $replica_name = $1;
+
+    # change name in config
+    my $new_config_contents = $config_contents;
+    $new_config_contents =~ s/$replica_name/new-name/;
+    Prophet::Util->write_file(
+        file => $ENV{PROPHET_APP_CONFIG},
+        content => $new_config_contents,
+    );
+
+    # publish again to a different location
+    my $new_published = tempdir( CLEANUP => ! $ENV{PROPHET_DEBUG} );
+    run_ok( 'prophet', [qw(publish --to), $new_published ] );
+    # make sure the subsection name was changed and the publish-url
+    # was updated, rather than a new section being created
+    $config_contents = Prophet::Util->slurp($ENV{PROPHET_APP_CONFIG});
+    like($config_contents, qr/
+\[core\]
+	config-format-version = \d+
+\[replica "new-name"\]
+	uuid = $Prophet::CLIContext::ID_REGEX
+	publish-url = $new_published
+/, 'publish-url variable created correctly in config');
+
+    # check to make sure that publish doesn't fall back to using
+    # url, since that would never make sense
+    $new_config_contents =~ /uuid = ($Prophet::CLIContext::ID_REGEX)/;
+    my $uuid = $1;
+    $new_published = tempdir( CLEANUP => ! $ENV{PROPHET_DEBUG} );
+    my $bogus_name = tempdir( CLEANUP => ! $ENV{PROPHET_DEBUG} );
+    Prophet::Util->write_file(
+        file => $ENV{PROPHET_APP_CONFIG},
+        content => <<EOF,
+[replica "$bogus_name"]
+	uuid = $uuid
+	url = $new_published
+EOF
+    );
+    # diag "publishing to $new_published";
+    # diag "bogus name is $bogus_name";
+    run_ok( 'prophet', [qw(publish --to), $bogus_name ] );
+    ok( ! -f File::Spec->catfile( $new_published, 'config' )
+        && -f File::Spec->catfile( $bogus_name, 'replica-uuid' ),
+        'did not fall back to url variable' );
 };
 
 my $path =$alice_published;
 
 as_bob {
+    $ENV{PROPHET_APP_CONFIG} = $bob_config;
     run_ok( 'prophet', ['clone', '--from', "file://$path"] );
+    my $config_contents = Prophet::Util->slurp($ENV{PROPHET_APP_CONFIG});
+    like($config_contents, qr|
+\[core\]
+	config-format-version = \d+
+\[replica "file://$path"\]
+	url = file://$path
+	uuid = $Prophet::CLIContext::ID_REGEX
+|, 'replica section created in config file after clone');
+
     run_output_matches( 'prophet', [qw(search --type Bug --regex .)], [qr/new/], [], " Found our record" );
 };
 as_alice {
+    $ENV{PROPHET_APP_CONFIG} = $alice_config;
     run_output_matches( 'prophet',
         [qw(create --type Pullall -- --status new --from alice )],
         [qr/Created Pullall \d+ \((\S+)\)(?{ $pullall_uuid = $1 })/],
@@ -39,12 +123,41 @@ as_alice {
 };
 
 as_bob {
-    run_ok( 'prophet', ['pull', '--all'] );
+    $ENV{PROPHET_APP_CONFIG} = $bob_config;
+
+    # change name in config
+    my $config_contents = Prophet::Util->slurp($ENV{PROPHET_APP_CONFIG});
+    $config_contents =~ /\[replica "(.*?)"\]/;
+    my $replica_name = $1;
+    my $new_config_contents = $config_contents;
+    $new_config_contents =~ s/$replica_name/new-name/;
+    Prophet::Util->write_file(
+        file => $ENV{PROPHET_APP_CONFIG},
+        content => $new_config_contents,
+    );
+    run_ok( 'prophet', ['pull', '--from', 'new-name'], 'pull from name works');
     run_output_matches( 'prophet', [qw(search --type Pullall --regex .)], [qr/new/], [], " Found our record" );
+
+    $new_config_contents =~ s/url/pull-url/;
+    Prophet::Util->write_file(
+        file => $ENV{PROPHET_APP_CONFIG},
+        content => $new_config_contents,
+    );
+    run_ok( 'prophet', ['pull', '--from', 'new-name'],
+        'pull from name works with pull-url var');
+
+    $new_config_contents .= "\turl = don't-use-this";
+    Prophet::Util->write_file(
+        file => $ENV{PROPHET_APP_CONFIG},
+        content => $new_config_contents,
+    );
+    run_ok( 'prophet', ['pull', '--from', 'new-name'],
+        'pull-url is preferred over url');
 };
 
 
 as_charlie {
+    (undef, $ENV{PROPHET_APP_CONFIG}) = tempfile( CLEANUP => ! $ENV{PROPHET_DEBUG} );
     run_ok( 'prophet', ['clone', '--from', "file://$path"] );
 };
 

commit aa63e50e604a0b02a4986747e185443a7eadaab8
Merge: 45c9882... a04cc4e...
Author: Christine Spang <spang at mit.edu>
Date:   Thu Jul 16 12:34:13 2009 +0100

    Merge branch 'master' of fsck.com:/git/prophet


-----------------------------------------------------------------------



More information about the Bps-public-commit mailing list