Provided by: libperinci-cmdline-perl_2.000.0-2_all bug

NAME

       Perinci::CmdLine::Manual::FAQ - FAQs

VERSION

       This document describes version 2.000.0 of Perinci::CmdLine::Manual::FAQ (from Perl
       distribution Perinci-CmdLine), released on 2021-12-19.

NOMENCLATURE

       "[PC::Classic]" denotes that the answer applies to Perinci::CmdLine::Classic only and not
       Perinci::CmdLine::Lite. "[PC::Lite]" denotes that the answer is specific to
       Perinci::CmdLine::Lite. "[PC::Any]" denotes that the answer is specific to
       Perinci::CmdLine::Any.

GENERAL

   Why are there multiple frameworks/flavors for Perinci::CmdLine?
       There are currently 3 (three) flavors of the framework: Perinci::CmdLine::Classic,
       Perinci::CmdLine::Lite, and Perinci::CmdLine::Inline. Which one you should use depends on
       your needs, because sadly, there is no one-size-fits-all.

       Perinci::CmdLine::Classic. Perinci::CmdLine::Classic (hereby called PC:Classic) is the
       first flavor which I developed (and it used to be called just Perinci::CmdLine). It has
       the most complete features as well as the prettiest output, but as it grows in features,
       other things like startup overhead and dependencies also grow.

       Perinci::CmdLine::Lite. So another project is started, Perinci::CmdLine::Lite (hereby
       called PC::Lite) that focuses on keeping startup overhead low to avoid making tab
       completion delay noticeable. PC:Lite aims to make CLI scripts typically start below 0.05s,
       while PC:Classic-based scripts currently start in about 0.2-0.5s which causes a noticeable
       delay when doing tab completion. PC:Lite also tries to reduce the number of dependencies
       (from 100+ down to 30+ or so). Some PC:Classic features are still missing in PC:Lite (see
       next question).

       PC:Lite stays more lightweight by avoiding the use of libraries that have large
       dependencies or add too much to startup overhead. This includes replacing Perinci::Access
       with Perinci::Access::Lite for metadata access and avoiding Text::ANSITable for formatting
       results.

       Implementation-wise, the two share a lot of common code in the form of their base class,
       Perinci::CmdLine::Base. The interface is also 99% the same.

       It is possible that in the future the two versions will merge.

       Perinci::CmdLine::Inline. There is another flavor called PC:Inline. The goal of this
       flavor is to make your CLI scripts depend on nothing but Perl and the core modules. (It is
       also possible to make PC:Classic- or PC:Lite-based CLI script to also be freestanding by
       techniques like fatpacking or datapacking, but the resulting packed script will be much
       larger.) It has the lowest number of dependencies and the fastest startup overhead (around
       0.01s). But currently it also has the least features.

       It reduces startup overhead further by skipping the Riap layer and prefetching the Rinci
       metadata, precomputing the command-line options, and embedding all these in the scripts.

       See Perinci::CmdLine::Inline for more details of the features it currently supports. This
       flavor is suitable for simple CLI scripts that need to be as lean and fast as possible,
       for example: hr (in App::hr) or gen-uuids (in App::UuidUtils).

       All the flavors share the basic concept: running your Rinci-described functions on the
       command-line.

       So which one should you choose? PC:Lite is the sane default choice, unless you need
       features that are currently not supported by PC:Lite, in which case you can consider using
       PC:Classic. If you really need fast startup, you can opt for PC:Inline. But note that when
       the backend function's Rinci metadata changes, you will need to rebuild the script because
       the metadata is embedded in the script (while in PC:Lite and PC:Classic, the script simply
       request the Rinci metadata during runtime).

   What Classic features are currently still missing in Lite?
       •   More sophisticated formatting

           Instead of Perinci::Result::Format (especially for 'text*' formats which use
           Data::Format::Pretty::Console and Text::ANSITable), to keep dependencies minimal and
           formatting quick, PC::Lite uses the following simple rules that work for a significant
           portion of common data structures:

           1) if result is undef, print nothing.

           2) if result is scalar, print it (with newline automatically added).

           3) if result is an array of scalars (check at most 5 first rows), print it one line
           for each element.

           4) if result is a hash of scalars (check at most 5 keys), print a two column table,
           first column is key and second column is value. Keys will be sorted.

           5) if result is an array of hashes of scalars (check at most 5 elements), print as
           table.

           6) if result is an array of arrays of scalars (check at most 5 elements), print as
           table.

           7) otherwise print as JSON (after cleaning it with Data::Clean::JSON).

           YAML and the other formats are not supported.

           Table is printed using the more lightweight and much faster Text::Table::Tiny.

           PC::Classic supports more sophisticated formatting, can keep colored and full-width
           Unicode characters stay aligned in a table.

       •   Support for extra protocols

           Instead of Perinci::Access, PC::Lite uses the more lightweight alternative
           Perinci::Access::Lite which does not support some URL schemes (riap+tcp, riap+unix,
           riap+pipe). http/https and local are supported though.

       •   Extra stuffs that Perinci::Sub::Wrapper adds

           PC::Classic uses function wrapper to automatically adds argument validation,
           dependency checking, and so on. However, this adds too much overhead so PC:Lite avoids
           it and do some of the stuffs by itself to avoid the overhead.

           PC:Lite does argument validation, as well as dependency checking. But there are other
           stuffs that Perinci::Sub::Wrapper adds that are not available, including: result
           validation, validation of input stream (streaming argument) as well as output stream
           (streaming result).

       •   Color themes

       •   Undo

       •   I18N

       •   The following environment variables

            PERINCI_CMDLINE_COLOR_THEME
            PERINCI_CMDLINE_SERVER
            COLOR
            UTF8

   What is Perinci::CmdLine::Any then?
       This is a module that allows you to select PC::Classic or PC::Lite. So your scripts do not
       need to be modified when user wants to switch between the two.

   How does Perinci::CmdLine compare with other CLI-app frameworks?
       The main difference is that Perinci::CmdLine accesses your code through Riap protocol, not
       directly. This means that aside from local Perl code, Perinci::CmdLine can also provide
       CLI for code in remote hosts/languages. For a very rough demo, download and run this PHP
       Riap::TCP server
       https://github.com/sharyanto/php-Phinci/blob/master/demo/phi-tcpserve-terbilang.php on
       your system. After that, try running:

        % peri-run riap+tcp://localhost:9090/terbilang --help
        % peri-run riap+tcp://localhost:9090/terbilang 1234

       Everything from help message, calling, argument checking, tab completion works for remote
       code as well as local Perl code.

   But my application is OO? But I want an OO framework?
       This framework is currently function-centric. There are already several OO-based command-
       line frameworks on CPAN.

