X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fgit-codeowners;a=blobdiff_plain;f=lib%2FFile%2FCodeowners.pm;h=9238a29a2939084390c3567eeadbda2480687839;hp=fb3ec552c889bd6431be1ac7dd9d3c0c000f3fa3;hb=39c158d76aefae4be3ff0c92e3977402c691323d;hpb=67e86f990f2556f12465052911eb7b96a03b8dcc diff --git a/lib/File/Codeowners.pm b/lib/File/Codeowners.pm index fb3ec55..9238a29 100644 --- a/lib/File/Codeowners.pm +++ b/lib/File/Codeowners.pm @@ -6,7 +6,7 @@ use warnings; use strict; use Encode qw(encode); -use Path::Tiny; +use Path::Tiny 0.089; use Scalar::Util qw(openhandle); use Text::Gitignore qw(build_gitignore_matcher); @@ -98,11 +98,13 @@ sub parse_from_fh { } elsif ($line =~ /^\h*#(.*)/) { my $comment = $1; + my $project; if ($comment =~ /^\h*Project:\h*(.+?)\h*$/i) { - $current_project = $1 || undef; + $project = $current_project = $1 || undef; } $lines[$lineno] = { comment => $comment, + $project ? (project => $project) : (), }; } elsif ($line =~ /^\h*$/) { @@ -190,7 +192,7 @@ sub write_to_filepath { my $self = shift; my $path = shift or _usage(q{$codeowners->write_to_filepath($filepath)}); - path($path)->spew_utf8([map { "$_\n" } @{$self->write_to_array('')}]); + path($path)->spew_utf8([map { "$_\n" } @{$self->write_to_array}]); } =method write_to_fh @@ -202,10 +204,11 @@ Format the file contents and write to a filehandle. =cut sub write_to_fh { - my $self = shift; - my $fh = shift or _usage(q{$codeowners->write_to_fh($fh)}); + my $self = shift; + my $fh = shift or _usage(q{$codeowners->write_to_fh($fh)}); + my $charset = shift; - for my $line (@{$self->write_to_array}) { + for my $line (@{$self->write_to_array($charset)}) { print $fh "$line\n"; } } @@ -219,9 +222,10 @@ Format the file contents and return a reference to a formatted string. =cut sub write_to_string { - my $self = shift; + my $self = shift; + my $charset = shift; - my $str = join("\n", @{$self->write_to_array}) . "\n"; + my $str = join("\n", @{$self->write_to_array($charset)}) . "\n"; return \$str; } @@ -235,7 +239,7 @@ Format the file contents as an arrayref of lines. sub write_to_array { my $self = shift; - my $charset = shift // 'UTF-8'; + my $charset = shift; my @format; @@ -261,7 +265,7 @@ sub write_to_array { } } - if ($charset) { + if (defined $charset) { $_ = encode($charset, $_) for @format; } return \@format; @@ -355,6 +359,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); @@ -376,11 +405,110 @@ sub update_owners { $self->_clear; + my $count = 0; + for my $line (@{$self->_lines}) { next if !$line->{pattern}; next if $pattern ne $line->{pattern}; $line->{owners} = [@$owners]; + ++$count; } + + return $count; +} + +=method update_owners_by_project + + $codeowners->update_owners_by_project($project => \@new_owners); + +Set a new set of owners for all patterns under the given project. + +Nothing happens if the file does not have a project with the given name. + +=cut + +sub update_owners_by_project { + my $self = shift; + my $project = shift; + my $owners = shift; + $project && $owners or _usage(q{$codeowners->update_owners_by_project($project => \@owners)}); + + $owners = [$owners] if ref($owners) ne 'ARRAY'; + + $self->_clear; + + my $count = 0; + + for my $line (@{$self->_lines}) { + next if !$line->{project} || !$line->{owners}; + next if $project ne $line->{project}; + $line->{owners} = [@$owners]; + ++$count; + } + + return $count; +} + +=method rename_owner + + $codeowners->rename_owner($old_name => $new_name); + +Rename an owner. + +Nothing happens if the file does not have an owner with the old name. + +=cut + +sub rename_owner { + my $self = shift; + my $old_owner = shift; + my $new_owner = shift; + $old_owner && $new_owner or _usage(q{$codeowners->rename_owner($owner => $new_owner)}); + + $self->_clear; + + my $count = 0; + + for my $line (@{$self->_lines}) { + next if !exists $line->{owners}; + for (my $i = 0; $i < @{$line->{owners}}; ++$i) { + next if $line->{owners}[$i] ne $old_owner; + $line->{owners}[$i] = $new_owner; + ++$count; + } + } + + return $count; +} + +=method rename_project + + $codeowners->rename_project($old_name => $new_name); + +Rename a project. + +Nothing happens if the file does not have a project with the old name. + +=cut + +sub rename_project { + my $self = shift; + my $old_project = shift; + my $new_project = shift; + $old_project && $new_project or _usage(q{$codeowners->rename_project($project => $new_project)}); + + $self->_clear; + + my $count = 0; + + for my $line (@{$self->_lines}) { + next if !exists $line->{project} || $old_project ne $line->{project}; + $line->{project} = $new_project; + $line->{comment} = " Project: $new_project" if exists $line->{comment}; + ++$count; + } + + return $count; } =method append @@ -497,6 +625,7 @@ sub _clear { delete $self->{match_lines}; delete $self->{owners}; delete $self->{patterns}; + delete $self->{projects}; } 1;