]> Dogcows Code - chaz/git-codeowners/commitdiff
add projects command and filtering to show command
authorCharles McGarvey <chazmcgarvey@brokenzipper.com>
Wed, 13 Nov 2019 04:46:47 +0000 (21:46 -0700)
committerCharles McGarvey <chazmcgarvey@brokenzipper.com>
Wed, 13 Nov 2019 04:46:47 +0000 (21:46 -0700)
bin/git-codeowners
lib/App/Codeowners.pm
lib/App/Codeowners/Options.pm
lib/File/Codeowners.pm
t/app-codeowners.t

index 8da69763788b3afa7913053a9ec13e3a42bbdeb0..be0025bf27d5955ca913d3293a737f00928e9ca5 100755 (executable)
@@ -6,7 +6,9 @@
 
     git-codeowners [--version|--help|--manual]
 
-    git-codeowners [show] [--format FORMAT] [--[no-]project] [PATH...]
+    git-codeowners [show] [--format FORMAT] [--owner OWNER]...
+                   [--pattern PATTERN]... [--[no-]patterns]
+                   [--project PROJECT]... [--[no-]projects] [PATH...]
 
     git-codeowners owners [--format FORMAT] [--pattern PATTERN]
 
@@ -94,18 +96,33 @@ Does not yet support Zsh...
 
 =head2 show
 
-    git-codeowners [show] [--format FORMAT] [--[no-]project] [PATH...]
+    git-codeowners [show] [--format FORMAT] [--owner OWNER]...
+                   [--pattern PATTERN]... [--[no-]patterns]
+                   [--project PROJECT]... [--[no-]projects] [PATH...]
 
 Show owners of one or more files in a repo.
 
+If C<--owner>, C<--project>, C<--pattern> are set, only show files with matching
+criteria. These can be repeated.
+
+Use C<--patterns> to also show the matching pattern associated with each file.
+
+By default the output might show associated projects if the C<CODEOWNERS> file
+defines them. You can control this by explicitly using C<--projects> or
+C<--no-projects> to always show or always hide defined projects, respectively.
+
 =head2 owners
 
     git-codeowners owners [--format FORMAT] [--pattern PATTERN]
 
+List all owners defined in the F<CODEOWNERS> file.
+
 =head2 patterns
 
     git-codeowners patterns [--format FORMAT] [--owner OWNER]
 
+List all patterns defined in the F<CODEOWNERS> file.
+
 =head2 create
 
     git-codeowners create [REPO_DIRPATH|CODEOWNERS_FILEPATH]
index 20be9855fa51d7917a683fb6ce8c0321f7c6ff87..1dc97cc49dba3ead168ab5e4bd23e2865c0d0424 100644 (file)
@@ -54,19 +54,46 @@ sub _command_show {
     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 => [qw(File Owner), $opts->{project} ? 'Project' : ()],
+        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));
+        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},
-            $opts->{project} ? $match->{project} : (),
+            $show_projects ? $match->{project} : (),
         ]);
     }
     $proc->wait and exit 1;
@@ -112,6 +139,26 @@ sub _command_patterns {
     $formatter->add_result(map { [$_] } @$results);
 }
 
+sub _command_projects {
+    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 = File::Codeowners->parse_from_filepath($codeowners_path);
+
+    my $results = $codeowners->projects;
+
+    my $formatter = App::Codeowners::Formatter->new(
+        format  => $opts->{format} || '%P',
+        handle  => *STDOUT,
+        columns => [qw(Project)],
+    );
+    $formatter->add_result(map { [$_] } @$results);
+}
+
 sub _command_create { goto &_command_update }
 sub _command_update {
     my $self = shift;
index 67dc3243c7a5c08645386fc8568aad336241c612..7b43b75cc5e5d0272af568bbaea4979cbfb4755c 100644 (file)
@@ -30,8 +30,13 @@ sub command_options {
         'patterns'  => {
             'owner=s'   => '',
         },
+        'projects'  => {},
         'show'      => {
-            'project!'  => 1,
+            'owner=s@'      => [],
+            'pattern=s@'    => [],
+            'project=s@'    => [],
+            'patterns!'     => 0,
+            'projects!'     => undef,
         },
         'update'    => {},
     };
index fb3ec552c889bd6431be1ac7dd9d3c0c000f3fa3..648390e1ea45888ab1ffd60f904a66b9b9db0b84 100644 (file)
@@ -355,6 +355,31 @@ sub patterns {
     return $patterns;
 }
 
+=method projects
+
+    $projects = $codeowners->projects;
+
+Get an arrayref of all projects defined.
+
+=cut
+
+sub projects {
+    my $self  = shift;
+
+    return $self->{projects} if $self->{projects};
+
+    my %projects;
+    for my $line (@{$self->_lines}) {
+        my $project = $line->{project};
+        $projects{$project}++ if $project;
+    }
+
+    my $projects = [sort keys %projects];
+    $self->{projects} = $projects;
+
+    return $projects;
+}
+
 =method update_owners
 
     $codeowners->update_owners($pattern => \@new_owners);
@@ -497,6 +522,7 @@ sub _clear {
     delete $self->{match_lines};
     delete $self->{owners};
     delete $self->{patterns};
+    delete $self->{projects};
 }
 
 1;
index 64415394b69acb1e0b01d6ac004d90d789123fb4..28309d3861ca0b802cf938133128494302850377 100644 (file)
@@ -65,7 +65,7 @@ END
     subtest 'format json' => sub {
         plan skip_all => 'No JSON::MaybeXS' if !eval { require JSON::MaybeXS };
 
-        ($stdout, $stderr, $exit) = run { App::Codeowners->main(qw{-f json show --no-project}) };
+        ($stdout, $stderr, $exit) = run { App::Codeowners->main(qw{-f json show --no-projects}) };
         is($exit, 0, 'exited without error');
         my $expect = '[{"File":"CODEOWNERS","Owner":null},{"File":"a/b/c/bar.txt","Owner":["@snickers"]},{"File":"foo.txt","Owner":["@twix"]}]';
         is($stdout, $expect, 'correct output with json format');
This page took 0.028206 seconds and 4 git commands to generate.