GENERATING DOCUMENTATION

   How do I add examples using Rinci metadata?
       In your Rinci function metadata, add the "examples" property, e.g.:

        # myapp script
        use Perinci::CmdLine::Any;
        our %SPEC;
        $SPEC{myadd} = {
            v => 1.1,
            args => {
                num1 => {summary=>'First number' , schema='float*', req=>1, pos=>0},
                num2 => {summary=>'Second number', schema='float*', req=>1, pos=>1},
                round => {
                    summary=>'Round to nearest integer',
                    schema =>'bool*',
                    cmdline_aliases=>{r=>{}},
                },
            },
            examples => [
                {
                    summary => 'Add two integers',
                    args => {num1=>7, num2=>5},
                },
                {
                    summary => 'Add two floats, round to nearest integer',
                    args => {num1=>7.1, num2=>5.5, round=>1},
                    result => 13,
                },
            ],
        }
        sub myadd { ... }
        Perinci::CmdLine::Any->new(url => '/main/myadd')->run;

       If you run "myapp --help", you'll see the examples shown as:

        Examples:
          Add two integers:
          % myadd 7 5

          Add two floats, round to the nearest integer:
          % myadd 7.1 5.5 --round

       If you use Dist::Zilla and Pod::Weaver and Pod::Weaver::Plugin::Rinci to generate your
       POD, you'll also have the Synopsis section filled with the above.

DEBUGGING

   How do I enable/view log messages?
       The framework produces log messages using Log::ger. You can display them on the screen,
       e.g. using Log::ger::App like:

        % TRACE=1 perl -MLog::ger::App /path/to/yourscript.pl

       or:

        % TRACE=1 PERL5OPT=-MLog::ger::App yourscript.pl

   How do I debug my CLI script?
       To see stack trace on error, you can use Devel::Confess.  Perinci::CmdLine::Base detects
       if Devel::Confess is loaded and will return the stack trace for you:

        % perl -d:Confess /path/to/yourscript.pl

       or:

        % PERL5OPT='-d:Confess' yourscript.pl

PROGRESS INDICATOR

   How do I show progress indicator?
       Perinci::CmdLine can work together with the Progress::Any framework. Either you setup
       progress output module manually:

        use Perinci::CmdLine::Any;
        use Progress::Any '$progress';
        use Progress::Any::Output 'TermProgressBarColor';

        $SPEC{app} = {
            v => 1.1,
            ...
        };
        sub app {
            $progress->target(5);
            for (1..5) {
                $progress->update(message => "Item $_");
                sleep 1;
            }
            [200];
        }

        Perinci::CmdLine::Any->new(url => "/main/app")->run;

       or you can set "progress" feature in your function metadata, in which case
       Perinci::CmdLine::Lite will setup Progress::Any::Output::TermProgressBarColor for you
       automatically:

        use Perinci::CmdLine::Any;
        use Progress::Any '$progress';

        $SPEC{app} = {
            v => 1.1,
            ...
            features => { progress=>1 },
        };
        sub app {
            $progress->target(5);
            for (1..5) {
                $progress->update(message => "Item $_");
                sleep 1;
            }
            [200];
        }

        Perinci::CmdLine::Any->new(url => "/main/app")->run;

       The former way gives you flexibility to choose/customize your progress output module.

HOMEPAGE

       Please visit the project's homepage at <https://metacpan.org/release/Perinci-CmdLine>.

SOURCE

       Source repository is at <https://github.com/perlancar/perl-Perinci-CmdLine>.

SEE ALSO

       Perinci::CmdLine::Manual

       For the Generating Documentation section: Rinci::function, Rinci::FAQ (the Documentation
       section)

AUTHOR

       perlancar <perlancar@cpan.org>

CONTRIBUTING

       To contribute, you can send patches by email/via RT, or send pull requests on GitHub.

       Most of the time, you don't need to build the distribution yourself. You can simply modify
       the code, then test via:

        % prove -l

       If you want to build the distribution (e.g. to try to install it locally on your system),
       you can install Dist::Zilla, Dist::Zilla::PluginBundle::Author::PERLANCAR, and sometimes
       one or two other Dist::Zilla plugin and/or Pod::Weaver::Plugin. Any additional steps
       required beyond that are considered a bug and can be reported to me.

COPYRIGHT AND LICENSE

       This software is copyright (c) 2021, 2018, 2017, 2016, 2015 by perlancar
       <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.

BUGS

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

       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.