[Bps-public-commit] Prophet branch, config-gitlike, updated. f66404963e5310b5916c94b9c3b43a0d09a4cce9

spang at bestpractical.com spang at bestpractical.com
Thu Jun 25 04:56:55 EDT 2009


The branch, config-gitlike has been updated
       via  f66404963e5310b5916c94b9c3b43a0d09a4cce9 (commit)
       via  28fa29a29c9fdf8ea8e300526d6223d4a97a1378 (commit)
       via  3faa5b45b03e4b4dacd14269d1866fb35fa2477b (commit)
       via  a781ff5b1c9878aad5760d03dbd57bfb7c6b0a63 (commit)
       via  c25d49f1a372cc744814b3d7f6d29b0aabdd6c2a (commit)
      from  2d306e0d96a396254a2d0c3740de76dec0d89215 (commit)

Summary of changes:
 lib/Prophet/CLI.pm                 |    5 +-
 lib/Prophet/CLI/Command/Aliases.pm |   98 ++++-----------------------
 lib/Prophet/CLI/Command/Clone.pm   |    2 +-
 lib/Prophet/CLI/Command/Config.pm  |  132 +++++++++++++++++++++++++++++++++---
 lib/Prophet/CLI/Command/Pull.pm    |   45 ++++++++-----
 lib/Prophet/CLI/Command/Shell.pm   |   12 +++-
 lib/Prophet/CLI/Dispatcher.pm      |   45 ++++++++++---
 lib/Prophet/Config.pm              |   38 +++++++----
 t/aliases.t                        |  109 +++++++++++++++++++++++------
 t/config.t                         |   23 +++++-
 10 files changed, 345 insertions(+), 164 deletions(-)

- Log -----------------------------------------------------------------
commit c25d49f1a372cc744814b3d7f6d29b0aabdd6c2a
Author: Christine Spang <spang at mit.edu>
Date:   Wed Jun 24 15:29:32 2009 +0300

    Quote elements of @ARGV that contain spaces before passing them
    off to Path::Dispatcher. Also, keep quoted text in a single
    element when parsing commands in the shell.

