package VCP::Dest::csv ; =head1 NAME VCP::Dest::csv - developement output =head1 DESCRIPTION Dump each revision's metadata in CSV format. Does not dump header/footer. =cut $VERSION = 0.1 ; use strict ; use VCP::Logger qw( pr ); use VCP::Utils qw( empty ); use base qw( VCP::Dest ); use fields ( 'FIELDS', ## Which fields to print ); sub new { my $class = shift ; $class = ref $class || $class ; my VCP::Dest::csv $self = $class->SUPER::new( @_ ) ; ## Parse the options my ( $spec, $options ) = @_ ; $self->parse_options( $options ); return $self ; } sub options_spec { my VCP::Dest::csv $self = shift ; return ( $self->SUPER::options_spec, "fields=s" => \$self->{FIELDS}, ); } sub csv_escape { local $_ = @_ ? shift : $_; return "" unless defined; return '""' unless length; ## crude but effective. s/\r/\\r/g; s/\n/\\n/g; s/"/""/g; $_ = qq{"$_"} if /[",]/; $_; } sub init { my VCP::Dest::csv $self = shift ; $self->SUPER::init; $self->{FIELDS} = [ !empty( $self->{FIELDS} ) ? do { my @names = split /,/, $self->{FIELDS}; my %fields = map { my $name = $_; $name =~ s/\@//; ( $name => $_ ); } VCP::Rev->fields; for ( @names ) { if ( ! exists $fields{$_} && !VCP::Rev->can($_) ) { pr "vcp: '$_' not a name, skipping"; next; } $_ = $fields{$_} if exists $fields{$_}; } @names; } : VCP::Rev->fields ]; } sub handle_header { my VCP::Dest::csv $self = shift ; print join( ",", map { my $name = $_; $name =~ s/\@//; csv_escape( $name ); } @{$self->{FIELDS}} ), "\n"; } sub handle_footer {} sub handle_rev { my VCP::Dest::csv $self = shift ; my ( $r ) = @_; print join( ",", map { my $name = $_; my $is_list = $name =~ s/\@//; csv_escape( $name eq "time" ? VCP::Rev::iso8601format( $r->$name ) : $is_list ? join ";", $r->$name : $r->$name ); } @{$self->{FIELDS}} ), "\n"; } =back =head1 AUTHOR Barrie Slaymaker =head1 COPYRIGHT Copyright (c) 2000, 2001, 2002 Perforce Software, Inc. All rights reserved. See L (C) for the terms of use. =cut 1