[Bps-public-commit] r11834 - in Prophet/trunk: . lib/Prophet/Replica lib/Prophet/Resolver t

jesse at bestpractical.com jesse at bestpractical.com
Tue Apr 22 20:34:04 EDT 2008


Author: jesse
Date: Tue Apr 22 20:34:02 2008
New Revision: 11834

Modified:
   Prophet/trunk/   (props changed)
   Prophet/trunk/Makefile.PL
   Prophet/trunk/lib/Prophet/App.pm
   Prophet/trunk/lib/Prophet/CLI.pm
   Prophet/trunk/lib/Prophet/Change.pm
   Prophet/trunk/lib/Prophet/ConflictingChange.pm
   Prophet/trunk/lib/Prophet/ConflictingPropChange.pm
   Prophet/trunk/lib/Prophet/Replica.pm
   Prophet/trunk/lib/Prophet/Replica/Native.pm
   Prophet/trunk/lib/Prophet/Replica/SVN.pm
   Prophet/trunk/lib/Prophet/Resolver/AlwaysTarget.pm
   Prophet/trunk/lib/Prophet/Resolver/Failed.pm
   Prophet/trunk/lib/Prophet/Resolver/FromResolutionDB.pm
   Prophet/trunk/lib/Prophet/Test.pm
   Prophet/trunk/t/canonicalize.t
   Prophet/trunk/t/create.t
   Prophet/trunk/t/validate.t

Log:
 r29979 at 31b:  jesse | 2008-04-22 17:23:49 -0400
 * Switched from YAML to JSON
 * Switched default replica type from SVN to Native
 


Modified: Prophet/trunk/Makefile.PL
==============================================================================
--- Prophet/trunk/Makefile.PL	(original)
+++ Prophet/trunk/Makefile.PL	Tue Apr 22 20:34:02 2008
@@ -4,46 +4,45 @@
 name('Prophet');
 author('clkao and jesse');
 license('DeathandRepudiation');
+
 requires('Params::Validate');
 requires('List::MoreUtils');
 requires('Class::Accessor');
 requires('IPC::Run3');
-requires('Test::Exception');
 requires('Data::UUID');
 requires('Path::Class');
 requires('YAML::Syck');
 requires('Test::Exception');
-requires('Acme::MetaSyntactic');
 requires('UNIVERSAL::require');
 requires('Class::Data::Inheritable');
-requires('DateTime::Format::HTTP');
-requires('Devel::Gladiator');
-requires('RT::Client::REST');
-requires('RT::Client::REST::Ticket');
-requires('RT::Client::REST::User');
 requires('Term::ReadKey');
-requires('Digest::SHA1');
-requires('LWP::Simple');
+requires('Digest::SHA1');  # Core in 5.10
+requires('LWP::Simple'); # Part of lib-www-perl
 requires('URI');
 requires('JSON');
 requires('Module::Pluggable');
-requires('Test::HTTP::Server::Simple');
-requires('HTTP::Server::Simple');
-requires('Test::WWW::Mechanize');
-requires('HTTP::Server::Simple::CGI');
-requires('SVN::Core');    # SVN::Repos SVN::Fs SVN::Ra SVN::Delta::Editor SVN::Client SVN::Delta
+
 features(
+    'REST Server' => [
+        -default => 1,
+        recommends('HTTP::Server::Simple'), # HTTP::Server::Simple::CGI'
+        recommends('Test::HTTP::Server::Simple'),
+        recommends('Test::WWW::Mechanize'),
+        recommends('HTTP::Server::Simple')
+    ],
+
+
+    'Subversion replica support' => [
+        -default => 0,
+        recommends( 'SVN::Core') # SVN::Repos SVN::Fs SVN::Ra SVN::Delta::Editor SVN::Client SVN::Delta
+    ],
     'Crazy debugging tools' => [
         -default   => 1,
-        recommends => 'Devel::Gladiator'
+        recommends('Acme::MetaSyntactic'),
+        recommends('Devel::Gladiator')
     ],
-    'Hiveminder sync' => [
-        -default => 0,
-        requires => 'Net::Jifty',
-        requires => 'Jifty',
-    ]
 );
 
 all_from('lib/Prophet.pm');
-
+auto_install;
 WriteAll();

Modified: Prophet/trunk/lib/Prophet/App.pm
==============================================================================
--- Prophet/trunk/lib/Prophet/App.pm	(original)
+++ Prophet/trunk/lib/Prophet/App.pm	Tue Apr 22 20:34:02 2008
@@ -6,6 +6,9 @@
 use Path::Class;
 __PACKAGE__->mk_accessors(qw/_resdb_handle/);
 