diff --git a/lib/Prophet/CLI.pm b/lib/Prophet/CLI.pm
index cbf0e75..5899261 100644
--- a/lib/Prophet/CLI.pm
+++ b/lib/Prophet/CLI.pm
@@ -103,7 +103,9 @@ sub run_one_command {
     $self->context( Prophet::CLIContext->new( app_handle => $self->app_handle ) );
     $self->context->setup_from_args(@args);
     my $dispatcher = $self->dispatcher_class->new( cli => $self );
-    my $dispatch = $dispatcher->dispatch( join ' ', @{ $self->context->primary_commands });
+    my $dispatch_command_string = join(' ', map { /\s/ ? qq{"$_"} : $_ }
+        @{ $self->context->primary_commands });
+    my $dispatch = $dispatcher->dispatch( $dispatch_command_string );
     $self->start_pager();
     $dispatch->run($dispatcher);
     $self->end_pager();
diff --git a/lib/Prophet/CLI/Command/Shell.pm b/lib/Prophet/CLI/Command/Shell.pm
index 852fca3..ff48e12 100644
--- a/lib/Prophet/CLI/Command/Shell.pm
+++ b/lib/Prophet/CLI/Command/Shell.pm
@@ -52,7 +52,17 @@ sub eval {
 
     eval {
         local $SIG{__DIE__} = 'DEFAULT';
-        $self->cli->run_one_command(split ' ', $line);
+        my @args;
+        while ($line) {
+            $line =~ s/^\s*//;
+            if ( $line =~ s/^["'](.+)["']// ) {
+                push @args, $1;
+            }
+            else {
+                push @args, $1 if $line =~ s/(\S+)//;
+            }
+        }
+        $self->cli->run_one_command(@args);
     };
     warn $@ if $@;
 }

commit a781ff5b1c9878aad5760d03dbd57bfb7c6b0a63
Author: Christine Spang <spang at mit.edu>
Date:   Wed Jun 24 15:32:01 2009 +0300

    Also support git-style 'alias "foo bar" "bar baz"' aliasing.

diff --git a/lib/Prophet/CLI/Command/Aliases.pm b/lib/Prophet/CLI/Command/Aliases.pm
index 74df7f1..4b1245f 100644
--- a/lib/Prophet/CLI/Command/Aliases.pm
+++ b/lib/Prophet/CLI/Command/Aliases.pm
@@ -46,11 +46,11 @@ sub run {
         if ( $self->has_arg('set') ) {
             my $value = $self->arg('set');
             if ( $value =~ /^\s*(.+?)\s*=\s*(.+?)\s*$/ ) {
-                my $old = $config->get( key => "alias.$1" );
+                my $old = $config->get( key => "alias.'$1'" );
                 if ( defined $old ) {
                     if ( $old ne $2 ) {
                         $config->set(
-                            key => "alias.$1",
+                            key => "alias.'$1'",
                             value => $2,
                             filename => $self->config_filename,
                         );
@@ -63,7 +63,7 @@ sub run {
                 }
                 else {
                     $config->set(
-                        key => "alias.$1",
+                        key => "alias.'$1'",
                         value => $2,
                         filename => $self->config_filename,
                     );
@@ -74,12 +74,12 @@ sub run {
         elsif ( $self->has_arg('delete') ) {
             my $key = $self->arg('delete');
 
-            if ( defined $config->get( key => "alias.$key" ) ) {
+            if ( defined $config->get( key => "alias.'$key'" ) ) {
                 print "deleted alias '$key = "
-                      .$config->get( key => "alias.$key" )."'\n";
+                      .$config->get( key => "alias.'$key'" )."'\n";
 
                 $config->set(
-                    key => "alias.$key",
+                    key => "alias.'$key'",
                     filename => $self->config_filename,
                 );
             }
diff --git a/lib/Prophet/CLI/Dispatcher.pm b/lib/Prophet/CLI/Dispatcher.pm
index b868f95..26e7760 100644
--- a/lib/Prophet/CLI/Dispatcher.pm
+++ b/lib/Prophet/CLI/Dispatcher.pm
@@ -75,23 +75,40 @@ on push => sub {
     run('merge', $self, @_);
 };
 
-on qr/^alias(?:es)?\s*(.*)/ => sub {
+on qr/^alias(?:es)?\s+(.*)/ => sub {
     my ( $self ) = @_;
     my $arg = $1;
+
     if ( $arg =~ /^show\b/ ) {
         $self->context->set_arg(show => 1);
     }
-    elsif ( $arg =~ /^delete\s+(.*)/ ) {
+    elsif ( $arg =~ /^edit\b/ ) {
+        $self->context->set_arg(edit => 1);
+    }
+    # arg *might* be quoted
+    elsif ( $arg =~ /^delete\s+"?([^"]+)"?/ ) {
         $self->context->set_arg(delete => $1);
     }
-    elsif ( $arg =~ /^(?:add|set)?\s+(.*)/ ) {
-        $self->context->set_arg(set => $1);
+    # prophet alias "foo bar" = "foo baz"
+    # prophet alias foo = bar
+    # prophet alias add foo bar = "bar baz"
+    # prophet alias add foo bar = bar baz
+    elsif ( $arg =~ 
+        /^(?:add |set )?\s*(?:(?:"([^"]+)"|([^"]+))\s+=\s+(?:"([^"]+)"|([^"]+)))$/ ) {
+        my ($orig, $new) = grep { defined } ($1, $2, $3, $4);
+        $self->context->set_arg(set => "$orig=$new");
     }
-    elsif ( $arg =~ /=/ ) {
-        $self->context->set_arg(set => $arg);
+    # prophet alias "foo = bar"
+    # prophet alias "foo bar = foo baz"
+    elsif ( $arg =~ /^(?:add |set )?\s*"([^"]+=[^"]+)"$/ ) {
+        $self->context->set_arg(set => $1);
     }
-    elsif ( $arg =~ /^edit\b/ ) {
-        $self->context->set_arg(edit => 1);
+    # alternate syntax (preferred):
+    # prophet alias "foo bar" "bar baz", prophet alias foo "bar baz",
+    # prophet alias foo bar, etc.
+    elsif ( $arg =~ /^(?:"([^"]+)"|([^"\s]+))\s+(?:"([^"]+)"|([^"\s]+))/ ) {
+        my ($orig, $new) = grep { defined } ($1, $2, $3, $4);
+        $self->context->set_arg(set => "$orig=$new");
     }
     else {
         die 'no idea what you mean, sorry';
diff --git a/t/aliases.t b/t/aliases.t
index 57859b3..cbcb983 100644
--- a/t/aliases.t
+++ b/t/aliases.t
@@ -2,7 +2,7 @@
 #
 use warnings;
 use strict;
-use Prophet::Test tests => 18;
+use Prophet::Test tests => 22;
 use File::Temp qw/tempfile/;
 
 $ENV{'PROPHET_REPO'} = $Prophet::Test::REPO_BASE . '/repo-' . $$;
@@ -38,7 +38,6 @@ my @cmds = (
         comment => 'add the same alias will not change anything',
     },
     {
-
         # this alias is bad, please don't use it in real life
         cmd => [ 'set', 'pull -a=pull --local' ],
         output =>
@@ -87,10 +86,34 @@ my @cmds = (
         comment => 'deleted alias foo bar',
     },
     {
-        cmd => [ 'set', 'foo', 'bar', '=bar baz'],
+        cmd => [ 'set', 'foo', 'bar', '=', 'bar baz'],
         output => qr/added alias 'foo bar = bar baz'/,
-        comment => 'readd alias foo bar = bar baz',
+        comment => 'read alias foo bar = bar baz',
+    },
+    # tests for alternate syntax
+    {
+        cmd => [ 'foo bar', 'bar baz'],
+        output  => qr/alias 'foo bar = bar baz' isn't changed, won't update/,
+        comment => 'read alias foo bar = bar baz',
+    },
+    {
+        cmd => [ 'foo', 'bar baz'],
+        output  => qr/added alias 'foo = bar baz'/,
+        comment => 'added alias foo',
+    },
+    {
+        cmd => [ 'foo bar', 'bar'],
+        output =>
+          qr/changed alias 'foo bar' from 'bar baz' to 'bar'/,
+        comment => 'changed alias foo bar',
+    },
+    {
+        cmd => [ 'pull --from http://www.example.com/', 'pfe'],
+        output =>
+          qr|added alias 'pull --from http://www.example.com/ = pfe'|,
+        comment => 'added alias with weird characters',
     },
+,
 );
 
 for my $item ( @cmds ) {
@@ -110,7 +133,9 @@ is_deeply(
     {
         'pull -l' => 'pull --local',
         'pull -a' => 'pull --all',
-        'foo bar' => 'bar baz',
+        'foo bar' => 'bar',
+        'foo' => 'bar baz',
+        'pull --from http://www.example.com/' => 'pfe',
     },
     'non empty aliases',
 );
@@ -125,7 +150,9 @@ is( $content, <<EOF, 'content in config' );
 [alias]
 	pull -a = pull --all
 	pull -l = pull --local
-	foo bar = bar baz
+	foo bar = bar
+	foo = bar baz
+	pull --from http://www.example.com/ = pfe
 EOF
 
 # TODO: need tests for interactive alias editing

commit 3faa5b45b03e4b4dacd14269d1866fb35fa2477b
Author: Christine Spang <spang at mit.edu>
Date:   Wed Jun 24 20:42:39 2009 +0300

    Move the majority of the aliases code to config.
    
    The config command can now also be used to update
    the config file, à la git.

diff --git a/lib/Prophet/CLI.pm b/lib/Prophet/CLI.pm
index 5899261..b746a4d 100644
--- a/lib/Prophet/CLI.pm
+++ b/lib/Prophet/CLI.pm
@@ -103,7 +103,8 @@ sub run_one_command {
     $self->context( Prophet::CLIContext->new( app_handle => $self->app_handle ) );
     $self->context->setup_from_args(@args);
     my $dispatcher = $self->dispatcher_class->new( cli => $self );
-    my $dispatch_command_string = join(' ', map { /\s/ ? qq{"$_"} : $_ }
+    # XXX this means you can't have a literal " in CLI commands...
+    my $dispatch_command_string = join(' ', map { s/"/'/g; /\s/ ? qq{"$_"} : $_ }
         @{ $self->context->primary_commands });
     my $dispatch = $dispatcher->dispatch( $dispatch_command_string );
     $self->start_pager();
diff --git a/lib/Prophet/CLI/Command/Aliases.pm b/lib/Prophet/CLI/Command/Aliases.pm
index 4b1245f..43be982 100644
--- a/lib/Prophet/CLI/Command/Aliases.pm
+++ b/lib/Prophet/CLI/Command/Aliases.pm
@@ -2,105 +2,35 @@ package Prophet::CLI::Command::Aliases;
 use Any::Moose;
 use Params::Validate qw/validate/;
 
-extends 'Prophet::CLI::Command';
-with 'Prophet::CLI::TextEditorCommand';
-
-has config_filename => (
-    is => 'rw',
-    isa => 'Str',
-    lazy => 1,
-    default => sub {
-        $_[0]->app_handle->config->replica_config_file;
-    },
-);
-
-has old_errors => (
-    is => 'rw',
-    isa => 'Str',
-    default => '',
-);
-
-sub ARG_TRANSLATIONS { shift->SUPER::ARG_TRANSLATIONS(),  a => 'add', d => 'delete', s => 'show' };
+extends 'Prophet::CLI::Command::Config';
+
+sub ARG_TRANSLATIONS { shift->SUPER::ARG_TRANSLATIONS(), s => 'show' };
 
 sub run {
     my $self     = shift;
 
-    my $config = $self->app_handle->config;
-
-    if ($self->has_arg('global')) {
-        $self->config_filename($config->global_file);
-    }
-    elsif ($self->has_arg('user')) {
-        $self->config_filename($config->user_file);
-    }
+    my $config = $self->config;
 
     my $template = $self->make_template;
 
+    # alias.pull --from http://foo-bar.com/
     # add is the same as set
     if ( $self->context->has_arg('add') ) {
         $self->context->set_arg('set', $self->arg('add') )
     }
 
-    if ( $self->has_arg('set') || $self->has_arg('delete') ) {
-
-        if ( $self->has_arg('set') ) {
-            my $value = $self->arg('set');
-            if ( $value =~ /^\s*(.+?)\s*=\s*(.+?)\s*$/ ) {
-                my $old = $config->get( key => "alias.'$1'" );
-                if ( defined $old ) {
-                    if ( $old ne $2 ) {
-                        $config->set(
-                            key => "alias.'$1'",
-                            value => $2,
-                            filename => $self->config_filename,
-                        );
-                        print
-                          "changed alias '$1' from '$old' to '$2'\n";
-                    }
-                    else {
-                        print "alias '$1 = $2' isn't changed, won't update\n";
-                    }
-                }
-                else {
-                    $config->set(
-                        key => "alias.'$1'",
-                        value => $2,
-                        filename => $self->config_filename,
-                    );
-                    print "added alias '$1 = $2'\n";
-                }
-            }
-        }
-        elsif ( $self->has_arg('delete') ) {
-            my $key = $self->arg('delete');
-
-            if ( defined $config->get( key => "alias.'$key'" ) ) {
-                print "deleted alias '$key = "
-                      .$config->get( key => "alias.'$key'" )."'\n";
-
-                $config->set(
-                    key => "alias.'$key'",
-                    filename => $self->config_filename,
-                );
-            }
-            else {
-                print "didn't find alias '$key'\n";
-            }
-        }
-
-    }
-    elsif ( $self->has_arg('edit') ) {
-        my $done = 0;
-
-        while ( !$done ) {
-            $done = $self->try_to_edit( template => \$template );
-        }
-    }
-    else {
+    if ( ! ( $self->has_arg('set') ||
+             $self->has_arg('delete') || $self->has_arg('edit') ) ) {
         print $template. "\n";
         return;
     }
-
+    else {
+        $self->set_arg('set', 'alias.'.$self->arg('set'))
+            if $self->has_arg('set');
+        $self->set_arg('delete', 'alias.'.$self->arg('delete'))
+            if $self->has_arg('delete');
+        $self->SUPER::run(@_);
+    }
 }
 
 sub make_template {
@@ -125,7 +55,7 @@ sub make_template {
             $content .= "$key = $aliases->{$key}\n";
         }
     }
-    else {
+    elsif ( !$self->has_arg('edit') ) {
         $content = "No aliases for the current repository.\n";
     }
 
diff --git a/lib/Prophet/CLI/Command/Config.pm b/lib/Prophet/CLI/Command/Config.pm
index 2f69352..64072af 100644
--- a/lib/Prophet/CLI/Command/Config.pm
+++ b/lib/Prophet/CLI/Command/Config.pm
@@ -1,24 +1,136 @@
 package Prophet::CLI::Command::Config;
 use Any::Moose;
+use Params::Validate qw/validate/;
 extends 'Prophet::CLI::Command';
 
+with 'Prophet::CLI::TextEditorCommand';
+
+has config_filename => (
+    is => 'rw',
+    isa => 'Str',
+    lazy => 1,
+    default => sub {
+        $_[0]->app_handle->config->replica_config_file;
+    },
+);
+
+has old_errors => (
+    is => 'rw',
+    isa => 'Str',
+    default => '',
+);
+
+sub ARG_TRANSLATIONS { shift->SUPER::ARG_TRANSLATIONS(),  a => 'add', d => 'delete', s => 'show' };
+
 sub run {
     my $self = shift;
 
     my $config = $self->config;
 
-    print "Configuration:\n\n";
-    my @files =@{$config->config_files};
-    if (!scalar @files) {
-        print $self->no_config_files;
-        return;
+    if ($self->has_arg('global')) {
+        $self->config_filename($config->global_file);
+    }
+    elsif ($self->has_arg('user')) {
+        $self->config_filename($config->user_file);
+    }
+
+    # add is the same as set
+    if ( $self->context->has_arg('add') ) {
+        $self->context->set_arg('set', $self->arg('add') )
+    }
+
+    if ( $self->has_arg('set') || $self->has_arg('delete') ) {
+
+        if ( $self->has_arg('set') ) {
+            my $value = $self->arg('set');
+            if ( $value =~ /^\s*(.+?)\s*=\s*(.+?)\s*$/ ) {
+                $config->set(
+                    key => $1,
+                    value => $2,
+                    filename => $self->config_filename,
+                );
+            }
+            # no value given, just print the current value
+            else {
+                print $config->get( key => $self->arg('set') ) . "\n";
+            }
+        }
+        elsif ( $self->has_arg('delete') ) {
+            my $key = $self->arg('delete');
+
+            $config->set(
+                key => $key,
+                filename => $self->config_filename,
+            );
+        }
+
     }
-    print "Config files:\n\n";
-    for my $file (@files) {
-        print "$file\n";
+    elsif ( $self->has_arg('edit') ) {
+        my $done = 0;
+
+        my $template = $self->make_template;
+
+        while ( !$done ) {
+            $done = $self->try_to_edit( template => \$template );
+        }
+    }
+    else {
+        print "Configuration:\n\n";
+        my @files =@{$config->config_files};
+        if (!scalar @files) {
+            print $self->no_config_files;
+            return;
+        }
+        print "Config files:\n\n";
+        for my $file (@files) {
+            print "$file\n";
+        }
+        print "\nYour configuration:\n\n";
+        $config->dump;
+    }
+}
+
+sub make_template {
+    my $self = shift;
+
+    return Prophet::Util->slurp($self->config_filename);
+}
+
+sub process_template {
+    my $self = shift;
+    my %args = validate( @_, { template => 1, edited => 1, record => 0 } );
+
+    # Attempt parsing the config. If we're good, remove any previous error
+    # sections, write to disk and load.
+    eval {
+        $self->config->parse_content(
+            content => $args{edited},
+            error => sub {
+                Config::GitLike::error_callback( @_, filename =>
+                    $self->config_filename );
+            },
+        );
+    };
+    if ($@) {
+        chomp $@;
+        my @error_lines = split "\n", $@;
+        my $error = join "\n", map { "# Error: '$_'" } @error_lines;
+        $self->handle_template_errors(
+            rtype => 'configuration',
+            template_ref => $args{template},
+            bad_template => $args{edited},
+            errors_pattern => '',
+            error => $error,
+            old_errors => $self->old_errors,
+        );
+        return 0;
     }
-    print "\nYour configuration:\n\n";
-    $config->dump;
+    my $old_errors = $self->old_errors;
+    Prophet::Util->write_file(
+        file => $self->config_filename,
+        content => $args{edited},
+    );
+    return 1;
 }
 
 sub no_config_files {
diff --git a/lib/Prophet/CLI/Dispatcher.pm b/lib/Prophet/CLI/Dispatcher.pm
index 26e7760..fedc6b3 100644
--- a/lib/Prophet/CLI/Dispatcher.pm
+++ b/lib/Prophet/CLI/Dispatcher.pm
@@ -75,9 +75,10 @@ on push => sub {
     run('merge', $self, @_);
 };
 
-on qr/^alias(?:es)?\s+(.*)/ => sub {
+on qr/^(alias(?:es)?|config)?\s+(.*)/ => sub {
     my ( $self ) = @_;
-    my $arg = $1;
+    my $cmd = $1;
+    my $arg = $2;
 
     if ( $arg =~ /^show\b/ ) {
         $self->context->set_arg(show => 1);
@@ -96,6 +97,7 @@ on qr/^alias(?:es)?\s+(.*)/ => sub {
     elsif ( $arg =~ 
         /^(?:add |set )?\s*(?:(?:"([^"]+)"|([^"]+))\s+=\s+(?:"([^"]+)"|([^"]+)))$/ ) {
         my ($orig, $new) = grep { defined } ($1, $2, $3, $4);
+        $orig = "'$orig'" if $cmd =~ /alias/ && $orig =~ /\./;
         $self->context->set_arg(set => "$orig=$new");
     }
     # prophet alias "foo = bar"
@@ -106,14 +108,20 @@ on qr/^alias(?:es)?\s+(.*)/ => sub {
     # alternate syntax (preferred):
     # prophet alias "foo bar" "bar baz", prophet alias foo "bar baz",
     # prophet alias foo bar, etc.
-    elsif ( $arg =~ /^(?:"([^"]+)"|([^"\s]+))\s+(?:"([^"]+)"|([^"\s]+))/ ) {
+    elsif ( $arg =~ /^(?:"([^"]+)"|([^"\s]+))(?:\s+(?:"([^"]+)"|([^"\s]+)))?/ ) {
         my ($orig, $new) = grep { defined } ($1, $2, $3, $4);
-        $self->context->set_arg(set => "$orig=$new");
+        $orig = "'$orig'" if $cmd =~ /alias/ && $orig =~ /\./;
+        if ( $new ) {
+            $self->context->set_arg(set => "$orig=$new");
+        }
+        else {
+            $self->context->set_arg(set => $orig);
+        }
     }
     else {
         die 'no idea what you mean, sorry';
     }
