The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
#!perl

use 5.010001;
use strict;
use warnings;
use experimental 'smartmatch';
use Log::Any '$log';

BEGIN { $ENV{LOG} //= 0 } # speedup startup

use Getopt::Long;

our $VERSION = '1.46'; # VERSION
our $DATE = '2014-09-16'; # DATE

my %opts = (
    library => [],
    subcommands => [],
    version => 0,
    long => 0,
);
Getopt::Long::Configure('pass_through', 'no_permute');
GetOptions(
    'library|I=s' =>  $opts{library},
    'help|h|?'    => \$opts{help},
    'version|v'   => \$opts{version},
    'list|l'      => \$opts{list},
    'long'        => \$opts{long},
);

my $me = $0; $me =~ s!.+/!!;

if ($opts{version}) {
    no warnings 'once';
    print "$me version $main::VERSION ($main::DATE)\n";
    require Data::Unixish;
    print "  Data::Unixish version $Data::Unixish::VERSION".
        " ($Data::Unixish::DATE)\n";
    exit 0;
} elsif ($opts{list}) {
    require Module::List;
    my $mm = Module::List::list_modules("Data::Unixish::",
                                        {list_modules=>1, recurse=>1});
    for my $mod (sort keys %$mm) {
        next unless $mod =~ /\AData::Unixish::((?:\w+::)*[a-z][a-z0-9_]*)\z/;
        my $duxf = $1;
        if ($opts{long}) {
            my ($is_itemfunc, $is_unsafe, $meta, $v, $summary, $tags);
            if (eval "require $mod") {
                no strict 'refs';
                my $duxfleaf = $duxf; $duxfleaf =~ s/.+:://;
                my $metas = \%{"$mod\::SPEC"};
                $meta     = $metas->{$duxfleaf};
                $tags     = $meta->{tags} // [];
                $v        = ${"$mod\::VERSION"};
                $summary  = $meta->{summary};
                $is_itemfunc = 'itemfunc' ~~ @$tags;
                $is_unsafe   = 'unsafe' ~~ @$tags;
            } else {
                $tags = [];
            }
            my $tags_s = join(",", sort @$tags);
            say sprintf(
                "%s%s------ %-16s %8s %s",
                ($is_itemfunc ? "i" : defined($is_itemfunc) ? "-" : "?"),
                ($is_unsafe ? "U" : defined($is_unsafe) ? "-" : "?"),
                $duxf,
                $v // '?',
                ($summary // "") . (length($tags_s) ? " ($tags_s)":""),
            );
        } else {
            say $duxf;
        }
    }
    exit 0;
} elsif ($opts{help} || !@ARGV) {
    print <<USAGE;
$me - Run dux function on the command-line

Usage:
  $me --help
  $me --list | -l [ --long ]
  $me [common options] <dux function> [function options]

*Common options* include: '--library' ('-I') to add directory to Perl search dir
(a la Perl's '-I'), can be specified multiple times.

Examples:
  Show usage for a dux function:
    % $me head --help

  Run dux function:
    % ls -l | $me head -n 3

USAGE
    exit 0;
}

for my $dir (@{ $opts{library} }) { require lib; lib->import($dir) }

require Perinci::CmdLine::dux;
my $cmd = Perinci::CmdLine::dux->new;

my $pkg = shift @ARGV;
require Module::Path;
die "Unknown dux function $pkg, ".
    "please see list of available functions using `$me -l`\n" unless
    Module::Path::module_path("Data::Unixish::$pkg");

$pkg =~ s!::!/!g;
my $func = $pkg; $func =~ s!.+/!!;
my $url  = "/Data/Unixish/$pkg/$func";
$cmd->url($url);
$cmd->program_name($func);
$cmd->pass_cmdline_object(1);
$cmd->run;

#ABSTRACT: Run dux function on the command-line
#PODNAME: dux

__END__

=pod

=encoding UTF-8

=head1 NAME

dux - Run dux function on the command-line

=head1 VERSION

This document describes version 1.46 of dux (from Perl distribution App-dux), released on 2014-09-16.

=head1 SYNOPSIS

 dux --help | -h
 dux --list | -l [ --long ]
 dux [common opts] <dux function> [function opts ...] [file ...]

=head1 DESCRIPTION

This script runs a dux function on the command line. Dux function receives items
as lines from files/stdin, and outputs items as lines of stdout.

=head1 COMMAND-LINE OPTIONS

=head2 --list, -l

List available dux functions. If run without the C<--long> option, will just
output names of dux functions. Otherwise will also display extra information:
whether function is an itemfunc (C<i> symbol), whether function is unsafe (C<U>
symbol, meaning function evals string from user input), function's version and
tags.

=over

=item --library=STR, -I

Like Perl's C<-I> option.

=back

=head1 ENVIRONMENT

See L<Perinci::CmdLine> for a more complete list.

=head2 COLOR (bool)

Whether to force enable/disable color. The default is to enable when running
interactively.

=head2 LOG (bool, default 0)

Whether to enable logging. By default this script sets LOG environment to 0. If
you want to enable logging, you have to specifically set LOG=1.

=head1 SEE ALSO

L<Data::Unixish>

=head1 HOMEPAGE

Please visit the project's homepage at L<https://metacpan.org/release/App-dux>.

=head1 SOURCE

Source repository is at L<https://github.com/perlancar/perl-App-dux>.

=head1 BUGS

Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=App-dux>

When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.

=head1 AUTHOR

perlancar <perlancar@cpan.org>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2014 by perlancar@cpan.org.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut