App-Codeowners

 view release on metacpan or  search on metacpan

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

package App::Codeowners;
# ABSTRACT: A tool for managing CODEOWNERS files

use v5.10.1;    # defined-or
use utf8;
use warnings;
use strict;

use App::Codeowners::Formatter;
use App::Codeowners::Options;
use App::Codeowners::Util qw(find_codeowners_in_directory run_git git_ls_files git_toplevel);
use Color::ANSI::Util 0.03 qw(ansifg);
use File::Codeowners 0.54;
use Path::Tiny;

our $VERSION = '0.51'; # VERSION


sub main {
    my $class = shift;
    my $self  = bless {}, $class;

    my $opts = App::Codeowners::Options->new(@_);

    my $color = $opts->{color};
    local $ENV{NO_COLOR} = 1 if defined $color && !$color;

    my $command = $opts->command;
    my $handler = $self->can("_command_$command")
        or die "Unknown command: $command\n";

    binmode(STDOUT, ':encoding(UTF-8)');
    $self->$handler($opts);

    exit 0;
}

sub _command_show {
    my $self = shift;
    my $opts = shift;

    my $toplevel = git_toplevel('.') or die "Not a git repo\n";

    my $codeowners_path = find_codeowners_in_directory($toplevel)
        or die "No CODEOWNERS file in $toplevel\n";
    local $ENV{GIT_CODEOWNERS_ALIASES} = 1 if $opts->{expand_aliases};
    my $codeowners = $self->_parse_codeowners($codeowners_path);

    my ($proc, $cdup) = run_git(qw{rev-parse --show-cdup});
    $proc->wait and exit 1;

    my $show_projects = $opts->{projects} // scalar @{$codeowners->projects};

    my $formatter = App::Codeowners::Formatter->new(
        format  => $opts->{format} || ' * %-50F %O',
        handle  => *STDOUT,
        columns => [
            'File',
            $opts->{patterns} ? 'Pattern' : (),
            'Owner',
            $show_projects ? 'Project' : (),
        ],
    );

    my %filter_owners   = map { $_ => 1 } @{$opts->{owner}};
    my %filter_projects = map { $_ => 1 } @{$opts->{project}};
    my %filter_patterns = map { $_ => 1 } @{$opts->{pattern}};

    $proc = git_ls_files('.', $opts->args);
    while (my $filepath = $proc->next) {
        my $match = $codeowners->match(path($filepath)->relative($cdup),
            expand => $opts->{expand_aliases});
        if (%filter_owners) {
            for my $owner (@{$match->{owners}}) {
                goto ADD_RESULT if $filter_owners{$owner};
            }
            next;
        }
        if (%filter_patterns) {
            goto ADD_RESULT if $filter_patterns{$match->{pattern} || ''};
            next;
        }
        if (%filter_projects) {
            goto ADD_RESULT if $filter_projects{$match->{project} || ''};
            next;
        }
        ADD_RESULT:
        $formatter->add_result([
            $filepath,
            $opts->{patterns} ? $match->{pattern} : (),
            $match->{owners},
            $show_projects ? $match->{project} : (),
        ]);
    }
    $proc->wait and exit 1;
}

sub _command_owners {
    my $self = shift;
    my $opts = shift;

    my $toplevel = git_toplevel('.') or die "Not a git repo\n";

    my $codeowners_path = find_codeowners_in_directory($toplevel)
        or die "No CODEOWNERS file in $toplevel\n";
    my $codeowners = $self->_parse_codeowners($codeowners_path);

    my $results = $codeowners->owners($opts->{pattern});

    my $formatter = App::Codeowners::Formatter->new(
        format  => $opts->{format} || '%O',
        handle  => *STDOUT,
        columns => [qw(Owner)],
    );
    $formatter->add_result(map { [$_] } @$results);
}

sub _command_patterns {
    my $self = shift;
    my $opts = shift;

    my $toplevel = git_toplevel('.') or die "Not a git repo\n";

    my $codeowners_path = find_codeowners_in_directory($toplevel)
        or die "No CODEOWNERS file in $toplevel\n";
    my $codeowners = $self->_parse_codeowners($codeowners_path);

    my $results = $codeowners->patterns($opts->{owner});

    my $formatter = App::Codeowners::Formatter->new(
        format  => $opts->{format} || '%T',
        handle  => *STDOUT,



( run in 2.370 seconds using v1.01-cache-2.11-cpan-97f6503c9c8 )