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

spang at bestpractical.com spang at bestpractical.com
Mon Jun 29 11:30:44 EDT 2009


The branch, config-gitlike has been updated
       via  9f8fc6ab5d1cd04894878d7a834918dd4f080fb0 (commit)
       via  2b3047d5941bcd1f39276b6e5bdb79838b607fc4 (commit)
       via  fef857c0e3fa5010aa6e5ed75d44d1281b86e80f (commit)
       via  9ff21d8419a90cfa4a603319f9738ad849e97280 (commit)
       via  51ae9fe731fc99cb9570e531737d269ed28a9264 (commit)
       via  caef981ec86f5719d3adfc15648335896d20c434 (commit)
       via  b9680355a4f613949e658a05a73b8f6472dfbbf3 (commit)
       via  0f370eb940e9b22c1e178a6952658d0bbfc8193d (commit)
      from  8defa13a5d4162cb9f95bf9046b570f4659cab7c (commit)

Summary of changes:
 lib/Prophet/CLI/Dispatcher.pm |    2 +-
 lib/Prophet/CLIContext.pm     |    4 +-
 lib/Prophet/Config.pm         |  183 ++++++++++++++++++++++++++++++++++++++++-
 lib/Prophet/Conflict.pm       |   14 +++-
 lib/Prophet/Test.pm           |    1 -
 t/aliases.t                   |   11 ++-
 t/cli-arg-translation.t       |    4 +-
 t/config.t                    |    5 +-
 8 files changed, 209 insertions(+), 15 deletions(-)

- Log -----------------------------------------------------------------
commit 51ae9fe731fc99cb9570e531737d269ed28a9264
Author: Christine Spang <spang at mit.edu>
Date:   Mon Jun 29 12:07:46 2009 +0300

    sometimes UUIDs contain lowercase letters

