App-ShellCheckWiki

 view release on metacpan or  search on metacpan

lib/App/ShellCheckWiki.pm  view on Meta::CPAN

package App::ShellCheckWiki;

use 5.006;
use strict;
use warnings;

use Term::ANSIColor;
use WWW::Mechanize;

our $VERSION = '0.03';

my $formats = {
    '# '   => 'bold green',   # H1
    '## '  => 'bold magenta', # H2
    '### ' => 'bold red',     # H3
    '```'  => 'yellow',       # Code Block
};

my $wiki_url = 'https://raw.githubusercontent.com/wiki/koalaman/shellcheck';
my $wiki_toc = 'https://github.com/koalaman/shellcheck/wiki';

my $mech = WWW::Mechanize->new( autocheck => 0 );

sub run {
    my $page = $ARGV[0];
    if (defined($page)) {
        my ($page_id) = $page =~ m|(\d+)$|;
        my $wiki_page = $wiki_url . '/SC' . $page_id . '.md';
        $mech->get($wiki_page);
        if ($mech->success) {
            print colored(['green'],"ShellCheck Error CS$page_id\n");
            format_page($mech->content());
        } else {
            print "Unable to find page '$page'!\n";
            show_topics();
        }
    } else {
        show_topics();
    }
    exit 0;
}

sub format_page {
    my ($content) = @_;
    my $indent  = 0;
    my $code_block = '```';
    my $code_block_format = $formats->{$code_block} || 'yellow';

    for my $line ( split /\n/, $content ) {
        my $matched = 0;
        for my $start ( sort keys %$formats ) {
            if ( my ($remainder) = starts_with( $line, $start ) ) {
                $matched = 1;
                my $format = $formats->{$start};
                if ( $start eq $code_block ) {
                    $indent = ( $indent + 1 ) % 2;
                    $code_block_format = $format;
                    print "\n";
                } else {
                    print $start;
                    print colored( [$format], $remainder )."\n";
                }
            }
        }

        # Regular Line or Code Block
        if ( not $matched ) {
            if ($indent) {
                # Code Block
                print colored( [$code_block_format], "    $line\n" );
            } else {
                # Regular Line
                print $line . "\n";
            }
        }
    }
    print "\n";
}

sub starts_with {
    my ($line, $format) = @_;
    return unless length($line) >= length($format);
    my $start = substr($line,0,length($format),'');
    return unless $start eq $format;
    return $line;
}

sub show_topics {
    print colored(['bold magenta'], "Checking for Available Topics: ");
    print colored(['green'], "SCxxxx\n");
    $mech->get($wiki_toc);
    my $topics = {};
    if ($mech->success()) {
        for my $link ($mech->links()) {
            next unless $link->url =~ m|SC(\d+)|;
            $topics->{$1}++;
        }
        my @ranges = number_range( keys %$topics );
        for my $range (@ranges) {
            print colored(['cyan'], $range . "\n");
        }
    } else {
        print "FAIL!";
    }
}

sub number_range {
    my (@numbers) = sort { $a <=> $b } @_;
    my @ranges;
    my $start = shift @numbers;
    my $stop = $start;
    while(scalar @numbers) {
        my $next = shift @numbers;
        if ( $next == $stop + 1 ) {
            $stop = $next;
        } else {
            if ($start == $stop) {
                push @ranges, $start;
            } else {
                push @ranges, $start . '-' . $stop;
            }
            $start = $stop = $next;
        }
    }

    # Group by Leading digits;
    my $groups;
    for my $range (@ranges) {
        my $leading = substr($range,0,2);
        push @{ $groups->{$leading} }, $range;
    }
    my @output_ranges;
    for my $leading ( sort keys %$groups ) {
        push @output_ranges, join(',', sort @{ $groups->{$leading} });
    }

    return @output_ranges;
}

1; # End of App::ShellCheckWiki
__END__

=head1 NAME

App::ShellCheckWiki - Check the wiki for details about shellcheck errors.

=head1 VERSION

Version 0.03



( run in 0.683 second using v1.01-cache-2.11-cpan-d7f47b0818f )