1 package App
::Codeowners
::Util
;
2 # ABSTRACT: Grab bag of utility subs for Codeowners modules
8 use Exporter
qw(import);
9 use File
::Codeowners
::Util
;
14 find_codeowners_in_directory
15 find_nearest_codeowners
26 our $VERSION = '0.50'; # VERSION
29 sub find_nearest_codeowners
{ goto &File
::Codeowners
::Util
::find_nearest_codeowners
}
32 sub find_codeowners_in_directory
{ goto &File
::Codeowners
::Util
::find_codeowners_in_directory
}
35 sub run_command
{ goto &File
::Codeowners
::Util
::run_command
}
38 sub run_git
{ goto &File
::Codeowners
::Util
::run_git
}
41 sub git_ls_files
{ goto &File
::Codeowners
::Util
::git_ls_files
}
44 sub git_toplevel
{ goto &File
::Codeowners
::Util
::git_toplevel
}
48 my $str = shift || '';
49 $str =~ s/\e\[[\d;]*m//g;
56 return ref($item) eq 'ARRAY' ? join(',', @$item) : $item;
60 # The stringf code is from String::Format (thanks SREZIC), with changes:
61 # - Use Unicode::GCString for better Unicode character padding,
62 # - Strip ANSI color sequences,
63 # - Prevent 'Negative repeat count does nothing' warnings
65 my ($args, $orig, $alignment, $min_width,
66 $max_width, $passme, $formchar) = @_;
68 # For unknown escapes, return the orignial
69 return $orig unless defined $args->{$formchar};
71 $alignment = '+' unless defined $alignment;
73 my $replacement = $args->{$formchar};
74 if (ref $replacement eq 'CODE') {
75 # $passme gets passed to subrefs.
78 $replacement = $replacement->($passme);
82 if (eval { require Unicode
::GCString
}) {
83 my $gcstring = Unicode
::GCString-
>new(colorstrip
($replacement));
84 $replength = $gcstring->columns;
87 $replength = length colorstrip
($replacement);
90 $min_width ||= $replength;
91 $max_width ||= $replength;
93 # length of replacement is between min and max
94 if (($replength > $min_width) && ($replength < $max_width)) {
98 # length of replacement is longer than max; truncate
99 if ($replength > $max_width) {
100 return substr($replacement, 0, $max_width);
103 my $padding = $min_width - $replength;
104 $padding = 0 if $padding < 0;
106 # length of replacement is less than min: pad
107 if ($alignment eq '-') {
108 # left align; pad in front
109 return $replacement . ' ' x
$padding;
112 # right align, pad at end
113 return ' ' x
$padding . $replacement;
117 (-)? # left-align, rather than right
118 (\d
*)? # (optional) minimum field width
119 (?:\
.(\d
*))? # (optional) maximum field width
120 (\
{.*?\
})? # (optional) stuff inside
121 (\S
) # actual format character
124 my $format = shift || return;
125 my $args = UNIVERSAL
::isa
($_[0], 'HASH') ? shift : { @_ };
126 $args->{'n'} = "\n" unless exists $args->{'n'};
127 $args->{'t'} = "\t" unless exists $args->{'t'};
128 $args->{'%'} = "%" unless exists $args->{'%'};
130 $format =~ s/$regex/_replace($args, $1, $2, $3, $4, $5, $6)/ge;
136 # The unbacklash code is from String::Escape (thanks EVO), with changes:
137 # - Handle \a, \b, \f and \v (thanks Berk Akinci)
141 # Earlier definitions are preferred to later ones, thus we output \n not \x0d
143 ( map { $_ => $_ } ( '\\', '"', '$', '@' ) ),
144 ( 'r' => "\r", 'n' => "\n", 't' => "\t" ),
145 ( map { 'x' . unpack('H2', chr($_)) => chr($_) } (0..255) ),
146 ( map { sprintf('%03o', $_) => chr($_) } (0..255) ),
147 ( 'a' => "\x07", 'b' => "\x08", 'f' => "\x0c", 'v' => "\x0b" ),
149 $str =~ s/ (\A|\G|[^\\]) \\ ( [0-7]{3} | x[\da-fA-F]{2} | . ) / $1 . $unbackslash{lc($2)} /gsxe;
154 # The zip code is from List::SomeUtils (thanks DROLSKY), copied just so as not
155 # to bring in the extra dependency.
156 sub zip
(\
@\
@) { ## no critic (Subroutines::ProhibitSubroutinePrototypes)
158 $max < $#$_ && ( $max = $#$_ ) foreach @_;
175 App::Codeowners::Util - Grab bag of utility subs for Codeowners modules
183 B<DO NOT USE> except in L<App::Codeowners> and related modules.
187 =head2 find_nearest_codeowners
191 Use L<File::Codeowners::Util/find_nearest_codeowners> instead.
193 =head2 find_codeowners_in_directory
197 Use L<File::Codeowners::Util/find_codeowners_in_directory> instead.
203 Use L<File::Codeowners::Util/run_command> instead.
209 Use L<File::Codeowners::Util/run_git> instead.
215 Use L<File::Codeowners::Util/git_ls_files> instead.
221 Use L<File::Codeowners::Util/git_toplevel> instead.
225 $str = colorstrip($str);
227 Strip ANSI color control commands.
231 $str = stringify($scalar);
232 $str = stringify(\@array);
234 Get a useful string representation of a scallar or arrayref.
244 Use L<File::Codeowners::Util/unbackslash> instead.
248 Same as L<List::SomeUtils/zip-ARRAY1-ARRAY2-[-ARRAY3-...-]>.
252 Please report any bugs or feature requests on the bugtracker website
253 L<https://github.com/chazmcgarvey/git-codeowners/issues>
255 When submitting a bug or request, please include a test-file or a
256 patch to an existing test-file that illustrates the bug or desired
261 Charles McGarvey <chazmcgarvey@brokenzipper.com>
263 =head1 COPYRIGHT AND LICENSE
265 This software is copyright (c) 2021 by Charles McGarvey.
267 This is free software; you can redistribute it and/or modify it under
268 the same terms as the Perl 5 programming language system itself.