diff --git a/lib/Prophet/CLI/Dispatcher.pm b/lib/Prophet/CLI/Dispatcher.pm
index e16cabf..16679d1 100644
--- a/lib/Prophet/CLI/Dispatcher.pm
+++ b/lib/Prophet/CLI/Dispatcher.pm
@@ -37,7 +37,7 @@ on qr{log\s+([0-9LATEST.~]+)} => sub {
 };
 
 on [ qr/^(update|edit|show|display|delete|del|rm|history)$/,
-     qr/^$Prophet::CLIContext::ID_REGEX$/ ] => sub {
+     qr/^$Prophet::CLIContext::ID_REGEX$/i ] => sub {
     my $self = shift;
     $self->context->set_id_from_primary_commands;
     run($1, $self, @_);
diff --git a/lib/Prophet/CLIContext.pm b/lib/Prophet/CLIContext.pm
index fc89d14..98c12aa 100644
--- a/lib/Prophet/CLIContext.pm
+++ b/lib/Prophet/CLIContext.pm
@@ -301,7 +301,7 @@ sub set_type {
     }
     # allowance for things like ticket show 77, where 'ticket' is the type
     elsif (
-        $self->primary_commands->[-1] =~ qr/^$Prophet::CLIContext::ID_REGEX$/
+        $self->primary_commands->[-1] =~ qr/^$Prophet::CLIContext::ID_REGEX$/i
             && $self->primary_commands->[-3] ) {
         $self->type( $self->primary_commands->[-3] );
     }

commit 9ff21d8419a90cfa4a603319f9738ad849e97280
Merge: 51ae9fe... caef981...
Author: Christine Spang <spang at mit.edu>
Date:   Mon Jun 29 12:08:17 2009 +0300

    Merge branch 'master' of fsck.com:/git/prophet into config-gitlike


commit fef857c0e3fa5010aa6e5ed75d44d1281b86e80f
Author: Christine Spang <spang at mit.edu>
Date:   Mon Jun 29 15:36:06 2009 +0300

    Old config -> new config migration code.
    
    Will automatically convert the old config file that would have been
    loaded and any config files in locations that will be loaded under the
    new layout to the new config format. For example, if you have both a
    replica-specific config file for the replica you're using and a file in
    ~/.sdrc, both will be converted. If config files are found in deprecated
    locations (e.g. replica_root/prophetrc), the new config file will be
    written to the new preferred location (replica_root/config).
    
    Backups are made of the old config files; they're located at
    $old_config.bak.

diff --git a/lib/Prophet/Config.pm b/lib/Prophet/Config.pm
index 2f6bfa3..778fafd 100644
--- a/lib/Prophet/Config.pm
+++ b/lib/Prophet/Config.pm
@@ -12,10 +12,12 @@ has app_handle => (
 );
 
 # reload config after setting values
-after set => sub  {
+override group_set => sub  {
     my $self = shift;
+    my ($filename, $args_ref, $override) = @_;
 
-    $self->load;
+    $self->SUPER::group_set($filename, $args_ref);
+    $self->load unless $override;
 };
 
 # per-replica config filename
@@ -133,6 +135,167 @@ sub display_name_for_uuid {
     return exists $sources_by_uuid{$uuid} ? $sources_by_uuid{$uuid} : $uuid;
 }
 
+### XXX BACKCOMPAT ONLY! We eventually want to kill this hash, modifier and
+### the following methods.
+
+# None of these need to have values mucked with at all, just the keys
+# migrated from old to new.
+our %KEYS_CONVERSION_TABLE = (
+    'email_address' => 'user.email-address',
+    'default_group_ticket_list' => 'ticket.list.default-group',
+    'default_sort_ticket_list' => 'ticket.list.default-sort',
+    'summary_format_ticket' => 'ticket.summary-format',
+    'default_summary_format' => 'record.summary-format',
+    'common_ticket_props' => 'ticket.common-props',
+    'disable_ticket_show_history_by_default' => 'ticket.show.disable-history',
+);
+
+override load => sub  {
+    my $self = shift;
+
+    Prophet::CLI->end_pager();
+
+    # Do backcompat stuff.
+    for my $file ( ($self->_old_app_config_file, $self->dir_file,
+            $self->user_file, $self->global_file) ) {
+        my $content = -f $file ? Prophet::Util->slurp($file) : '[';
+
+        # config file is old
+
+        # Also "converts" empty files but that's fine. If it ever
+        # does happen, we get the positive benefit of writing the
+        # config format to it.
+        if ( $content !~ /\[/ ) {
+            print "Detected old format config file $file. Converting to ".
+                  "new format... ";
+
+            # read in and parse old config
+            my $config = { _sources => {}, _aliases => {} };
+            $self->_load_old_config_from_file( $file, $config );
+            my $aliases = delete $config->{_aliases};
+            my $sources = delete $config->{_sources};
+
+            # new configuration will include a config format version #
+            my @config_to_set = ( {
+                    key => 'core.config-format-version',
+                    value => '0',
+            } );
+
+            # convert its keys to new-style keys by comparing to a conversion
+            # table
+            for my $key ( keys %$config ) {
+                die "Unknown key '$key' in old format config file '$file'."
+                    ." Remove it or ask\non irc.freenode.net #prophet if you"
+                    ." think this is a bug.\n"
+                        unless exists $KEYS_CONVERSION_TABLE{$key};
+                push @config_to_set, {
+                    key   => $KEYS_CONVERSION_TABLE{$key},
+                    value => $config->{$key},
+                };
+            }
+            # convert its aliases
+            for my $alias ( keys %$aliases ) {
+                push @config_to_set, {
+                    key   => "alias.'$alias'",
+                    value => $aliases->{$alias},
+                };
+            }
+            # convert its sources
+            for my $name ( keys %$sources ) {
+                my ($url, $uuid) = split(/ \| /, $sources->{$name}, 2);
+                push @config_to_set, {
+                    key   => "replica.'$name'.url",
+                    value => $url,
+                }, {
+                    key   => "replica.'$name'.uuid",
+                    value => $uuid,
+                };
+            }
+            # move the old config file to a backup
+            my $backup_file = $file;
+            unless ( $self->_deprecated_repo_config_names->{$file} ) {
+                $backup_file = "$file.bak";
+                rename $file, $backup_file;
+            }
+
+            # we want to write the new file to a supported filename if
+            # it's from a deprecated config name (replica/prophetrc)
+            $file = File::Spec->catfile( $self->app_handle->handle->fs_root, 'config' )
+                if $self->_deprecated_repo_config_names->{$file};
+
+            # write the new config file (with group_set)
+            $self->group_set( $file, \@config_to_set, 1);
+
+            # tell the user that we're done
+            print "done.\nOld config can be found at $backup_file; "
+                  ,"new config is $file.\n\n";
+
+            Prophet::CLI->start_pager();
+        }
+
+    }
+
+    # Do a regular load.
+    $self->SUPER::load;
+};
+
+sub _deprecated_repo_config_names {
+    my $self = shift;
+
+    my %filenames = ( File::Spec->catfile( $self->app_handle->handle->fs_root =>
+            'prophetrc' ) => 1 );
+
+    return wantarray ? %filenames : \%filenames;
+};
+
+sub _old_app_config_file {
+    my $self = shift;
+    my $config_env_var
+        = $_{config_env_var} ?  $_{config_env_var} : 'PROPHET_APP_CONFIG';
+
+    return $self->_file_if_exists($ENV{$config_env_var})
+        || $self->_file_if_exists( $self->_old_replica_config_file)
+        || $self->_file_if_exists( File::Spec->catfile( $ENV{'HOME'} => '.prophetrc' ))
+        || $self->_old_replica_config_file
+}
+
+sub _old_replica_config_file {
+    my $self = shift;
+     return
+     $self->_file_if_exists( File::Spec->catfile( $self->app_handle->handle->fs_root => 'config' )) ||
+     $self->_file_if_exists( File::Spec->catfile( $self->app_handle->handle->fs_root => 'prophetrc' )) ||
+      File::Spec->catfile( $self->app_handle->handle->fs_root => 'config' );
+}
+
+sub _load_old_config_from_file {
+    my $self   = shift;
+    my $file   = shift;
+    my $config = shift || {};
+
+    for my $line (Prophet::Util->slurp($file) ) {
+        $line =~ s/\#.*$//; # strip comments
+        next unless ($line =~ /^(.*?)\s*=\s*(.*)$/);
+        my $key = $1;
+        my $val = $2;
+        if ($key =~ m!alias\s+(.+)!) {
+            $config->{_aliases}->{$1} = $val;
+        } elsif ($key =~ m!source\s+(.+)!) {
+            $config->{_sources}->{$1} = $val;
+        } else {
+            $config->{$key} = $val;
+        }
+    }
+    $config->{_aliases} ||= {}; # default aliases is null.
+    $config->{_sources} ||= {}; # default to no sources.
+}
+
+sub _file_if_exists {
+    my $self = shift;
+    my $file = shift || ''; # quiet warnings
+
+    return (-e $file) ? $file : '';
+}
+
 __PACKAGE__->meta->make_immutable;
 no Any::Moose;
 
diff --git a/t/aliases.t b/t/aliases.t
index b8f5c8a..90a67f8 100644
--- a/t/aliases.t
+++ b/t/aliases.t
@@ -2,7 +2,7 @@
 #
 use warnings;
 use strict;
-use Prophet::Test tests => 32;
+use Prophet::Test tests => 33;
 use File::Temp qw/tempfile/;
 
 $ENV{'PROPHET_REPO'} = $Prophet::Test::REPO_BASE . '/repo-' . $$;
@@ -13,9 +13,11 @@ diag("Using config file $ENV{PROPHET_APP_CONFIG}");
 mkdir $ENV{PROPHET_REPO};
 
 use_ok('Prophet::CLI');
-use_ok('Prophet::Config');
 
-my $config = Prophet::CLI->new()->config;
+my $a = Prophet::CLI->new();
+can_ok($a, 'app_handle');
+can_ok($a->app_handle, 'config');
+my $config = $a->config;
 $config->load;
 
 is_deeply( scalar $config->aliases, {}, 'initial alias is empty' );
@@ -184,7 +186,8 @@ open my $fh, '<', $ENV{'PROPHET_APP_CONFIG'}
   or die "failed to open $ENV{'PROPHET_APP_CONFIG'}: $!";
 { local $/; $content = <$fh>; }
 is( $content, <<EOF, 'content in config' );
-
+[core]
+	config-format-version = 0
 [alias]
 	pull -a = pull --all
 	pull -l = pull --local
diff --git a/t/cli-arg-translation.t b/t/cli-arg-translation.t
index 74ae7bc..4510933 100644
--- a/t/cli-arg-translation.t
+++ b/t/cli-arg-translation.t
@@ -1,6 +1,6 @@
 use warnings;
 use strict;
-use Prophet::Test tests => 7;
+use Prophet::Test tests => 9;
 use File::Temp qw'tempdir';
 
 # test coverage for Prophet::CLI::Command arg translation
@@ -9,6 +9,8 @@ use_ok('Prophet::CLI');
 $ENV{'PROPHET_REPO'} = tempdir( CLEANUP => ! $ENV{PROPHET_DEBUG}  ) . '/repo-' . $$;
 
 my $cli = Prophet::CLI->new();
+can_ok($cli, 'app_handle');
+can_ok($cli, 'handle');
 my $cxn = $cli->handle;
 isa_ok( $cxn, 'Prophet::Replica', "Got the cxn" );
 
diff --git a/t/config.t b/t/config.t
index 88c47fd..e96b4ba 100644
--- a/t/config.t
+++ b/t/config.t
@@ -34,8 +34,10 @@ is( scalar @keys, 0, 'no config options are set' );
     local $ENV{'PROPHET_APP_CONFIG'}
         = File::Spec->catfile($repo,'test_app.conf');
 
+    my $app_handle = Prophet::CLI->new->app_handle;
     my $conf = Prophet::Config->new(
-        app_handle => Prophet::CLI->new->app_handle,
+        app_handle => $app_handle,
+        handle => $app_handle->handle,
         confname => 'testrc',
     );
     $conf->load;

commit 2b3047d5941bcd1f39276b6e5bdb79838b607fc4
Author: Christine Spang <spang at mit.edu>
Date:   Mon Jun 29 17:42:19 2009 +0300

    Quiet a warning when primary_commands is empty

diff --git a/lib/Prophet/CLIContext.pm b/lib/Prophet/CLIContext.pm
index 98c12aa..609e68d 100644
--- a/lib/Prophet/CLIContext.pm
+++ b/lib/Prophet/CLIContext.pm
@@ -300,7 +300,7 @@ sub set_type {
         $self->type($type);
     }
     # allowance for things like ticket show 77, where 'ticket' is the type
-    elsif (
+    elsif ( $self->primary_commands->[-1] &&
         $self->primary_commands->[-1] =~ qr/^$Prophet::CLIContext::ID_REGEX$/i
             && $self->primary_commands->[-3] ) {
         $self->type( $self->primary_commands->[-3] );

commit 9f8fc6ab5d1cd04894878d7a834918dd4f080fb0
Author: Christine Spang <spang at mit.edu>
Date:   Mon Jun 29 18:10:24 2009 +0300

    Set core.config-format-version config var in any config file we set to that doesn't have it set in already.

diff --git a/lib/Prophet/Config.pm b/lib/Prophet/Config.pm
index 778fafd..dfc79af 100644
--- a/lib/Prophet/Config.pm
+++ b/lib/Prophet/Config.pm
@@ -11,15 +11,31 @@ has app_handle => (
     required => 1
 );
 
+use constant FORMAT_VERSION => 0;
+
 # reload config after setting values
 override group_set => sub  {
     my $self = shift;
     my ($filename, $args_ref, $override) = @_;
 
+    # Set a config format version on this config file if
+    # it doesn't have one already.
+    push @$args_ref, {
+        key => 'core.config-format-version',
+        value => FORMAT_VERSION,
+    } unless _file_has_config_format_version( $filename );
+
     $self->SUPER::group_set($filename, $args_ref);
     $self->load unless $override;
 };
 
+sub _file_has_config_format_version {
+    my $filename = shift;
+    my $content = -f  $filename ? Prophet::Util->slurp($filename) : '';
+
+    return $content =~ 'core.config-format-version';
+}
+
 # per-replica config filename
 override dir_file => sub { 'config' };
 
@@ -178,7 +194,7 @@ override load => sub  {
             # new configuration will include a config format version #
             my @config_to_set = ( {
                     key => 'core.config-format-version',
-                    value => '0',
+                    value => FORMAT_VERSION,
             } );
 
             # convert its keys to new-style keys by comparing to a conversion
diff --git a/t/config.t b/t/config.t
index e96b4ba..3b353bd 100644
--- a/t/config.t
+++ b/t/config.t
@@ -87,6 +87,7 @@ $repo/test_app.conf
 Your configuration:
 
 alias.tlist=ticket list
+core.config-format-version=0
 replica.sd.url=http://fsck.com/sd/
 replica.sd.uuid=32b13934-910a-4792-b5ed-c9977b212245
 test.foo=bar

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



More information about the Bps-public-commit mailing list