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 start_dir_rel2abs ); use base qw( VCP::Dest ); use fields ( 'FIELDS', ## Which fields to print 'FILE', ## Where to write output, if not STDOUT 'FH', ## The filehandle for output ); 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_repo_spec( $spec ); $self->parse_options( $options ); return $self ; } sub options_spec { my VCP::Dest::csv $self = shift ; return ( $self->SUPER::options_spec, "fields=s" => \$self->{FIELDS}, "file=s" => \$self->{FILE}, ); } 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 ; $self->{FILE} = $self->repo_filespec if empty $self->{FILE}; if ( empty $self->{FILE} ) { $self->{FH} = \*STDOUT; } else { local *F; my $fn = start_dir_rel2abs( $self->{FILE} ); open F, "> $fn" or die "$! opening $fn\n"; $self->{FH} = *F{IO}; } my $fh = $self->{FH}; print $fh 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 ) = @_; my $fh = $self->{FH}; print $fh 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 <barries@slaysys.com> =head1 COPYRIGHT Copyright (c) 2000, 2001, 2002 Perforce Software, Inc. All rights reserved. See L<VCP::License|VCP::License> (C<vcp help license>) for the terms of use. =cut 1
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#6 | 5403 | Barrie Slaymaker | - Misc logging, maintainability & debugging improvements | ||
#5 | 4496 | Barrie Slaymaker | - minor POD cleanups to prevent nags when building VCP::Help | ||
#4 | 4021 | Barrie Slaymaker |
- Remove all phashes and all base & fields pragmas - Work around SWASHGET error |
||
#3 | 4012 | Barrie Slaymaker | - Remove dependance on pseudohashes (deprecated Perl feature) | ||
#2 | 3946 | Barrie Slaymaker |
- VCP::Source::vss now parses history records that do not cause files to have new revisions, such as project labels. |
||
#1 | 3828 | Barrie Slaymaker | - VCP::Dest::csv dumps rev metadata in CSV format |