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

NAME

Text::Yeti::Table - Render a table like "docker ps" does

VERSION

version 0.3.0

SYNOPSIS

    use Text::Yeti::Table qw(render_table);

    render_table( $list, $spec );

DESCRIPTION

Text::Yeti::Table renders a table of data into text. Given a table (which is an arrayref of hashrefs) and a specification, it creates output such as below.

    CONTAINER ID   IMAGE                   CREATED       STATUS               NAME           
    632495650e4e   alpine:latest           5 days ago    Exited 5 days ago    zealous_galileo
    6459c004a7b4   postgres:9.6.1-alpine   23 days ago   Up 23 days           hardcore_sammet
    63a4c1b60c9f   f348af3681e0            2 weeks ago   Exited 12 days ago   elastic_ride   

The specification can be as simple as:

    [ 'key1', 'key2', 'key3' ]

For complex values, a function can be given for the text conversion.

    [ 'name', 'id', 'node', 'address', [ 'tags', sub {"@{$_[0]}"} ] ]

Usually headers are computed from keys, but that can be overriden.

    [ 'ServiceName', 'ServiceID', 'Node', [ 'Datacenter', undef, 'DC' ] ]

EXAMPLE

The following code illustrates a full example:

    my @items = (
        {   ContainerId => '632495650e4e',
            Image       => 'alpine:latest',
            Created     => { unit => 'days', amount => 5 },
            ExitedAt    => { unit => 'days', amount => 5 },
            Name        => '/zealous_galileo',
        },
        {   ContainerId => '6459c004a7b4',
            Image       => 'postgres:9.6.1-alpine',
            Created     => { unit => 'days', amount => 23 },
            StartedAt   => { unit => 'days', amount => 23 },
            Running     => true,
            Name        => '/hardcore_sammet',
        },
        {   ContainerId => '63a4c1b60c9f',
            Image       => 'f348af3681e0',
            Created     => { unit => 'weeks', amount => 2 },
            ExitedAt    => { unit => 'days', amount => 12 },
            Name        => '/elastic_ride',
        },
    );

    sub status_of {
        my ( $running, $item ) = ( shift, shift );
        $running
          ? "Up $item->{StartedAt}{amount} $item->{StartedAt}{unit}"
          : "Exited $item->{ExitedAt}{amount} $item->{ExitedAt}{unit} ago";
    }

    my @spec = (
        'ContainerId',
        'Image',
        [ 'Created', sub {"$_[0]->{amount} $_[0]->{unit} ago"} ],
        [   'Running', \&status_of, 'STATUS' ],
        [ 'Name', sub { substr( shift, 1 ) } ],
    );

    render_table( \@items, \@spec );

The corresponding output is the table in "DESCRIPTION".

FUNCTIONS

Text::Yeti::Table implements the following functions, which can be imported individually.

render_table

    render_table( \@items, $spec );
    render_table( \@items, $spec, $io );

The $spec is an arrayref whose entries can be:

  • a string (like 'key'), which is equivalent to

        ['key']
  • an arrayref, with up to 3 entries

        ['key', $to_s, $header]

    $to_s is a function to convert the value under 'key' to text. By default, it stringifies the value, except for undef which becomes "<none>".

    $header is the header for the corresponding column. By default, it is computed from the key, as in the examples below:

        "image"       -> "IMAGE"
        "ContainerID" -> "CONTAINER ID"
  • a hashref, with keys

        k => 'key',       required
        s => $to_s,
        h => $header,
        x => $exclude,

    where

    $to_s is a function to convert the value under k to text. By default, undef becomes '<none>', and everything else is stringfied.

    $header is the header for the corresponding column. If not given, it is computed from the key as above.

    $exclude is a coderef which given all the values of a column (as an arrayref) should return true if the column should be excluded or false if the column is to be kept. As an example,

        use List::Util 'all';
        (x => sub { all { $_ eq '<none>' } @{$_[0]} })

    will exclude the corresponding column if all values collapse to '<none>'.

The $io is a handle. By default, output goes to STDOUT.

AUTHOR

Adriano Ferreira <ferreira@cpan.org>

CONTRIBUTOR

Adriano Ferreira <a.r.ferreira@gmail.com>

COPYRIGHT AND LICENSE

This software is copyright (c) 2017-2018 by Adriano Ferreira.

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