App-cpangrep
view release on metacpan or search on metacpan
lib/App/cpangrep.pm view on Meta::CPAN
my $search = search($query)
or return 2;
if ($list) {
display_list($search);
} else {
display($search);
}
return 0;
}
return 0;
}
sub help {
return <<' USAGE';
usage: cpangrep [--debug] <query>
The query is a Perl regular expression without look-ahead/look-behind.
Several operators are supported as well for advanced use.
See <http://grep.cpan.me/about#re> for more information.
Multiple query arguments will be joined with spaces for convenience.
-l List only matching filenames. Note that omitted results are
not mentioned, but your pattern is likely to match many more
files than output.
--color Enable colored output even if STDOUT isn't a terminal
--no-color Disable colored output
--no-pager Disable output through a pager
--server Specifies an alternate server to use, for example:
--server http://localhost:5000
--debug Print debug messages to stderr
--help Show this help and exit
--version Show version
USAGE
}
sub search_url { "$SERVER/?q=" . uri_escape(shift) }
sub search_api_url { "$SERVER/api?q=" . uri_escape(shift) }
sub search {
my $query = shift;
my $ua = LWP::UserAgent->new(
agent => "cpangrep/$VERSION",
);
$ua->env_proxy;
my $response = $ua->get( search_api_url($query) );
if (not $response->is_success) {
warn "Request failed: ", $response->status_line, "\n";
return;
}
my $content = $response->decoded_content;
debug("Successfully received " . length($content) . " bytes");
my $result = eval { decode_json($content) };
if ($@ or not $result) {
warn "Error decoding JSON response: $@\n";
debug($content);
return;
}
return $result;
}
sub display {
my $search = shift or return;
my $results = $search->{results} || [];
printf "%d result%s in %d file%s.",
$search->{count}, ($search->{count} != 1 ? "s" : ""),
scalar @$results, (@$results != 1 ? "s" : "");
my $display_total = sum map { scalar @{$_->{results}} }
map { @{$_->{files}} }
@$results;
printf " Showing first %d results.", $display_total
if $display_total and $display_total != $search->{count};
print "\n\n";
for my $result (@$results) {
my $fulldist = $result->{dist};
$fulldist =~ s{^(?=(([A-Z])[A-Z]))}{$2/$1/};
my $dist = CPAN::DistnameInfo->new($fulldist);
for my $file (@{$result->{files}}) {
print colored(["GREEN"], join("/", $dist->cpanid, $dist->distvname, $file->{file})), "\n";
for my $match (@{$file->{results}}) {
my $snippet = $match->{text};
my ($start, $len) = @{$match->{match}};
$len -= $start;
# XXX TODO: Track down the grep.cpan.me api bug that causes
# this. An example that fails for me today:
#
# cpangrep dist:App-Prefix file:Changes '^\s*\[.+?\]\s*$'
#
# -trs, 29 Jan 2014
if (length $snippet < $start + $len) {
warn colored("API returned an out of bounds match; skipping! (use --debug to see details)", "RED"),
color("reset"), "\n";
if ($DEBUG) {
require Data::Dumper;
debug("snippet: «$snippet» (length ", length $snippet, ")");
debug("reported match starts at «$start», length «$len» (ends at «@{[$start+$len]}»)");
debug("raw match response: ", Data::Dumper::Dumper($match));
}
next;
}
substr($snippet, $start, $len) = colored(substr($snippet, $start, $len), "BOLD RED");
if ($match->{line}) {
( run in 0.496 second using v1.01-cache-2.11-cpan-600a1bdf6e4 )