The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

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

VERSION

version 0.1.9

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 are:

  • 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"

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 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.