-    run( 'aliases', $self, @_ );
+    run( $cmd, $self, @_ );
 };
 
 sub run_command {
diff --git a/t/aliases.t b/t/aliases.t
index cbcb983..f627413 100644
--- a/t/aliases.t
+++ b/t/aliases.t
@@ -2,7 +2,7 @@
 #
 use warnings;
 use strict;
-use Prophet::Test tests => 22;
+use Prophet::Test tests => 30;
 use File::Temp qw/tempfile/;
 
 $ENV{'PROPHET_REPO'} = $Prophet::Test::REPO_BASE . '/repo-' . $$;
@@ -20,6 +20,7 @@ $config->load;
 
 is_deeply( scalar $config->aliases, {}, 'initial alias is empty' );
 
+# no news is good news
 my @cmds = (
     {
         cmd => [ 'show' ],
@@ -29,90 +30,127 @@ my @cmds = (
 
     {
         cmd => [ 'add', 'pull -a=pull --all' ],
-        output  => qr/added alias 'pull -a = pull --all/,
+        output  => qr//,
         comment => 'add a new alias',
     },
     {
-        cmd => [ 'add', 'pull -a=pull --all' ],
-        output  => qr/alias 'pull -a = pull --all' isn't changed, won't update/,
-        comment => 'add the same alias will not change anything',
+        cmd => [ 'pull -a' ],
+        output  => qr/pull --all/,
+        comment => 'new alias set correctly',
     },
     {
         # this alias is bad, please don't use it in real life
         cmd => [ 'set', 'pull -a=pull --local' ],
-        output =>
-          qr/changed alias 'pull -a' from 'pull --all' to 'pull --local'/,
+        output => qr//,
         comment =>
           q{changed alias 'pull -a' from 'pull --all' to 'pull --local'},
     },
     {
+        cmd => [ 'pull -a' ],
+        output  => qr/pull --local/,
+        comment => 'alias changed correctly',
+    },
+    {
         cmd     => [ 'delete', 'pull -a' ],
-        output  => qr/deleted alias 'pull -a = pull --local'/,
+        output  => qr//,
         comment => q{deleted alias 'pull -a = pull --local'},
     },
     {
         cmd     => [ 'delete', 'pull -a' ],
-        output  => qr/didn't find alias 'pull -a'/,
+        output  => qr//,
         comment => q{delete an alias that doesn't exist any more},
     },
     {
         cmd => [ 'add', 'pull -a=pull --all' ],
-        output  => qr/added alias 'pull -a = pull --all/,
-        comment => 'read a new alias',
+        output  => qr//,
+        comment => 'add a new alias',
+    },
+    {
+        cmd => [ 'pull -a' ],
+        output  => qr/pull --all/,
+        comment => 'alias is set correctly',
     },
     {
         cmd => [ 'add', 'pull -l=pull --local' ],
-        output  => qr/added alias 'pull -l = pull --local/,
+        output  => qr//,
         comment => 'add a new alias',
     },
     {
+        cmd => [ 'pull -l' ],
+        output  => qr/pull --local/,
+        comment => 'alias is set correctly',
+    },
+    {
         cmd => [ 'show' ],
         output  => qr/Active aliases for the current repository \(including user-wide and global\naliases if not overridden\):\n\npull -l = pull --local\npull -a = pull --all/s,
         comment => 'show',
     },
     {
         cmd => [ 'add', 'foo', 'bar', '=', 'bar',  'baz' ],
-        output  => qr/added alias 'foo bar = bar baz'/,
+        output  => qr//,
         comment => 'added alias foo bar',
     },
     {
-        cmd => [ 'foo', 'bar', '=', 'bar',  'baz' ],
-        output  => qr/alias 'foo bar = bar baz' isn't changed, won't update/,
+        cmd => [ 'foo bar' ],
+        output  => qr/bar baz/,
+        comment => 'alias is set correctly',
+    },
+    {
+        cmd => [ 'foo', 'bar', '=bar',  'baz' ],
+        output  => qr//,
         comment => 'read alias foo bar',
     },
     {
+        cmd => [ 'foo bar' ],
+        output  => qr/bar baz/,
+        comment => 'alias foo bar still the same',
+    },
+    {
         cmd => [ 'delete', 'foo', 'bar' ],
-        output  => qr/deleted alias 'foo bar = bar baz'/,
+        output  => qr//,
         comment => 'deleted alias foo bar',
     },
     {
+        cmd => [ 'foo', 'bar' ],
+        output  => qr//,
+        comment => 'deleted alias no longer exists',
+    },
+    {
         cmd => [ 'set', 'foo', 'bar', '=', 'bar baz'],
-        output => qr/added alias 'foo bar = bar baz'/,
-        comment => 'read alias foo bar = bar baz',
+        output => qr//,
+        comment => 'set alias again with different syntax',
     },
     # tests for alternate syntax
     {
         cmd => [ 'foo bar', 'bar baz'],
-        output  => qr/alias 'foo bar = bar baz' isn't changed, won't update/,
-        comment => 'read alias foo bar = bar baz',
+        output  => qr//,
+        comment => 'alias foo bar = bar baz didn\'t change',
     },
     {
         cmd => [ 'foo', 'bar baz'],
-        output  => qr/added alias 'foo = bar baz'/,
+        output  => qr//,
         comment => 'added alias foo',
     },
     {
+        cmd => [ 'foo' ],
+        output  => qr/bar baz/,
+        comment => 'alias foo set correctly',
+    },
+    {
         cmd => [ 'foo bar', 'bar'],
-        output =>
-          qr/changed alias 'foo bar' from 'bar baz' to 'bar'/,
+        output => qr//,
         comment => 'changed alias foo bar',
     },
     {
         cmd => [ 'pull --from http://www.example.com/', 'pfe'],
-        output =>
-          qr|added alias 'pull --from http://www.example.com/ = pfe'|,
+        output => qr//,
         comment => 'added alias with weird characters',
     },
+    {
+        cmd => [ 'pull --from http://www.example.com/'],
+        output => qr/pfe/,
+        comment => 'alias with weird chars is correct',
+    },
 ,
 );
 
@@ -150,8 +188,8 @@ is( $content, <<EOF, 'content in config' );
 [alias]
 	pull -a = pull --all
 	pull -l = pull --local
-	foo bar = bar
 	foo = bar baz
+	foo bar = bar
 	pull --from http://www.example.com/ = pfe
 EOF
 

commit 28fa29a29c9fdf8ea8e300526d6223d4a97a1378
Author: Christine Spang <spang at mit.edu>
Date:   Wed Jun 24 21:59:31 2009 +0300

    Update recording replica pulls to new config format.

diff --git a/lib/Prophet/CLI/Command/Pull.pm b/lib/Prophet/CLI/Command/Pull.pm
index dec663e..cb3ed91 100644
--- a/lib/Prophet/CLI/Command/Pull.pm
+++ b/lib/Prophet/CLI/Command/Pull.pm
@@ -42,22 +42,36 @@ sub run {
 
 }
 
+# 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 = $self->app_handle->config->sources;
-    my %sources_by_url = map {
-            my $name = $_;
-            my ($url, $uuid);
-            ($url, $uuid ) = split(qr/ \| /, $previous_sources{$name}, 2);
-         ($url => $uuid )
-     } keys %previous_sources;
-    if ( !exists $sources_by_url{$source}) {
-        $self->app_handle->config->set(
-            key => "source.'$source'",
-            value => "$source | $from_uuid",
-            filename => $self->app_handle->config->replica_config_file,
+
+    my %previous_sources
+        = $self->app_handle->config->get_regexp( key => "^replica\..+\.url" );
+
+    my $found_prev_replica;
+    for my $key (keys %previous_sources) {
+        $found_prev_replica = $previous_sources{$key}
+            if $previous_sources{$key} eq $source;
+    }
+
+    if ( !$found_prev_replica ) {
+        warn "setting new 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,
+            },
+            ],
         );
     }
 }

commit f66404963e5310b5916c94b9c3b43a0d09a4cce9
Author: Christine Spang <spang at mit.edu>
Date:   Thu Jun 25 11:53:15 2009 +0300

    Friendly names and related changes.

diff --git a/lib/Prophet/CLI/Command/Clone.pm b/lib/Prophet/CLI/Command/Clone.pm
index fa87866..634aa2a 100644
--- a/lib/Prophet/CLI/Command/Clone.pm
+++ b/lib/Prophet/CLI/Command/Clone.pm
@@ -44,7 +44,7 @@ sub run {
     $target->initialize(%init_args);
 
     $self->app_handle->config->set(
-        key => 'source.'.$self->arg('from'),
+        key => 'replica.'.$self->arg('from').'.url',
         value => $self->arg('from'),
         filename => $self->app_handle->config->replica_config_file,
     );
diff --git a/lib/Prophet/CLI/Command/Pull.pm b/lib/Prophet/CLI/Command/Pull.pm
index cb3ed91..94017e0 100644
--- a/lib/Prophet/CLI/Command/Pull.pm
+++ b/lib/Prophet/CLI/Command/Pull.pm
@@ -10,19 +10,21 @@ sub run {
 
     Prophet::CLI->end_pager();
 
-    my $previous_sources = $self->app_handle->config->sources;
+    my %previous_sources_by_name = $self->app_handle->config->sources;
 
     my $explicit_from = '';
 
     if ($self->has_arg('from')) {
-        $explicit_from = $self->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')}
+            : $self->arg('from');
         push @from, $explicit_from;
     }
     elsif ($self->has_arg('all')){
-        for my $source (values %$previous_sources) {
-            my ($url, $uuid ) = split(qr/ \| /,$source,2);
+        for my $url (values %previous_sources_by_name) {
             push @from, $url;
-
         }
     }
 
@@ -49,17 +51,12 @@ sub record_pull_from_source {
     my $source = shift;
     my $from_uuid = shift;
 
-    my %previous_sources
-        = $self->app_handle->config->get_regexp( key => "^replica\..+\.url" );
+    my %previous_sources_by_url
+        = $self->app_handle->config->sources( by_url => 1 );
 
-    my $found_prev_replica;
-    for my $key (keys %previous_sources) {
-        $found_prev_replica = $previous_sources{$key}
-            if $previous_sources{$key} eq $source;
-    }
+    my $found_prev_replica = $previous_sources_by_url{$source};
 
     if ( !$found_prev_replica ) {
-        warn "setting new replica";
         $self->app_handle->config->group_set(
             $self->app_handle->config->replica_config_file,
             [
diff --git a/lib/Prophet/Config.pm b/lib/Prophet/Config.pm
index 5dd7a68..fbeff1b 100644
--- a/lib/Prophet/Config.pm
+++ b/lib/Prophet/Config.pm
@@ -44,7 +44,8 @@ override global_file => sub {
     return exists $ENV{PROPHET_APP_CONFIG} ? '' : $self->SUPER::global_file(@_);
 };
 
-# grab all values in the 'alias' section and strip away the section name
+# grab all values in the 'alias' section (of the file, if given) and strip
+# away the section name
 sub aliases {
     my $self = shift;
     my $file = shift;
@@ -88,16 +89,20 @@ sub aliases {
     return wantarray ? %new_aliases : \%new_aliases;
 }
 
-# grab all values in the 'source' section and strip away the section name
+# grab all the replicas we know of and return a hash of
+# name => url, or url => name if $args{by_url} is true
 sub sources {
     my $self = shift;
+    my %args = (
+        by_url => undef,
+        @_,
+    );
 
-    my %sources = $self->get_regexp( key => '^source\.' );
+    my %sources = $self->get_regexp( key => '^replica\..*\.url$' );
 
     my %new_sources = map {
-        my $source = $_;
-        $source =~ s/^source\.//;
-        ( $source => $sources{$_} );
+        $_ =~ /^replica\.(.*)\.url$/;
+        $args{by_url} ? ( $sources{$_} => $1 ) : ( $1 => $sources{$_} );
     } keys %sources;
 
     return wantarray ? %new_sources : \%new_sources;
@@ -112,13 +117,20 @@ sub replica_config_file {
     );
 }
 
-# friendly replica names go in the [display] section
+# friendly names are replica subsections
 sub display_name_for_uuid {
     my $self = shift;
     my $uuid = shift;
 
-    my $friendly = $self->get( key => "display.$uuid" );
-    return defined($friendly) ? $friendly : $uuid;
+    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;
 }
 
 __PACKAGE__->meta->make_immutable;
@@ -184,14 +196,12 @@ are defined in that particular config file.
 
 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 => 'URL', uuid => 'UUID } }. (Basically, every entry in the 'replica'
-section of the config file.)
+'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.
-
-TODO: regexp search for 'replica.(.*).UUID' and extract the section
+Returns a "friendly" id for the given uuid. UUIDs are for computers, friendly
+names are for people.
 
 =head1 CONFIG VARIABLES
 
diff --git a/t/config.t b/t/config.t
index a7ff1f4..88c47fd 100644
--- a/t/config.t
+++ b/t/config.t
@@ -2,7 +2,7 @@
 #
 use warnings;
 use strict;
-use Prophet::Test tests => 11;
+use Prophet::Test tests => 13;
 use File::Copy;
 use File::Temp qw'tempdir';
 
@@ -49,14 +49,28 @@ is( scalar @keys, 0, 'no config options are set' );
     is( $conf->aliases->{tlist}, 'ticket list', 'Got correct alias' );
     # test automatic reload after setting
     $conf->set(
-        key => 'source.sd',
+        key => 'replica.sd.url',
         value => 'http://fsck.com/sd/',
         filename => File::Spec->catfile($repo, 'test_app.conf'),
     );
-    is( $conf->get( key => 'source.sd' ), 'http://fsck.com/sd/',
+    is( $conf->get( key => 'replica.sd.url' ), 'http://fsck.com/sd/',
         '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/'},
+        'sd',
+        'Got correct alias',
+    );
+    # test the display_name_for_uuid 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'),
+        'sd',
+        'Got correct display name'
+    );
 
     # run the cli "config" command
     # make sure it matches with our file
@@ -71,7 +85,8 @@ $repo/test_app.conf
 Your configuration:
 
 alias.tlist=ticket list
-source.sd=http://fsck.com/sd/
+replica.sd.url=http://fsck.com/sd/
+replica.sd.uuid=32b13934-910a-4792-b5ed-c9977b212245
 test.foo=bar
 test.re=rawr
 EOF

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



More information about the Bps-public-commit mailing list