webgui/lib/WGDev/Command/Ls.pm

224 lines
5.8 KiB
Perl

package WGDev::Command::Ls;
# ABSTRACT: List WebGUI assets
use strict;
use warnings;
use 5.008008;
use parent qw(WGDev::Command::Base);
sub config_options {
return qw(
format|f=s
long|l
recursive|r
excludeClass=s@
includeOnlyClass=s@
limit=n
isa=s
filter=s
);
}
sub option_filter {
my $self = shift;
my $filter = shift;
my ( $filter_prop, $filter_sense, $filter_match )
= $filter =~ m{%(\w+)% \s* ([~!])~ \s* (.*)}msx;
if ( !defined $filter_prop
|| !defined $filter_sense
|| !defined $filter_match )
{
WGDev::X->throw("Invalid filter specified: $filter");
}
if ( $filter_match =~ m{\A/(.*)/\Z}msx ) {
eval { $filter_match = qr/$1/msx; }
|| WGDev::X->throw(
"Specified filter is not a valid regular expression: $1");
}
else {
$filter_match = qr/\A\Q$filter_match\E\z/msx;
}
$self->{filter_property} = $filter_prop;
$self->{filter_sense} = $filter_sense eq q{~};
$self->{filter_match} = $filter_match;
return;
}
sub process {
my $self = shift;
my $wgd = $self->wgd;
my $format = $self->option('format');
if ( $self->option('long') ) {
$format = '%assetId% %url:-35% %title%';
}
elsif ( !$format ) {
$format = '%url%';
}
my $relatives = $self->option('recursive') ? 'descendants' : 'children';
my @parents = $self->arguments;
my $show_header = @parents > 1;
my $exclude_classes = $self->option('excludeClass');
my $include_only_classes = $self->option('includeOnlyClass');
my $limit = $self->option('limit');
my $isa = $self->option('isa');
my $error;
PARENT:
while ( my $parent = shift @parents ) {
my $asset;
if ( !eval { $asset = $wgd->asset->find($parent) } ) {
warn "wgd ls: $parent: No such asset\n";
$error++;
next;
}
if ($show_header) {
print "$parent:\n";
}
my $child_iter = $asset->getLineageIterator(
[$relatives],
{
$exclude_classes ? ( excludeClasses => $exclude_classes )
: (),
$include_only_classes
? ( includeOnlyClasses => $include_only_classes )
: (),
defined $limit
&& !defined $self->{filter_match} ? ( limit => $limit )
: (),
$isa ? ( isa => $isa ) : (),
} );
while ( my $child = $child_iter->() ) {
next
if !$self->pass_filter($child);
# Handle limit ourselves because smartmatch filtering happens
# *after* getLineage returns its results
last PARENT
if defined $limit && $limit-- <= 0;
my $output = $self->format_output( $format, $child );
print $output . "\n";
}
if (@parents) {
print "\n";
}
}
return (! $error);
}
sub pass_filter {
my ( $self, $asset ) = @_;
my $filter_prop = $self->{filter_property};
my $filter_sense = $self->{filter_sense};
my $filter_match = $self->{filter_match};
return 1
if !defined $filter_match;
{
no warnings 'uninitialized';
if ($filter_sense) {
return $asset->get($filter_prop) =~ $filter_match;
}
else {
return $asset->get($filter_prop) !~ $filter_match;
}
}
}
sub format_output {
my ( $self, $format, $asset ) = @_;
{
no warnings 'uninitialized';
$format =~ s{% (?: (\w+) (?: :(-?\d+) )? )? %}{
my $replace;
if ($1) {
$replace = $asset->get($1);
if ($2) {
$replace = sprintf('%*2$s', $replace, $2);
}
}
else {
$replace = '%';
}
$replace;
}msxeg;
}
return $format;
}
1;
=head1 SYNOPSIS
wgd ls [-l] [--format=<format>] [-r] <asset> [<asset> ...]
=head1 DESCRIPTION
Lists children of WebGUI assets
=head1 OPTIONS
=over 8
=item C<-l> C<--long>
Use long list format, which includes asset ID, URL, and title.
=item C<-f> C<--format=>
Use arbitrary formatting. Format looks like C<%url:30%>, where 'C<url>' is
the field to display, and 30 is the length to left pad/cut to. Negative
lengths can be specified for right padding. Percent signs can be included by
using C<%%>.
=item C<-r> C<--recursive>
Recursively list all descendants (by default we only list children).
=item C<--includeOnlyClass=>
Specify one or more times to limit the results to a certain set of asset classes.
=item C<--excludeClass=>
Specify one or more times to filter out certain asset class(es) from the results.
=item C<--limit=>
The maximum amount of entries to return
=item C<--isa=>
A class name where you can look for classes of a similar base class.
For example, if you're looking for Donations, Subscriptions, Products
and other subclasses of L<WebGUI::Asset::Sku>, then specify the
parameter C<--isa=WebGUI::Asset::Sku>.
=item C<--filter=>
Apply smart match filtering against the results. Format looks like
C<%url% ~~ smartmatch>, where C<url> is the field to filter against,
and C<smartmatch> is either a Perl regular expression such as
C</(?i:partial_match)/> or a string such as C<my_exact_match>.
=back
=method C<format_output ( $format, $asset )>
Returns the formatted information about an asset. C<$format> is
the format to output as specified in the L<format option|/-f>.
=method C<option_filter ( $filter )>
Takes a filter specification, verifies that it is specified properly, and saves it.
=method C<pass_filter ( $asset )>
Checks if a given asset passes the saved filter. Returns true or false.
=cut