+use constant DEFAULT_REPLICA_TYPE => 'prophet';
+
+
 sub _handle {
     my $self = shift;
     $self->{_handle} = shift if (@_);
@@ -31,7 +34,7 @@
     my $self = shift;
     unless ( $self->_handle() ) {
         my $root = $ENV{'PROPHET_REPO'} || dir( $ENV{'HOME'}, '.prophet' );
-        my $type = $ENV{'PROPHET_REPLICA_TYPE'} || 'svn';
+        my $type = $ENV{'PROPHET_REPLICA_TYPE'} || DEFAULT_REPLICA_TYPE;
         $self->_handle( Prophet::Replica->new( { url => $type.':file://' . $root } ) );
     }
     return $self->_handle();
@@ -47,7 +50,7 @@
     return ($self->handle->resolution_db_handle) if ($self->handle->resolution_db_handle);
     unless ( $self->_resdb_handle ) {
         my $root = ( $ENV{'PROPHET_REPO'} || dir( $ENV{'HOME'}, '.prophet' ) ) . "_res";
-        my $type = $ENV{'PROPHET_REPLICA_TYPE'} || 'svn';
+        my $type = $ENV{'PROPHET_REPLICA_TYPE'} || DEFAULT_REPLICA_TYPE;
         $self->_resdb_handle( Prophet::Replica->new( { url => $type.':file://' . $root } ) );
     }
     return $self->_resdb_handle();

Modified: Prophet/trunk/lib/Prophet/CLI.pm
==============================================================================
--- Prophet/trunk/lib/Prophet/CLI.pm	(original)
+++ Prophet/trunk/lib/Prophet/CLI.pm	Tue Apr 22 20:34:02 2008
@@ -234,8 +234,7 @@
 
 sub do_push {
     my $self         = shift;
-    my $replica_type = $ENV{'PROPHET_REPLICA_TYPE'} || 'svn';
-    my $source_me    = Prophet::Replica->new( { url => $replica_type. ":file://" . $self->app_handle->handle->fs_root } );
+    my $source_me    = $self->app_handle->handle;
     my $other        = shift @ARGV;
     my $source_other = Prophet::Replica->new( { url => $other } );
     my $resdb        = $source_me->import_resolutions_from_remote_replica( from => $source_other );
@@ -245,21 +244,16 @@
 
 sub do_export {
     my $self      = shift;
-    my $replica_type = $ENV{'PROPHET_REPLICA_TYPE'} || 'svn';
-    my $source_me = Prophet::Replica->new( { url => $replica_type.":file://" . $self->app_handle->handle->fs_root } );
-    my $path      = $self->args->{'path'};
-    $source_me->export_to( path => $path );
+    $self->app_handle->handle->export_to( path => $self->args->{path} );
 }
 
 sub do_pull {
     my $self         = shift;
-    my $replica_type = $ENV{'PROPHET_REPLICA_TYPE'} || 'svn';
-    my $source_me    = Prophet::Replica->new( { url => $replica_type. ":file://" . $self->app_handle->handle->fs_root } );
     my $other        = shift @ARGV;
     my $source_other = Prophet::Replica->new( { url => $other } );
-    my $resdb        = $source_me->import_resolutions_from_remote_replica( from => $source_other );
+    $self->app_handle->handle->import_resolutions_from_remote_replica( from => $source_other );
 
-    $self->_do_merge( $source_other, $source_me );
+    $self->_do_merge( $source_other, $self->app_handle->handle );
 
 }
 

Modified: Prophet/trunk/lib/Prophet/Change.pm
==============================================================================
--- Prophet/trunk/lib/Prophet/Change.pm	(original)
+++ Prophet/trunk/lib/Prophet/Change.pm	Tue Apr 22 20:34:02 2008
@@ -51,7 +51,7 @@
     my ( $class, $conflict ) = @_;
     my $self = $class->new(
         {   is_resolution  => 1,
-            resolution_cas => $conflict->cas_key,
+            resolution_cas => $conflict->fingerprint,
             change_type    => $conflict->change_type,
             record_type      => $conflict->record_type,
             record_uuid      => $conflict->record_uuid

Modified: Prophet/trunk/lib/Prophet/ConflictingChange.pm
==============================================================================
--- Prophet/trunk/lib/Prophet/ConflictingChange.pm	(original)
+++ Prophet/trunk/lib/Prophet/ConflictingChange.pm	Tue Apr 22 20:34:02 2008
@@ -1,4 +1,3 @@
-
 use warnings;
 use strict;
 
@@ -6,7 +5,8 @@
 use Prophet::ConflictingPropChange;
 
 use base qw/Class::Accessor/;
-use Storable 'dclone';
+use JSON qw'to_json';
+use Digest::SHA1 'sha1_hex';
 
 # change_type is one of: add_file add_dir update delete
 __PACKAGE__->mk_accessors(qw/record_type record_uuid source_record_exists target_record_exists change_type file_op_conflict/);
@@ -25,33 +25,38 @@
 
 }
 
-=head2 neutralize
-
-Returns the clone of the changeset, except hte propchanges will have target_value and source_new_value as a sorted "choices" field of arrayref.
-
-=cut
 
-sub neutralize {
-    my $self   = shift;
-    my $struct = dclone($self);
-    for ( @{ $struct->{prop_conflicts} } ) {
-        $_->{choices} = [ sort ( delete $_->{source_new_value}, delete $_->{target_value} ) ];
+sub as_hash {
+    my $self = shift;
+    my $struct = {
+        map { $_ => $self->$_() } (
+            qw/record_type record_uuid source_record_exists target_record_exists change_type file_op_conflict/
+        )
+    };
+    for ( @{ $self->prop_conflicts } ) {
+        push @{ $struct->{'prop_conflicts'} }, $_->as_hash;
     }
+
     return $struct;
 }
 
-=head2 cas_key
+=head2 fingerprint
 
-returned the key signatured by the content of the conflicting change.
+Returns a fingerprint of the content of this conflicting change
 
 =cut
 
-use YAML::Syck;
-use Digest::MD5 'md5_hex';
 
-sub cas_key {
+sub fingerprint {
     my $self = shift;
-    return md5_hex( YAML::Syck::Dump( $self->neutralize ) );
-}
 
+    my $struct = $self->as_hash;
+    for ( @{ $struct->{prop_conflicts} } ) {
+        $_->{choices} = [ sort ( delete $_->{source_new_value}, delete $_->{target_value} ) ];
+    }
+
+    return  sha1_hex(to_json($struct, {utf8 => 1, canonical => 1}));
+
+
+}
 1;

Modified: Prophet/trunk/lib/Prophet/ConflictingPropChange.pm
==============================================================================
--- Prophet/trunk/lib/Prophet/ConflictingPropChange.pm	(original)
+++ Prophet/trunk/lib/Prophet/ConflictingPropChange.pm	Tue Apr 22 20:34:02 2008
@@ -35,4 +35,15 @@
 
 =cut
 
+sub as_hash {
+    my $self = shift;
+    my $hashref = {};
+
+    for  (qw(name source_old_value target_value source_new_value)) {
+         $hashref->{$_} = $self->$_()
+    }
+    return $hashref;
+}
+
+
 1;

Modified: Prophet/trunk/lib/Prophet/Replica.pm
==============================================================================
--- Prophet/trunk/lib/Prophet/Replica.pm	(original)
+++ Prophet/trunk/lib/Prophet/Replica.pm	Tue Apr 22 20:34:02 2008
@@ -1,10 +1,12 @@
 use warnings;
 use strict;
 
+
 package Prophet::Replica;
 use base qw/Class::Accessor/;
 use Params::Validate qw(:all);
 use UNIVERSAL::require;
+use Data::UUID;
 
 
 __PACKAGE__->mk_accessors(qw(state_handle resolution_db_handle is_resdb is_state_handle db_uuid url));

Modified: Prophet/trunk/lib/Prophet/Replica/Native.pm
==============================================================================
--- Prophet/trunk/lib/Prophet/Replica/Native.pm	(original)
+++ Prophet/trunk/lib/Prophet/Replica/Native.pm	Tue Apr 22 20:34:02 2008
@@ -3,15 +3,16 @@
 
 package Prophet::Replica::Native;
 use base qw/Prophet::Replica/;
+
 use Params::Validate qw(:all);
 use LWP::Simple ();
-use File::Slurp;
 use Path::Class;
-use Digest::SHA1 qw(sha1 sha1_hex);
-use YAML::Syck;
+use Digest::SHA1 qw(sha1_hex);
+use File::Find::Rule;
+use JSON;
+
 use Prophet::ChangeSet;
 use Prophet::Conflict;
-use File::Find::Rule;
 
 __PACKAGE__->mk_accessors(qw/url _db_uuid _uuid/);
 __PACKAGE__->mk_accessors(
@@ -40,15 +41,19 @@
     $self->fs_root_parent( $self->url =~ m{^file://(.*)/.*?$} );
     $self->_probe_or_create_db();
 
+# $self->state_handle( Prophet::Replica->new( { url => "prophet:".$self->{url}, is_state_handle =>1 } ) ) unless ( $self->is_state_handle || $self->state_handle);
 
-    # $self->state_handle( Prophet::Replica->new( { url => "prophet:".$self->{url}, is_state_handle =>1 } ) ) unless ( $self->is_state_handle || $self->state_handle);
-
-    $self->resolution_db_handle( Prophet::Replica->new( { url => "prophet:".$self->{url}.'/resolutions', is_resdb => 1 } ) )
-        unless ( $self->is_resdb || $self->is_state_handle);
+    $self->resolution_db_handle(
+        Prophet::Replica->new(
+            {   url      => "prophet:" . $self->{url} . '/resolutions',
+                is_resdb => 1
+            }
+        )
+    ) unless ( $self->is_resdb || $self->is_state_handle );
 
-#    warn "I AM ".$ENV{'PROPHET_USER'};
-#    warn $self->uuid;
-#    warn $self->state_handle->uuid unless ($self->is_state_handle);
+    #    warn "I AM ".$ENV{'PROPHET_USER'};
+    #    warn $self->uuid;
+    #    warn $self->state_handle->uuid unless ($self->is_state_handle);
 
 }
 
@@ -81,10 +86,13 @@
 sub initialize {
     my $self = shift;
     my %args = validate( @_, { db_uuid => 0 } );
-     dir( $self->fs_root, $_ )->mkpath
-        for ($self->record_dir, $self->cas_root, $self->record_cas_dir, $self->changeset_cas_dir );
+    dir( $self->fs_root, $_ )->mkpath
+        for (
+        $self->record_dir,     $self->cas_root,
+        $self->record_cas_dir, $self->changeset_cas_dir
+        );
 
-    $self->set_db_uuid($args{'db_uuid'} || Data::UUID->new->create_str);
+    $self->set_db_uuid( $args{'db_uuid'} || Data::UUID->new->create_str );
     $self->set_latest_sequence_no("0");
     $self->set_replica_uuid( Data::UUID->new->create_str );
     $self->_write_file(
@@ -93,7 +101,6 @@
     );
 }
 
-
 sub latest_sequence_no {
     my $self = shift;
     $self->_read_file('latest-sequence-no');
@@ -110,13 +117,11 @@
 
 sub _increment_sequence_no {
     my $self = shift;
-    my $seq = $self->latest_sequence_no +1;
+    my $seq  = $self->latest_sequence_no + 1;
     $self->set_latest_sequence_no($seq);
     return $seq;
 }
 
-
-
 =head2 uuid
 
 Return the replica SVN repository's UUID
@@ -133,16 +138,16 @@
     my $self = shift;
     my $uuid = shift;
     $self->_write_file(
-        path    =>  'replica-uuid',
+        path    => 'replica-uuid',
         content => $uuid
     );
 
 }
 
-
 sub db_uuid {
     my $self = shift;
-    $self->_db_uuid( $self->_read_file('database-uuid') ) unless $self->_db_uuid;
+    $self->_db_uuid( $self->_read_file('database-uuid') )
+        unless $self->_db_uuid;
     return $self->_db_uuid;
 }
 
@@ -150,15 +155,12 @@
     my $self = shift;
     my $uuid = shift;
     $self->_write_file(
-        path    => 'database-uuid' ,
+        path    => 'database-uuid',
         content => $uuid
     );
 
 }
 
-
-
-
 =head1 Internals of record handling
 
 =cut
@@ -177,13 +179,13 @@
     my $self = shift;
     my %args = validate( @_, { type => 1, uuid => 1, props => 1 } );
 
-    for ( keys %{$args{'props'}}) {
-         delete $args{'props'}->{$_} if (!defined $args{'props'}->{$_} || $args{'props'}->{$_} eq '');
+    for ( keys %{ $args{'props'} } ) {
+        delete $args{'props'}->{$_}
+            if ( !defined $args{'props'}->{$_} || $args{'props'}->{$_} eq '' );
     }
-    my $content = YAML::Syck::Dump( $args{'props'} );
     my ($cas_key) = $self->_write_to_cas(
-        content_ref => \$content,
-        cas_dir     => $self->record_cas_dir
+        data    => $args{props},
+        cas_dir => $self->record_cas_dir
     );
     $self->_write_record_index_entry(
         uuid    => $args{uuid},
@@ -200,14 +202,16 @@
         type => $args{type}
     );
 
-    my $index_path = file($self->fs_root, $idx_filename);
+    my $index_path = file( $self->fs_root, $idx_filename );
     $index_path->parent->mkpath;
 
     my $record_index = $index_path->openw;
+
     # XXX TODO: skip if the index already has this version of the record;
     # XXX TODO FETCH THAT
     my $record_last_changed_changeset = 1;
-    my $index_row = pack( 'NH40', $record_last_changed_changeset, $args{cas_key} );
+    my $index_row
+        = pack( 'NH40', $record_last_changed_changeset, $args{cas_key} );
     print $record_index $index_row || die $!;
     close $record_index;
 }
@@ -227,13 +231,14 @@
 sub _read_serialized_record {
     my $self         = shift;
     my %args         = validate( @_, { type => 1, uuid => 1 } );
-    my $idx_filename = $self->_record_index_filename( uuid => $args{uuid}, type => $args{type});
-    
-    
+    my $idx_filename = $self->_record_index_filename(
+        uuid => $args{uuid},
+        type => $args{type}
+    );
+
     my $index = $self->_read_file($idx_filename);
     return undef unless $index;
 
-
     # XXX TODO THIS CODE IS FUCKING HACKY AND SHOULD BE SHOT;
     my $count = length($index) / RECORD_INDEX_SIZE;
 
@@ -249,7 +254,7 @@
     );
 
     # That's the props
-    return  YAML::Syck::Load( $self->_read_file($casfile) );
+    return from_json( $self->_read_file($casfile), { utf8 => 1} );
 }
 
 sub _record_index_filename {
@@ -279,21 +284,21 @@
 
     my $hash_changeset = $changeset->as_hash;
 
-    # XXX TODO: we should not be calculating the changeset's sha1 with the 'replica_uuid' and 'sequence_no' inside it. that makes every replica have a different hash for what should be a unique changeset.
+# XXX TODO: we should not be calculating the changeset's sha1 with the 'replica_uuid' and 'sequence_no' inside it. that makes every replica have a different hash for what should be the samechangeset.
+
+    # These ttwo things should never actually get stored
+   my $seqno = delete $hash_changeset->{'sequence_no'};
+    my $uuid  = delete $hash_changeset->{'replica_uuid'};
 
-    my $content = YAML::Syck::Dump($hash_changeset);
     my $cas_key = $self->_write_to_cas(
-        content_ref => \$content,
-        cas_dir     => $self->changeset_cas_dir
+        data    => $hash_changeset,
+        cas_dir => $self->changeset_cas_dir
     );
 
-    # XXX TODO we should only actually be encoding the sha1 of content once
-    # and then converting. this is wasteful
-
-    my $packed_cas_key = sha1($content);
+    my $packed_cas_key = pack( 'H40', $cas_key );
 
     my $changeset_index_line = pack( 'Na16Na20',
-        $changeset->sequence_no,
+        $seqno,
         Data::UUID->new->from_string( $changeset->original_source_uuid ),
         $changeset->original_sequence_no,
         $packed_cas_key );
@@ -324,18 +329,25 @@
     my $first_rev = ( $args{'after'} + 1 ) || 1;
     my $latest    = $self->latest_sequence_no();
     my $chgidx    = $self->_read_file( $self->changeset_index );
-   
+
     $self->log("Traversing changesets between $first_rev and $latest");
     for my $rev ( $first_rev .. $latest ) {
-        my $index_record =  substr( $chgidx, ( $rev - 1 ) * CHG_RECORD_SIZE, CHG_RECORD_SIZE );
-        my ( $seq, $orig_uuid, $orig_seq, $key ) = unpack( 'Na16NH40', $index_record);
-
+        my $index_record = substr( $chgidx, ( $rev - 1 ) * CHG_RECORD_SIZE,
+            CHG_RECORD_SIZE );
+        my ( $seq, $orig_uuid, $orig_seq, $key )
+            = unpack( 'Na16NH40', $index_record );
 
         $orig_uuid = Data::UUID->new->to_string($orig_uuid);
-        $self->log("REV: $rev - seq $seq - originally $orig_seq from ".substr( $orig_uuid,0,6)  ." data key $key");
-    
+        $self->log( "REV: $rev - seq $seq - originally $orig_seq from "
+                . substr( $orig_uuid, 0, 6 )
+                . " data key $key" );
+
         # XXX: deserialize the changeset content from the cas with $key
-        my $casfile = file( $self->changeset_cas_dir, substr( $key, 0, 1 ), substr( $key, 1, 1 ), $key);
+        my $casfile = file(
+            $self->changeset_cas_dir,
+            substr( $key, 0, 1 ),
+            substr( $key, 1, 1 ), $key
+        );
 
         my $changeset = $self->_deserialize_changeset(
             content              => $self->_read_file($casfile),
@@ -347,7 +359,6 @@
     }
 }
 
-
 sub _deserialize_changeset {
     my $self = shift;
     my %args = validate(
@@ -358,7 +369,7 @@
             sequence_no          => 1
         }
     );
-    my $content_struct = YAML::Syck::Load( $args{content} );
+    my $content_struct = from_json( $args{content} , { utf8 => 1 });
     my $changeset      = Prophet::ChangeSet->new_from_hashref($content_struct);
 
     $changeset->source_uuid( $self->uuid );
@@ -371,20 +382,26 @@
 sub _get_changeset_index_handle {
     my $self = shift;
 
-    open( my $cs_file, ">>" . file( $self->fs_root, $self->changeset_index ) ) || die $!;
+    open( my $cs_file, ">>" . file( $self->fs_root, $self->changeset_index ) )
+        || die $!;
     return $cs_file;
 }
 
-
 sub _write_to_cas {
-    my $self             = shift;
-    my %args             = validate( @_, { content_ref => 1, cas_dir => 1 } );
-    my $content          = ${ $args{'content_ref'} };
-    my $fingerprint      = sha1_hex($content);
-    my $content_filename = file( $args{'cas_dir'},
+    my $self = shift;
+    my %args = validate( @_,
+        { content_ref => 0, cas_dir => 1, data => 0  } );
+    my $content;
+    if ( $args{'content_ref'} ) {
+        $content = ${ $args{'content_ref'} };
+    } elsif ( $args{'data'} ) {
+        $content = to_json($args{'data'}, { canonical => 1, pretty=> 0, utf8=>1}  );
+    }
+    my $fingerprint = sha1_hex($content);
+    my $content_filename = file(
+        $args{'cas_dir'},
         substr( $fingerprint, 0, 1 ),
-        substr( $fingerprint, 1, 1 ), 
-        $fingerprint
+        substr( $fingerprint, 1, 1 ), $fingerprint
     );
 
     $self->_write_file( path => $content_filename, content => $content );
@@ -395,14 +412,15 @@
     my $self = shift;
     my %args = validate( @_, { path => 1, content => 1 } );
 
-    my $file = file($self->fs_root => $args{'path'});
+    my $file = file( $self->fs_root => $args{'path'} );
     my $parent = $file->parent;
-    unless (-d $parent) {
-     $parent->mkpath || die "Failed to create directory ".$file->parent;;
-    } 
+    unless ( -d $parent ) {
+        $parent->mkpath || die "Failed to create directory " . $file->parent;
+    }
 
     my $fh = $file->openw;
-    print $fh scalar($args{'content'}); # can't do "||" as we die if we print 0" || die "Could not write to " . $args{'path'} . " " . $!;
+    print $fh scalar( $args{'content'} )
+        ; # can't do "||" as we die if we print 0" || die "Could not write to " . $args{'path'} . " " . $!;
     close $fh || die $!;
 }
 
@@ -416,61 +434,63 @@
     my $self = shift;
     my ($file) = validate_pos( @_, 1 );
 
-    if ($self->fs_root) {
-          my $path = file($self->fs_root, $file);
-          if (-f $path ) { return 1}
-          elsif (-d $path ) { return 2}
-          else { return 0 }
+    if ( $self->fs_root ) {
+        my $path = file( $self->fs_root, $file );
+        if    ( -f $path ) { return 1 }
+        elsif ( -d $path ) { return 2 }
+        else               { return 0 }
     } else {
-          return $self->_read_file($file) ? 1 : 0;
+        return $self->_read_file($file) ? 1 : 0;
     }
 }
 
 sub _read_file {
     my $self = shift;
     my ($file) = validate_pos( @_, 1 );
-    if ($self->fs_root ) {
-        if ( $self->_file_exists($file)) {
-            return scalar file($self->fs_root => $file)->slurp;
+    if ( $self->fs_root ) {
+        if ( $self->_file_exists($file) ) {
+            return scalar file( $self->fs_root => $file )->slurp;
         } else {
             return undef;
         }
-    } else { # http replica 
-    return LWP::Simple::get( $self->url . "/" . $file );
-}
+    } else {    # http replica
+        return LWP::Simple::get( $self->url . "/" . $file );
+    }
 }
 
-
 sub begin_edit {
     my $self = shift;
-    $self->current_edit( Prophet::ChangeSet->new({ source_uuid => $self->uuid }) );
+    $self->current_edit(
+        Prophet::ChangeSet->new( { source_uuid => $self->uuid } ) );
 }
 
-
 sub _set_original_source_metadata_for_current_edit {
     my $self = shift;
     my ($changeset) = validate_pos( @_, { isa => 'Prophet::ChangeSet' } );
 
-    $self->current_edit->original_source_uuid( $changeset->original_source_uuid );
-    $self->current_edit->original_sequence_no( $changeset->original_sequence_no );
+    $self->current_edit->original_source_uuid(
+        $changeset->original_source_uuid );
+    $self->current_edit->original_sequence_no(
+        $changeset->original_sequence_no );
 }
 
-
 sub commit_edit {
-    my $self = shift;
+    my $self     = shift;
     my $sequence = $self->_increment_sequence_no;
-    $self->current_edit->original_sequence_no($sequence) unless ($self->current_edit->original_sequence_no);
-    $self->current_edit->original_source_uuid($self->uuid) unless ($self->current_edit->original_source_uuid);
+    $self->current_edit->original_sequence_no($sequence)
+        unless ( $self->current_edit->original_sequence_no );
+    $self->current_edit->original_source_uuid( $self->uuid )
+        unless ( $self->current_edit->original_source_uuid );
     $self->current_edit->sequence_no($sequence);
-    $self->_write_changeset_to_index($self->current_edit);
+    $self->_write_changeset_to_index( $self->current_edit );
 }
 
 sub _write_changeset_to_index {
-    my $self = shift;
+    my $self      = shift;
     my $changeset = shift;
-    my $handle = $self->_get_changeset_index_handle;
-    $self->_write_changeset( index_handle => $handle, changeset => $changeset);
-    close($handle) || die "Failed to close changeset handle: ".$handle;
+    my $handle    = $self->_get_changeset_index_handle;
+    $self->_write_changeset( index_handle => $handle, changeset => $changeset );
+    close($handle) || die "Failed to close changeset handle: " . $handle;
     $self->current_edit(undef);
 }
 
@@ -482,9 +502,6 @@
     $self->current_edit->is_resolution( $changeset->is_resolution );
 }
 
-
-
-
 sub create_record {
     my $self = shift;
     my %args = validate( @_, { uuid => 1, props => 1, type => 1 } );
@@ -492,27 +509,28 @@
     my $inside_edit = $self->current_edit ? 1 : 0;
     $self->begin_edit() unless ($inside_edit);
 
-
     $self->_write_serialized_record(
         type  => $args{'type'},
         uuid  => $args{'uuid'},
         props => $args{'props'}
     );
 
-   my $change =      Prophet::Change->new({
-        record_type => $args{'type'},
-        record_uuid => $args{'uuid'},
-        change_type => 'add_file' });
-
+    my $change = Prophet::Change->new(
+        {   record_type => $args{'type'},
+            record_uuid => $args{'uuid'},
+            change_type => 'add_file'
+        }
+    );
 
     foreach my $name ( keys %{ $args{props} } ) {
         $change->add_prop_change(
             name => $name,
             old  => undef,
-            new  => $args{props}->{$name});
+            new  => $args{props}->{$name}
+        );
     }
 
-    $self->current_edit->add_change(change => $change );
+    $self->current_edit->add_change( change => $change );
 
     $self->commit_edit unless ($inside_edit);
 }
@@ -526,26 +544,30 @@
 
 # XXX TODO Write out an entry to the record's index file marking it as a special deleted uuid? - this has lots of ramifications for list, load, exists, create
     $self->_delete_record_index( uuid => $args{uuid}, type => $args{type} );
-   
-    my $change =      Prophet::Change->new({
-        record_type => $args{'type'},
-        record_uuid => $args{'uuid'},
-        change_type => 'delete'} );
-    $self->current_edit->add_change(change => $change );
 
-        $self->commit_edit() unless ($inside_edit);
+    my $change = Prophet::Change->new(
+        {   record_type => $args{'type'},
+            record_uuid => $args{'uuid'},
+            change_type => 'delete'
+        }
+    );
+    $self->current_edit->add_change( change => $change );
+
+    $self->commit_edit() unless ($inside_edit);
     return 1;
 }
 
 sub set_record_props {
-    my $self      = shift;
-    my %args      = validate( @_, { uuid => 1, props => 1, type => 1 } );
+    my $self = shift;
+    my %args = validate( @_, { uuid => 1, props => 1, type => 1 } );
 
     my $inside_edit = $self->current_edit ? 1 : 0;
     $self->begin_edit() unless ($inside_edit);
 
-    my $old_props = $self->get_record_props( uuid => $args{'uuid'},
-        type => $args{'type'} );
+    my $old_props = $self->get_record_props(
+        uuid => $args{'uuid'},
+        type => $args{'type'}
+    );
     my %new_props = %$old_props;
     foreach my $prop ( %{ $args{props} } ) {
         if ( !defined $args{props}->{$prop} ) {
@@ -560,21 +582,23 @@
         props => \%new_props
     );
 
-    my $change =      Prophet::Change->new({
-        record_type => $args{'type'},
-        record_uuid => $args{'uuid'},
-        change_type => 'update_file'} );
-    
+    my $change = Prophet::Change->new(
+        {   record_type => $args{'type'},
+            record_uuid => $args{'uuid'},
+            change_type => 'update_file'
+        }
+    );
+
     foreach my $name ( keys %{ $args{props} } ) {
         $change->add_prop_change(
             name => $name,
             old  => $old_props->{$name},
-            new  => $args{props}->{$name});
+            new  => $args{props}->{$name}
+        );
     }
-    $self->current_edit->add_change(change => $change );
-
+    $self->current_edit->add_change( change => $change );
 
-        $self->commit_edit() unless ($inside_edit);
+    $self->commit_edit() unless ($inside_edit);
 
 }
 
@@ -615,9 +639,10 @@
 
 sub list_types {
     my $self = shift;
+
     return [ map { my @path = split( qr'/', $_ ); pop @path }
-            File::Find::Rule->mindepth(1)->maxdepth(1)->in( dir( $self->fs_root, $self->record_dir ) ) 
-            ];
+            File::Find::Rule->mindepth(1)->maxdepth(1)
+            ->in( dir( $self->fs_root, $self->record_dir ) ) ];
 
 }
 
@@ -627,5 +652,4 @@
     return $self->_file_exists( $self->_record_type_root( $args{'type'} ) );
 }
 
-
 1;

Modified: Prophet/trunk/lib/Prophet/Replica/SVN.pm
==============================================================================
--- Prophet/trunk/lib/Prophet/Replica/SVN.pm	(original)
+++ Prophet/trunk/lib/Prophet/Replica/SVN.pm	Tue Apr 22 20:34:02 2008
@@ -7,7 +7,6 @@
 use UNIVERSAL::require;
  
 
-use Data::UUID;
 
 
 

Modified: Prophet/trunk/lib/Prophet/Resolver/AlwaysTarget.pm
==============================================================================
--- Prophet/trunk/lib/Prophet/Resolver/AlwaysTarget.pm	(original)
+++ Prophet/trunk/lib/Prophet/Resolver/AlwaysTarget.pm	Tue Apr 22 20:34:02 2008
@@ -3,6 +3,7 @@
 
 package Prophet::Resolver::AlwaysTarget;
 use base qw/Prophet::Resolver/;
+use Data::Dumper;
 
 sub run {
     my $self               = shift;
@@ -15,7 +16,7 @@
     } elsif ( $conflicting_change->file_op_conflict eq 'delete_missing_file' ) {
         return $resolution;
     } elsif ( $conflicting_change->file_op_conflict ) {
-        die YAML::Syck::Dump( $conflict, $conflicting_change );
+        die Dumper($conflict,$conflicting_change);
     }
 
     for my $prop_change ( @{ $conflicting_change->prop_conflicts } ) {

Modified: Prophet/trunk/lib/Prophet/Resolver/Failed.pm
==============================================================================
--- Prophet/trunk/lib/Prophet/Resolver/Failed.pm	(original)
+++ Prophet/trunk/lib/Prophet/Resolver/Failed.pm	Tue Apr 22 20:34:02 2008
@@ -4,14 +4,17 @@
 package Prophet::Resolver::Failed;
 use base qw/Prophet::Resolver/;
 
+use Data::Dumper;
+
 sub run {
     my $self               = shift;
     my $conflicting_change = shift;
     my $conflict           = shift;
 
-    use YAML::Syck; die 
-    " The resolution was not resolved. Sorry dude. (Once Prophet works, you should NEVER see this message)".
-    YAML::Syck::Dump($conflicting_change, $conflict);
+    die
+        " The resolution was not resolved. Sorry dude. (Once Prophet works, you should NEVER see this message)"
+        . Dumper($conflict, $conflicting_change);
+
 }
 
 1;

Modified: Prophet/trunk/lib/Prophet/Resolver/FromResolutionDB.pm
==============================================================================
--- Prophet/trunk/lib/Prophet/Resolver/FromResolutionDB.pm	(original)
+++ Prophet/trunk/lib/Prophet/Resolver/FromResolutionDB.pm	Tue Apr 22 20:34:02 2008
@@ -4,7 +4,8 @@
 package Prophet::Resolver::FromResolutionDB;
 use base qw/Prophet::Resolver/;
 use Prophet::Change;
-use Digest::MD5 'md5_hex';
+use JSON;
+use Digest::SHA1 'sha1_hex';
 
 sub run {
     my $self               = shift;
@@ -14,7 +15,8 @@
 
     my $res = Prophet::Collection->new(
         handle => $resdb,
-        type   => '_prophet_resolution-' . $conflicting_change->cas_key
+        # XXX TODO PULL THIS TYPE FROM A CONSTANT
+        type   => '_prophet_resolution-' . $conflicting_change->fingerprint
     );
     $res->matching( sub {1} );
     return unless @{ $res->as_array_ref };
@@ -25,7 +27,7 @@
     my %answer_count;
 
     for my $answer ( @{ $res->as_array_ref } ) {
-        my $key = md5_hex( YAML::Syck::Dump( $answer->get_props ) );
+        my $key = sha1_hex( to_json($answer->get_props, {utf8 => 1, pretty => 1, canonical => 1}));
         $answer_map{$key} ||= $answer;
         $answer_count{$key}++;
     }

Modified: Prophet/trunk/lib/Prophet/Test.pm
==============================================================================
--- Prophet/trunk/lib/Prophet/Test.pm	(original)
+++ Prophet/trunk/lib/Prophet/Test.pm	Tue Apr 22 20:34:02 2008
@@ -16,9 +16,6 @@
 
 use Prophet::CLI;
 
-use constant DEFAULT_REPLICA_TYPE => 'svn';
-
-
 our $REPO_BASE = File::Temp::tempdir();
 Test::More->import;
 diag( "Replicas can be found in" . $REPO_BASE );
@@ -207,7 +204,7 @@
     my $path = repo_path_for($username);
     $path =~ s{^|\\}{/}g if IS_WIN32;
 
-    return ($ENV{'PROPHET_REPLICA_TYPE'}|| __PACKAGE__->DEFAULT_REPLICA_TYPE) . ':file://' . $path;
+    return ($ENV{'PROPHET_REPLICA_TYPE'}|| Prophet::App->DEFAULT_REPLICA_TYPE) . ':file://' . $path;
 }
 
 sub replica_uuid {

Modified: Prophet/trunk/t/canonicalize.t
==============================================================================
--- Prophet/trunk/t/canonicalize.t	(original)
+++ Prophet/trunk/t/canonicalize.t	Tue Apr 22 20:34:02 2008
@@ -3,12 +3,15 @@
 use Test::More  tests => 7;
 use File::Temp qw'tempdir';
 use lib 't/lib';
-my $SCHEME = $ENV{'PROPHET_REPLICA_TYPE'} || 'svn';
 
-use_ok('Prophet::Replica');
-my $REPO = tempdir( CLEANUP => 0 ) . '/repo-' . $$;
-my $cxn = Prophet::Replica->new( {url  => "$SCHEME:file://$REPO"} );
-isa_ok( $cxn, 'Prophet::Replica', "Got the cxn" );
+
+
+use_ok('Prophet::CLI');
+$ENV{'PROPHET_REPO'} = tempdir( CLEANUP => 0 ) . '/repo-' . $$;
+my $cli = Prophet::CLI->new();
+my $cxn = $cli->app_handle->handle;
+isa_ok($cxn, 'Prophet::Replica');
+
 use_ok('TestApp::Bug');
 
 my $record = TestApp::Bug->new( handle => $cxn );

Modified: Prophet/trunk/t/create.t
==============================================================================
--- Prophet/trunk/t/create.t	(original)
+++ Prophet/trunk/t/create.t	Tue Apr 22 20:34:02 2008
@@ -4,11 +4,11 @@
 
 use File::Temp qw'tempdir';
 
-my $SCHEME = $ENV{'PROPHET_REPLICA_TYPE'} || 'svn';
-use_ok('Prophet::Replica');
-my $REPO = tempdir( CLEANUP => 0 ) . '/repo-' . $$;
-diag($REPO);
-my $cxn = Prophet::Replica->new({ url => "$SCHEME:file://$REPO" });
+use_ok('Prophet::CLI');
+$ENV{'PROPHET_REPO'} = tempdir( CLEANUP => 0 ) . '/repo-' . $$;
+my $cli = Prophet::CLI->new();
+my $cxn = $cli->app_handle->handle;
+
 isa_ok( $cxn, 'Prophet::Replica', "Got the cxn" );
 use_ok('Prophet::Record');
 my $record = Prophet::Record->new( handle => $cxn, type => 'Person' );

Modified: Prophet/trunk/t/validate.t
==============================================================================
--- Prophet/trunk/t/validate.t	(original)
+++ Prophet/trunk/t/validate.t	Tue Apr 22 20:34:02 2008
@@ -6,11 +6,11 @@
 use lib 't/lib';
 use Test::Exception;
 
-my $SCHEME = $ENV{'PROPHET_REPLICA_TYPE'} || 'svn';
 
-use_ok('Prophet::Replica');
-my $REPO = tempdir( CLEANUP => 0 ) . '/repo-' . $$;
-my $cxn = Prophet::Replica->new( { url => "$SCHEME:file://$REPO" });
+use_ok('Prophet::CLI');
+$ENV{'PROPHET_REPO'} = tempdir( CLEANUP => 0 ) . '/repo-' . $$;
+my $cli = Prophet::CLI->new();
+my $cxn = $cli->app_handle->handle;
 isa_ok( $cxn, 'Prophet::Replica', "Got the cxn" );
 use_ok('TestApp::Bug');
 



More information about the Bps-public-commit mailing list