--- trunk/lib/Frey/SVK.pm 2008/11/24 21:31:54 498 +++ trunk/lib/Frey/SVK.pm 2008/11/29 15:58:23 619 @@ -1,19 +1,61 @@ package Frey::SVK; use Moose; -with 'Frey::Escape'; +extends 'Frey'; +with 'Frey::Web'; -sub modified { - my ($self) = @_; - my @modified; - open(my $svk, '-|', 'svk status -q') or die $@; +use Moose::Util::TypeConstraints; + +enum 'SVK_Action' => ( 'commit', 'revert' ); + +has action => ( + is => 'rw', + isa => 'SVK_Action', +); + +has path => ( + documentation => 'path to work with', + is => 'rw', + isa => 'Str', +); + +has message => ( + documentation => 'commit message', + is => 'rw', + isa => 'Str', +); + +sub svk { + my ( $self, $exec, $coderef ) = @_; + open(my $svk, '-|', 'svk ' . $exec) or die "svk $exec: $@"; while(<$svk>) { chomp; - push @modified, $1 if /^M\s+(.+)/; + $coderef->( $_ ); } + close($svk) or die "can't close svk $exec: $@"; +} + +sub modified { + my ($self) = @_; + my @modified; + my $svk = $self->svk('status -q', sub { + push @modified, $1 if /^\w+\s+(.+)/; + }); return @modified; } +our $info; # cache, we use it on every hit +sub info { + my ($self) = @_; + return $info if $info; + my $svk = $self->svk('info', sub { + my ( $label, $value ) = split(/:\s+/, $_, 2); + $info->{$label} = $value if $label; + }); + warn "# svk info ",$self->dump( $info ); + return $info; +} + sub as_data { my ($self) = @_; { @@ -21,18 +63,97 @@ } } -sub as_markup { +sub status_as_markup { my ($self) = @_; - my $status = `svk status -q`; +# $status =~ s{^(\w+\s+)(\S+)$}{$1$2}gm; # FIXME + $status =~ s{^(\w+\s+)(\S+)$}{$1$2}gm; + if ( $status ) { + $self->add_css(qq| + pre.l a { text-decoration: none; } + div.commit { + background: #ffd; + padding: 1em 1em; + position: fixed; + top: 1em; + right: 1em; + z-index: 10; + } + | ); + + $status = qq| +
+
+ +
+
+
+
$status
+ |; + $self->add_status( $status ); + + } + warn "status_as_markup ",length($status)," bytes"; + return $status; +} + +sub diff_as_markup { + my ($self) = @_; + my $diff = `svk diff`; - my $html - = qq|
$status

|
-		. $self->html_escape( $diff )
-		. qq|
| - ; - warn "diff ",length($html)," bytes"; + $diff = $self->html_escape( $diff ); + $self->add_css( qq| + pre span.add { background: #dfd } + pre span.del { background: #fdd } + pre form.revert { display: inline } + | ); + $diff =~ s{^(\+.+?)$}{$1}gm; + $diff =~ s{^(\-.+?)$}{$1}gm; + $diff =~ s{^(===\s+)(\S+)$}{$1
$2}gm; + + $diff = qq|
$diff
|; + warn "diff_as_markup ",length($diff)," bytes"; + return $diff; +} + +sub as_markup { + my ($self) = @_; + + my $html = ''; + + if ( $self->action ) { + my $cmd = 'svk ' . $self->action . ' ' . $self->path; + if ( $self->action eq 'commit' ) { + confess "need message" unless $self->message; + my $msg = $self->message; + $msg =~ s{"}{\\"}gs; + $cmd .= qq{ -m "$msg"}; + } else { + confess "need path" unless $self->path; + } + $cmd .= ' 2>&1'; + my $out = `$cmd`; + warn "$cmd $out"; + $html .= qq| + + $cmd\n + $out + + |; + } + + $self->title( 'svk' . ( $self->action ? ' - ' . $self->action : '' ) ); # XXX without this we get wrong icon and title + + if ( ! $self->can('html_escape') ) { + Frey::Web->meta->apply( $self ); + $self->TODO( "Frey::Web role missing" ); + } + + $html .= $self->status_as_markup || 'No changes in files tracked by SVK'; + $html .= $self->diff_as_markup; + + warn "as_markup ",length($html)," bytes"; return $html; }