CPAN-Info-FromURL

 view release on metacpan or  search on metacpan

lib/CPAN/Info/FromURL.pm  view on Meta::CPAN

package CPAN::Info::FromURL;

our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
our $DATE = '2020-10-02'; # DATE
our $DIST = 'CPAN-Info-FromURL'; # DIST
our $VERSION = '0.092'; # VERSION

use 5.010001;
use strict;
use warnings;

use Exporter qw(import);
our @EXPORT_OK = qw(extract_cpan_info_from_url);

our %SPEC;

our $re_proto_http = qr!(?:https?://)!i;
our $re_author   = qr/(?:\w+)/;
our $re_dist     = qr/(?:\w+(?:-\w+)*)/;
our $re_mod      = qr/(?:\w+(?:::\w+)*)/;
our $re_version  = qr/(?:v?[0-9]+(?:\.[0-9]+)*(?:_[0-9]+|-TRIAL)?)/;
our $re_end_or_q = qr/(?:[?&#]|\z)/;

sub _normalize_mod {
    my $mod = shift;
    $mod =~ s/'/::/g;
    $mod;
}

$SPEC{extract_cpan_info_from_url} = {
    v => 1.1,
    summary => 'Extract/guess information from a URL',
    description => <<'_',

Return a hash of information from a CPAN-related URL. Possible keys include:
`site` (site nickname, include: `mcpan` [metacpan.org, api.metacpan.org,
fastapi.metacpan.org], `sco` [search.cpan.org], `cpanratings`
[cpanratings.perl.org], `rt` ([rt.cpan.org]), `cpan` [any normal CPAN mirror]),
`author` (CPAN author ID), `module` (module name), `dist` (distribution name),
`version` (distribution version). Some keys might not exist, depending on what
information the URL provides. Return undef if URL is not detected to be of some
CPAN-related URL.

_
    args => {
        url => {
            schema => 'str*',
            req => 1,
            pos => 0,
        },
    },
    args_as => 'array',
    result => {
        schema => 'hash',
    },
    result_naked => 1,
    examples => [

        {
            name => "mcpan/pod/MOD",
            args => {url=>'https://metacpan.org/pod/Foo::Bar'},
            result => {site=>'mcpan', module=>'Foo::Bar'},
        },
        {
            name => "mcpan/module/MOD",
            args => {url=>'metacpan.org/module/Foo?'},
            result => {site=>'mcpan', module=>'Foo'},
        },
        {
            name => "mcpan/pod/release/AUTHOR/DIST-VERSION/lib/MOD.pm",
            args => {url=>'http://metacpan.org/pod/release/SRI/Mojolicious-6.46/lib/Mojo.pm'},
            result => {site=>'mcpan', author=>'SRI', dist=>'Mojolicious', version=>'6.46', module=>'Mojo'},
        },
        {
            name => "mcpan/pod/release/AUTHOR/DIST-VERSION/bin/SCRIPT",
            args => {url=>'http://metacpan.org/pod/release/PERLANCAR/App-PMUtils-1.23/bin/pmpath'},
            result => {site=>'mcpan', author=>'PERLANCAR', dist=>'App-PMUtils', version=>'1.23', script=>'pmpath'},
        },
        {
            name => "mcpan/source/AUTHOR/DIST-VERSION/lib/MOD.pm",
            args => {url=>'http://metacpan.org/source/SRI/Mojolicious-6.46/lib/Mojo.pm?'},
            result => {site=>'mcpan', author=>'SRI', dist=>'Mojolicious', version=>'6.46', module=>'Mojo'},
        },
        {
            name => "api.mcpan/source/AUTHOR/DIST-VERSION",
            args => {url=>'http://api.metacpan.org/source/SRI/Mojolicious-6.46?'},
            result => {site=>'mcpan', author=>'SRI', dist=>'Mojolicious', version=>'6.46'},
        },
        {
            name => "fastapi.mcpan/v1/module/MODULE",
            args => {url=>'http://fastapi.metacpan.org/v1/module/Moose'},
            result => {site=>'mcpan', module=>'Moose'},

lib/CPAN/Info/FromURL.pm  view on Meta::CPAN

        $res->{site} = 'cpanratings';
        if ($url =~ m!\Adist/
                     ($re_dist)/?
                     $re_end_or_q!x) {
            $res->{dist} = $1;
        }

    } elsif ($url =~ s!\A$re_proto_http?perldoc\.perl\.org/?!!i) {

        $res->{site} = 'perldoc.perl.org';
        if ($url =~ m!^(\w+(?:/\w+)*)\.html!) {
            my $mod = $1;
            $mod =~ s!/!::!g;
            $res->{module} = $mod;
        }

    } elsif ($url =~ s!\A$re_proto_http?rt\.cpan\.org/?!!i) {

        $res->{site} = 'rt';
        if ($url =~ m!\A(?:Public/)?Dist/Display\.html!) {
            if ($url =~ m![?&#](?:Queue|Name)=(.+?)(?:&|#|\z)!) {
                require URI::Escape;
                $res->{dist} = URI::Escape::uri_unescape($1);
            }
        }

    } elsif ($url =~ s!\A$re_proto_http?mojolicious\.org/?!!i) {

        $res->{site} = 'mojo';
        if ($url =~ m!\Aperldoc/([^?&#]+)!) {
            my $mod = $1;
            $mod =~ s!/!::!g;
            $res->{module} = $mod;
        }

    } elsif ($url =~ m!\A(?:$re_proto_http|\w+\@|git://)?(gitlab|github)\.com[:/]([A-Za-z0-9_-]+)/([A-Za-z0-9_-]+)(\.git|\z|/)!i) {
        $res->{site} = $1;
        $res->{github_user} = $2;
        $res->{github_repo} = $3;
        require CPAN::Dist::FromRepoName;
        my $dist = CPAN::Dist::FromRepoName::extract_cpan_dist_from_repo_name($3);
        $res->{dist} = $dist if defined $dist;
    } elsif ($url =~ m!/authors/id/(\w)/\1(\w)/(\1\2\w+)
                       (?:/
                           (?:[^/]+/)* # subdir
                           (($re_dist)-($re_version)\.(?:tar\.\w+|tar|zip|tgz|tbz|tbz2))
                       )?
                       $re_end_or_q!ix) {
        $res->{site} = 'cpan';
        $res->{author} = $3;
        if (defined $4) {
            $res->{release} = $4;
            $res->{dist} = $5;
            $res->{version} = $6;
        }
    }
    $res;
}

1;
# ABSTRACT: Extract/guess information from a URL

__END__

=pod

=encoding UTF-8

=head1 NAME

CPAN::Info::FromURL - Extract/guess information from a URL

=head1 VERSION

This document describes version 0.092 of CPAN::Info::FromURL (from Perl distribution CPAN-Info-FromURL), released on 2020-10-02.

=head1 FUNCTIONS


=head2 extract_cpan_info_from_url

Usage:

 extract_cpan_info_from_url($url) -> hash

ExtractE<sol>guess information from a URL.

Examples:

=over

=item * Example #1 (mcpanE<sol>podE<sol>MOD):

 extract_cpan_info_from_url("https://metacpan.org/pod/Foo::Bar"); # -> { module => "Foo::Bar", site => "mcpan" }

=item * Example #2 (mcpanE<sol>moduleE<sol>MOD):

 extract_cpan_info_from_url("metacpan.org/module/Foo?"); # -> { module => "Foo", site => "mcpan" }

=item * Example #3 (mcpanE<sol>podE<sol>releaseE<sol>AUTHORE<sol>DIST-VERSIONE<sol>libE<sol>MOD.pm):

 extract_cpan_info_from_url("http://metacpan.org/pod/release/SRI/Mojolicious-6.46/lib/Mojo.pm");

Result:

 {
   author  => "SRI",
   dist    => "Mojolicious",
   module  => "Mojo",
   site    => "mcpan",
   version => 6.46,
 }

=item * Example #4 (mcpanE<sol>podE<sol>releaseE<sol>AUTHORE<sol>DIST-VERSIONE<sol>binE<sol>SCRIPT):

 extract_cpan_info_from_url("http://metacpan.org/pod/release/PERLANCAR/App-PMUtils-1.23/bin/pmpath");

Result:

 {
   author  => "PERLANCAR",
   dist    => "App-PMUtils",
   script  => "pmpath",
   site    => "mcpan",
   version => 1.23,
 }

=item * Example #5 (mcpanE<sol>sourceE<sol>AUTHORE<sol>DIST-VERSIONE<sol>libE<sol>MOD.pm):

 extract_cpan_info_from_url("http://metacpan.org/source/SRI/Mojolicious-6.46/lib/Mojo.pm?");

Result:

 {
   author  => "SRI",
   dist    => "Mojolicious",
   module  => "Mojo",
   site    => "mcpan",
   version => 6.46,
 }

=item * Example #6 (api.mcpanE<sol>sourceE<sol>AUTHORE<sol>DIST-VERSION):

 extract_cpan_info_from_url("http://api.metacpan.org/source/SRI/Mojolicious-6.46?");

Result:



( run in 0.553 second using v1.01-cache-2.11-cpan-5735350b133 )