diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 000000000..9a883d851 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,38 @@ +--- +# Use the latest 2.1 version of CircleCI pipeline process engine. See: +# https://circleci.com/docs/2.0/configuration-reference +version: 2.1 +orbs: + codecov: codecov/codecov@4.1.0 +# Orchestrate or schedule a set of jobs +workflows: + docker-compose: + jobs: + - build-and-test +jobs: + build-and-test: + machine: true + resource_class: large + steps: + - run: + name: docker compose version + command: docker compose version + - checkout + - run: + name: create coverage directory + command: | + mkdir cover_db + chmod o+w cover_db + - run: + name: docker compose build + command: | + docker compose --profile test build api-test + - run: + name: run tests with coverage + command: | + docker compose --profile test run --env HARNESS_PERL_SWITCHES=-MDevel::Cover -v ./cover_db:/app/cover_db/ api-test bash -c 'prove -lr -j4 t && cover -report codecovbash' + # We are relying on environment variables from the host to be available when + # we publish the report, so we publish from the host rather than trying + # to propagate env variables to the container. + - codecov/upload: + file: cover_db/codecov.json diff --git a/.editorconfig b/.editorconfig index 112ded780..7ff72b0cc 100644 --- a/.editorconfig +++ b/.editorconfig @@ -17,5 +17,6 @@ charset = utf-8 #trim_trailing_whitespace = true insert_final_newline = true -[.travis.yml] +# yaml indents are weird +[*.{yml,yaml}] indent_size = 2 diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..675a53345 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,8 @@ +--- +version: 2 +updates: + - package-ecosystem: 'github-actions' + directory: '/' + schedule: + # Check for updates to GitHub Actions every week + interval: 'weekly' diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml new file mode 100644 index 000000000..a9b56fc7e --- /dev/null +++ b/.github/workflows/automerge.yml @@ -0,0 +1,22 @@ +name: Enable Auto-Merge For bots +on: + pull_request_target: + types: [opened] + +jobs: + enable-auto-merge: + runs-on: ubuntu-latest + if: > + github.event.pull_request.user.login == 'metacpan-automation[bot]' + || github.event.pull_request.user.login == 'dependabot[bot]' + steps: + - name: Generate Auth Token + uses: actions/create-github-app-token@v2 + id: app-token + with: + app-id: ${{ secrets.APP_ID }} + private-key: ${{ secrets.APP_PRIVATE_KEY }} + - uses: peter-evans/enable-pull-request-automerge@v3 + with: + token: ${{ steps.app-token.outputs.token }} + pull-request-number: ${{ github.event.pull_request.number }} diff --git a/.github/workflows/build-container.yml b/.github/workflows/build-container.yml new file mode 100644 index 000000000..00d325bee --- /dev/null +++ b/.github/workflows/build-container.yml @@ -0,0 +1,44 @@ +name: Build container +on: + push: + branches: + - master + - staging + - prod + pull_request: + types: [opened, synchronize, labeled] + branches: + - master + workflow_dispatch: +jobs: + docker-build: + if: github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'build-container') + runs-on: ubuntu-22.04 + name: Docker Build and Push + steps: + - name: Generate Auth Token + uses: actions/create-github-app-token@v2 + id: app-token + with: + app-id: ${{ secrets.APP_ID }} + private-key: ${{ secrets.APP_PRIVATE_KEY }} + owner: metacpan + - uses: actions/checkout@v5 + with: + token: ${{ steps.app-token.outputs.token }} + - uses: metacpan/metacpan-actions/docker-build-push@master + id: build-push + with: + docker_hub_username: ${{ secrets.DOCKER_HUB_USER }} + docker_hub_password: ${{ secrets.DOCKER_HUB_TOKEN }} + ghcr_username: ${{ github.repository_owner }} + ghcr_password: ${{ secrets.GITHUB_TOKEN }} + - name: Update deployed image + if: ${{ fromJSON(steps.build-push.outputs.tag-fq).latest }} + uses: metacpan/metacpan-actions/update-deployed-tag@master + with: + token: ${{ steps.app-token.outputs.token }} + app: api + environment: prod + base-tag: ${{ fromJSON(steps.build-push.outputs.tag-fq).latest }} + tag: ${{ fromJSON(steps.build-push.outputs.tag-fq).sha }} diff --git a/.github/workflows/code-formatting.yml b/.github/workflows/code-formatting.yml new file mode 100644 index 000000000..b833d372c --- /dev/null +++ b/.github/workflows/code-formatting.yml @@ -0,0 +1,49 @@ +--- +name: Code Formatting +on: + push: + branches: + - 'master' + merge_group: + pull_request: + branches: + - '*' + workflow_dispatch: + +jobs: + code-formatting: + runs-on: ubuntu-24.04 + name: Code Formatting + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - name: Fetch base ref + if: ${{ github.event.pull_request }} + run: git fetch origin ${{ github.base_ref }}:upstream + - name: Install Carton + uses: perl-actions/install-with-cpm@v1 + with: + install: Carton + - name: Install CPAN deps + uses: perl-actions/install-with-cpm@v1 + with: + cpanfile: 'cpanfile' + args: > + --resolver=snapshot + --with-develop + - name: Install precious + run: ./bin/install-precious /usr/local/bin + env: + GITHUB_TOKEN: ${{ github.token }} + - run: perltidy --version + - name: Select files + id: select-files + run: | + if [[ -n "${{ github.event.pull_request.number }}" ]]; then + echo 'precious-args=--git-diff-from upstream' >> "$GITHUB_OUTPUT" + else + echo 'precious-args=--all' >> "$GITHUB_OUTPUT" + fi + - name: Lint files + run: precious lint ${{ steps.select-files.outputs.precious-args }} diff --git a/.github/workflows/update-snapshot.yml b/.github/workflows/update-snapshot.yml new file mode 100644 index 000000000..816301081 --- /dev/null +++ b/.github/workflows/update-snapshot.yml @@ -0,0 +1,35 @@ +name: Update cpanfile.snapshot +on: + schedule: + - cron: "1 15 * * 0" + workflow_dispatch: +jobs: + update-dep: + runs-on: "ubuntu-22.04" + container: + image: perl:5.22-buster + steps: + - name: Generate Auth Token + uses: actions/create-github-app-token@v2 + id: app-token + with: + app-id: ${{ secrets.APP_ID }} + private-key: ${{ secrets.APP_PRIVATE_KEY }} + - uses: haarg/setup-git-user@v1 + with: + app: ${{ steps.app-token.output.app-slug }} + - uses: actions/checkout@v5 + with: + token: ${{ steps.app-token.outputs.token }} + - name: Update cpanfile.snapshot + uses: metacpan/metacpan-actions/update-snapshot@master + - name: Create Pull Request + uses: peter-evans/create-pull-request@v7 + with: + token: ${{ steps.app-token.outputs.token }} + commit-message: Update cpanfile.snapshot + title: Update cpanfile.snapshot + sign-commits: true + body: | + [GitHub Action Run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) + branch: update-cpanfile-snapshot diff --git a/.gitignore b/.gitignore index fc940f289..cd6e79b24 100644 --- a/.gitignore +++ b/.gitignore @@ -1,25 +1,25 @@ -# carton/local::lib -# coverage -# generated by Makefile.PL (for instance when doing `cpanm --installdeps .`) -# tidyall -*.komodoproject -*.kpf -*.sqlite* -*.sw* -.DS_Store -.tidyall.d /MYMETA.* /Makefile /Makefile.old /blib -/etc/metacpan_local.pl +/cover_db/ +/local/ +/log4perl_local.conf +/metacpan_server_local.* +/metacpan_server_testing_local.* +/perltidy.LOG /pm_to_blib +/var +/bin/omegasort +/bin/precious +/bin/ubi +/etc/metacpan_local.pl /t/var/darkpan/ /t/var/log/ /t/var/tmp/ -/var -cover_db/ -local/ -log4perl_local.conf -metacpan_server_local.conf -perltidy.LOG +*.komodoproject +*.kpf +*.sqlite* +*.sw* +.DS_Store +.tidyall.d diff --git a/.mailmap b/.mailmap index f28c7504c..8c9325def 100644 --- a/.mailmap +++ b/.mailmap @@ -2,30 +2,43 @@ Amrita Mathew Andreas Marienborg +Andreea Pirvulescu +Andreea Pirvulescu Andrew Fresh Andrew Fresh Barry Walsh Brad Lhotsky Chris Nehren +Christopher White +Christopher White +Christopher White Clinton Gormley +Ed J Gabor Szabo Grant McLean Grant McLean J. Bobby Lopez +Jess Robinson Joel Berger Johannes Plunien +Mario Zieschang Mark Fowler Matthew Horsfall (alh) Michael Peters Michael Peters Michiel Beijen +Mickey Nasriachi +Mickey Nasriachi Mickey Nasriachi Moritz Onken +Nicolas R Olaf Alders Olaf Alders +Olaf Alders Randy Stauner Renee Baecker Shawn M Moore +Shawn Sorichetti Sunny Patel Sunny Patel Talina Shrotriya @@ -35,5 +48,6 @@ Thomas Sibley Tim Bunce Vyacheslav Matyukhin Zachary Dykstra +lnation oiami oiami diff --git a/.perlcriticrc b/.perlcriticrc index 6e80016cd..578566da8 100644 --- a/.perlcriticrc +++ b/.perlcriticrc @@ -5,17 +5,20 @@ verbose = 11 theme = core [-ControlStructures::ProhibitPostfixControls] -[-Documentation::RequirePodLinksIncludeText] [-Documentation::RequirePodSections] +[-InputOutput::ProhibitInteractiveTest] [-Modules::RequireVersionVar] [-RegularExpressions::RequireDotMatchAnything] [-RegularExpressions::RequireExtendedFormatting] [-RegularExpressions::RequireLineBoundaryMatching] [-Subroutines::ProhibitExplicitReturnUndef] +[-TestingAndDebugging::ProhibitNoStrict] [-ValuesAndExpressions::ProhibitNoisyQuotes] -[-ValuesAndExpressions::ProhibitAccessOfPrivateData] [-Variables::ProhibitPunctuationVars] +# doesn't understand signatures +[-Subroutines::ProhibitSubroutinePrototypes] + [CodeLayout::RequireTrailingCommas] severity = 4 diff --git a/.perltidyrc b/.perltidyrc index 961585943..ab8fed578 100644 --- a/.perltidyrc +++ b/.perltidyrc @@ -1,6 +1,17 @@ --pbp --nst - +--maximum-line-length=78 +--indent-columns=4 +--continuation-indentation=4 +--standard-error-output +--vertical-tightness=2 +--closing-token-indentation=0 +--paren-tightness=1 +--brace-tightness=1 +--square-bracket-tightness=1 +--block-brace-tightness=1 +--nospace-for-semicolon +--nooutdent-long-quotes +--want-break-before="% + - * / x != == >= <= =~ !~ < > | & = **= += *= &= <<= &&= -= /= |= >>= ||= //= .= %= ^= x=" # Break a line after opening/before closing token. --vt=0 --vtc=0 +--vertical-tightness=0 +--vertical-tightness-closing=0 +--weld-nested-containers diff --git a/.tidyallrc b/.tidyallrc deleted file mode 100644 index 32ce372e6..000000000 --- a/.tidyallrc +++ /dev/null @@ -1,65 +0,0 @@ -[PerlTidy] -select = {lib,t}/**/*.{pl,pm,t,psgi} -select = bin/daemon-control.pl -select = app.psgi -ignore = t/var/**/* -argv = --profile=$ROOT/.perltidyrc - -[PerlCritic] -select = {lib,t}/**/*.{pl,pm,t,psgi} -ignore = t/var/**/* -ignore = bin/build_test_CPAN_dir.pl -ignore = bin/check_json.pl -ignore = bin/convert_authors.pl -ignore = bin/get_fields.pl -ignore = bin/mirror_cpan_for_developers.pl -ignore = bin/unlisted_prereqs.pl -ignore = bin/write_config_json -ignore = lib/Catalyst/Action/Deserialize/MetaCPANSanitizedJSON.pm -ignore = lib/Catalyst/Authentication/Store/Proxy.pm -ignore = lib/Catalyst/Plugin/OAuth2/Provider.pm -ignore = lib/Catalyst/Plugin/Session/Store/ElasticSearch.pm -ignore = lib/MetaCPAN/Document/Distribution.pm -ignore = lib/MetaCPAN/Document/File.pm -ignore = lib/MetaCPAN/Document/Rating.pm -ignore = lib/MetaCPAN/Document/Release.pm -ignore = lib/MetaCPAN/Model.pm -ignore = lib/MetaCPAN/Pod/XHTML.pm -ignore = lib/MetaCPAN/Role/Common.pm -ignore = lib/MetaCPAN/Script/Author.pm -ignore = lib/MetaCPAN/Script/Backup.pm -ignore = lib/MetaCPAN/Script/CPANTesters.pm -ignore = lib/MetaCPAN/Script/Check.pm -ignore = lib/MetaCPAN/Script/First.pm -ignore = lib/MetaCPAN/Script/Latest.pm -ignore = lib/MetaCPAN/Script/Mapping.pm -ignore = lib/MetaCPAN/Script/Pagerank.pm -ignore = lib/MetaCPAN/Script/PerlMongers.pm -ignore = lib/MetaCPAN/Script/Query.pm -ignore = lib/MetaCPAN/Script/ReindexDist.pm -ignore = lib/MetaCPAN/Script/Release.pm -ignore = lib/MetaCPAN/Script/Runner.pm -ignore = lib/MetaCPAN/Script/Tickets.pm -ignore = lib/MetaCPAN/Script/Watcher.pm -ignore = lib/MetaCPAN/Server/Controller.pm -ignore = lib/MetaCPAN/Server/Controller/Changes.pm -ignore = lib/MetaCPAN/Server/Controller/File.pm -ignore = lib/MetaCPAN/Server/Controller/Login.pm -ignore = lib/MetaCPAN/Server/Controller/Login/PAUSE.pm -ignore = lib/MetaCPAN/Server/Controller/Login/Twitter.pm -ignore = lib/MetaCPAN/Server/Controller/Root.pm -ignore = lib/MetaCPAN/Server/Controller/Search/Autocomplete.pm -ignore = lib/MetaCPAN/Server/Controller/Source.pm -ignore = lib/MetaCPAN/Server/Controller/User/Favorite.pm -ignore = lib/MetaCPAN/Server/Model/CPAN.pm -ignore = lib/MetaCPAN/Server/Model/Source.pm -ignore = lib/MetaCPAN/Server/View/JSON.pm -ignore = lib/MetaCPAN/Server/View/Pod.pm -ignore = lib/MetaCPAN/Util.pm -ignore = lib/Plack/Session/Store/ElasticSearch.pm - -[SortLines] -select = .gitignore - -[UniqueLines] -select = .gitignore diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 3fa01ded4..000000000 --- a/.travis.yml +++ /dev/null @@ -1,100 +0,0 @@ -language: perl -perl: - - "5.22" - -notifications: - email: - recipients: - - olaf@wundersolutions.com - on_success: always - on_failure: always - irc: "irc.perl.org#metacpan-travis" - -env: - global: - # We use a non-standard port to avoid trashing production - # but travis will have it running on the standard port. - - ES=localhost:9200 - - # Instantiate Catalyst models using metacpan_server_testing.conf - - METACPAN_SERVER_CONFIG_LOCAL_SUFFIX=testing - - - DEVEL_COVER_OPTIONS="-ignore,^local/" - - PERL_CARTON_PATH=$HOME/local - matrix: - - CPAN_RESOLVER=metadb PERL_CARTON_PATH=$HOME/no-snapshot HARNESS_VERBOSE=1 - - CPAN_RESOLVER=snapshot - -matrix: - allow_failures: - - env: CPAN_RESOLVER=metadb PERL_CARTON_PATH=$HOME/no-snapshot HARNESS_VERBOSE=1 - fast_finish: true - -addons: - apt: - packages: - # libgmp-dev required by Net::OpenID::Consumer - - libgmp-dev - # postgresql-server-dev-all is required by DBD::Pg - - postgresql-server-dev-all - -before_install: - - git clone git://github.com/travis-perl/helpers ~/travis-perl-helpers - - source ~/travis-perl-helpers/init - - - sudo mkdir -p /etc/elasticsearch/scripts/ && sudo mkdir /tmp/es && sudo chmod 777 /tmp/es - - - sudo curl -O -L https://github.com/metacpan/metacpan-puppet/raw/master/modules/metacpan_elasticsearch/files/etc/scripts/prefer_shorter_module_names_100.groovy > /tmp/es/prefer_shorter_module_names_100.groovy - - - sudo curl -O -L https://github.com/metacpan/metacpan-puppet/raw/master/modules/metacpan_elasticsearch/files/etc/scripts/prefer_shorter_module_names_400.groovy > /tmp/es/prefer_shorter_module_names_400.groovy - - - sudo curl -O -L https://github.com/metacpan/metacpan-puppet/raw/master/modules/metacpan_elasticsearch/files/etc/scripts/status_is_latest.groovy > /tmp/es/status_is_latest.groovy - - - sudo curl -O -L https://github.com/metacpan/metacpan-puppet/raw/master/modules/metacpan_elasticsearch/files/etc/scripts/score_version_numified.groovy > /tmp/es/score_version_numified.groovy - - - sudo cp /tmp/es/* /etc/elasticsearch/scripts/ - - - sudo service elasticsearch stop && curl -O -L https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-2.4.3.deb && sudo dpkg -i --force-confnew elasticsearch-2.4.3.deb && sudo service elasticsearch start - - - sudo service elasticsearch stop && curl -O -L https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-2.4.3.deb && sudo dpkg -i --force-confnew elasticsearch-2.4.3.deb && sudo service elasticsearch start - - sudo service elasticsearch restart - - - cpanm -n Carton - - cpanm -n App::cpm - - # Carton refuses to update Safe.pm to the version specified in the cpanfile and the - # version that's core in 5.16 is too old (it fails to work with Devel::Cover). - - cpanm -n Safe@2.35 - -install: - - AUTHOR_TESTING=0 cpm install -L $PERL_CARTON_PATH --resolver $CPAN_RESOLVER --workers $(test-jobs) || (cat ~/.perl-cpm/build.log; false) - -before_script: - - "perl -i -pe 's/(servers :)9900/localhost:9200/' metacpan_server_testing.conf" - - bin/wait-for-open http://localhost:9200/ - - coverage-setup - -script: - - carton exec prove -It/lib -lr -j$(test-jobs) t - -after_success: - - coverage-report - -#after_failure: -# - cat ~/.cpanm/build.log - -services: - - elasticsearch - -# caching /local should save about 5 minutes in module install time -cache: - directories: - - local - - ~/perl5 - -addons: - artifacts: - debug: true - s3_region: "us-east-1" - paths: - - $TRAVIS_BUILD_DIR/cpanfile.snapshot diff --git a/Dockerfile b/Dockerfile index 30275baac..2948c9f24 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,27 +1,101 @@ -FROM perl:5.22 +ARG SLIM_BUILD +ARG MAYBE_BASE_BUILD=${SLIM_BUILD:+server-base-slim} +ARG BASE_BUILD=${MAYBE_BASE_BUILD:-server-base} -ENV PERL_MM_USE_DEFAULT=1 PERL_CARTON_PATH=/carton +################### Web Server Base +FROM metacpan/metacpan-base:main-20250531-090128 AS server-base +FROM metacpan/metacpan-base:main-20250531-090129-slim AS server-base-slim -COPY cpanfile cpanfile.snapshot /metacpan-api/ -WORKDIR /metacpan-api +################### CPAN Prereqs +FROM server-base AS build-cpan-prereqs +SHELL [ "/bin/bash", "-euo", "pipefail", "-c" ] -RUN apt-get update \ - && apt-get install -y libgmp-dev rsync \ - && cpanm App::cpm \ - && cpm install -g Carton \ - && useradd -m metacpan-api -g users \ - && mkdir /carton /CPAN \ - && cpm install -L /carton \ - && rm -fr /root/.cpanm /root/.perl-cpm /var/cache/apt/lists/* /tmp/* +WORKDIR /app/ -RUN chown -R metacpan-api:users /metacpan-api /carton /CPAN +COPY cpanfile cpanfile.snapshot ./ +RUN \ + --mount=type=cache,target=/root/.perl-cpm,sharing=private \ +<new( + $config = Config::ZOMG->open( name => 'MetaCPAN::Server', path => $root_dir, ); @@ -36,15 +42,13 @@ BEGIN { $root_dir ); Log::Log4perl::init($log4perl_config); - package MetaCPAN::Server::WarnHandler; + package MetaCPAN::Server::WarnHandler; ## no critic (Modules::RequireFilenameMatchesPackage) Log::Log4perl->wrapper_register(__PACKAGE__); my $logger = Log::Log4perl->get_logger; $SIG{__WARN__} = sub { $logger->warn(@_) }; } -use lib "$root_dir/lib"; - -use MetaCPAN::Server; +use MetaCPAN::Server (); STDERR->autoflush; @@ -53,12 +57,44 @@ if ( -e "/.dockerenv" and MetaCPAN::Server->log->isa('Catalyst::Log') ) { STDOUT->autoflush; } +sub _add_headers { + my ( $app, $add_headers ) = @_; + sub { + Plack::Util::response_cb( + $app->(@_), + sub { + my $res = shift; + my ( $status, $headers ) = @$res; + if ( $status >= 200 && $status < 300 ) { + push @$headers, @$add_headers; + } + return $res; + } + ); + }; +} + my $static = Plack::App::Directory->new( { root => path( $root_dir, 'root', 'static' ) } )->to_app; my $urlmap = Plack::App::URLMap->new; +$urlmap->map( + '/favicon.ico' => _add_headers( + Plack::App::File->new( + file => path( $root_dir, 'root', 'static', 'favicon.ico' ) + )->to_app, + [ + 'Cache-Control' => 'public, max-age=' . ( 60 * 60 * 24 ), + 'Surrogate-Control' => 'max-age=' . ( 60 * 60 * 24 * 365 ), + 'Surrogate-Key' => 'static', + ], + ) +); $urlmap->map( '/static' => $static ); -$urlmap->map( '/' => MetaCPAN::Server->app ); +if ( $ENV{PLACK_ENV} && $ENV{PLACK_ENV} eq 'development' ) { + $urlmap->map( '/v1' => MetaCPAN::Server->app ); +} +$urlmap->map( '/' => MetaCPAN::Server->app ); return $urlmap->to_app; diff --git a/bin/api.pl b/bin/api.pl new file mode 100755 index 000000000..40ffdc72e --- /dev/null +++ b/bin/api.pl @@ -0,0 +1,40 @@ +#!/usr/bin/env perl + +use strict; +use warnings; + +=head2 DESCRIPTION + +This is the API web server interface. + + # On vagrant VM + ./bin/run morbo bin/api.pl + +To run the api web server, run the following on one of the servers: + + # Run the daemon on a local port (tunnel to display on your browser) + ./bin/run bin/api.pl daemon + +Start Minion worker on vagrant: + + cd /home/vagrant/metacpan-api + ./bin/run bin/api.pl minion worker + +Get status on jobs and workers. + +On production: + + sh /home/metacpan/bin/metacpan-api-carton-exec bin/api.pl minion job -s + +On vagrant: + + cd /home/vagrant/metacpan-api + ./bin/run bin/api.pl minion job -s + +=cut + +use lib 'lib'; + +# Start command line interface for application +require Mojolicious::Commands; +Mojolicious::Commands->start_app('MetaCPAN::API'); diff --git a/bin/build_test_CPAN_dir.pl b/bin/build_test_CPAN_dir.pl deleted file mode 100644 index cdc0d9436..000000000 --- a/bin/build_test_CPAN_dir.pl +++ /dev/null @@ -1,103 +0,0 @@ -#!/usr/bin/env perl - -# Script to create a /tmp/CPAN/ directory with a 02packages.details.txt.gz file -# To use as a basic for the ElasticSearch index and CPAN-API testing -# and development on the development virtual machine - -use strict; -use warnings; -use ElasticSearch; -use LWP::Simple qw(mirror is_success is_redirect); -use Path::Class; -use OrePAN2 0.07; -use OrePAN2::Injector; -use OrePAN2::Indexer; -use feature qw( say ); - -my $OUT_DIR = '/tmp/tmp_tar_files/'; -my $CPAN_DIR = '/tmp/CPAN/'; - -my $modules_to_fetch = { - 'Data::Pageset' => '1.06', - 'ElasticSearch' => '0.65', -}; - -my $injector = OrePAN2::Injector->new( directory => $CPAN_DIR, ); - -my $es = ElasticSearch->new( - no_refresh => 1, - servers => 'fastapi.metacpan.org', - - # trace_calls => \*STDOUT, -); - -my %seen; -foreach my $module_name ( keys %{$modules_to_fetch} ) { - my $version = $modules_to_fetch->{$module_name}; - - _download_with_dependencies( $module_name, $version ); -} - -# build the 02packages.details.txt.gz file -OrePAN2::Indexer->new( directory => $CPAN_DIR )->make_index(); - -sub _download_with_dependencies { - my ( $module_name, $version ) = @_; - - my $seen_key = $module_name . $version; - return if $seen{$seen_key}; - - my ( $module, $release ) = _get_meta( $module_name, $version ); - - foreach my $dep ( @{ $release->{dependency} } ) { - - # Find latest version? - # FIXME: What to do here? - - } - - # work out where to mirror to... - my $file = $release->{download_url}; - $file =~ s{^.+/authors/}{}; - $file = file( $OUT_DIR, $file ); - $file->dir->mkpath(); - - my $status = mirror( $release->{download_url}, $file->stringify ); - if ( is_success($status) || is_redirect($status) ) { - $seen{$seen_key} = 1; - $injector->{author} = $release->{author}; - $injector->inject( $file->stringify ); - } else { - warn "Unable to mirror: " . $release->{download_url}; - } -} - -sub _get_meta { - my ( $module_name, $version ) = @_; - - my $module = $es->search( - index => 'v0', - type => 'file', - query => { match_all => {} }, - filter => { - and => [ - { term => { 'file.authorized' => 'true' } }, - { term => { 'file.module.name' => $module_name } }, - { term => { 'file.module.version' => $version } } - ] - }, - ); - - my $release_name = $module->{hits}{hits}[0]{_source}{release}; - - my $release = $es->search( - index => 'v0', - type => 'release', - query => { match_all => {} }, - filter => { term => { 'release.name' => $release_name } }, - ); - return $module->{hits}{hits}[0]{_source}, - $release->{hits}{hits}[0]{_source}; - -} - diff --git a/bin/check_json.pl b/bin/check_json.pl deleted file mode 100755 index c358f94ea..000000000 --- a/bin/check_json.pl +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env perl -# PODNAME: check_json.pl -use 5.010; - -use Data::Dumper; -use Cpanel::JSON::XS; - -foreach my $file ( @ARGV ) { - say "Processing $file"; - eval { - my $hash = decode_json( - do { local ( @ARGV, $/ ) = $file; <> } - ); - print Dumper( $hash ); - }; - - if ( $@ ) { say "\terror in $file: $@" } -} diff --git a/bin/convert_authors.pl b/bin/convert_authors.pl deleted file mode 100644 index cd1fad30b..000000000 --- a/bin/convert_authors.pl +++ /dev/null @@ -1,90 +0,0 @@ -# PODNAME: foo - -use strict; -use warnings; -use Cpanel::JSON::XS; -use File::Find; - -my @files; -find( - sub { - push( @files, $File::Find::name ); - }, - 'conf/authors' ); - -foreach my $file (@files) { - next unless ( -f $file ); - next if($file =~ /1/); - next unless($file =~ /\.json$/); - my $json; - { - local $/ = undef; - local *FILE; - open FILE, "<$file"; - $json = ; - close FILE - } - warn $file; - my $data = decode_json($json); - my ($author) = keys %$data; - ($data) = values %$data; - my $raw = { donation => [], - profile => [], }; - my %profiles = ( "delicious_username" => 'delicious', - "facebook_public_profile" => 'facebook', - "github_username" => 'github', - "linkedin_public_profile" => "linkedin", - "stackoverflow_public_profile" => 'stackoverflow', - "perlmonks_username" => 'perlmonks', - "twitter_username" => 'twitter', - "slideshare_url" => 'slideshare', - "youtube_channel_url" => 'youtube', - slashdot_username => 'slashdot', - "amazon_author_profile" => 'amazon', - aim => 'aim', - icq => 'icq', - jabber => 'jabber', - msn_messenger => 'msn_messenger', - "oreilly_author_profile" => 'oreilly', - slideshare_username => 'slideshare', - stumbleupon_profile => 'stumbleupon', - xing_public_profile => 'xing', - ACT_id => 'act', - irc_nick => 'irc', - irc_nickname => 'irc' ); - - while ( my ( $k, $v ) = each %profiles ) { - next unless ( my $value = delete $data->{$k} ); - $value =~ s/^.*\///; - push( @{ $raw->{profile} }, - { name => $v, - id => $value - } ); - } - - if ( my $pp = delete $data->{paypal_address} ) { - delete $data->{accepts_donations}; - push( @{ $raw->{donation} }, - { id => $pp, - name => 'paypal' - } ); - } - - if ( $data->{blog_url} ) { - $raw->{blog} = [ - { url => delete $data->{blog_url}, - feed => delete $data->{blog_feed} } ]; - } - delete $data->{perlmongers} if ( ref $data->{perlmongers} ); - if ( $data->{perlmongers} ) { - $raw->{perlmongers} = { name => delete $data->{perlmongers}, - url => delete $data->{perlmongers_url}, }; - } - $raw->{$_} = delete $data->{$_} - for (qw(city country email region website openid)); - unlink $file; - (my $base = $file) =~ s/^(.*)\/.*?$/$1/; - open FILE, '>', "$base/author-1.0.json"; - print FILE JSON->new->pretty->encode( $raw ); - close FILE; -} diff --git a/bin/cron/author.sh b/bin/cron/author.sh index c94913643..e3f279773 100755 --- a/bin/cron/author.sh +++ b/bin/cron/author.sh @@ -3,7 +3,4 @@ # export ES_SCRIPT_INDEX=author_01 # /home/metacpan/bin/metacpan-api-carton-exec bin/metacpan author --index author_01 -export ES_SCRIPT_INDEX=cpan_v1_01 -/home/metacpan/bin/metacpan-api-carton-exec bin/metacpan author --index cpan_v1_01 - -unset ES_SCRIPT_INDEX \ No newline at end of file +/home/metacpan/bin/metacpan-api-carton-exec bin/metacpan author diff --git a/bin/cron/backups.sh b/bin/cron/backups.sh index 0c68600e9..16ed9f950 100755 --- a/bin/cron/backups.sh +++ b/bin/cron/backups.sh @@ -1,16 +1,6 @@ #!/bin/sh -#export ES_SCRIPT_INDEX=favorite_01 -#/home/metacpan/bin/metacpan-api-carton-exec bin/metacpan backup --index favorite_01 --type favorite - -#export ES_SCRIPT_INDEX=author_01 -#/home/metacpan/bin/metacpan-api-carton-exec bin/metacpan backup --index author_01 --type author - -export ES_SCRIPT_INDEX=cpan_v1_01 /home/metacpan/bin/metacpan-api-carton-exec bin/metacpan backup --index cpan_v1_01 --type favorite /home/metacpan/bin/metacpan-api-carton-exec bin/metacpan backup --index cpan_v1_01 --type author -export ES_SCRIPT_INDEX=user /home/metacpan/bin/metacpan-api-carton-exec bin/metacpan backup --index user - -unset ES_SCRIPT_INDEX \ No newline at end of file diff --git a/bin/get_fields.pl b/bin/get_fields.pl deleted file mode 100644 index b1a81b7c8..000000000 --- a/bin/get_fields.pl +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env perl -# PODNAME: get_fields.pl -use Data::Dumper; -use Cpanel::JSON::XS; -use File::Find::Rule; -use File::Basename; -use Path::Class; - -my $current_dir = dirname( __FILE__ ); -my $author_dir = Path::Class::Dir->new( $current_dir, '..', 'conf' ); -my @files = File::Find::Rule->file->name( '*.json' )->in( $author_dir ); - -my %fields; - -foreach my $file ( @files ) { - warn "Processing $file"; - my $hash; - - eval { - $hash = decode_json( do { local( @ARGV, $/ ) = $file; <> } ); - } or print "\terror in $file: $@"; - - while ( my ($author, $info) = each %{$hash} ) { - my @local_fields = keys %{$info}; - @fields{@local_fields} = @local_fields; - } -} - -print $_ for sort keys %fields; diff --git a/bin/install-precious b/bin/install-precious new file mode 100755 index 000000000..0d712a470 --- /dev/null +++ b/bin/install-precious @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +# This is for installing precious and other 3rd party libs needed for linting +# in CI + +set -euo pipefail + +if [ -z "${1:-}" ]; then + echo "usage: ./bin/install-precious /path/to/bin/dir" + exit 1 +fi + +TARGET=$1 +export TARGET + +TARGET=$1 +export TARGET + +curl --silent --location \ + https://raw.githubusercontent.com/houseabsolute/ubi/master/bootstrap/bootstrap-ubi.sh | + sh + +ubi --project houseabsolute/omegasort --in "$TARGET" +ubi --project houseabsolute/precious --in "$TARGET" diff --git a/bin/metacpan b/bin/metacpan index 555f9721e..e57c34fdb 100755 --- a/bin/metacpan +++ b/bin/metacpan @@ -6,7 +6,7 @@ bin/metacpan release /path/to/cpan/authors/id/ bin/metacpan release /path/to/cpan/authors/id/{A,B} - bin/metacpan release /path/to/cpan/authors/id/D/DO/DOY/Try-Tiny-0.09.tar.gz + bin/metacpan release /path/to/cpan/authors/id/D/DO/DOY/Try-Tiny-0.09.tar.gz bin/metacpan latest bin/metacpan server --cpan /path/to/cpan/ @@ -14,8 +14,10 @@ use strict; use warnings; -use FindBin; +use FindBin (); use lib "$FindBin::RealBin/../lib"; -use MetaCPAN::Script::Runner; +use MetaCPAN::Script::Runner (); MetaCPAN::Script::Runner->run; + +exit $MetaCPAN::Script::Runner::EXIT_CODE; diff --git a/bin/mirror_cpan_for_developers.pl b/bin/mirror_cpan_for_developers.pl old mode 100644 new mode 100755 index ef700b3d8..7a8d4de10 --- a/bin/mirror_cpan_for_developers.pl +++ b/bin/mirror_cpan_for_developers.pl @@ -1,11 +1,15 @@ +#!/usr/bin/env perl +use strict; +use warnings; + # This script is only needed if you are developing metacpan, -# on the live servers we use File::Rsync::Mirror::Recent +# on the live servers we use File::Rsync::Mirror::Recent # https://github.com/metacpan/metacpan-puppet/tree/master/modules/rrrclient use CPAN::Mini; - + CPAN::Mini->update_mirror( - remote => 'http://www.cpan.org/', - local => "/home/metacpan/CPAN", - log_level => 'warn', + remote => 'http://www.cpan.org/', + local => "/home/metacpan/CPAN", + log_level => 'warn', ); diff --git a/bin/munin/monitor_minion_queue.pl b/bin/munin/monitor_minion_queue.pl index ab17c66df..91a83e6ff 100755 --- a/bin/munin/monitor_minion_queue.pl +++ b/bin/munin/monitor_minion_queue.pl @@ -9,10 +9,10 @@ my $config_mode = 0; $config_mode = 1 if $ARGV[0] && $ARGV[0] eq 'config'; -if($config_mode) { +if ($config_mode) { -# Dump this (though we supported dynamic below) so it's faster -print <<'EOF'; + # Dump this (though we supported dynamic below) so it's faster + print <<'EOF'; graph_title Minion Queue stats graph_vlabel count graph_category metacpan_api @@ -25,32 +25,34 @@ jobs_finished.label Finished jobs EOF -exit; + exit; } # Get the stats -my $stats_report = `/home/metacpan/bin/metacpan-api-carton-exec bin/queue.pl minion job -s`; +my $stats_report + = `/home/metacpan/bin/metacpan-api-carton-exec bin/queue.pl minion job -s`; -my @lines = split("\n", $stats_report); +my @lines = split( "\n", $stats_report ); for my $line (@lines) { - my ($label, $num) = split ':', $line; + my ( $label, $num ) = split ':', $line; - $num =~ s/\D//g; + $num =~ s/\D//g; - my $key = lc($label); # Was 'Inactive jobs' + my $key = lc($label); # Was 'Inactive jobs' - # Swap type and status around so idle_jobs becomes jobs_idle - $key =~ s/(\w+)\s+(\w+)/$2_$1/g; + # Swap type and status around so idle_jobs becomes jobs_idle + $key =~ s/(\w+)\s+(\w+)/$2_$1/g; - if( $config_mode ) { - # config - print "${key}.label $label\n"; + if ($config_mode) { - } else { - # results - print "${key}.value $num\n" if $num; - } + # config + print "${key}.label $label\n"; + } + else { + # results + print "${key}.value $num\n" if $num; + } } diff --git a/bin/prove b/bin/prove deleted file mode 100755 index 3f4cf5e63..000000000 --- a/bin/prove +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -export EMAIL_SENDER_TRANSPORT=Test -export ES=${ES_TEST:-"localhost:9900"} -export METACPAN_SERVER_CONFIG_LOCAL_SUFFIX=testing -unset ES_SCRIPT_INDEX - -`dirname "$0"`/run prove -It/lib -lvr "$@" diff --git a/bin/queue.pl b/bin/queue.pl deleted file mode 100755 index dad5619c0..000000000 --- a/bin/queue.pl +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env perl - -use strict; -use warnings; - -=head2 DESCRIPTION - -Start Minion worker on vagrant: - - cd /home/vagrant/metacpan-api - ./bin/run bin/queue.pl minion worker - -Get status on jobs and workers. - -On production: - - sh /home/metacpan/bin/metacpan-api-carton-exec bin/queue.pl minion job -s - -On vagrant: - - cd /home/vagrant/metacpan-api - ./bin/run bin/queue.pl minion job -s - -=cut - -# For vagrant -use lib 'lib'; - -# Start command line interface for application -require Mojolicious::Commands; -Mojolicious::Commands->start_app('MetaCPAN::Queue'); diff --git a/bin/queue.pl b/bin/queue.pl new file mode 120000 index 000000000..5474dbc6e --- /dev/null +++ b/bin/queue.pl @@ -0,0 +1 @@ +api.pl \ No newline at end of file diff --git a/bin/unlisted_prereqs.pl b/bin/unlisted_prereqs.pl deleted file mode 100644 index 5750c9fbe..000000000 --- a/bin/unlisted_prereqs.pl +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env perl -# PODNAME: check_prereqs.pl - -# TODO: this stuff should be in other modules somewhere - -use strict; -use warnings; -use Perl::PrereqScanner 1.014; -use CPAN::Meta::Requirements; -use File::Find::Rule::Perl; -use List::Util qw(sum); -use version 0.77; - -# TODO: use CPAN::Meta::Prereqs - -my @found = File::Find::Rule->not( - File::Find::Rule->name(qw( - .git - t/var/tmp - var - ))->prune->discard, -)->perl_file->in('.'); - -my $local = {}; -my $files = {}; - -foreach ( @found ){ - # FIXME: unix slashes - my $phase = - # beneath t/ or xt/ - m{^(\./)?x?t/} ? 'build' : - 'runtime'; - - push @{ $files->{ $phase } }, $_; - - if( m{^(?:\./)?(?:t/)?lib/(.+?)\.pm$} ){ - (my $pm = $1) =~ s!/!::!g; - $local->{ $pm } = $_; - } -} - -my $scanner = Perl::PrereqScanner->new( - # TODO: extra_scanners => [qw( PlackMiddleware Catalyst )], -); - -my $reqs = {}; - -foreach my $phase ( keys %$files ){ - my $pr = CPAN::Meta::Requirements->new; - foreach my $file ( @{ $files->{ $phase } } ){ - $pr->add_requirements( $scanner->scan_file( $file ) ); - } - - # ignore packages we provide locally - $pr->clear_requirement($_) - for grep { exists $local->{$_} } $pr->required_modules; - - $reqs->{ $phase } = $pr->as_string_hash; -} - -# don't duplicate runtime deps into build deps -foreach my $dep ( keys %{ $reqs->{runtime} } ){ - # TODO: check version - delete $reqs->{build}{ $dep }; -} - -sub check_prereqs { - my ($scanned, $mm) = @_; - foreach my $dep ( keys %$scanned ){ - if( exists($mm->{ $dep }) ){ - delete $scanned->{ $dep } - if version->parse($scanned->{ $dep }) <= version->parse($mm->{ $dep }); - } - } -} - -my ($PREREQ_PM, $BUILD_REQUIRES, $MIN_PERL_VERSION); - -my $mm_prereqs = qx{$^X Makefile.PL PREREQ_PRINT=1}; -eval $mm_prereqs; - -check_prereqs($reqs->{runtime}, $PREREQ_PM); -check_prereqs($reqs->{build}, $BUILD_REQUIRES); -delete $reqs->{runtime}{perl} - if version->parse($reqs->{runtime}{perl}) <= version->parse($MIN_PERL_VERSION); - -use Data::Dumper; -$Data::Dumper::Sortkeys = 1; -print Data::Dumper->Dump([$reqs], ['requires']); - -exit sum map { scalar keys %{ $reqs->{$_} } } keys %$reqs; diff --git a/bin/wait-for-open b/bin/wait-for-open index 96a38b2fe..a9729260e 100755 --- a/bin/wait-for-open +++ b/bin/wait-for-open @@ -5,8 +5,8 @@ use warnings; my $server = shift; my $timeout = 30; -while ($timeout--) { - if (!system "curl -s '$server' 2>/dev/null 1>&2") { +while ( $timeout-- ) { + if ( !system "curl -s '$server' 2>/dev/null 1>&2" ) { exit 0; } sleep 1; diff --git a/bin/write_config_json b/bin/write_config_json deleted file mode 100644 index f2cdb7087..000000000 --- a/bin/write_config_json +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/perl - -# PODNAME: write_config_json -# -# takes the root directory of an extracted distribution and outputs a JSON file -# suitable for CPAN::Faker to STDOUT -use strictures 1; -use Cpanel::JSON::XS; -use YAML; - -use IO::All; -use Email::Address; -use File::Find; -use File::Spec; -use Path::Class; - -my ($dir) = @ARGV; - -my $meta_data; -if(-e "$dir/META.yml") { - $meta_data = YAML::LoadFile("$dir/META.yml"); -} elsif(-e "$dir/META.json") { - $meta_data = JSON::decode_json(io("$dir/META.json")->all); -} else { - die "no meta file"; -} - -my $authors = $meta_data->{author}; -my @authors = map { my ($addr) = Email::Address->parse($_); $addr->name } @$authors; - -my $files; -File::Find::find( - { - no_chdir => 1, - wanted => sub { - return unless -f; - push @$files, { - file => File::Spec->abs2rel($File::Find::name, dir($dir)), - content => io($_)->all, - } - }, - }, - $dir -); - -my $output = { - name => $meta_data->{name}, - version => $meta_data->{version}, - abstract => $meta_data->{abstract}, - X_Module_Faker => { - cpan_author => [ @authors ], - append => [ - $files - ] - }, -}; - -print JSON->new->pretty->encode($output); - -__DATA__ -{ - "name": "MetaFile-Both", - "abstract": "A dist with META.yml and META.json", - "version": 1.1, - "X_Module_Faker": { - "cpan_author": "LOCAL", - "append": [ { - "file": "lib/MetaFile/Both.pm", - "content": "package MetaFile::Both;\n\n=head1 NAME\n\nMetaFile::Both - abstract" - }, - { - "file": "META.json", - "content": "{\"meta-spec\":{\"version\":2,\"url\":\"http://search.cpan.org/perldoc?CPAN::Meta::Spec\"},\"generated_by\":\"hand\",\"version\":1.1,\"name\":\"MetaFile-Both\",\"dynamic_config\":0,\"author\":\"LOCAL\",\"license\":\"unknown\",\"abstract\":\"A dist with META.yml and META.json\",\"release_status\":\"stable\",\"x_meta_file\":\"json\"}" - }, - { - "file": "t/foo.t", - "content": "use Test::More;" - } ] - } -} - ---- -name: SignedModule -version: 1.1 -abstract: A signed dist -author: - - LOCAL -generated_by: Module::Faker version -license: unknown -meta-spec: - url: http://module-build.sourceforge.net/META-spec-v1.3.html - version: 1.3 diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 000000000..be10c0793 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,16 @@ +--- +comment: + layout: 'diff, files' + behavior: default + require_changes: true # if true: only post the comment if coverage changes + require_base: false # [true :: must have a base report to post] + require_head: true # [true :: must have a head report to post] + hide_project_coverage: false # [true :: only show coverage on the git diff] +coverage: + status: + patch: + default: + threshold: 1% + project: + default: + threshold: 1% diff --git a/cpanfile b/cpanfile index 004e3dc51..dd1d4513f 100644 --- a/cpanfile +++ b/cpanfile @@ -1,204 +1,166 @@ +use strict; +use warnings; + requires 'perl', '5.010'; -requires 'Archive::Any', 0.0942; -requires 'Archive::Tar', '2.04'; -requires 'BackPAN::Index', '0.42'; -requires 'CHI', '0.60'; -requires 'CPAN::DistnameInfo', '0.12'; -requires 'CPAN::Meta', '2.150005'; # Avoid issues with List::Util dep under carton install. -requires 'CPAN::Meta::Requirements', '2.140'; -requires 'CPAN::Meta::YAML', '0.018'; -requires 'CPAN::Repository::Perms'; -requires 'Captcha::reCAPTCHA', '0.99'; -requires 'Catalyst', '5.90103'; -requires 'Catalyst::Action::RenderView'; -requires 'Catalyst::Controller'; -requires 'Catalyst::Controller::REST'; -requires 'Catalyst::Model'; +requires 'Archive::Any', '0.0946'; +requires 'Archive::Tar', '2.40'; +requires 'Authen::SASL', '2.16'; # for Email::Sender::Transport::SMTP +requires 'Catalyst', '5.90128'; +requires 'Catalyst::Action::RenderView', '0.16'; +requires 'Catalyst::Controller::REST', '1.21'; requires 'Catalyst::Plugin::Authentication'; -requires 'Catalyst::Plugin::ConfigLoader'; -requires 'Catalyst::Plugin::Session'; +requires 'Catalyst::Plugin::Session', '0.43'; requires 'Catalyst::Plugin::Session::State::Cookie'; requires 'Catalyst::Plugin::Session::Store'; requires 'Catalyst::Plugin::Static::Simple'; -requires 'Catalyst::Plugin::Unicode::Encoding'; -requires 'Catalyst::Utils'; -requires 'Catalyst::View'; -requires 'Catalyst::View::JSON', '0.36'; -requires 'CatalystX::Component::Traits'; +requires 'Catalyst::View::JSON', '0.37'; requires 'CatalystX::Fastly::Role::Response', '0.06'; -requires 'CatalystX::InjectComponent'; -requires 'CatalystX::RoleApplicator'; -requires 'Config::ZOMG', '>=', '1.000000'; +requires 'CHI', '0.61'; +requires 'Config::General', '2.63'; +requires 'Config::ZOMG', '1.000000'; requires 'Const::Fast'; -requires 'Cpanel::JSON::XS', '3.0115'; +requires 'CPAN::DistnameInfo', '0.12'; +requires 'Cpanel::JSON::XS', '4.32'; +requires 'CPAN::Meta', '2.150005'; # Avoid issues with List::Util dep under carton install. +requires 'CPAN::Meta::Requirements', '2.140'; +requires 'CPAN::Meta::YAML', '0.018'; +requires 'CPAN::Repository::Perms'; requires 'Cwd'; -requires 'DBD::SQLite', '>=1.50'; -requires 'DBI', '1.616'; -requires 'Data::DPath'; -requires 'Data::Dump'; requires 'Data::Dumper'; -requires 'Data::Printer', '0.38'; -requires 'DateTime', '1.24'; +requires 'Data::Visitor::Callback'; +requires 'DateTime', '1.54'; requires 'DateTime::Format::ISO8601'; -requires 'Devel::ArgNames'; +requires 'DBD::SQLite', '1.66'; +requires 'DBI', '1.643'; requires 'Digest::MD5'; requires 'Digest::SHA'; -requires 'EV'; -requires 'ElasticSearchX::Model', '1.0.2'; -requires 'Email::Address'; +requires 'ElasticSearchX::Model', '2.0.1'; requires 'Email::Sender::Simple'; requires 'Email::Simple'; -requires 'Email::Valid', '1.198'; -requires 'Encode'; +requires 'Email::Valid', '1.203'; +requires 'Encode', '3.17'; requires 'Encoding::FixLatin'; requires 'Encoding::FixLatin::XS'; -requires 'Exporter'; -requires 'ExtUtils::HasCompiler'; -requires 'Facebook::Graph'; +requires 'EV'; +requires 'Exporter', '5.74'; requires 'File::Basename'; +requires 'File::Copy'; requires 'File::Find'; requires 'File::Find::Rule'; requires 'File::Find::Rule::Perl'; requires 'File::Spec'; requires 'File::Spec::Functions'; -requires 'File::Temp'; +requires 'File::pushd'; requires 'File::stat'; -requires 'Find::Lib'; +requires 'File::Temp'; requires 'FindBin'; -requires 'Gazelle'; -requires 'Git::Helpers'; -requires 'Graph::Centrality::Pagerank'; +requires 'Getopt::Long::Descriptive', '0.103'; requires 'Gravatar::URL'; -requires 'HTML::Entities'; -requires 'HTML::TokeParser::Simple'; -requires 'HTTP::Request::Common'; requires 'Hash::Merge::Simple'; -requires 'IO::All'; -requires 'IO::Interactive'; -requires 'IO::Prompt'; -requires 'IO::String'; -requires 'IO::Uncompress::Bunzip2'; +requires 'HTML::Entities'; +requires 'HTTP::Request::Common', '6.36'; +requires 'IO::Prompt::Tiny'; +requires 'IO::Uncompress::Bunzip2', '2.106'; requires 'IO::Zlib'; -requires 'IPC::Run3'; -requires 'LWP::Protocol::https'; -requires 'LWP::UserAgent', '6.15'; -requires 'LWP::UserAgent::Paranoid'; -requires 'List::AllUtils', '0.09'; -requires 'List::MoreUtils', '0.413'; -requires 'List::Util', '1.45'; +requires 'IPC::Run3', '0.048'; +requires 'List::Util', '1.62'; +requires 'Log::Any::Adapter'; +requires 'Log::Any::Adapter::Log4perl'; requires 'Log::Contextual'; +requires 'Log::Dispatch'; +requires 'Log::Dispatch::Syslog'; requires 'Log::Log4perl'; requires 'Log::Log4perl::Appender::ScreenColoredLevels'; +requires 'Log::Log4perl::Catalyst'; +requires 'Log::Log4perl::Layout::JSON'; +requires 'LWP::Protocol::https'; +requires 'LWP::UserAgent', '6.66'; requires 'MetaCPAN::Moose'; -requires 'MetaCPAN::Pod::XHTML'; -requires 'MetaCPAN::Role', '0.06'; -requires 'Minion', '>= 9.03'; +requires 'MetaCPAN::Pod::HTML' => '0.004000'; +requires 'MetaCPAN::Role', '1.00'; +requires 'MIME::Base64', '3.15'; +requires 'Minion', '9.03'; requires 'Minion::Backend::SQLite'; requires 'Module::Load'; -requires 'Module::Metadata', '1.000022'; +requires 'Module::Metadata', '1.000038'; requires 'Module::Pluggable'; requires 'Module::Runtime'; -requires 'Mojo::Pg', '>= 4.08'; -requires 'Moose', ' >= 2.1403'; -requires 'Moose::Role'; -requires 'Moose::Util'; -requires 'MooseX::Aliases'; +requires 'Mojolicious::Plugin::MountPSGI', '0.14'; +requires 'Mojolicious::Plugin::OpenAPI'; +requires 'Mojolicious::Plugin::Web::Auth', '0.17'; +requires 'Mojo::Pg', '4.08'; +requires 'Moose', '2.2201'; requires 'MooseX::Attribute::Deflator', '2.1.5'; -requires 'MooseX::ChainedAccessors'; -requires 'MooseX::ClassAttribute'; requires 'MooseX::Fastly::Role', '0.02'; requires 'MooseX::Getopt', '0.71'; requires 'MooseX::Getopt::Dashes'; requires 'MooseX::Getopt::OptionTypeMap'; requires 'MooseX::StrictConstructor'; requires 'MooseX::Types'; -requires 'MooseX::Types::Common::String'; -requires 'MooseX::Types::ElasticSearch', ' == 0.0.4'; +requires 'MooseX::Types::ElasticSearch', '0.0.4'; requires 'MooseX::Types::Moose'; -requires 'MooseX::Types::Path::Class::MoreCoercions'; -requires 'MooseX::Types::Structured'; -requires 'MooseX::Types::URI'; -requires 'Mozilla::CA'; -requires 'Net::DNS::Paranoid'; -requires 'Net::Fastly', '1.05'; -requires 'Net::OpenID::Consumer'; -requires 'Net::Twitter', '4.01010'; -requires 'OrePAN2'; -requires 'PAUSE::Permissions'; +requires 'Mozilla::CA', '20211001'; +requires 'namespace::autoclean'; +requires 'Net::Fastly', '1.12'; +requires 'Net::GitHub::V4'; requires 'Parse::CPAN::Packages::Fast', '0.09'; -requires 'Parse::CSV', '2.04'; -requires 'Parse::PMFile', '0.41'; -requires 'Path::Class', '>= 0.36'; -requires 'Path::Class::File'; +requires 'Parse::PMFile', '0.43'; requires 'Path::Iterator::Rule', '>=1.011'; +requires 'PAUSE::Permissions', '0.17'; requires 'PerlIO::gzip'; -requires 'Pithub', '0.01033'; -requires 'Plack', '1.0039'; +requires 'Plack', '1.0048'; requires 'Plack::App::Directory'; -requires 'Plack::Handler::Twiggy'; -requires 'Plack::MIME'; -requires 'Plack::Middleware::Header'; requires 'Plack::Middleware::ReverseProxy'; -requires 'Plack::Middleware::Rewrite'; -requires 'Plack::Middleware::ServerStatus::Lite'; requires 'Plack::Middleware::Session'; requires 'Plack::Session::Store'; -requires 'Plack::Test'; -requires 'Plack::Util::Accessor'; -requires 'Pod::Coverage::Moose', '0.02'; -requires 'Pod::Markdown', '3.002'; -requires 'Pod::POM'; -requires 'Pod::Simple', '3.29'; -requires 'Pod::Simple::XHTML', '3.24'; -requires 'Pod::Text'; +requires 'Pod::Markdown', '3.300'; +requires 'Pod::Text', '4.14'; requires 'Ref::Util'; -requires 'Regexp::Common'; -requires 'Regexp::Common::time'; requires 'Safe', '2.35'; # bug fixes (used by Parse::PMFile) -requires 'Search::Elasticsearch', '== 2.03'; -requires 'Starman'; +requires 'Scalar::Util', '1.62'; # Moose +requires 'Search::Elasticsearch' => '8.12'; +requires 'Search::Elasticsearch::Client::2_0' => '6.81'; requires 'Throwable::Error'; -requires 'Time::Local'; -requires 'Try::Tiny', '0.24'; -requires 'URI', '1.71'; -requires 'URI::Escape'; -requires 'WWW::Mechanize', '1.75'; -requires 'WWW::Mechanize::Cached', '1.50'; -requires 'XML::Simple'; -requires 'YAML', '1.15'; -requires 'YAML::Syck', '1.29'; -requires 'base'; -requires 'feature'; -requires 'namespace::autoclean'; -requires 'strict'; -requires 'strictures', 1; -requires 'utf8'; -requires 'version', '0.9901'; -requires 'warnings'; +requires 'Term::Size::Any'; # for Catalyst +requires 'Text::CSV_XS'; +requires 'Try::Tiny', '0.30'; +requires 'Type::Tiny', '2.000001'; +requires 'Types::Path::Tiny'; +requires 'Types::URI'; +requires 'Twitter::API', '1.0006'; +requires 'URI', '5.10'; +requires 'version', '0.9929'; +requires 'XML::XPath'; +requires 'YAML::XS', '0.83'; # Mojolicious::Plugin::OpenAPI YAML loading -test_requires 'App::Prove'; -test_requires 'CPAN::Faker', '0.010'; -test_requires 'Code::TidyAll', '>= 0.47'; -test_requires 'Code::TidyAll::Plugin::UniqueLines'; -test_requires 'Config::General'; -test_requires 'Devel::Confess'; -test_requires 'File::Copy'; -test_requires 'HTTP::Cookies'; -test_requires 'LWP::ConsoleLogger::Easy'; -test_requires 'MetaCPAN::Client', '>=', '2.017000'; -test_requires 'Module::Faker', '0.015'; -test_requires 'Module::Faker::Dist', '0.010'; -test_requires 'Perl::Tidy' => '20180220'; -test_requires 'Plack::Test::Agent'; -test_requires 'Test::Code::TidyAll'; -test_requires 'Test::More', '0.99'; -test_requires 'Test::Most'; -test_requires 'Test::OpenID::Server', '0.03'; -test_requires 'Test::Perl::Critic'; -test_requires 'Test::RequiresInternet'; -test_requires 'Test::Routine', '0.012'; -test_requires 'Test::Routine::Util', '0'; -test_requires 'Test::Vars'; +# test requirements +on test => sub { + requires 'CPAN::Faker', '0.011'; + requires 'Devel::Confess'; + requires 'HTTP::Cookies', '6.10'; + requires 'MetaCPAN::Client', '2.029000'; + requires 'Module::Faker', '== 0.017'; + requires 'Module::Faker::Dist', '== 0.017'; + requires 'OrePAN2', '0.48'; + requires 'Test::Deep'; + requires 'Test::Fatal'; + requires 'Test::Harness', '3.44'; # Contains App::Prove + requires 'Test::More', '1.302190'; + requires 'Test::RequiresInternet'; + requires 'Test::Routine', '0.012'; + requires 'Test::Vars', '0.015'; +}; -author_requires 'Plack::Middleware::Rewrite'; +# author requirements +on develop => sub { + requires 'App::perlimports'; + requires 'Perl::Critic', '0.140'; + requires 'Perl::Tidy' => '== 20240511'; + requires 'PPI', '1.274'; # Perl::Critic + requires 'PPIx::QuoteLike', '0.022'; # Perl::Critic + requires 'PPIx::Regexp', '0.085'; # Perl::Critic + requires 'String::Format', '1.18'; # Perl::Critic + requires 'Devel::Cover'; + requires 'Devel::Cover::Report::Codecovbash'; +}; diff --git a/cpanfile.forced b/cpanfile.forced new file mode 100644 index 000000000..47023795c --- /dev/null +++ b/cpanfile.forced @@ -0,0 +1,12 @@ +# transitive deps +# Not used directly, but they need to be explicitly listed to ensure they are +# in our cpanfile.snapshot at appropriate versions. Either for older perl +# versions, or unpredictable dynamic deps. These will be installed using a +# different process to ensure they are present in the snapshot, even if they +# would be satisfied by core. +requires 'CPAN::Meta', '2.141520'; +requires 'Devel::PPPort', '3.62'; # for older perls +requires 'ExtUtils::MakeMaker', '7.76'; +requires 'version', '0.9929'; # for older perls +requires 'Module::Signature', '0.90'; +requires 'Pod::Parser', '1.67'; # for newer perls diff --git a/cpanfile.snapshot b/cpanfile.snapshot index db1763ca7..c3272cc2c 100644 --- a/cpanfile.snapshot +++ b/cpanfile.snapshot @@ -1,19 +1,10 @@ # carton snapshot format: version 1.0 DISTRIBUTIONS - Algorithm-C3-0.10 - pathname: H/HA/HAARG/Algorithm-C3-0.10.tar.gz + Algorithm-Diff-1.201 + pathname: R/RJ/RJBS/Algorithm-Diff-1.201.tar.gz provides: - Algorithm::C3 0.10 - requirements: - Carp 0.01 - ExtUtils::MakeMaker 0 - Test::More 0.47 - perl 5.006 - Algorithm-Diff-1.1903 - pathname: T/TY/TYEMQ/Algorithm-Diff-1.1903.tar.gz - provides: - Algorithm::Diff 1.1903 - Algorithm::Diff::_impl 1.1903 + Algorithm::Diff 1.201 + Algorithm::Diff::_impl 1.201 requirements: ExtUtils::MakeMaker 0 Any-URI-Escape-0.01 @@ -23,89 +14,77 @@ DISTRIBUTIONS requirements: ExtUtils::MakeMaker 0 URI::Escape 0 - AnyEvent-7.14 - pathname: M/ML/MLEHMANN/AnyEvent-7.14.tar.gz - provides: - AE undef - AE::Log::COLLECT undef - AE::Log::FILTER undef - AE::Log::LOG undef - AnyEvent 7.14 - AnyEvent::Base 7.14 - AnyEvent::CondVar 7.14 - AnyEvent::CondVar::Base 7.14 - AnyEvent::DNS undef - AnyEvent::Debug undef - AnyEvent::Debug::Backtrace undef - AnyEvent::Debug::Wrap undef - AnyEvent::Debug::Wrapped undef - AnyEvent::Debug::shell undef - AnyEvent::Handle undef - AnyEvent::IO undef - AnyEvent::IO::IOAIO undef - AnyEvent::IO::Perl undef - AnyEvent::Impl::Cocoa undef - AnyEvent::Impl::EV undef - AnyEvent::Impl::Event undef - AnyEvent::Impl::EventLib undef - AnyEvent::Impl::FLTK undef - AnyEvent::Impl::Glib undef - AnyEvent::Impl::IOAsync undef - AnyEvent::Impl::Irssi undef - AnyEvent::Impl::POE undef - AnyEvent::Impl::Perl undef - AnyEvent::Impl::Qt undef - AnyEvent::Impl::Qt::Io undef - AnyEvent::Impl::Qt::Timer undef - AnyEvent::Impl::Tk undef - AnyEvent::Impl::UV undef - AnyEvent::Log undef - AnyEvent::Log::COLLECT undef - AnyEvent::Log::Ctx undef - AnyEvent::Log::FILTER undef - AnyEvent::Log::LOG undef - AnyEvent::Loop undef - AnyEvent::Socket undef - AnyEvent::Strict undef - AnyEvent::TLS undef - AnyEvent::Util undef - requirements: - Canary::Stability 0 - ExtUtils::MakeMaker 6.52 - Apache-LogFormat-Compiler-0.35 - pathname: K/KA/KAZEBURO/Apache-LogFormat-Compiler-0.35.tar.gz + Apache-LogFormat-Compiler-0.36 + pathname: K/KA/KAZEBURO/Apache-LogFormat-Compiler-0.36.tar.gz provides: - Apache::LogFormat::Compiler 0.35 + Apache::LogFormat::Compiler 0.36 requirements: Module::Build::Tiny 0.035 POSIX 0 POSIX::strftime::Compiler 0.30 Time::Local 0 perl 5.008001 - App-Cache-0.37 - pathname: L/LB/LBROCARD/App-Cache-0.37.tar.gz - provides: - App::Cache 0.37 + App-perlimports-0.000056 + pathname: O/OA/OALDERS/App-perlimports-0.000056.tar.gz + provides: + App::perlimports 0.000056 + App::perlimports::Annotations 0.000056 + App::perlimports::CLI 0.000056 + App::perlimports::Config 0.000056 + App::perlimports::Document 0.000056 + App::perlimports::ExportInspector 0.000056 + App::perlimports::Include 0.000056 + App::perlimports::Role::Logger 0.000056 + App::perlimports::Sandbox 0.000056 requirements: - Class::Accessor::Chained::Fast 0 + Capture::Tiny 0 + Class::Inspector 1.36 + Cpanel::JSON::XS 0 + Data::Dumper 0 + Data::UUID 0 ExtUtils::MakeMaker 0 - File::Find::Rule 0 - File::HomeDir 0 - File::stat 0 - HTTP::Cookies 0 - LWP::UserAgent 0 - Path::Class 0 - Storable 0 - Test::More 0 - Archive-Any-0.0945 - pathname: O/OA/OALDERS/Archive-Any-0.0945.tar.gz + File::Basename 0 + File::XDG 1.01 + Getopt::Long::Descriptive 0 + List::Util 0 + Log::Dispatch 2.70 + Memoize 0 + Module::Runtime 0 + Moo 0 + Moo::Role 0 + MooX::StrictConstructor 0 + PPI 1.276 + PPI::Document 0 + PPIx::Utils::Classification 0 + Path::Iterator::Rule 0 + Path::Tiny 0 + Perl::Tidy 20220613 + Pod::Usage 0 + Ref::Util 0 + Scalar::Util 0 + Sereal::Decoder 0 + Sereal::Encoder 0 + Sub::HandlesVia 0 + Symbol::Get 0.10 + TOML::Tiny 0.16 + Text::Diff 0 + Text::SimpleTable::AutoWidth 0 + Try::Tiny 0 + Types::Standard 0 + feature 0 + perl v5.18.0 + strict 0 + utf8 0 + warnings 0 + Archive-Any-0.0946 + pathname: O/OA/OALDERS/Archive-Any-0.0946.tar.gz provides: - Archive::Any 0.0945 - Archive::Any::Plugin 0.0945 - Archive::Any::Plugin::Tar 0.0945 - Archive::Any::Plugin::Zip 0.0945 - Archive::Any::Tar 0.0945 - Archive::Any::Zip 0.0945 + Archive::Any 0.0946 + Archive::Any::Plugin 0.0946 + Archive::Any::Plugin::Tar 0.0946 + Archive::Any::Plugin::Zip 0.0946 + Archive::Any::Tar 0.0946 + Archive::Any::Zip 0.0946 requirements: Archive::Tar 0 Archive::Zip 0 @@ -114,9 +93,9 @@ DISTRIBUTIONS File::MMagic 0 File::Spec::Functions 0 MIME::Types 0 - Module::Build 0.28 Module::Find 0 base 0 + perl 5.006 strict 0 warnings 0 Archive-Any-Create-0.03 @@ -132,10 +111,10 @@ DISTRIBUTIONS ExtUtils::MakeMaker 6.30 IO::Zlib 0 UNIVERSAL::require 0 - Archive-Extract-0.80 - pathname: B/BI/BINGOS/Archive-Extract-0.80.tar.gz + Archive-Extract-0.88 + pathname: B/BI/BINGOS/Archive-Extract-0.88.tar.gz provides: - Archive::Extract 0.80 + Archive::Extract 0.88 requirements: ExtUtils::MakeMaker 0 File::Basename 0 @@ -147,36 +126,41 @@ DISTRIBUTIONS Params::Check 0.07 Test::More 0 if 0 - Archive-Peek-0.35 - pathname: L/LB/LBROCARD/Archive-Peek-0.35.tar.gz + Archive-Tar-3.04 + pathname: B/BI/BINGOS/Archive-Tar-3.04.tar.gz provides: - Archive::Peek 0.35 - Archive::Peek::Tar undef - Archive::Peek::Zip undef + Archive::Tar 3.04 + Archive::Tar::Constant 3.04 + Archive::Tar::File 3.04 requirements: - Archive::Tar 0 - Archive::Zip 0 + Compress::Zlib 2.015 ExtUtils::MakeMaker 0 - Moose 0 - MooseX::Types::Path::Class 0 + File::Spec 0.82 + IO::Compress::Base 2.015 + IO::Compress::Bzip2 2.015 + IO::Compress::Gzip 2.015 + IO::Zlib 1.01 + Test::Harness 2.26 Test::More 0 - Archive-Zip-1.59 - pathname: P/PH/PHRED/Archive-Zip-1.59.tar.gz - provides: - Archive::Zip 1.59 - Archive::Zip::Archive 1.59 - Archive::Zip::BufferedFileHandle 1.59 - Archive::Zip::DirectoryMember 1.59 - Archive::Zip::FileMember 1.59 - Archive::Zip::Member 1.59 - Archive::Zip::MemberRead 1.59 - Archive::Zip::MockFileHandle 1.59 - Archive::Zip::NewFileMember 1.59 - Archive::Zip::StringMember 1.59 - Archive::Zip::Tree 1.59 - Archive::Zip::ZipFileMember 1.59 + perl 5.00503 + Archive-Zip-1.68 + pathname: P/PH/PHRED/Archive-Zip-1.68.tar.gz + provides: + Archive::Zip 1.68 + Archive::Zip::Archive 1.68 + Archive::Zip::BufferedFileHandle 1.68 + Archive::Zip::DirectoryMember 1.68 + Archive::Zip::FileMember 1.68 + Archive::Zip::Member 1.68 + Archive::Zip::MemberRead 1.68 + Archive::Zip::MockFileHandle 1.68 + Archive::Zip::NewFileMember 1.68 + Archive::Zip::StringMember 1.68 + Archive::Zip::Tree 1.68 + Archive::Zip::ZipFileMember 1.68 requirements: Compress::Raw::Zlib 2.017 + Encode 0 ExtUtils::MakeMaker 0 File::Basename 0 File::Copy 0 @@ -189,28 +173,43 @@ DISTRIBUTIONS IO::Seekable 0 Time::Local 0 perl 5.006 - Array-Iterator-0.11 - pathname: S/SH/SHARYANTO/Array-Iterator-0.11.tar.gz - provides: - Array::Iterator 0.11 - Array::Iterator::BiDirectional 0.11 - Array::Iterator::Circular 0.11 - Array::Iterator::Reusable 0.11 - requirements: - ExtUtils::MakeMaker 6.30 - B-Hooks-EndOfScope-0.21 - pathname: E/ET/ETHER/B-Hooks-EndOfScope-0.21.tar.gz + Authen-SASL-2.1800 + pathname: E/EH/EHUELS/Authen-SASL-2.1800.tar.gz + provides: + Authen::SASL 2.1800 + Authen::SASL::CRAM_MD5 2.1800 + Authen::SASL::EXTERNAL 2.1800 + Authen::SASL::Perl 2.1800 + Authen::SASL::Perl::ANONYMOUS 2.1800 + Authen::SASL::Perl::CRAM_MD5 2.1800 + Authen::SASL::Perl::DIGEST_MD5 2.1800 + Authen::SASL::Perl::EXTERNAL 2.1800 + Authen::SASL::Perl::GSSAPI 2.1800 + Authen::SASL::Perl::LOGIN 2.1800 + Authen::SASL::Perl::OAUTHBEARER 2.1800 + Authen::SASL::Perl::PLAIN 2.1800 + Authen::SASL::Perl::XOAUTH2 2.1800 + requirements: + Digest::HMAC_MD5 0 + Digest::MD5 0 + ExtUtils::MakeMaker 0 + perl 5.014000 + B-Hooks-EndOfScope-0.28 + pathname: E/ET/ETHER/B-Hooks-EndOfScope-0.28.tar.gz provides: - B::Hooks::EndOfScope 0.21 - B::Hooks::EndOfScope::PP 0.21 - B::Hooks::EndOfScope::XS 0.21 + B::Hooks::EndOfScope 0.28 + B::Hooks::EndOfScope::PP 0.28 + B::Hooks::EndOfScope::XS 0.28 requirements: ExtUtils::MakeMaker 0 + Hash::Util::FieldHash 0 Module::Implementation 0.05 + Scalar::Util 0 Sub::Exporter::Progressive 0.001006 Text::ParseWords 0 + Tie::Hash 0 Variable::Magic 0.48 - perl 5.008001 + perl 5.006001 strict 0 warnings 0 B-Hooks-OP-Check-0.22 @@ -225,93 +224,22 @@ DISTRIBUTIONS perl 5.008001 strict 0 warnings 0 - B-Keywords-1.15 - pathname: R/RU/RURBAN/B-Keywords-1.15.tar.gz + B-Keywords-1.27 + pathname: R/RU/RURBAN/B-Keywords-1.27.tar.gz provides: - B::Keywords 1.15 + B::Keywords 1.27 requirements: B 0 ExtUtils::MakeMaker 0 - BackPAN-Index-0.42 - pathname: M/MS/MSCHWERN/BackPAN-Index-0.42.tar.gz - provides: - BackPAN::Index 0.42 - BackPAN::Index::Database 0 - BackPAN::Index::Dist 0 - BackPAN::Index::File 0 - BackPAN::Index::IndexFile 0 - BackPAN::Index::Release 0 - BackPAN::Index::Role::AsHash 0 - BackPAN::Index::Role::HasCache 0 - BackPAN::Index::Role::Log 0 - BackPAN::Index::Schema 0 - BackPAN::Index::Types 0 - Parse::BACKPAN::Packages 0.40 - requirements: - App::Cache 0.37 - Archive::Extract 0 - CLASS 1.00 - CPAN::DistnameInfo 0.09 - DBD::SQLite 1.25 - DBIx::Class 0.08109 - LWP::Simple 0 - Module::Build 0.340201 - Mouse 0.64 - Path::Class 0.17 - Test::Compile 0.11 - Test::More 0.90 - URI 1.54 - autodie 0 - parent 0 - perl 5.008001 - Browser-Open-0.04 - pathname: C/CF/CFRANKS/Browser-Open-0.04.tar.gz + CGI-Simple-1.281 + pathname: M/MA/MANWAR/CGI-Simple-1.281.tar.gz provides: - Browser::Open 0.04 + CGI::Simple 1.281 + CGI::Simple::Cookie 1.281 + CGI::Simple::Standard 1.281 + CGI::Simple::Util 1.281 requirements: ExtUtils::MakeMaker 0 - Test::More 0.92 - parent 0 - CGI-4.37 - pathname: L/LE/LEEJO/CGI-4.37.tar.gz - provides: - CGI 4.37 - CGI::Carp 4.37 - CGI::Cookie 4.37 - CGI::File::Temp 4.37 - CGI::HTML::Functions undef - CGI::MultipartBuffer 4.37 - CGI::Pretty 4.37 - CGI::Push 4.37 - CGI::Util 4.37 - Fh 4.37 - requirements: - Carp 0 - Config 0 - Encode 0 - Exporter 0 - ExtUtils::MakeMaker 0 - File::Spec 0.82 - File::Temp 0.17 - HTML::Entities 3.69 - base 0 - if 0 - overload 0 - parent 0.225 - perl 5.008001 - strict 0 - utf8 0 - warnings 0 - CGI-Simple-1.115 - pathname: S/SZ/SZABGAB/CGI-Simple-1.115.tar.gz - provides: - CGI::Simple 1.115 - CGI::Simple::Cookie 1.114 - CGI::Simple::Standard 1.114 - CGI::Simple::Util 1.114 - requirements: - IO::Scalar 0 - Test::More 0 CGI-Struct-1.21 pathname: F/FU/FULLERMD/CGI-Struct-1.21.tar.gz provides: @@ -321,24 +249,24 @@ DISTRIBUTIONS Storable 0 Test::Deep 0 Test::More 0 - CHI-0.60 - pathname: J/JS/JSWARTZ/CHI-0.60.tar.gz - provides: - CHI 0.60 - CHI::CacheObject 0.60 - CHI::Driver 0.60 - CHI::Driver::Base::CacheContainer 0.60 - CHI::Driver::CacheCache 0.60 - CHI::Driver::FastMmap 0.60 - CHI::Driver::File 0.60 - CHI::Driver::Memory 0.60 - CHI::Driver::Metacache 0.60 - CHI::Driver::Null 0.60 - CHI::Driver::RawMemory 0.60 - CHI::Driver::Role::HasSubcaches 0.60 - CHI::Driver::Role::IsSizeAware 0.60 - CHI::Driver::Role::IsSubcache 0.60 - CHI::Stats 0.60 + CHI-0.61 + pathname: A/AS/ASB/CHI-0.61.tar.gz + provides: + CHI 0.61 + CHI::CacheObject 0.61 + CHI::Driver 0.61 + CHI::Driver::Base::CacheContainer 0.61 + CHI::Driver::CacheCache 0.61 + CHI::Driver::FastMmap 0.61 + CHI::Driver::File 0.61 + CHI::Driver::Memory 0.61 + CHI::Driver::Metacache 0.61 + CHI::Driver::Null 0.61 + CHI::Driver::RawMemory 0.61 + CHI::Driver::Role::HasSubcaches 0.61 + CHI::Driver::Role::IsSizeAware 0.61 + CHI::Driver::Role::IsSubcache 0.61 + CHI::Stats 0.61 requirements: Carp::Assert 0.20 Class::Load 0 @@ -362,17 +290,10 @@ DISTRIBUTIONS Time::Duration::Parse 0.03 Time::HiRes 1.30 Try::Tiny 0.05 - CLASS-1.00 - pathname: M/MS/MSCHWERN/CLASS-1.00.tar.gz - provides: - CLASS 1.00 - requirements: - ExtUtils::MakeMaker 0 - Test::More 0.07 - CPAN-Checksums-2.12 - pathname: A/AN/ANDK/CPAN-Checksums-2.12.tar.gz + CPAN-Checksums-2.14 + pathname: A/AN/ANDK/CPAN-Checksums-2.14.tar.gz provides: - CPAN::Checksums 2.12 + CPAN::Checksums 2.14 requirements: Compress::Bzip2 0 Compress::Zlib 0 @@ -392,16 +313,16 @@ DISTRIBUTIONS requirements: ExtUtils::MakeMaker 0 Test::More 0 - CPAN-Faker-0.010 - pathname: R/RJ/RJBS/CPAN-Faker-0.010.tar.gz + CPAN-Faker-0.012 + pathname: R/RJ/RJBS/CPAN-Faker-0.012.tar.gz provides: - CPAN::Faker 0.010 + CPAN::Faker 0.012 requirements: CPAN::Checksums 0 Compress::Zlib 0 Cwd 0 Data::Section 0 - ExtUtils::MakeMaker 6.30 + ExtUtils::MakeMaker 6.78 File::Find 0 File::Next 0 File::Path 0 @@ -412,6 +333,7 @@ DISTRIBUTIONS Moose 0 Sort::Versions 0 Text::Template 0 + perl 5.014000 strict 0 warnings 0 CPAN-Meta-2.150010 @@ -440,22 +362,23 @@ DISTRIBUTIONS strict 0 version 0.88 warnings 0 - CPAN-Meta-Requirements-2.140 - pathname: D/DA/DAGOLDEN/CPAN-Meta-Requirements-2.140.tar.gz + CPAN-Meta-Requirements-2.143 + pathname: R/RJ/RJBS/CPAN-Meta-Requirements-2.143.tar.gz provides: - CPAN::Meta::Requirements 2.140 + CPAN::Meta::Requirements 2.143 + CPAN::Meta::Requirements::Range 2.143 requirements: B 0 Carp 0 ExtUtils::MakeMaker 6.17 - perl 5.006 + perl 5.010000 strict 0 version 0.88 warnings 0 - CPAN-Meta-YAML-0.018 - pathname: D/DA/DAGOLDEN/CPAN-Meta-YAML-0.018.tar.gz + CPAN-Meta-YAML-0.020 + pathname: E/ET/ETHER/CPAN-Meta-YAML-0.020.tar.gz provides: - CPAN::Meta::YAML 0.018 + CPAN::Meta::YAML 0.020 requirements: B 0 Carp 0 @@ -485,35 +408,6 @@ DISTRIBUTIONS IO::File 1.14 IO::Zlib 1.10 Moo 0.009013 - Cache-Cache-1.08 - pathname: R/RJ/RJBS/Cache-Cache-1.08.tar.gz - provides: - Cache::BaseCache undef - Cache::BaseCacheTester undef - Cache::Cache 1.08 - Cache::CacheMetaData undef - Cache::CacheSizer undef - Cache::CacheTester undef - Cache::CacheUtils undef - Cache::FileBackend undef - Cache::FileCache undef - Cache::MemoryBackend undef - Cache::MemoryCache undef - Cache::NullCache undef - Cache::Object undef - Cache::SharedMemoryBackend undef - Cache::SharedMemoryCache undef - Cache::SizeAwareCache undef - Cache::SizeAwareCacheTester undef - Cache::SizeAwareFileCache undef - Cache::SizeAwareMemoryCache undef - Cache::SizeAwareSharedMemoryCache undef - requirements: - Digest::SHA1 2.02 - Error 0.15 - ExtUtils::MakeMaker 0 - File::Spec 0.82 - Storable 1.014 Cache-LRU-0.04 pathname: K/KA/KAZUHO/Cache-LRU-0.04.tar.gz provides: @@ -523,25 +417,23 @@ DISTRIBUTIONS Test::More 0.88 Test::Requires 0 perl 5.008001 - Canary-Stability-2012 - pathname: M/ML/MLEHMANN/Canary-Stability-2012.tar.gz + Call-Context-0.05 + pathname: F/FE/FELIPE/Call-Context-0.05.tar.gz provides: - Canary::Stability 2012 + Call::Context 0.05 + Call::Context::X 0.05 requirements: ExtUtils::MakeMaker 0 - Captcha-reCaptcha-0.99 - pathname: S/SU/SUNNYP/Captcha-reCaptcha-0.99.tar.gz + Canary-Stability-2013 + pathname: M/ML/MLEHMANN/Canary-Stability-2013.tar.gz provides: - Captcha::reCAPTCHA 0.99 + Canary::Stability 2013 requirements: ExtUtils::MakeMaker 0 - HTML::Tiny 0.904 - LWP::UserAgent 0 - Test::More 0 - Capture-Tiny-0.46 - pathname: D/DA/DAGOLDEN/Capture-Tiny-0.46.tar.gz + Capture-Tiny-0.50 + pathname: D/DA/DAGOLDEN/Capture-Tiny-0.50.tar.gz provides: - Capture::Tiny 0.46 + Capture::Tiny 0.50 requirements: Carp 0 Exporter 0 @@ -553,10 +445,10 @@ DISTRIBUTIONS perl 5.006 strict 0 warnings 0 - Carp-Assert-0.21 - pathname: N/NE/NEILB/Carp-Assert-0.21.tar.gz + Carp-Assert-0.22 + pathname: Y/YV/YVES/Carp-Assert-0.22.tar.gz provides: - Carp::Assert 0.21 + Carp::Assert 0.22 requirements: Carp 0 Exporter 0 @@ -565,52 +457,43 @@ DISTRIBUTIONS strict 0 vars 0 warnings 0 - Carp-Assert-More-1.16 - pathname: P/PE/PETDANCE/Carp-Assert-More-1.16.tar.gz + Carp-Clan-6.08 + pathname: E/ET/ETHER/Carp-Clan-6.08.tar.gz provides: - Carp::Assert::More 1.16 + Carp::Clan 6.08 requirements: - Carp 0 - Carp::Assert 0 ExtUtils::MakeMaker 0 - Scalar::Util 0 - Test::Exception 0 - Test::More 0.18 - Carp-Clan-6.06 - pathname: K/KE/KENTNL/Carp-Clan-6.06.tar.gz - provides: - Carp::Clan 6.06 - requirements: - ExtUtils::MakeMaker 0 - Test::Exception 0 - Catalyst-Action-REST-1.20 - pathname: J/JJ/JJNAPIORK/Catalyst-Action-REST-1.20.tar.gz - provides: - Catalyst::Action::Deserialize 1.20 - Catalyst::Action::Deserialize::Callback 1.20 - Catalyst::Action::Deserialize::JSON 1.20 - Catalyst::Action::Deserialize::JSON::XS 1.20 - Catalyst::Action::Deserialize::View 1.20 - Catalyst::Action::Deserialize::XML::Simple 1.20 - Catalyst::Action::Deserialize::YAML 1.20 - Catalyst::Action::DeserializeMultiPart 1.20 - Catalyst::Action::REST 1.20 - Catalyst::Action::REST::ForBrowsers 1.20 - Catalyst::Action::Serialize 1.20 - Catalyst::Action::Serialize::Callback 1.20 - Catalyst::Action::Serialize::JSON 1.20 - Catalyst::Action::Serialize::JSON::XS 1.20 - Catalyst::Action::Serialize::JSONP 1.20 - Catalyst::Action::Serialize::View 1.20 - Catalyst::Action::Serialize::XML::Simple 1.20 - Catalyst::Action::Serialize::YAML 1.20 - Catalyst::Action::Serialize::YAML::HTML 1.20 - Catalyst::Action::SerializeBase 1.20 - Catalyst::Controller::REST 1.20 - Catalyst::Request::REST 1.20 - Catalyst::Request::REST::ForBrowsers 1.20 - Catalyst::TraitFor::Request::REST 1.20 - Catalyst::TraitFor::Request::REST::ForBrowsers 1.20 + overload 0 + perl 5.006 + strict 0 + Catalyst-Action-REST-1.21 + pathname: J/JJ/JJNAPIORK/Catalyst-Action-REST-1.21.tar.gz + provides: + Catalyst::Action::Deserialize 1.21 + Catalyst::Action::Deserialize::Callback 1.21 + Catalyst::Action::Deserialize::JSON 1.21 + Catalyst::Action::Deserialize::JSON::XS 1.21 + Catalyst::Action::Deserialize::View 1.21 + Catalyst::Action::Deserialize::XML::Simple 1.21 + Catalyst::Action::Deserialize::YAML 1.21 + Catalyst::Action::DeserializeMultiPart 1.21 + Catalyst::Action::REST 1.21 + Catalyst::Action::REST::ForBrowsers 1.21 + Catalyst::Action::Serialize 1.21 + Catalyst::Action::Serialize::Callback 1.21 + Catalyst::Action::Serialize::JSON 1.21 + Catalyst::Action::Serialize::JSON::XS 1.21 + Catalyst::Action::Serialize::JSONP 1.21 + Catalyst::Action::Serialize::View 1.21 + Catalyst::Action::Serialize::XML::Simple 1.21 + Catalyst::Action::Serialize::YAML 1.21 + Catalyst::Action::Serialize::YAML::HTML 1.21 + Catalyst::Action::SerializeBase 1.21 + Catalyst::Controller::REST 1.21 + Catalyst::Request::REST 1.21 + Catalyst::Request::REST::ForBrowsers 1.21 + Catalyst::TraitFor::Request::REST 1.21 + Catalyst::TraitFor::Request::REST::ForBrowsers 1.21 requirements: Catalyst::Runtime 5.80030 Class::Inspector 1.13 @@ -622,19 +505,18 @@ DISTRIBUTIONS Params::Validate 0.76 URI::Find 0 namespace::autoclean 0 - Catalyst-Action-RenderView-0.16 - pathname: B/BO/BOBTFISH/Catalyst-Action-RenderView-0.16.tar.gz + Catalyst-Action-RenderView-0.17 + pathname: H/HA/HAARG/Catalyst-Action-RenderView-0.17.tar.gz provides: - Catalyst::Action::RenderView 0.16 + Catalyst::Action::RenderView 0.17 requirements: Catalyst::Runtime 5.80030 Data::Visitor 0.24 - ExtUtils::MakeMaker 6.42 - HTTP::Request::AsCGI 0 + ExtUtils::MakeMaker 0 MRO::Compat 0 - Test::More 0.88 - Catalyst-Plugin-Authentication-0.10023 - pathname: B/BO/BOBTFISH/Catalyst-Plugin-Authentication-0.10023.tar.gz + perl 5.008005 + Catalyst-Plugin-Authentication-0.10024 + pathname: J/JJ/JJNAPIORK/Catalyst-Plugin-Authentication-0.10024.tar.gz provides: Catalyst::Authentication::Credential::NoPassword undef Catalyst::Authentication::Credential::Password undef @@ -646,93 +528,78 @@ DISTRIBUTIONS Catalyst::Authentication::Store::Null undef Catalyst::Authentication::User undef Catalyst::Authentication::User::Hash undef - Catalyst::Plugin::Authentication 0.10023 + Catalyst::Plugin::Authentication 0.10024 Catalyst::Plugin::Authentication::Credential::Password undef Catalyst::Plugin::Authentication::Store::Minimal undef Catalyst::Plugin::Authentication::User undef Catalyst::Plugin::Authentication::User::Hash undef requirements: - Catalyst::Plugin::Session 0.10 Catalyst::Runtime 0 - Class::Inspector 0 - Class::MOP 0 - ExtUtils::MakeMaker 6.59 + ExtUtils::MakeMaker 0 MRO::Compat 0 Moose 0 MooseX::Emulate::Class::Accessor::Fast 0 String::RewritePrefix 0 - Test::Exception 0 - Test::More 0.88 Try::Tiny 0 namespace::autoclean 0 - perl 5.008001 - Catalyst-Plugin-ConfigLoader-0.34 - pathname: B/BO/BOBTFISH/Catalyst-Plugin-ConfigLoader-0.34.tar.gz + Catalyst-Plugin-ConfigLoader-0.35 + pathname: H/HA/HAARG/Catalyst-Plugin-ConfigLoader-0.35.tar.gz provides: - Catalyst::Plugin::ConfigLoader 0.34 + Catalyst::Plugin::ConfigLoader 0.35 requirements: Catalyst::Runtime 5.7008 Config::Any 0.20 Data::Visitor 0.24 - ExtUtils::MakeMaker 6.59 + ExtUtils::MakeMaker 0 MRO::Compat 0.09 - Path::Class 0 - Test::More 0 - perl 5.008 - Catalyst-Plugin-Session-0.40 - pathname: J/JJ/JJNAPIORK/Catalyst-Plugin-Session-0.40.tar.gz + Catalyst-Plugin-Session-0.43 + pathname: H/HA/HAARG/Catalyst-Plugin-Session-0.43.tar.gz provides: - Catalyst::Plugin::Session 0.40 - Catalyst::Plugin::Session::State undef - Catalyst::Plugin::Session::Store undef - Catalyst::Plugin::Session::Store::Dummy undef - Catalyst::Plugin::Session::Test::Store 123 + Catalyst::Plugin::Session 0.43 + Catalyst::Plugin::Session::State 0.43 + Catalyst::Plugin::Session::Store 0.43 + Catalyst::Plugin::Session::Store::Dummy 0.43 + Catalyst::Plugin::Session::Test::Store 0.43 requirements: Catalyst::Runtime 5.71001 Digest 0 - ExtUtils::MakeMaker 6.59 + ExtUtils::MakeMaker 0 File::Spec 0 File::Temp 0 + HTML::Entities 0 List::Util 0 MRO::Compat 0 Moose 0.76 MooseX::Emulate::Class::Accessor::Fast 0.00801 Object::Signature 0 - Test::Deep 0 - Test::Exception 0 Test::More 0.88 - Test::WWW::Mechanize::PSGI 0 - Tie::RefHash 1.34 namespace::clean 0.10 perl 5.008 - Catalyst-Plugin-Session-State-Cookie-0.17 - pathname: M/MS/MSTROUT/Catalyst-Plugin-Session-State-Cookie-0.17.tar.gz + Catalyst-Plugin-Session-State-Cookie-0.18 + pathname: H/HA/HAARG/Catalyst-Plugin-Session-State-Cookie-0.18.tar.gz provides: - Catalyst::Plugin::Session::State::Cookie 0.17 + Catalyst::Plugin::Session::State::Cookie 0.18 requirements: Catalyst 5.80005 Catalyst::Plugin::Session 0.27 - ExtUtils::MakeMaker 6.42 + ExtUtils::MakeMaker 0 MRO::Compat 0 Moose 0 - Test::More 0 namespace::autoclean 0 - Catalyst-Plugin-Static-Simple-0.34 - pathname: F/FR/FREW/Catalyst-Plugin-Static-Simple-0.34.tar.gz + Catalyst-Plugin-Static-Simple-0.37 + pathname: I/IL/ILMARI/Catalyst-Plugin-Static-Simple-0.37.tar.gz provides: - Catalyst::Plugin::Static::Simple 0.34 + Catalyst::Plugin::Static::Simple 0.37 requirements: Catalyst::Runtime 5.80008 - ExtUtils::MakeMaker 6.36 + ExtUtils::MakeMaker 0 MIME::Types 2.03 Moose 0 - MooseX::Types 0 - Test::More 0 namespace::autoclean 0 - Catalyst-Runtime-5.90115 - pathname: J/JJ/JJNAPIORK/Catalyst-Runtime-5.90115.tar.gz + Catalyst-Runtime-5.90132 + pathname: J/JJ/JJNAPIORK/Catalyst-Runtime-5.90132.tar.gz provides: - Catalyst 5.90115 + Catalyst 5.90132 Catalyst::Action undef Catalyst::ActionChain undef Catalyst::ActionContainer undef @@ -763,13 +630,13 @@ DISTRIBUTIONS Catalyst::Log undef Catalyst::Middleware::Stash undef Catalyst::Model undef - Catalyst::Plugin::Unicode::Encoding 99.0 + Catalyst::Plugin::Unicode::Encoding 5.90132 Catalyst::Request undef Catalyst::Request::PartData undef Catalyst::Request::Upload undef Catalyst::Response undef Catalyst::Response::Writer undef - Catalyst::Runtime 5.90115 + Catalyst::Runtime 5.90132 Catalyst::Script::CGI undef Catalyst::Script::Create undef Catalyst::Script::FastCGI undef @@ -786,34 +653,30 @@ DISTRIBUTIONS CGI::Struct 0 Carp 1.25 Class::C3::Adopt::NEXT 0.07 - Class::Data::Inheritable 0 Class::Load 0.12 Data::Dump 0 Data::OptList 0 Devel::InnerPackage 0 Encode 2.49 - ExtUtils::MakeMaker 6.59 + ExtUtils::MakeMaker 0 HTML::Entities 0 HTML::HeadParser 0 HTTP::Body 1.22 HTTP::Headers 1.64 HTTP::Request 5.814 - HTTP::Request::AsCGI 1.0 - HTTP::Request::Common 0 HTTP::Response 5.813 - HTTP::Status 0 Hash::MultiValue 0 - IO::Scalar 0 JSON::MaybeXS 1.000000 LWP 5.837 - List::MoreUtils 0 + List::Util 1.45 MRO::Compat 0 Module::Pluggable 4.7 - Moose 1.03 + Moose 2.1400 MooseX::Emulate::Class::Accessor::Fast 0.00903 MooseX::Getopt 0.48 MooseX::MethodAttributes::Role::AttrContainer::Inheritable 0.24 Path::Class 0.09 + PerlIO::utf8_strict 0 Plack 0.9991 Plack::Middleware::Conditional 0 Plack::Middleware::ContentLength 0 @@ -830,79 +693,39 @@ DISTRIBUTIONS Plack::Test::ExternalServer 0 Safe::Isa 0 Scalar::Util 0 + Socket 1.96 Stream::Buffered 0 String::RewritePrefix 0.004 Sub::Exporter 0 Task::Weaken 0 - Test::Fatal 0 - Test::More 0.88 Text::Balanced 0 Text::SimpleTable 0.03 Time::HiRes 0 Tree::Simple 1.15 - Tree::Simple::Visitor::FindByPath 0 + Tree::Simple::Visitor::FindByUID 0 Try::Tiny 0.17 URI 1.65 URI::ws 0.03 - namespace::autoclean 0.28 namespace::clean 0.23 perl 5.008003 - Catalyst-View-JSON-0.36 - pathname: J/JJ/JJNAPIORK/Catalyst-View-JSON-0.36.tar.gz + Catalyst-View-JSON-0.37 + pathname: H/HA/HAARG/Catalyst-View-JSON-0.37.tar.gz provides: Catalyst::Helper::View::JSON undef - Catalyst::View::JSON 0.36 + Catalyst::View::JSON 0.37 requirements: - Catalyst 5.6 - ExtUtils::MakeMaker 6.59 + Catalyst 5.60 + ExtUtils::MakeMaker 0 JSON::MaybeXS 1.003000 MRO::Compat 0 - Test::More 0 - YAML 0 - perl 5.008001 - CatalystX-Component-Traits-0.19 - pathname: R/RK/RKITOVER/CatalystX-Component-Traits-0.19.tar.gz - provides: - CatalystX::Component::Traits 0.19 - requirements: - Carp 0 - Catalyst 0 - Class::Load 0 - ExtUtils::MakeMaker 6.30 - List::MoreUtils 0 - Moose::Role 0 - MooseX::Traits::Pluggable 0 - Scalar::Util 0 - namespace::autoclean 0 CatalystX-Fastly-Role-Response-0.07 - pathname: L/LL/LLAP/CatalystX-Fastly-Role-Response-0.07.tar.gz + pathname: H/HA/HAARG/CatalystX-Fastly-Role-Response-0.07.tar.gz provides: CatalystX::Fastly::Role::Response 0.07 requirements: - Carp 0 - ExtUtils::MakeMaker 0 - Moose::Role 0 - CatalystX-InjectComponent-0.025 - pathname: R/RO/ROKR/CatalystX-InjectComponent-0.025.tar.gz - provides: - CatalystX::InjectComponent 0.025 - requirements: - Catalyst::Runtime 5.8 - Class::Inspector 0 - Devel::InnerPackage 0 - ExtUtils::MakeMaker 6.30 - Test::Most 0 - parent 0 - CatalystX-RoleApplicator-0.005 - pathname: H/HD/HDP/CatalystX-RoleApplicator-0.005.tar.gz - provides: - CatalystX::RoleApplicator 0.005 - requirements: - Catalyst::Runtime 5.7 - Class::MOP 0.80 ExtUtils::MakeMaker 0 - Moose 0.73 - MooseX::RelatedClassRoles 0.003 + Moose::Role 2.2200 + perl 5.008005 Class-Accessor-0.51 pathname: K/KA/KASEI/Class-Accessor-0.51.tar.gz provides: @@ -912,44 +735,6 @@ DISTRIBUTIONS requirements: ExtUtils::MakeMaker 0 base 1.01 - Class-Accessor-Chained-0.01 - pathname: R/RC/RCLAMP/Class-Accessor-Chained-0.01.tar.gz - provides: - Class::Accessor::Chained 0.01 - Class::Accessor::Chained::Fast undef - requirements: - Class::Accessor 0 - Test::More 0 - Class-Accessor-Grouped-0.10012 - pathname: R/RI/RIBASUSHI/Class-Accessor-Grouped-0.10012.tar.gz - provides: - Class::Accessor::Grouped 0.10012 - requirements: - Carp 0 - Class::XSAccessor 1.19 - ExtUtils::CBuilder 0.27 - ExtUtils::MakeMaker 6.59 - Module::Runtime 0.012 - Scalar::Util 0 - Sub::Name 0.05 - Test::Exception 0.31 - Test::More 0.88 - perl 5.006 - Class-Accessor-Lite-0.08 - pathname: K/KA/KAZUHO/Class-Accessor-Lite-0.08.tar.gz - provides: - Class::Accessor::Lite 0.08 - requirements: - ExtUtils::MakeMaker 6.36 - Class-C3-0.33 - pathname: H/HA/HAARG/Class-C3-0.33.tar.gz - provides: - Class::C3 0.33 - requirements: - Algorithm::C3 0.07 - ExtUtils::MakeMaker 0 - Scalar::Util 0 - perl 5.006 Class-C3-Adopt-NEXT-0.14 pathname: E/ET/ETHER/Class-C3-Adopt-NEXT-0.14.tar.gz provides: @@ -963,47 +748,30 @@ DISTRIBUTIONS strict 0 warnings 0 warnings::register 0 - Class-C3-Componentised-1.001000 - pathname: F/FR/FREW/Class-C3-Componentised-1.001000.tar.gz + Class-Data-Inheritable-0.10 + pathname: R/RS/RSHERER/Class-Data-Inheritable-0.10.tar.gz provides: - Class::C3::Componentised 1.001000 - Class::C3::Componentised::ApplyHooks undef - requirements: - Carp 0 - Class::C3 0.20 - Class::Inspector 0 - ExtUtils::MakeMaker 6.42 - MRO::Compat 0 - Test::Exception 0 - perl 5.006002 - Class-Data-Inheritable-0.08 - pathname: T/TM/TMTM/Class-Data-Inheritable-0.08.tar.gz - provides: - Class::Data::Inheritable 0.08 + Class::Data::Inheritable 0.10 requirements: ExtUtils::MakeMaker 0 - Class-Factory-Util-1.7 - pathname: D/DR/DROLSKY/Class-Factory-Util-1.7.tar.gz - provides: - Class::Factory::Util 1.7 - requirements: - Class-Inspector-1.32 - pathname: P/PL/PLICEASE/Class-Inspector-1.32.tar.gz + Class-Inspector-1.36 + pathname: P/PL/PLICEASE/Class-Inspector-1.36.tar.gz provides: - Class::Inspector 1.32 - Class::Inspector::Functions 1.32 + Class::Inspector 1.36 + Class::Inspector::Functions 1.36 requirements: ExtUtils::MakeMaker 0 File::Spec 0.80 - perl 5.006 - Class-Load-0.24 - pathname: E/ET/ETHER/Class-Load-0.24.tar.gz + base 0 + perl 5.008 + Class-Load-0.25 + pathname: E/ET/ETHER/Class-Load-0.25.tar.gz provides: - Class::Load 0.24 - Class::Load::PP 0.24 + Class::Load 0.25 + Class::Load::PP 0.25 requirements: Carp 0 - Data::OptList 0 + Data::OptList 0.110 Exporter 0 ExtUtils::MakeMaker 0 Module::Implementation 0.04 @@ -1026,10 +794,10 @@ DISTRIBUTIONS perl 5.006 strict 0 warnings 0 - Class-Method-Modifiers-2.12 - pathname: E/ET/ETHER/Class-Method-Modifiers-2.12.tar.gz + Class-Method-Modifiers-2.15 + pathname: E/ET/ETHER/Class-Method-Modifiers-2.15.tar.gz provides: - Class::Method::Modifiers 2.12 + Class::Method::Modifiers 2.15 requirements: B 0 Carp 0 @@ -1039,23 +807,34 @@ DISTRIBUTIONS perl 5.006 strict 0 warnings 0 - Class-Singleton-1.5 - pathname: S/SH/SHAY/Class-Singleton-1.5.tar.gz + Class-Singleton-1.6 + pathname: S/SH/SHAY/Class-Singleton-1.6.tar.gz provides: - Class::Singleton 1.5 + Class::Singleton 1.6 requirements: - ExtUtils::MakeMaker 0 - Class-Tiny-1.006 - pathname: D/DA/DAGOLDEN/Class-Tiny-1.006.tar.gz + ExtUtils::MakeMaker 6.64 + perl 5.008001 + strict 0 + warnings 0 + Class-Tiny-1.008 + pathname: D/DA/DAGOLDEN/Class-Tiny-1.008.tar.gz provides: - Class::Tiny 1.006 - Class::Tiny::Object 1.006 + Class::Tiny 1.008 + Class::Tiny::Object 1.008 requirements: Carp 0 ExtUtils::MakeMaker 6.17 perl 5.006 strict 0 warnings 0 + Class-Tiny-Chained-0.004 + pathname: D/DB/DBOOK/Class-Tiny-Chained-0.004.tar.gz + provides: + Class::Tiny::Chained 0.004 + requirements: + Class::Tiny 1.003 + ExtUtils::MakeMaker 0 + perl 5.006 Class-XSAccessor-1.19 pathname: S/SM/SMUELLER/Class-XSAccessor-1.19.tar.gz provides: @@ -1067,66 +846,58 @@ DISTRIBUTIONS Time::HiRes 0 XSLoader 0 perl 5.008 - Clone-0.39 - pathname: G/GA/GARU/Clone-0.39.tar.gz + Clone-0.47 + pathname: A/AT/ATOOMIC/Clone-0.47.tar.gz provides: - Clone 0.39 + Clone 0.47 requirements: ExtUtils::MakeMaker 0 - Test::More 0 - Clone-Choose-0.008 - pathname: H/HE/HERMES/Clone-Choose-0.008.tar.gz + Clone-Choose-0.010 + pathname: H/HE/HERMES/Clone-Choose-0.010.tar.gz provides: - Clone::Choose 0.008 + Clone::Choose 0.010 requirements: ExtUtils::MakeMaker 0 Storable 0 perl 5.008001 - Clone-PP-1.07 - pathname: N/NE/NEILB/Clone-PP-1.07.tar.gz - provides: - Clone::PP 1.07 - requirements: - Exporter 0 - ExtUtils::MakeMaker 0 - perl 5.006 - strict 0 - vars 0 - warnings 0 - Code-TidyAll-0.69 - pathname: D/DR/DROLSKY/Code-TidyAll-0.69.tar.gz - provides: - Code::TidyAll 0.69 - Code::TidyAll::Cache 0.69 - Code::TidyAll::CacheModel 0.69 - Code::TidyAll::CacheModel::Shared 0.69 - Code::TidyAll::Config::INI::Reader 0.69 - Code::TidyAll::Git::Precommit 0.69 - Code::TidyAll::Git::Prereceive 0.69 - Code::TidyAll::Git::Util 0.69 - Code::TidyAll::Plugin 0.69 - Code::TidyAll::Plugin::CSSUnminifier 0.69 - Code::TidyAll::Plugin::JSBeautify 0.69 - Code::TidyAll::Plugin::JSHint 0.69 - Code::TidyAll::Plugin::JSLint 0.69 - Code::TidyAll::Plugin::JSON 0.69 - Code::TidyAll::Plugin::MasonTidy 0.69 - Code::TidyAll::Plugin::PHPCodeSniffer 0.69 - Code::TidyAll::Plugin::PerlCritic 0.69 - Code::TidyAll::Plugin::PerlTidy 0.69 - Code::TidyAll::Plugin::PerlTidySweet 0.69 - Code::TidyAll::Plugin::PodChecker 0.69 - Code::TidyAll::Plugin::PodSpell 0.69 - Code::TidyAll::Plugin::PodTidy 0.69 - Code::TidyAll::Plugin::SortLines 0.69 - Code::TidyAll::Result 0.69 - Code::TidyAll::Role::HasIgnore 0.69 - Code::TidyAll::Role::RunsCommand 0.69 - Code::TidyAll::Role::Tempdir 0.69 - Code::TidyAll::SVN::Precommit 0.69 - Code::TidyAll::SVN::Util 0.69 - Code::TidyAll::Util::Zglob 0.69 - Test::Code::TidyAll 0.69 + Code-TidyAll-0.84 + pathname: D/DR/DROLSKY/Code-TidyAll-0.84.tar.gz + provides: + Code::TidyAll 0.84 + Code::TidyAll::Cache 0.84 + Code::TidyAll::CacheModel 0.84 + Code::TidyAll::CacheModel::Shared 0.84 + Code::TidyAll::Config::INI::Reader 0.84 + Code::TidyAll::Git::Precommit 0.84 + Code::TidyAll::Git::Prereceive 0.84 + Code::TidyAll::Git::Util 0.84 + Code::TidyAll::Plugin 0.84 + Code::TidyAll::Plugin::CSSUnminifier 0.84 + Code::TidyAll::Plugin::GenericTransformer 0.84 + Code::TidyAll::Plugin::GenericValidator 0.84 + Code::TidyAll::Plugin::JSBeautify 0.84 + Code::TidyAll::Plugin::JSHint 0.84 + Code::TidyAll::Plugin::JSLint 0.84 + Code::TidyAll::Plugin::JSON 0.84 + Code::TidyAll::Plugin::MasonTidy 0.84 + Code::TidyAll::Plugin::PHPCodeSniffer 0.84 + Code::TidyAll::Plugin::PerlCritic 0.84 + Code::TidyAll::Plugin::PerlTidy 0.84 + Code::TidyAll::Plugin::PerlTidySweet 0.84 + Code::TidyAll::Plugin::PodChecker 0.84 + Code::TidyAll::Plugin::PodSpell 0.84 + Code::TidyAll::Plugin::PodTidy 0.84 + Code::TidyAll::Plugin::SortLines 0.84 + Code::TidyAll::Result 0.84 + Code::TidyAll::Role::GenericExecutable 0.84 + Code::TidyAll::Role::HasIgnore 0.84 + Code::TidyAll::Role::RunsCommand 0.84 + Code::TidyAll::Role::Tempdir 0.84 + Code::TidyAll::SVN::Precommit 0.84 + Code::TidyAll::SVN::Util 0.84 + Code::TidyAll::Util::Zglob 0.84 + Code::TidyAll::Zglob 0.84 + Test::Code::TidyAll 0.84 requirements: Capture::Tiny 0 Config::INI::Reader 0 @@ -1136,10 +907,10 @@ DISTRIBUTIONS Digest::SHA 0 Exporter 0 ExtUtils::MakeMaker 0 + File::Basename 0 File::Find 0 File::Spec 0 File::Which 0 - File::Zglob 0 File::pushd 0 Getopt::Long 0 IPC::Run3 0 @@ -1167,6 +938,7 @@ DISTRIBUTIONS Try::Tiny 0 base 0 constant 0 + perl 5.008008 strict 0 warnings 0 Code-TidyAll-Plugin-UniqueLines-0.000003 @@ -1181,10 +953,10 @@ DISTRIBUTIONS perl 5.006 strict 0 warnings 0 - Compress-Bzip2-2.26 - pathname: R/RU/RURBAN/Compress-Bzip2-2.26.tar.gz + Compress-Bzip2-2.28 + pathname: R/RU/RURBAN/Compress-Bzip2-2.28.tar.gz provides: - Compress::Bzip2 2.26 + Compress::Bzip2 2.28 requirements: Carp 0 Config 0 @@ -1195,10 +967,22 @@ DISTRIBUTIONS Getopt::Std 0 Test::More 0 constant 1.04 - Config-Any-0.32 - pathname: H/HA/HAARG/Config-Any-0.32.tar.gz + Compress-Raw-Bzip2-2.213 + pathname: P/PM/PMQS/Compress-Raw-Bzip2-2.213.tar.gz + provides: + Compress::Raw::Bzip2 2.213 + requirements: + ExtUtils::MakeMaker 0 + Compress-Raw-Zlib-2.213 + pathname: P/PM/PMQS/Compress-Raw-Zlib-2.213.tar.gz + provides: + Compress::Raw::Zlib 2.213 + requirements: + ExtUtils::MakeMaker 0 + Config-Any-0.33 + pathname: H/HA/HAARG/Config-Any-0.33.tar.gz provides: - Config::Any 0.32 + Config::Any 0.33 Config::Any::Base undef Config::Any::General undef Config::Any::INI undef @@ -1208,42 +992,41 @@ DISTRIBUTIONS Config::Any::YAML undef requirements: Module::Pluggable::Object 3.6 - Config-General-2.63 - pathname: T/TL/TLINDEN/Config-General-2.63.tar.gz + Config-General-2.67 + pathname: T/TL/TLINDEN/Config-General-2.67.tar.gz provides: - Config::General 2.63 + Config::General 2.67 Config::General::Extended 2.07 - Config::General::Interpolated 2.15 + Config::General::Interpolated 2.16 requirements: ExtUtils::MakeMaker 0 File::Glob 0 File::Spec::Functions 0 FileHandle 0 IO::File 0 - Config-INI-0.025 - pathname: R/RJ/RJBS/Config-INI-0.025.tar.gz + Config-INI-0.029 + pathname: R/RJ/RJBS/Config-INI-0.029.tar.gz provides: - Config::INI 0.025 - Config::INI::Reader 0.025 - Config::INI::Writer 0.025 + Config::INI 0.029 + Config::INI::Reader 0.029 + Config::INI::Writer 0.029 requirements: Carp 0 - ExtUtils::MakeMaker 0 - Mixin::Linewise::Readers 0.105 + ExtUtils::MakeMaker 6.78 + Mixin::Linewise::Readers 0.110 Mixin::Linewise::Writers 0 - strict 0 + perl 5.012 warnings 0 - Config-Tiny-2.23 - pathname: R/RS/RSAVAGE/Config-Tiny-2.23.tgz + Config-Tiny-2.30 + pathname: R/RS/RSAVAGE/Config-Tiny-2.30.tgz provides: - Config::Tiny 2.23 + Config::Tiny 2.30 requirements: ExtUtils::MakeMaker 0 - File::Spec 3.3 + File::Spec 3.30 File::Temp 0.22 Test::More 0.47 - UNIVERSAL 0 - perl v5.8.1 + perl 5.008001 strict 0 utf8 0 Config-ZOMG-1.000000 @@ -1271,66 +1054,74 @@ DISTRIBUTIONS perl 5.008 strict 0 warnings 0 - Context-Preserve-0.03 - pathname: E/ET/ETHER/Context-Preserve-0.03.tar.gz + Cookie-Baker-0.12 + pathname: K/KA/KAZEBURO/Cookie-Baker-0.12.tar.gz + provides: + Cookie::Baker 0.12 + requirements: + Exporter 0 + Module::Build::Tiny 0.035 + URI::Escape 0 + perl 5.008001 + Cpanel-JSON-XS-4.39 + pathname: R/RU/RURBAN/Cpanel-JSON-XS-4.39.tar.gz provides: - Context::Preserve 0.03 + Cpanel::JSON::XS 4.39 + Cpanel::JSON::XS::Type undef requirements: Carp 0 + Config 0 + Encode 1.9801 Exporter 0 ExtUtils::MakeMaker 0 - base 0 - perl 5.006 + Pod::Text 2.08 + XSLoader 0 + overload 0 strict 0 warnings 0 - Cookie-Baker-0.08 - pathname: K/KA/KAZEBURO/Cookie-Baker-0.08.tar.gz + Crypt-SysRandom-0.007 + pathname: L/LE/LEONT/Crypt-SysRandom-0.007.tar.gz provides: - Cookie::Baker 0.08 + Crypt::SysRandom 0.007 requirements: + Carp 0 Exporter 0 - Module::Build::Tiny 0.035 - URI::Escape 0 - perl 5.008001 - Cpanel-JSON-XS-3.0239 - pathname: R/RU/RURBAN/Cpanel-JSON-XS-3.0239.tar.gz - provides: - Cpanel::JSON::XS 3.0239 - requirements: ExtUtils::MakeMaker 0 - Pod::Text 2.08 - Crypt-DH-GMP-0.00012 - pathname: D/DM/DMAKI/Crypt-DH-GMP-0.00012.tar.gz + perl 5.006 + strict 0 + warnings 0 + Crypt-URandom-0.54 + pathname: D/DD/DDICK/Crypt-URandom-0.54.tar.gz provides: - Crypt::DH::GMP 0.00012 - Crypt::DH::GMP::Compat undef + Crypt::URandom 0.54 requirements: - Devel::CheckLib 0.4 - Devel::PPPort 3.19 - ExtUtils::MakeMaker 6.59 - ExtUtils::ParseXS 3.18 - Test::More 0 - Test::Requires 0 - XSLoader 0.02 - perl 5.0080001 - DBD-Pg-3.7.0 - pathname: T/TU/TURNSTEP/DBD-Pg-3.7.0.tar.gz + Carp 1.26 + English 0 + Exporter 0 + ExtUtils::MakeMaker 0 + FileHandle 0 + constant 0 + perl 5.006 + DBD-Pg-3.18.0 + pathname: T/TU/TURNSTEP/DBD-Pg-3.18.0.tar.gz provides: - Bundle::DBD::Pg v3.7.0 - DBD::Pg v3.7.0 + Bundle::DBD::Pg v3.18.0 + DBD::Pg v3.18.0 requirements: DBI 1.614 - ExtUtils::MakeMaker 6.11 + ExtUtils::MakeMaker 6.58 + File::Temp 0 Test::More 0.88 Time::HiRes 0 version 0 - DBD-SQLite-1.54 - pathname: I/IS/ISHIGAKI/DBD-SQLite-1.54.tar.gz + DBD-SQLite-1.76 + pathname: I/IS/ISHIGAKI/DBD-SQLite-1.76.tar.gz provides: - DBD::SQLite 1.54 + DBD::SQLite 1.76 DBD::SQLite::Constants undef - DBD::SQLite::VirtualTable 1.54 - DBD::SQLite::VirtualTable::Cursor 1.54 + DBD::SQLite::GetInfo undef + DBD::SQLite::VirtualTable 1.76 + DBD::SQLite::VirtualTable::Cursor 1.76 DBD::SQLite::VirtualTable::FileContent undef DBD::SQLite::VirtualTable::FileContent::Cursor undef DBD::SQLite::VirtualTable::PerlData undef @@ -1339,12 +1130,11 @@ DISTRIBUTIONS DBI 1.57 ExtUtils::MakeMaker 0 File::Spec 0.82 - Test::Builder 0.86 - Test::More 0.47 + Test::More 0.88 Tie::Hash 0 perl 5.006 - DBI-1.637 - pathname: T/TI/TIMB/DBI-1.637.tar.gz + DBI-1.647 + pathname: H/HM/HMBRAND/DBI-1.647.tgz provides: Bundle::DBI 12.008696 DBD::DBM 0.08 @@ -1379,6 +1169,13 @@ DISTRIBUTIONS DBD::Gofer::db 0.015327 DBD::Gofer::dr 0.015327 DBD::Gofer::st 0.015327 + DBD::Mem 0.001 + DBD::Mem::DataSource 0.001 + DBD::Mem::Statement 0.001 + DBD::Mem::Table 0.001 + DBD::Mem::db 0.001 + DBD::Mem::dr 0.001 + DBD::Mem::st 0.001 DBD::NullP 12.014715 DBD::NullP::db 12.014715 DBD::NullP::dr 12.014715 @@ -1393,7 +1190,7 @@ DISTRIBUTIONS DBD::Sponge::dr 12.010003 DBD::Sponge::st 12.010003 DBDI 12.015129 - DBI 1.637 + DBI 1.647 DBI::Const::GetInfo::ANSI 2.008697 DBI::Const::GetInfo::ODBC 2.011374 DBI::Const::GetInfoReturn 2.008697 @@ -1433,174 +1230,27 @@ DISTRIBUTIONS DBI::SQL::Nano::Table_ 1.015544 DBI::Util::CacheMemory 0.010315 DBI::Util::_accessor 0.009479 - DBI::common 1.637 + DBI::common 1.647 requirements: ExtUtils::MakeMaker 6.48 Test::Simple 0.90 - perl 5.008 - DBIx-Class-0.082840 - pathname: R/RI/RIBASUSHI/DBIx-Class-0.082840.tar.gz - provides: - DBIx::Class 0.082840 - DBIx::Class::AccessorGroup undef - DBIx::Class::Admin undef - DBIx::Class::CDBICompat undef - DBIx::Class::Core undef - DBIx::Class::Cursor undef - DBIx::Class::DB undef - DBIx::Class::Exception undef - DBIx::Class::FilterColumn undef - DBIx::Class::InflateColumn undef - DBIx::Class::InflateColumn::DateTime undef - DBIx::Class::InflateColumn::File undef - DBIx::Class::Optional::Dependencies undef - DBIx::Class::Ordered undef - DBIx::Class::PK undef - DBIx::Class::PK::Auto undef - DBIx::Class::Relationship undef - DBIx::Class::Relationship::Base undef - DBIx::Class::ResultClass::HashRefInflator undef - DBIx::Class::ResultSet undef - DBIx::Class::ResultSetColumn undef - DBIx::Class::ResultSetManager undef - DBIx::Class::ResultSource undef - DBIx::Class::ResultSource::Table undef - DBIx::Class::ResultSource::View undef - DBIx::Class::ResultSourceHandle undef - DBIx::Class::ResultSourceProxy::Table undef - DBIx::Class::Row undef - DBIx::Class::SQLMaker undef - DBIx::Class::SQLMaker::LimitDialects undef - DBIx::Class::SQLMaker::OracleJoins undef - DBIx::Class::Schema undef - DBIx::Class::Schema::Versioned undef - DBIx::Class::Serialize::Storable undef - DBIx::Class::StartupCheck undef - DBIx::Class::Storage undef - DBIx::Class::Storage::DBI undef - DBIx::Class::Storage::DBI::ACCESS undef - DBIx::Class::Storage::DBI::ADO undef - DBIx::Class::Storage::DBI::ADO::MS_Jet undef - DBIx::Class::Storage::DBI::ADO::MS_Jet::Cursor undef - DBIx::Class::Storage::DBI::ADO::Microsoft_SQL_Server undef - DBIx::Class::Storage::DBI::ADO::Microsoft_SQL_Server::Cursor undef - DBIx::Class::Storage::DBI::AutoCast undef - DBIx::Class::Storage::DBI::Cursor undef - DBIx::Class::Storage::DBI::DB2 undef - DBIx::Class::Storage::DBI::Firebird undef - DBIx::Class::Storage::DBI::Firebird::Common undef - DBIx::Class::Storage::DBI::IdentityInsert undef - DBIx::Class::Storage::DBI::Informix undef - DBIx::Class::Storage::DBI::InterBase undef - DBIx::Class::Storage::DBI::MSSQL undef - DBIx::Class::Storage::DBI::NoBindVars undef - DBIx::Class::Storage::DBI::ODBC undef - DBIx::Class::Storage::DBI::ODBC::ACCESS undef - DBIx::Class::Storage::DBI::ODBC::DB2_400_SQL undef - DBIx::Class::Storage::DBI::ODBC::Firebird undef - DBIx::Class::Storage::DBI::ODBC::Microsoft_SQL_Server undef - DBIx::Class::Storage::DBI::ODBC::SQL_Anywhere undef - DBIx::Class::Storage::DBI::Oracle undef - DBIx::Class::Storage::DBI::Oracle::Generic undef - DBIx::Class::Storage::DBI::Oracle::WhereJoins undef - DBIx::Class::Storage::DBI::Pg undef - DBIx::Class::Storage::DBI::Replicated undef - DBIx::Class::Storage::DBI::Replicated::Balancer undef - DBIx::Class::Storage::DBI::Replicated::Balancer::First undef - DBIx::Class::Storage::DBI::Replicated::Balancer::Random undef - DBIx::Class::Storage::DBI::Replicated::Pool undef - DBIx::Class::Storage::DBI::Replicated::Replicant undef - DBIx::Class::Storage::DBI::Replicated::WithDSN undef - DBIx::Class::Storage::DBI::SQLAnywhere undef - DBIx::Class::Storage::DBI::SQLAnywhere::Cursor undef - DBIx::Class::Storage::DBI::SQLite undef - DBIx::Class::Storage::DBI::Sybase undef - DBIx::Class::Storage::DBI::Sybase::ASE undef - DBIx::Class::Storage::DBI::Sybase::ASE::NoBindVars undef - DBIx::Class::Storage::DBI::Sybase::FreeTDS undef - DBIx::Class::Storage::DBI::Sybase::MSSQL undef - DBIx::Class::Storage::DBI::Sybase::Microsoft_SQL_Server undef - DBIx::Class::Storage::DBI::Sybase::Microsoft_SQL_Server::NoBindVars undef - DBIx::Class::Storage::DBI::UniqueIdentifier undef - DBIx::Class::Storage::DBI::mysql undef - DBIx::Class::Storage::Statistics undef - DBIx::Class::Storage::TxnScopeGuard undef - DBIx::Class::UTF8Columns undef - SQL::Translator::Parser::DBIx::Class 1.10 - SQL::Translator::Producer::DBIx::Class::File 0.1 - requirements: - Class::Accessor::Grouped 0.10012 - Class::C3::Componentised 1.0009 - Class::Inspector 1.24 - Config::Any 0.20 - Context::Preserve 0.01 - DBD::SQLite 1.29 - DBI 1.57 - Data::Dumper::Concise 2.020 - Data::Page 2.00 - Devel::GlobalDestruction 0.09 - ExtUtils::MakeMaker 6.59 - File::Temp 0.22 - Hash::Merge 0.12 - List::Util 1.16 - MRO::Compat 0.12 - Module::Find 0.07 - Moo 2.000 - Package::Stash 0.28 - Path::Class 0.18 - SQL::Abstract 1.81 - Scope::Guard 0.03 - Sub::Name 0.04 - Test::Deep 0.101 - Test::Exception 0.31 - Test::More 0.94 - Test::Warn 0.21 - Text::Balanced 2.00 - Try::Tiny 0.07 - namespace::clean 0.24 perl 5.008001 - Data-Compare-1.25 - pathname: D/DC/DCANTRELL/Data-Compare-1.25.tar.gz + Data-Compare-1.29 + pathname: D/DC/DCANTRELL/Data-Compare-1.29.tar.gz provides: - Data::Compare 1.25 - Data::Compare::Plugins::Scalar::Properties 1 + Data::Compare 1.29 + Data::Compare::Plugins::Scalar::Properties 1.25 requirements: - ExtUtils::MakeMaker 0 + Clone 0.43 + ExtUtils::MakeMaker 6.48 File::Find::Rule 0.1 Scalar::Util 0 - Data-DPath-0.57 - pathname: S/SC/SCHWIGON/Data-DPath-0.57.tar.gz - provides: - Data::DPath 0.57 - Data::DPath::Attrs 0.57 - Data::DPath::Context 0.57 - Data::DPath::Filters 0.57 - Data::DPath::Path 0.57 - Data::DPath::Point 0.57 - Data::DPath::Step 0.57 - requirements: - Class::XSAccessor 0 - Class::XSAccessor::Array 0 - Data::Dumper 0 - ExtUtils::MakeMaker 0 - Iterator::Util 0 - List::MoreUtils 0 - List::Util 0 - POSIX 0 - Safe 2.30 - Scalar::Util 0 - Sub::Exporter 0 - Text::Balanced 2.02 - aliased 0.33 - constant 0 - if 0 - perl 5.008 - strict 0 - warnings 0 - Data-Dump-1.23 - pathname: G/GA/GAAS/Data-Dump-1.23.tar.gz + Test::More 0.88 + perl 5.006 + Data-Dump-1.25 + pathname: G/GA/GARU/Data-Dump-1.25.tar.gz provides: - Data::Dump 1.23 + Data::Dump 1.25 Data::Dump::FilterContext undef Data::Dump::Filtered undef Data::Dump::Trace 0.02 @@ -1622,109 +1272,86 @@ DISTRIBUTIONS Exporter 0 ExtUtils::MakeMaker 0 perl 5.006 - Data-OptList-0.110 - pathname: R/RJ/RJBS/Data-OptList-0.110.tar.gz + Data-OptList-0.114 + pathname: R/RJ/RJBS/Data-OptList-0.114.tar.gz provides: - Data::OptList 0.110 + Data::OptList 0.114 requirements: - ExtUtils::MakeMaker 0 + ExtUtils::MakeMaker 6.78 List::Util 0 Params::Util 0 Sub::Install 0.921 + perl 5.012 strict 0 warnings 0 - Data-Page-2.02 - pathname: L/LB/LBROCARD/Data-Page-2.02.tar.gz - provides: - Data::Page 2.02 - requirements: - Class::Accessor::Chained::Fast 0 - Test::Exception 0 - Test::More 0 - Data-Printer-0.40 - pathname: G/GA/GARU/Data-Printer-0.40.tar.gz - provides: - DDP undef - Data::Printer 0.40 - Data::Printer::Filter undef - Data::Printer::Filter::DB undef - Data::Printer::Filter::DateTime undef - Data::Printer::Filter::Digest undef - requirements: - Carp 0 - Clone::PP 0 - ExtUtils::MakeMaker 0 - Fcntl 0 - File::HomeDir 0.91 - File::Spec 0 - File::Temp 0 - Package::Stash 0.3 - Scalar::Util 0 - Sort::Naturally 0 - Term::ANSIColor 3 - Test::More 0.88 - version 0.77 - Data-Section-0.200007 - pathname: R/RJ/RJBS/Data-Section-0.200007.tar.gz + Data-Section-0.200008 + pathname: R/RJ/RJBS/Data-Section-0.200008.tar.gz provides: - Data::Section 0.200007 + Data::Section 0.200008 requirements: Encode 0 - ExtUtils::MakeMaker 0 + ExtUtils::MakeMaker 6.78 MRO::Compat 0.09 Sub::Exporter 0.979 + perl 5.012 strict 0 warnings 0 - Data-UUID-1.221 - pathname: R/RJ/RJBS/Data-UUID-1.221.tar.gz + Data-UUID-1.227 + pathname: G/GT/GTERMARS/Data-UUID-1.227.tar.gz provides: - Data::UUID 1.221 + Data::UUID 1.227 requirements: Digest::MD5 0 ExtUtils::MakeMaker 0 - Data-Visitor-0.30 - pathname: D/DO/DOY/Data-Visitor-0.30.tar.gz + Data-Visitor-0.32 + pathname: E/ET/ETHER/Data-Visitor-0.32.tar.gz provides: - Data::Visitor 0.30 - Data::Visitor::Callback 0.30 + Data::Visitor 0.32 + Data::Visitor::Callback 0.32 requirements: - Class::Load 0.06 - ExtUtils::MakeMaker 6.30 + Carp 0 + ExtUtils::MakeMaker 0 Moose 0.89 - Task::Weaken 0 + Scalar::Util 0 + Symbol 0 Tie::ToObject 0.01 + constant 0 namespace::clean 0.19 - DateTime-1.44 - pathname: D/DR/DROLSKY/DateTime-1.44.tar.gz - provides: - DateTime 1.44 - DateTime::Duration 1.44 - DateTime::Helpers 1.44 - DateTime::Infinite 1.44 - DateTime::Infinite::Future 1.44 - DateTime::Infinite::Past 1.44 - DateTime::LeapSecond 1.44 - DateTime::PP 1.44 - DateTime::PPExtra 1.44 - DateTime::Types 1.44 + overload 0 + perl 5.006 + strict 0 + warnings 0 + DateTime-1.66 + pathname: D/DR/DROLSKY/DateTime-1.66.tar.gz + provides: + DateTime 1.66 + DateTime::Duration 1.66 + DateTime::Helpers 1.66 + DateTime::Infinite 1.66 + DateTime::Infinite::Future 1.66 + DateTime::Infinite::Past 1.66 + DateTime::LeapSecond 1.66 + DateTime::PP 1.66 + DateTime::PPExtra 1.66 + DateTime::Types 1.66 requirements: Carp 0 DateTime::Locale 1.06 - DateTime::TimeZone 2.02 + DateTime::TimeZone 2.44 Dist::CheckConflicts 0.02 ExtUtils::MakeMaker 0 POSIX 0 - Params::ValidationCompiler 0.13 + Params::ValidationCompiler 0.26 Scalar::Util 0 - Specio 0.18 + Specio 0.50 Specio::Declare 0 Specio::Exporter 0 Specio::Library::Builtins 0 Specio::Library::Numeric 0 Specio::Library::String 0 + Specio::Subs 0 Try::Tiny 0 XSLoader 0 - base 0 integer 0 namespace::autoclean 0.19 overload 0 @@ -1733,29 +1360,25 @@ DISTRIBUTIONS strict 0 warnings 0 warnings::register 0 - DateTime-Format-Builder-0.81 - pathname: D/DR/DROLSKY/DateTime-Format-Builder-0.81.tar.gz - provides: - DateTime::Format::Builder 0.81 - DateTime::Format::Builder::Parser 0.81 - DateTime::Format::Builder::Parser::Dispatch 0.81 - DateTime::Format::Builder::Parser::Quick 0.81 - DateTime::Format::Builder::Parser::Regex 0.81 - DateTime::Format::Builder::Parser::Strptime 0.81 - DateTime::Format::Builder::Parser::generic 0.81 - DateTime::Format::Fall undef - DateTime::Format::Simple undef + DateTime-Format-Builder-0.83 + pathname: D/DR/DROLSKY/DateTime-Format-Builder-0.83.tar.gz + provides: + DateTime::Format::Builder 0.83 + DateTime::Format::Builder::Parser 0.83 + DateTime::Format::Builder::Parser::Dispatch 0.83 + DateTime::Format::Builder::Parser::Quick 0.83 + DateTime::Format::Builder::Parser::Regex 0.83 + DateTime::Format::Builder::Parser::Strptime 0.83 + DateTime::Format::Builder::Parser::generic 0.83 requirements: Carp 0 - Class::Factory::Util 1.6 DateTime 1.00 DateTime::Format::Strptime 1.04 - ExtUtils::MakeMaker 6.30 + ExtUtils::MakeMaker 0 Params::Validate 0.72 Scalar::Util 0 - base 0 + parent 0 strict 0 - vars 0 warnings 0 DateTime-Format-Epoch-0.16 pathname: C/CH/CHORNY/DateTime-Format-Epoch-0.16.tar.gz @@ -1780,38 +1403,50 @@ DISTRIBUTIONS Test::More 0 perl 5.00503 warnings 0 - DateTime-Format-ISO8601-0.08 - pathname: J/JH/JHOBLITT/DateTime-Format-ISO8601-0.08.tar.gz + DateTime-Format-ISO8601-0.17 + pathname: D/DR/DROLSKY/DateTime-Format-ISO8601-0.17.tar.gz provides: - DateTime::Format::ISO8601 0.08 + DateTime::Format::ISO8601 0.17 + DateTime::Format::ISO8601::Types 0.17 requirements: - DateTime 0.18 + Carp 0 + DateTime 1.45 DateTime::Format::Builder 0.77 - DateTime-Format-RFC3339-v1.2.0 - pathname: I/IK/IKEGAMI/DateTime-Format-RFC3339-v1.2.0.tar.gz + ExtUtils::MakeMaker 0 + Params::ValidationCompiler 0.26 + Specio 0.18 + Specio::Declare 0 + Specio::Exporter 0 + Specio::Library::Builtins 0 + namespace::autoclean 0 + parent 0 + strict 0 + warnings 0 + DateTime-Format-RFC3339-v1.10.0 + pathname: I/IK/IKEGAMI/DateTime-Format-RFC3339-v1.10.0.tar.gz provides: - DateTime::Format::RFC3339 1.002000 + DateTime::Format::RFC3339 1.010000 requirements: DateTime 0 ExtUtils::MakeMaker 0 + perl 5.01 strict 0 version 0 warnings 0 - DateTime-Format-Strptime-1.74 - pathname: D/DR/DROLSKY/DateTime-Format-Strptime-1.74.tar.gz + DateTime-Format-Strptime-1.79 + pathname: D/DR/DROLSKY/DateTime-Format-Strptime-1.79.tar.gz provides: - DateTime::Format::Strptime 1.74 - DateTime::Format::Strptime::Types 1.74 + DateTime::Format::Strptime 1.79 + DateTime::Format::Strptime::Types 1.79 requirements: Carp 0 DateTime 1.00 - DateTime::Locale 1.05 + DateTime::Locale 1.30 DateTime::Locale::Base 0 DateTime::Locale::FromData 0 DateTime::TimeZone 2.09 Exporter 0 ExtUtils::MakeMaker 0 - Package::DeprecationManager 0.15 Params::ValidationCompiler 0 Specio 0.33 Specio::Declare 0 @@ -1823,15 +1458,15 @@ DISTRIBUTIONS parent 0 strict 0 warnings 0 - DateTime-Locale-1.17 - pathname: D/DR/DROLSKY/DateTime-Locale-1.17.tar.gz + DateTime-Locale-1.45 + pathname: D/DR/DROLSKY/DateTime-Locale-1.45.tar.gz provides: - DateTime::Locale 1.17 - DateTime::Locale::Base 1.17 - DateTime::Locale::Catalog 1.17 - DateTime::Locale::Data 1.17 - DateTime::Locale::FromData 1.17 - DateTime::Locale::Util 1.17 + DateTime::Locale 1.45 + DateTime::Locale::Base 1.45 + DateTime::Locale::Catalog 1.45 + DateTime::Locale::Data 1.45 + DateTime::Locale::FromData 1.45 + DateTime::Locale::Util 1.45 requirements: Carp 0 Dist::CheckConflicts 0.02 @@ -1839,388 +1474,345 @@ DISTRIBUTIONS ExtUtils::MakeMaker 0 File::ShareDir 0 File::ShareDir::Install 0.06 + File::Spec 0 List::Util 1.45 Params::ValidationCompiler 0.13 Specio::Declare 0 Specio::Library::String 0 + Storable 0 namespace::autoclean 0.19 perl 5.008004 strict 0 warnings 0 - DateTime-TimeZone-2.15 - pathname: D/DR/DROLSKY/DateTime-TimeZone-2.15.tar.gz - provides: - DateTime::TimeZone 2.15 - DateTime::TimeZone::Africa::Abidjan 2.15 - DateTime::TimeZone::Africa::Accra 2.15 - DateTime::TimeZone::Africa::Algiers 2.15 - DateTime::TimeZone::Africa::Bissau 2.15 - DateTime::TimeZone::Africa::Cairo 2.15 - DateTime::TimeZone::Africa::Casablanca 2.15 - DateTime::TimeZone::Africa::Ceuta 2.15 - DateTime::TimeZone::Africa::El_Aaiun 2.15 - DateTime::TimeZone::Africa::Johannesburg 2.15 - DateTime::TimeZone::Africa::Juba 2.15 - DateTime::TimeZone::Africa::Khartoum 2.15 - DateTime::TimeZone::Africa::Lagos 2.15 - DateTime::TimeZone::Africa::Maputo 2.15 - DateTime::TimeZone::Africa::Monrovia 2.15 - DateTime::TimeZone::Africa::Nairobi 2.15 - DateTime::TimeZone::Africa::Ndjamena 2.15 - DateTime::TimeZone::Africa::Tripoli 2.15 - DateTime::TimeZone::Africa::Tunis 2.15 - DateTime::TimeZone::Africa::Windhoek 2.15 - DateTime::TimeZone::America::Adak 2.15 - DateTime::TimeZone::America::Anchorage 2.15 - DateTime::TimeZone::America::Araguaina 2.15 - DateTime::TimeZone::America::Argentina::Buenos_Aires 2.15 - DateTime::TimeZone::America::Argentina::Catamarca 2.15 - DateTime::TimeZone::America::Argentina::Cordoba 2.15 - DateTime::TimeZone::America::Argentina::Jujuy 2.15 - DateTime::TimeZone::America::Argentina::La_Rioja 2.15 - DateTime::TimeZone::America::Argentina::Mendoza 2.15 - DateTime::TimeZone::America::Argentina::Rio_Gallegos 2.15 - DateTime::TimeZone::America::Argentina::Salta 2.15 - DateTime::TimeZone::America::Argentina::San_Juan 2.15 - DateTime::TimeZone::America::Argentina::San_Luis 2.15 - DateTime::TimeZone::America::Argentina::Tucuman 2.15 - DateTime::TimeZone::America::Argentina::Ushuaia 2.15 - DateTime::TimeZone::America::Asuncion 2.15 - DateTime::TimeZone::America::Atikokan 2.15 - DateTime::TimeZone::America::Bahia 2.15 - DateTime::TimeZone::America::Bahia_Banderas 2.15 - DateTime::TimeZone::America::Barbados 2.15 - DateTime::TimeZone::America::Belem 2.15 - DateTime::TimeZone::America::Belize 2.15 - DateTime::TimeZone::America::Blanc_Sablon 2.15 - DateTime::TimeZone::America::Boa_Vista 2.15 - DateTime::TimeZone::America::Bogota 2.15 - DateTime::TimeZone::America::Boise 2.15 - DateTime::TimeZone::America::Cambridge_Bay 2.15 - DateTime::TimeZone::America::Campo_Grande 2.15 - DateTime::TimeZone::America::Cancun 2.15 - DateTime::TimeZone::America::Caracas 2.15 - DateTime::TimeZone::America::Cayenne 2.15 - DateTime::TimeZone::America::Chicago 2.15 - DateTime::TimeZone::America::Chihuahua 2.15 - DateTime::TimeZone::America::Costa_Rica 2.15 - DateTime::TimeZone::America::Creston 2.15 - DateTime::TimeZone::America::Cuiaba 2.15 - DateTime::TimeZone::America::Curacao 2.15 - DateTime::TimeZone::America::Danmarkshavn 2.15 - DateTime::TimeZone::America::Dawson 2.15 - DateTime::TimeZone::America::Dawson_Creek 2.15 - DateTime::TimeZone::America::Denver 2.15 - DateTime::TimeZone::America::Detroit 2.15 - DateTime::TimeZone::America::Edmonton 2.15 - DateTime::TimeZone::America::Eirunepe 2.15 - DateTime::TimeZone::America::El_Salvador 2.15 - DateTime::TimeZone::America::Fort_Nelson 2.15 - DateTime::TimeZone::America::Fortaleza 2.15 - DateTime::TimeZone::America::Glace_Bay 2.15 - DateTime::TimeZone::America::Godthab 2.15 - DateTime::TimeZone::America::Goose_Bay 2.15 - DateTime::TimeZone::America::Grand_Turk 2.15 - DateTime::TimeZone::America::Guatemala 2.15 - DateTime::TimeZone::America::Guayaquil 2.15 - DateTime::TimeZone::America::Guyana 2.15 - DateTime::TimeZone::America::Halifax 2.15 - DateTime::TimeZone::America::Havana 2.15 - DateTime::TimeZone::America::Hermosillo 2.15 - DateTime::TimeZone::America::Indiana::Indianapolis 2.15 - DateTime::TimeZone::America::Indiana::Knox 2.15 - DateTime::TimeZone::America::Indiana::Marengo 2.15 - DateTime::TimeZone::America::Indiana::Petersburg 2.15 - DateTime::TimeZone::America::Indiana::Tell_City 2.15 - DateTime::TimeZone::America::Indiana::Vevay 2.15 - DateTime::TimeZone::America::Indiana::Vincennes 2.15 - DateTime::TimeZone::America::Indiana::Winamac 2.15 - DateTime::TimeZone::America::Inuvik 2.15 - DateTime::TimeZone::America::Iqaluit 2.15 - DateTime::TimeZone::America::Jamaica 2.15 - DateTime::TimeZone::America::Juneau 2.15 - DateTime::TimeZone::America::Kentucky::Louisville 2.15 - DateTime::TimeZone::America::Kentucky::Monticello 2.15 - DateTime::TimeZone::America::La_Paz 2.15 - DateTime::TimeZone::America::Lima 2.15 - DateTime::TimeZone::America::Los_Angeles 2.15 - DateTime::TimeZone::America::Maceio 2.15 - DateTime::TimeZone::America::Managua 2.15 - DateTime::TimeZone::America::Manaus 2.15 - DateTime::TimeZone::America::Martinique 2.15 - DateTime::TimeZone::America::Matamoros 2.15 - DateTime::TimeZone::America::Mazatlan 2.15 - DateTime::TimeZone::America::Menominee 2.15 - DateTime::TimeZone::America::Merida 2.15 - DateTime::TimeZone::America::Metlakatla 2.15 - DateTime::TimeZone::America::Mexico_City 2.15 - DateTime::TimeZone::America::Miquelon 2.15 - DateTime::TimeZone::America::Moncton 2.15 - DateTime::TimeZone::America::Monterrey 2.15 - DateTime::TimeZone::America::Montevideo 2.15 - DateTime::TimeZone::America::Nassau 2.15 - DateTime::TimeZone::America::New_York 2.15 - DateTime::TimeZone::America::Nipigon 2.15 - DateTime::TimeZone::America::Nome 2.15 - DateTime::TimeZone::America::Noronha 2.15 - DateTime::TimeZone::America::North_Dakota::Beulah 2.15 - DateTime::TimeZone::America::North_Dakota::Center 2.15 - DateTime::TimeZone::America::North_Dakota::New_Salem 2.15 - DateTime::TimeZone::America::Ojinaga 2.15 - DateTime::TimeZone::America::Panama 2.15 - DateTime::TimeZone::America::Pangnirtung 2.15 - DateTime::TimeZone::America::Paramaribo 2.15 - DateTime::TimeZone::America::Phoenix 2.15 - DateTime::TimeZone::America::Port_au_Prince 2.15 - DateTime::TimeZone::America::Port_of_Spain 2.15 - DateTime::TimeZone::America::Porto_Velho 2.15 - DateTime::TimeZone::America::Puerto_Rico 2.15 - DateTime::TimeZone::America::Punta_Arenas 2.15 - DateTime::TimeZone::America::Rainy_River 2.15 - DateTime::TimeZone::America::Rankin_Inlet 2.15 - DateTime::TimeZone::America::Recife 2.15 - DateTime::TimeZone::America::Regina 2.15 - DateTime::TimeZone::America::Resolute 2.15 - DateTime::TimeZone::America::Rio_Branco 2.15 - DateTime::TimeZone::America::Santarem 2.15 - DateTime::TimeZone::America::Santiago 2.15 - DateTime::TimeZone::America::Santo_Domingo 2.15 - DateTime::TimeZone::America::Sao_Paulo 2.15 - DateTime::TimeZone::America::Scoresbysund 2.15 - DateTime::TimeZone::America::Sitka 2.15 - DateTime::TimeZone::America::St_Johns 2.15 - DateTime::TimeZone::America::Swift_Current 2.15 - DateTime::TimeZone::America::Tegucigalpa 2.15 - DateTime::TimeZone::America::Thule 2.15 - DateTime::TimeZone::America::Thunder_Bay 2.15 - DateTime::TimeZone::America::Tijuana 2.15 - DateTime::TimeZone::America::Toronto 2.15 - DateTime::TimeZone::America::Vancouver 2.15 - DateTime::TimeZone::America::Whitehorse 2.15 - DateTime::TimeZone::America::Winnipeg 2.15 - DateTime::TimeZone::America::Yakutat 2.15 - DateTime::TimeZone::America::Yellowknife 2.15 - DateTime::TimeZone::Antarctica::Casey 2.15 - DateTime::TimeZone::Antarctica::Davis 2.15 - DateTime::TimeZone::Antarctica::DumontDUrville 2.15 - DateTime::TimeZone::Antarctica::Macquarie 2.15 - DateTime::TimeZone::Antarctica::Mawson 2.15 - DateTime::TimeZone::Antarctica::Palmer 2.15 - DateTime::TimeZone::Antarctica::Rothera 2.15 - DateTime::TimeZone::Antarctica::Syowa 2.15 - DateTime::TimeZone::Antarctica::Troll 2.15 - DateTime::TimeZone::Antarctica::Vostok 2.15 - DateTime::TimeZone::Asia::Almaty 2.15 - DateTime::TimeZone::Asia::Amman 2.15 - DateTime::TimeZone::Asia::Anadyr 2.15 - DateTime::TimeZone::Asia::Aqtau 2.15 - DateTime::TimeZone::Asia::Aqtobe 2.15 - DateTime::TimeZone::Asia::Ashgabat 2.15 - DateTime::TimeZone::Asia::Atyrau 2.15 - DateTime::TimeZone::Asia::Baghdad 2.15 - DateTime::TimeZone::Asia::Baku 2.15 - DateTime::TimeZone::Asia::Bangkok 2.15 - DateTime::TimeZone::Asia::Barnaul 2.15 - DateTime::TimeZone::Asia::Beirut 2.15 - DateTime::TimeZone::Asia::Bishkek 2.15 - DateTime::TimeZone::Asia::Brunei 2.15 - DateTime::TimeZone::Asia::Chita 2.15 - DateTime::TimeZone::Asia::Choibalsan 2.15 - DateTime::TimeZone::Asia::Colombo 2.15 - DateTime::TimeZone::Asia::Damascus 2.15 - DateTime::TimeZone::Asia::Dhaka 2.15 - DateTime::TimeZone::Asia::Dili 2.15 - DateTime::TimeZone::Asia::Dubai 2.15 - DateTime::TimeZone::Asia::Dushanbe 2.15 - DateTime::TimeZone::Asia::Famagusta 2.15 - DateTime::TimeZone::Asia::Gaza 2.15 - DateTime::TimeZone::Asia::Hebron 2.15 - DateTime::TimeZone::Asia::Ho_Chi_Minh 2.15 - DateTime::TimeZone::Asia::Hong_Kong 2.15 - DateTime::TimeZone::Asia::Hovd 2.15 - DateTime::TimeZone::Asia::Irkutsk 2.15 - DateTime::TimeZone::Asia::Jakarta 2.15 - DateTime::TimeZone::Asia::Jayapura 2.15 - DateTime::TimeZone::Asia::Jerusalem 2.15 - DateTime::TimeZone::Asia::Kabul 2.15 - DateTime::TimeZone::Asia::Kamchatka 2.15 - DateTime::TimeZone::Asia::Karachi 2.15 - DateTime::TimeZone::Asia::Kathmandu 2.15 - DateTime::TimeZone::Asia::Khandyga 2.15 - DateTime::TimeZone::Asia::Kolkata 2.15 - DateTime::TimeZone::Asia::Krasnoyarsk 2.15 - DateTime::TimeZone::Asia::Kuala_Lumpur 2.15 - DateTime::TimeZone::Asia::Kuching 2.15 - DateTime::TimeZone::Asia::Macau 2.15 - DateTime::TimeZone::Asia::Magadan 2.15 - DateTime::TimeZone::Asia::Makassar 2.15 - DateTime::TimeZone::Asia::Manila 2.15 - DateTime::TimeZone::Asia::Nicosia 2.15 - DateTime::TimeZone::Asia::Novokuznetsk 2.15 - DateTime::TimeZone::Asia::Novosibirsk 2.15 - DateTime::TimeZone::Asia::Omsk 2.15 - DateTime::TimeZone::Asia::Oral 2.15 - DateTime::TimeZone::Asia::Pontianak 2.15 - DateTime::TimeZone::Asia::Pyongyang 2.15 - DateTime::TimeZone::Asia::Qatar 2.15 - DateTime::TimeZone::Asia::Qyzylorda 2.15 - DateTime::TimeZone::Asia::Riyadh 2.15 - DateTime::TimeZone::Asia::Sakhalin 2.15 - DateTime::TimeZone::Asia::Samarkand 2.15 - DateTime::TimeZone::Asia::Seoul 2.15 - DateTime::TimeZone::Asia::Shanghai 2.15 - DateTime::TimeZone::Asia::Singapore 2.15 - DateTime::TimeZone::Asia::Srednekolymsk 2.15 - DateTime::TimeZone::Asia::Taipei 2.15 - DateTime::TimeZone::Asia::Tashkent 2.15 - DateTime::TimeZone::Asia::Tbilisi 2.15 - DateTime::TimeZone::Asia::Tehran 2.15 - DateTime::TimeZone::Asia::Thimphu 2.15 - DateTime::TimeZone::Asia::Tokyo 2.15 - DateTime::TimeZone::Asia::Tomsk 2.15 - DateTime::TimeZone::Asia::Ulaanbaatar 2.15 - DateTime::TimeZone::Asia::Urumqi 2.15 - DateTime::TimeZone::Asia::Ust_Nera 2.15 - DateTime::TimeZone::Asia::Vladivostok 2.15 - DateTime::TimeZone::Asia::Yakutsk 2.15 - DateTime::TimeZone::Asia::Yangon 2.15 - DateTime::TimeZone::Asia::Yekaterinburg 2.15 - DateTime::TimeZone::Asia::Yerevan 2.15 - DateTime::TimeZone::Atlantic::Azores 2.15 - DateTime::TimeZone::Atlantic::Bermuda 2.15 - DateTime::TimeZone::Atlantic::Canary 2.15 - DateTime::TimeZone::Atlantic::Cape_Verde 2.15 - DateTime::TimeZone::Atlantic::Faroe 2.15 - DateTime::TimeZone::Atlantic::Madeira 2.15 - DateTime::TimeZone::Atlantic::Reykjavik 2.15 - DateTime::TimeZone::Atlantic::South_Georgia 2.15 - DateTime::TimeZone::Atlantic::Stanley 2.15 - DateTime::TimeZone::Australia::Adelaide 2.15 - DateTime::TimeZone::Australia::Brisbane 2.15 - DateTime::TimeZone::Australia::Broken_Hill 2.15 - DateTime::TimeZone::Australia::Currie 2.15 - DateTime::TimeZone::Australia::Darwin 2.15 - DateTime::TimeZone::Australia::Eucla 2.15 - DateTime::TimeZone::Australia::Hobart 2.15 - DateTime::TimeZone::Australia::Lindeman 2.15 - DateTime::TimeZone::Australia::Lord_Howe 2.15 - DateTime::TimeZone::Australia::Melbourne 2.15 - DateTime::TimeZone::Australia::Perth 2.15 - DateTime::TimeZone::Australia::Sydney 2.15 - DateTime::TimeZone::CET 2.15 - DateTime::TimeZone::CST6CDT 2.15 - DateTime::TimeZone::Catalog 2.15 - DateTime::TimeZone::EET 2.15 - DateTime::TimeZone::EST 2.15 - DateTime::TimeZone::EST5EDT 2.15 - DateTime::TimeZone::Europe::Amsterdam 2.15 - DateTime::TimeZone::Europe::Andorra 2.15 - DateTime::TimeZone::Europe::Astrakhan 2.15 - DateTime::TimeZone::Europe::Athens 2.15 - DateTime::TimeZone::Europe::Belgrade 2.15 - DateTime::TimeZone::Europe::Berlin 2.15 - DateTime::TimeZone::Europe::Brussels 2.15 - DateTime::TimeZone::Europe::Bucharest 2.15 - DateTime::TimeZone::Europe::Budapest 2.15 - DateTime::TimeZone::Europe::Chisinau 2.15 - DateTime::TimeZone::Europe::Copenhagen 2.15 - DateTime::TimeZone::Europe::Dublin 2.15 - DateTime::TimeZone::Europe::Gibraltar 2.15 - DateTime::TimeZone::Europe::Helsinki 2.15 - DateTime::TimeZone::Europe::Istanbul 2.15 - DateTime::TimeZone::Europe::Kaliningrad 2.15 - DateTime::TimeZone::Europe::Kiev 2.15 - DateTime::TimeZone::Europe::Kirov 2.15 - DateTime::TimeZone::Europe::Lisbon 2.15 - DateTime::TimeZone::Europe::London 2.15 - DateTime::TimeZone::Europe::Luxembourg 2.15 - DateTime::TimeZone::Europe::Madrid 2.15 - DateTime::TimeZone::Europe::Malta 2.15 - DateTime::TimeZone::Europe::Minsk 2.15 - DateTime::TimeZone::Europe::Monaco 2.15 - DateTime::TimeZone::Europe::Moscow 2.15 - DateTime::TimeZone::Europe::Oslo 2.15 - DateTime::TimeZone::Europe::Paris 2.15 - DateTime::TimeZone::Europe::Prague 2.15 - DateTime::TimeZone::Europe::Riga 2.15 - DateTime::TimeZone::Europe::Rome 2.15 - DateTime::TimeZone::Europe::Samara 2.15 - DateTime::TimeZone::Europe::Saratov 2.15 - DateTime::TimeZone::Europe::Simferopol 2.15 - DateTime::TimeZone::Europe::Sofia 2.15 - DateTime::TimeZone::Europe::Stockholm 2.15 - DateTime::TimeZone::Europe::Tallinn 2.15 - DateTime::TimeZone::Europe::Tirane 2.15 - DateTime::TimeZone::Europe::Ulyanovsk 2.15 - DateTime::TimeZone::Europe::Uzhgorod 2.15 - DateTime::TimeZone::Europe::Vienna 2.15 - DateTime::TimeZone::Europe::Vilnius 2.15 - DateTime::TimeZone::Europe::Volgograd 2.15 - DateTime::TimeZone::Europe::Warsaw 2.15 - DateTime::TimeZone::Europe::Zaporozhye 2.15 - DateTime::TimeZone::Europe::Zurich 2.15 - DateTime::TimeZone::Floating 2.15 - DateTime::TimeZone::HST 2.15 - DateTime::TimeZone::Indian::Chagos 2.15 - DateTime::TimeZone::Indian::Christmas 2.15 - DateTime::TimeZone::Indian::Cocos 2.15 - DateTime::TimeZone::Indian::Kerguelen 2.15 - DateTime::TimeZone::Indian::Mahe 2.15 - DateTime::TimeZone::Indian::Maldives 2.15 - DateTime::TimeZone::Indian::Mauritius 2.15 - DateTime::TimeZone::Indian::Reunion 2.15 - DateTime::TimeZone::Local 2.15 - DateTime::TimeZone::Local::Android 2.15 - DateTime::TimeZone::Local::Unix 2.15 - DateTime::TimeZone::Local::VMS 2.15 - DateTime::TimeZone::MET 2.15 - DateTime::TimeZone::MST 2.15 - DateTime::TimeZone::MST7MDT 2.15 - DateTime::TimeZone::OffsetOnly 2.15 - DateTime::TimeZone::OlsonDB 2.15 - DateTime::TimeZone::OlsonDB::Change 2.15 - DateTime::TimeZone::OlsonDB::Observance 2.15 - DateTime::TimeZone::OlsonDB::Rule 2.15 - DateTime::TimeZone::OlsonDB::Zone 2.15 - DateTime::TimeZone::PST8PDT 2.15 - DateTime::TimeZone::Pacific::Apia 2.15 - DateTime::TimeZone::Pacific::Auckland 2.15 - DateTime::TimeZone::Pacific::Bougainville 2.15 - DateTime::TimeZone::Pacific::Chatham 2.15 - DateTime::TimeZone::Pacific::Chuuk 2.15 - DateTime::TimeZone::Pacific::Easter 2.15 - DateTime::TimeZone::Pacific::Efate 2.15 - DateTime::TimeZone::Pacific::Enderbury 2.15 - DateTime::TimeZone::Pacific::Fakaofo 2.15 - DateTime::TimeZone::Pacific::Fiji 2.15 - DateTime::TimeZone::Pacific::Funafuti 2.15 - DateTime::TimeZone::Pacific::Galapagos 2.15 - DateTime::TimeZone::Pacific::Gambier 2.15 - DateTime::TimeZone::Pacific::Guadalcanal 2.15 - DateTime::TimeZone::Pacific::Guam 2.15 - DateTime::TimeZone::Pacific::Honolulu 2.15 - DateTime::TimeZone::Pacific::Kiritimati 2.15 - DateTime::TimeZone::Pacific::Kosrae 2.15 - DateTime::TimeZone::Pacific::Kwajalein 2.15 - DateTime::TimeZone::Pacific::Majuro 2.15 - DateTime::TimeZone::Pacific::Marquesas 2.15 - DateTime::TimeZone::Pacific::Nauru 2.15 - DateTime::TimeZone::Pacific::Niue 2.15 - DateTime::TimeZone::Pacific::Norfolk 2.15 - DateTime::TimeZone::Pacific::Noumea 2.15 - DateTime::TimeZone::Pacific::Pago_Pago 2.15 - DateTime::TimeZone::Pacific::Palau 2.15 - DateTime::TimeZone::Pacific::Pitcairn 2.15 - DateTime::TimeZone::Pacific::Pohnpei 2.15 - DateTime::TimeZone::Pacific::Port_Moresby 2.15 - DateTime::TimeZone::Pacific::Rarotonga 2.15 - DateTime::TimeZone::Pacific::Tahiti 2.15 - DateTime::TimeZone::Pacific::Tarawa 2.15 - DateTime::TimeZone::Pacific::Tongatapu 2.15 - DateTime::TimeZone::Pacific::Wake 2.15 - DateTime::TimeZone::Pacific::Wallis 2.15 - DateTime::TimeZone::UTC 2.15 - DateTime::TimeZone::WET 2.15 + DateTime-TimeZone-2.65 + pathname: D/DR/DROLSKY/DateTime-TimeZone-2.65.tar.gz + provides: + DateTime::TimeZone 2.65 + DateTime::TimeZone::Africa::Abidjan 2.65 + DateTime::TimeZone::Africa::Algiers 2.65 + DateTime::TimeZone::Africa::Bissau 2.65 + DateTime::TimeZone::Africa::Cairo 2.65 + DateTime::TimeZone::Africa::Casablanca 2.65 + DateTime::TimeZone::Africa::Ceuta 2.65 + DateTime::TimeZone::Africa::El_Aaiun 2.65 + DateTime::TimeZone::Africa::Johannesburg 2.65 + DateTime::TimeZone::Africa::Juba 2.65 + DateTime::TimeZone::Africa::Khartoum 2.65 + DateTime::TimeZone::Africa::Lagos 2.65 + DateTime::TimeZone::Africa::Maputo 2.65 + DateTime::TimeZone::Africa::Monrovia 2.65 + DateTime::TimeZone::Africa::Nairobi 2.65 + DateTime::TimeZone::Africa::Ndjamena 2.65 + DateTime::TimeZone::Africa::Sao_Tome 2.65 + DateTime::TimeZone::Africa::Tripoli 2.65 + DateTime::TimeZone::Africa::Tunis 2.65 + DateTime::TimeZone::Africa::Windhoek 2.65 + DateTime::TimeZone::America::Adak 2.65 + DateTime::TimeZone::America::Anchorage 2.65 + DateTime::TimeZone::America::Araguaina 2.65 + DateTime::TimeZone::America::Argentina::Buenos_Aires 2.65 + DateTime::TimeZone::America::Argentina::Catamarca 2.65 + DateTime::TimeZone::America::Argentina::Cordoba 2.65 + DateTime::TimeZone::America::Argentina::Jujuy 2.65 + DateTime::TimeZone::America::Argentina::La_Rioja 2.65 + DateTime::TimeZone::America::Argentina::Mendoza 2.65 + DateTime::TimeZone::America::Argentina::Rio_Gallegos 2.65 + DateTime::TimeZone::America::Argentina::Salta 2.65 + DateTime::TimeZone::America::Argentina::San_Juan 2.65 + DateTime::TimeZone::America::Argentina::San_Luis 2.65 + DateTime::TimeZone::America::Argentina::Tucuman 2.65 + DateTime::TimeZone::America::Argentina::Ushuaia 2.65 + DateTime::TimeZone::America::Asuncion 2.65 + DateTime::TimeZone::America::Bahia 2.65 + DateTime::TimeZone::America::Bahia_Banderas 2.65 + DateTime::TimeZone::America::Barbados 2.65 + DateTime::TimeZone::America::Belem 2.65 + DateTime::TimeZone::America::Belize 2.65 + DateTime::TimeZone::America::Boa_Vista 2.65 + DateTime::TimeZone::America::Bogota 2.65 + DateTime::TimeZone::America::Boise 2.65 + DateTime::TimeZone::America::Cambridge_Bay 2.65 + DateTime::TimeZone::America::Campo_Grande 2.65 + DateTime::TimeZone::America::Cancun 2.65 + DateTime::TimeZone::America::Caracas 2.65 + DateTime::TimeZone::America::Cayenne 2.65 + DateTime::TimeZone::America::Chicago 2.65 + DateTime::TimeZone::America::Chihuahua 2.65 + DateTime::TimeZone::America::Ciudad_Juarez 2.65 + DateTime::TimeZone::America::Costa_Rica 2.65 + DateTime::TimeZone::America::Coyhaique 2.65 + DateTime::TimeZone::America::Cuiaba 2.65 + DateTime::TimeZone::America::Danmarkshavn 2.65 + DateTime::TimeZone::America::Dawson 2.65 + DateTime::TimeZone::America::Dawson_Creek 2.65 + DateTime::TimeZone::America::Denver 2.65 + DateTime::TimeZone::America::Detroit 2.65 + DateTime::TimeZone::America::Edmonton 2.65 + DateTime::TimeZone::America::Eirunepe 2.65 + DateTime::TimeZone::America::El_Salvador 2.65 + DateTime::TimeZone::America::Fort_Nelson 2.65 + DateTime::TimeZone::America::Fortaleza 2.65 + DateTime::TimeZone::America::Glace_Bay 2.65 + DateTime::TimeZone::America::Goose_Bay 2.65 + DateTime::TimeZone::America::Grand_Turk 2.65 + DateTime::TimeZone::America::Guatemala 2.65 + DateTime::TimeZone::America::Guayaquil 2.65 + DateTime::TimeZone::America::Guyana 2.65 + DateTime::TimeZone::America::Halifax 2.65 + DateTime::TimeZone::America::Havana 2.65 + DateTime::TimeZone::America::Hermosillo 2.65 + DateTime::TimeZone::America::Indiana::Indianapolis 2.65 + DateTime::TimeZone::America::Indiana::Knox 2.65 + DateTime::TimeZone::America::Indiana::Marengo 2.65 + DateTime::TimeZone::America::Indiana::Petersburg 2.65 + DateTime::TimeZone::America::Indiana::Tell_City 2.65 + DateTime::TimeZone::America::Indiana::Vevay 2.65 + DateTime::TimeZone::America::Indiana::Vincennes 2.65 + DateTime::TimeZone::America::Indiana::Winamac 2.65 + DateTime::TimeZone::America::Inuvik 2.65 + DateTime::TimeZone::America::Iqaluit 2.65 + DateTime::TimeZone::America::Jamaica 2.65 + DateTime::TimeZone::America::Juneau 2.65 + DateTime::TimeZone::America::Kentucky::Louisville 2.65 + DateTime::TimeZone::America::Kentucky::Monticello 2.65 + DateTime::TimeZone::America::La_Paz 2.65 + DateTime::TimeZone::America::Lima 2.65 + DateTime::TimeZone::America::Los_Angeles 2.65 + DateTime::TimeZone::America::Maceio 2.65 + DateTime::TimeZone::America::Managua 2.65 + DateTime::TimeZone::America::Manaus 2.65 + DateTime::TimeZone::America::Martinique 2.65 + DateTime::TimeZone::America::Matamoros 2.65 + DateTime::TimeZone::America::Mazatlan 2.65 + DateTime::TimeZone::America::Menominee 2.65 + DateTime::TimeZone::America::Merida 2.65 + DateTime::TimeZone::America::Metlakatla 2.65 + DateTime::TimeZone::America::Mexico_City 2.65 + DateTime::TimeZone::America::Miquelon 2.65 + DateTime::TimeZone::America::Moncton 2.65 + DateTime::TimeZone::America::Monterrey 2.65 + DateTime::TimeZone::America::Montevideo 2.65 + DateTime::TimeZone::America::New_York 2.65 + DateTime::TimeZone::America::Nome 2.65 + DateTime::TimeZone::America::Noronha 2.65 + DateTime::TimeZone::America::North_Dakota::Beulah 2.65 + DateTime::TimeZone::America::North_Dakota::Center 2.65 + DateTime::TimeZone::America::North_Dakota::New_Salem 2.65 + DateTime::TimeZone::America::Nuuk 2.65 + DateTime::TimeZone::America::Ojinaga 2.65 + DateTime::TimeZone::America::Panama 2.65 + DateTime::TimeZone::America::Paramaribo 2.65 + DateTime::TimeZone::America::Phoenix 2.65 + DateTime::TimeZone::America::Port_au_Prince 2.65 + DateTime::TimeZone::America::Porto_Velho 2.65 + DateTime::TimeZone::America::Puerto_Rico 2.65 + DateTime::TimeZone::America::Punta_Arenas 2.65 + DateTime::TimeZone::America::Rankin_Inlet 2.65 + DateTime::TimeZone::America::Recife 2.65 + DateTime::TimeZone::America::Regina 2.65 + DateTime::TimeZone::America::Resolute 2.65 + DateTime::TimeZone::America::Rio_Branco 2.65 + DateTime::TimeZone::America::Santarem 2.65 + DateTime::TimeZone::America::Santiago 2.65 + DateTime::TimeZone::America::Santo_Domingo 2.65 + DateTime::TimeZone::America::Sao_Paulo 2.65 + DateTime::TimeZone::America::Scoresbysund 2.65 + DateTime::TimeZone::America::Sitka 2.65 + DateTime::TimeZone::America::St_Johns 2.65 + DateTime::TimeZone::America::Swift_Current 2.65 + DateTime::TimeZone::America::Tegucigalpa 2.65 + DateTime::TimeZone::America::Thule 2.65 + DateTime::TimeZone::America::Tijuana 2.65 + DateTime::TimeZone::America::Toronto 2.65 + DateTime::TimeZone::America::Vancouver 2.65 + DateTime::TimeZone::America::Whitehorse 2.65 + DateTime::TimeZone::America::Winnipeg 2.65 + DateTime::TimeZone::America::Yakutat 2.65 + DateTime::TimeZone::Antarctica::Casey 2.65 + DateTime::TimeZone::Antarctica::Davis 2.65 + DateTime::TimeZone::Antarctica::Macquarie 2.65 + DateTime::TimeZone::Antarctica::Mawson 2.65 + DateTime::TimeZone::Antarctica::Palmer 2.65 + DateTime::TimeZone::Antarctica::Rothera 2.65 + DateTime::TimeZone::Antarctica::Troll 2.65 + DateTime::TimeZone::Antarctica::Vostok 2.65 + DateTime::TimeZone::Asia::Almaty 2.65 + DateTime::TimeZone::Asia::Amman 2.65 + DateTime::TimeZone::Asia::Anadyr 2.65 + DateTime::TimeZone::Asia::Aqtau 2.65 + DateTime::TimeZone::Asia::Aqtobe 2.65 + DateTime::TimeZone::Asia::Ashgabat 2.65 + DateTime::TimeZone::Asia::Atyrau 2.65 + DateTime::TimeZone::Asia::Baghdad 2.65 + DateTime::TimeZone::Asia::Baku 2.65 + DateTime::TimeZone::Asia::Bangkok 2.65 + DateTime::TimeZone::Asia::Barnaul 2.65 + DateTime::TimeZone::Asia::Beirut 2.65 + DateTime::TimeZone::Asia::Bishkek 2.65 + DateTime::TimeZone::Asia::Chita 2.65 + DateTime::TimeZone::Asia::Colombo 2.65 + DateTime::TimeZone::Asia::Damascus 2.65 + DateTime::TimeZone::Asia::Dhaka 2.65 + DateTime::TimeZone::Asia::Dili 2.65 + DateTime::TimeZone::Asia::Dubai 2.65 + DateTime::TimeZone::Asia::Dushanbe 2.65 + DateTime::TimeZone::Asia::Famagusta 2.65 + DateTime::TimeZone::Asia::Gaza 2.65 + DateTime::TimeZone::Asia::Hebron 2.65 + DateTime::TimeZone::Asia::Ho_Chi_Minh 2.65 + DateTime::TimeZone::Asia::Hong_Kong 2.65 + DateTime::TimeZone::Asia::Hovd 2.65 + DateTime::TimeZone::Asia::Irkutsk 2.65 + DateTime::TimeZone::Asia::Jakarta 2.65 + DateTime::TimeZone::Asia::Jayapura 2.65 + DateTime::TimeZone::Asia::Jerusalem 2.65 + DateTime::TimeZone::Asia::Kabul 2.65 + DateTime::TimeZone::Asia::Kamchatka 2.65 + DateTime::TimeZone::Asia::Karachi 2.65 + DateTime::TimeZone::Asia::Kathmandu 2.65 + DateTime::TimeZone::Asia::Khandyga 2.65 + DateTime::TimeZone::Asia::Kolkata 2.65 + DateTime::TimeZone::Asia::Krasnoyarsk 2.65 + DateTime::TimeZone::Asia::Kuching 2.65 + DateTime::TimeZone::Asia::Macau 2.65 + DateTime::TimeZone::Asia::Magadan 2.65 + DateTime::TimeZone::Asia::Makassar 2.65 + DateTime::TimeZone::Asia::Manila 2.65 + DateTime::TimeZone::Asia::Nicosia 2.65 + DateTime::TimeZone::Asia::Novokuznetsk 2.65 + DateTime::TimeZone::Asia::Novosibirsk 2.65 + DateTime::TimeZone::Asia::Omsk 2.65 + DateTime::TimeZone::Asia::Oral 2.65 + DateTime::TimeZone::Asia::Pontianak 2.65 + DateTime::TimeZone::Asia::Pyongyang 2.65 + DateTime::TimeZone::Asia::Qatar 2.65 + DateTime::TimeZone::Asia::Qostanay 2.65 + DateTime::TimeZone::Asia::Qyzylorda 2.65 + DateTime::TimeZone::Asia::Riyadh 2.65 + DateTime::TimeZone::Asia::Sakhalin 2.65 + DateTime::TimeZone::Asia::Samarkand 2.65 + DateTime::TimeZone::Asia::Seoul 2.65 + DateTime::TimeZone::Asia::Shanghai 2.65 + DateTime::TimeZone::Asia::Singapore 2.65 + DateTime::TimeZone::Asia::Srednekolymsk 2.65 + DateTime::TimeZone::Asia::Taipei 2.65 + DateTime::TimeZone::Asia::Tashkent 2.65 + DateTime::TimeZone::Asia::Tbilisi 2.65 + DateTime::TimeZone::Asia::Tehran 2.65 + DateTime::TimeZone::Asia::Thimphu 2.65 + DateTime::TimeZone::Asia::Tokyo 2.65 + DateTime::TimeZone::Asia::Tomsk 2.65 + DateTime::TimeZone::Asia::Ulaanbaatar 2.65 + DateTime::TimeZone::Asia::Urumqi 2.65 + DateTime::TimeZone::Asia::Ust_Nera 2.65 + DateTime::TimeZone::Asia::Vladivostok 2.65 + DateTime::TimeZone::Asia::Yakutsk 2.65 + DateTime::TimeZone::Asia::Yangon 2.65 + DateTime::TimeZone::Asia::Yekaterinburg 2.65 + DateTime::TimeZone::Asia::Yerevan 2.65 + DateTime::TimeZone::Atlantic::Azores 2.65 + DateTime::TimeZone::Atlantic::Bermuda 2.65 + DateTime::TimeZone::Atlantic::Canary 2.65 + DateTime::TimeZone::Atlantic::Cape_Verde 2.65 + DateTime::TimeZone::Atlantic::Faroe 2.65 + DateTime::TimeZone::Atlantic::Madeira 2.65 + DateTime::TimeZone::Atlantic::South_Georgia 2.65 + DateTime::TimeZone::Atlantic::Stanley 2.65 + DateTime::TimeZone::Australia::Adelaide 2.65 + DateTime::TimeZone::Australia::Brisbane 2.65 + DateTime::TimeZone::Australia::Broken_Hill 2.65 + DateTime::TimeZone::Australia::Darwin 2.65 + DateTime::TimeZone::Australia::Eucla 2.65 + DateTime::TimeZone::Australia::Hobart 2.65 + DateTime::TimeZone::Australia::Lindeman 2.65 + DateTime::TimeZone::Australia::Lord_Howe 2.65 + DateTime::TimeZone::Australia::Melbourne 2.65 + DateTime::TimeZone::Australia::Perth 2.65 + DateTime::TimeZone::Australia::Sydney 2.65 + DateTime::TimeZone::Catalog 2.65 + DateTime::TimeZone::Europe::Andorra 2.65 + DateTime::TimeZone::Europe::Astrakhan 2.65 + DateTime::TimeZone::Europe::Athens 2.65 + DateTime::TimeZone::Europe::Belgrade 2.65 + DateTime::TimeZone::Europe::Berlin 2.65 + DateTime::TimeZone::Europe::Brussels 2.65 + DateTime::TimeZone::Europe::Bucharest 2.65 + DateTime::TimeZone::Europe::Budapest 2.65 + DateTime::TimeZone::Europe::Chisinau 2.65 + DateTime::TimeZone::Europe::Dublin 2.65 + DateTime::TimeZone::Europe::Gibraltar 2.65 + DateTime::TimeZone::Europe::Helsinki 2.65 + DateTime::TimeZone::Europe::Istanbul 2.65 + DateTime::TimeZone::Europe::Kaliningrad 2.65 + DateTime::TimeZone::Europe::Kirov 2.65 + DateTime::TimeZone::Europe::Kyiv 2.65 + DateTime::TimeZone::Europe::Lisbon 2.65 + DateTime::TimeZone::Europe::London 2.65 + DateTime::TimeZone::Europe::Madrid 2.65 + DateTime::TimeZone::Europe::Malta 2.65 + DateTime::TimeZone::Europe::Minsk 2.65 + DateTime::TimeZone::Europe::Moscow 2.65 + DateTime::TimeZone::Europe::Paris 2.65 + DateTime::TimeZone::Europe::Prague 2.65 + DateTime::TimeZone::Europe::Riga 2.65 + DateTime::TimeZone::Europe::Rome 2.65 + DateTime::TimeZone::Europe::Samara 2.65 + DateTime::TimeZone::Europe::Saratov 2.65 + DateTime::TimeZone::Europe::Simferopol 2.65 + DateTime::TimeZone::Europe::Sofia 2.65 + DateTime::TimeZone::Europe::Tallinn 2.65 + DateTime::TimeZone::Europe::Tirane 2.65 + DateTime::TimeZone::Europe::Ulyanovsk 2.65 + DateTime::TimeZone::Europe::Vienna 2.65 + DateTime::TimeZone::Europe::Vilnius 2.65 + DateTime::TimeZone::Europe::Volgograd 2.65 + DateTime::TimeZone::Europe::Warsaw 2.65 + DateTime::TimeZone::Europe::Zurich 2.65 + DateTime::TimeZone::Floating 2.65 + DateTime::TimeZone::Indian::Chagos 2.65 + DateTime::TimeZone::Indian::Maldives 2.65 + DateTime::TimeZone::Indian::Mauritius 2.65 + DateTime::TimeZone::Local 2.65 + DateTime::TimeZone::Local::Android 2.65 + DateTime::TimeZone::Local::Unix 2.65 + DateTime::TimeZone::Local::VMS 2.65 + DateTime::TimeZone::OffsetOnly 2.65 + DateTime::TimeZone::OlsonDB 2.65 + DateTime::TimeZone::OlsonDB::Change 2.65 + DateTime::TimeZone::OlsonDB::Observance 2.65 + DateTime::TimeZone::OlsonDB::Rule 2.65 + DateTime::TimeZone::OlsonDB::Zone 2.65 + DateTime::TimeZone::Pacific::Apia 2.65 + DateTime::TimeZone::Pacific::Auckland 2.65 + DateTime::TimeZone::Pacific::Bougainville 2.65 + DateTime::TimeZone::Pacific::Chatham 2.65 + DateTime::TimeZone::Pacific::Easter 2.65 + DateTime::TimeZone::Pacific::Efate 2.65 + DateTime::TimeZone::Pacific::Fakaofo 2.65 + DateTime::TimeZone::Pacific::Fiji 2.65 + DateTime::TimeZone::Pacific::Galapagos 2.65 + DateTime::TimeZone::Pacific::Gambier 2.65 + DateTime::TimeZone::Pacific::Guadalcanal 2.65 + DateTime::TimeZone::Pacific::Guam 2.65 + DateTime::TimeZone::Pacific::Honolulu 2.65 + DateTime::TimeZone::Pacific::Kanton 2.65 + DateTime::TimeZone::Pacific::Kiritimati 2.65 + DateTime::TimeZone::Pacific::Kosrae 2.65 + DateTime::TimeZone::Pacific::Kwajalein 2.65 + DateTime::TimeZone::Pacific::Marquesas 2.65 + DateTime::TimeZone::Pacific::Nauru 2.65 + DateTime::TimeZone::Pacific::Niue 2.65 + DateTime::TimeZone::Pacific::Norfolk 2.65 + DateTime::TimeZone::Pacific::Noumea 2.65 + DateTime::TimeZone::Pacific::Pago_Pago 2.65 + DateTime::TimeZone::Pacific::Palau 2.65 + DateTime::TimeZone::Pacific::Pitcairn 2.65 + DateTime::TimeZone::Pacific::Port_Moresby 2.65 + DateTime::TimeZone::Pacific::Rarotonga 2.65 + DateTime::TimeZone::Pacific::Tahiti 2.65 + DateTime::TimeZone::Pacific::Tarawa 2.65 + DateTime::TimeZone::Pacific::Tongatapu 2.65 + DateTime::TimeZone::UTC 2.65 requirements: Class::Singleton 1.03 Cwd 3 @@ -2241,40 +1833,16 @@ DISTRIBUTIONS perl 5.008004 strict 0 warnings 0 - Devel-ArgNames-0.03 - pathname: N/NU/NUFFIN/Devel-ArgNames-0.03.tar.gz - provides: - Devel::ArgNames 0.03 - requirements: - ExtUtils::MakeMaker 0 - PadWalker 0 - Test::use::ok 0 - Devel-CheckCompiler-0.07 - pathname: S/SY/SYOHEX/Devel-CheckCompiler-0.07.tar.gz - provides: - Devel::AssertC99 undef - Devel::CheckCompiler 0.07 - requirements: - Exporter 0 - ExtUtils::CBuilder 0 - File::Temp 0 - Module::Build::Tiny 0.035 - Test::More 0.98 - parent 0 - perl 5.008001 - Devel-CheckLib-1.11 - pathname: M/MA/MATTN/Devel-CheckLib-1.11.tar.gz + Devel-CheckLib-1.16 + pathname: M/MA/MATTN/Devel-CheckLib-1.16.tar.gz provides: - Devel::CheckLib 1.11 + Devel::CheckLib 1.16 requirements: Exporter 0 ExtUtils::MakeMaker 0 File::Spec 0 File::Temp 0.16 - IO::CaptureOutput 1.0801 - Mock::Config 0.02 - Test::More 0.62 - perl 5.00405 + perl 5.004050 Devel-Confess-0.009004 pathname: H/HA/HAARG/Devel-Confess-0.009004.tar.gz provides: @@ -2295,24 +1863,27 @@ DISTRIBUTIONS ExtUtils::MakeMaker 0 Sub::Exporter::Progressive 0.001011 perl 5.006 - Devel-Hide-0.0009 - pathname: F/FE/FERREIRA/Devel-Hide-0.0009.tar.gz + Devel-Hide-0.0015 + pathname: D/DC/DCANTRELL/Devel-Hide-0.0015.tar.gz provides: - Devel::Hide 0.0009 + Devel::Hide 0.0015 requirements: ExtUtils::MakeMaker 0 - Test::More 0 - Devel-OverloadInfo-0.004 - pathname: I/IL/ILMARI/Devel-OverloadInfo-0.004.tar.gz + File::Temp 0 + perl 5.006001 + Devel-OverloadInfo-0.007 + pathname: I/IL/ILMARI/Devel-OverloadInfo-0.007.tar.gz provides: - Devel::OverloadInfo 0.004 + Devel::OverloadInfo 0.007 requirements: + B 0 Exporter 5.57 ExtUtils::MakeMaker 0 MRO::Compat 0 Package::Stash 0.14 Scalar::Util 0 - Sub::Identify 0 + Sub::Util 1.40 + Text::ParseWords 0 overload 0 perl 5.006 strict 0 @@ -2331,11 +1902,11 @@ DISTRIBUTIONS perl 5.006001 strict 0 warnings 0 - Devel-StackTrace-2.02 - pathname: D/DR/DROLSKY/Devel-StackTrace-2.02.tar.gz + Devel-StackTrace-2.05 + pathname: D/DR/DROLSKY/Devel-StackTrace-2.05.tar.gz provides: - Devel::StackTrace 2.02 - Devel::StackTrace::Frame 2.02 + Devel::StackTrace 2.05 + Devel::StackTrace::Frame 2.05 requirements: ExtUtils::MakeMaker 0 File::Spec 0 @@ -2351,27 +1922,17 @@ DISTRIBUTIONS requirements: Devel::StackTrace 0 ExtUtils::MakeMaker 0 - Devel-Symdump-2.18 - pathname: A/AN/ANDK/Devel-Symdump-2.18.tar.gz + Digest-HMAC-1.05 + pathname: A/AR/ARODLAND/Digest-HMAC-1.05.tar.gz provides: - Devel::Symdump 2.18 - Devel::Symdump::Export undef - requirements: - Compress::Zlib 0 - ExtUtils::MakeMaker 0 - Test::More 0 - perl 5.004 - Digest-HMAC-1.03 - pathname: G/GA/GAAS/Digest-HMAC-1.03.tar.gz - provides: - Digest::HMAC 1.03 - Digest::HMAC_MD5 1.01 - Digest::HMAC_SHA1 1.03 + Digest::HMAC 1.05 + Digest::HMAC_MD5 1.05 + Digest::HMAC_SHA1 1.05 requirements: Digest::MD5 2 Digest::SHA 1 ExtUtils::MakeMaker 0 - perl 5.004 + perl 5.008001 Digest-JHash-0.10 pathname: S/SH/SHLOMIF/Digest-JHash-0.10.tar.gz provides: @@ -2384,14 +1945,6 @@ DISTRIBUTIONS strict 0 vars 0 warnings 0 - Digest-SHA1-2.13 - pathname: G/GA/GAAS/Digest-SHA1-2.13.tar.gz - provides: - Digest::SHA1 2.13 - requirements: - Digest::base 1.00 - ExtUtils::MakeMaker 0 - perl 5.004 Dist-CheckConflicts-0.11 pathname: D/DO/DOY/Dist-CheckConflicts-0.11.tar.gz provides: @@ -2404,10 +1957,10 @@ DISTRIBUTIONS base 0 strict 0 warnings 0 - Dist-Data-0.006 - pathname: G/GE/GETTY/Dist-Data-0.006.tar.gz + Dist-Data-0.007 + pathname: G/GE/GETTY/Dist-Data-0.007.tar.gz provides: - Dist::Data 0.006 + Dist::Data 0.007 requirements: Archive::Any 0.0932 CPAN::Meta 2.113640 @@ -2416,7 +1969,7 @@ DISTRIBUTIONS ExtUtils::MakeMaker 0 File::Find::Object v0.2.3 File::Temp 0.22 - Module::Extract::Namespaces 0.14 + Module::Metadata 0 Moo 0.009013 Dist-Metadata-0.927 pathname: R/RW/RWSTAUNER/Dist-Metadata-0.927.tar.gz @@ -2450,53 +2003,53 @@ DISTRIBUTIONS perl 5.006 strict 0 warnings 0 - EV-4.22 - pathname: M/ML/MLEHMANN/EV-4.22.tar.gz + EV-4.34 + pathname: M/ML/MLEHMANN/EV-4.34.tar.gz provides: - EV 4.22 + EV 4.34 EV::MakeMaker undef requirements: Canary::Stability 0 ExtUtils::MakeMaker 6.52 common::sense 0 - ElasticSearchX-Model-1.0.2 - pathname: O/OA/OALDERS/ElasticSearchX-Model-1.0.2.tar.gz - provides: - ElasticSearchX::Model v1.0.2 - ElasticSearchX::Model::Bulk v1.0.2 - ElasticSearchX::Model::Document v1.0.2 - ElasticSearchX::Model::Document::EmbeddedRole v1.0.2 - ElasticSearchX::Model::Document::Mapping v1.0.2 - ElasticSearchX::Model::Document::Role v1.0.2 - ElasticSearchX::Model::Document::Set v1.0.2 - ElasticSearchX::Model::Document::Trait::Attribute v1.0.2 - ElasticSearchX::Model::Document::Trait::Class v1.0.2 - ElasticSearchX::Model::Document::Trait::Class::ID v1.0.2 - ElasticSearchX::Model::Document::Trait::Class::Timestamp v1.0.2 - ElasticSearchX::Model::Document::Trait::Class::Version v1.0.2 - ElasticSearchX::Model::Document::Trait::Field::ID v1.0.2 - ElasticSearchX::Model::Document::Trait::Field::TTL v1.0.2 - ElasticSearchX::Model::Document::Trait::Field::Timestamp v1.0.2 - ElasticSearchX::Model::Document::Trait::Field::Version v1.0.2 - ElasticSearchX::Model::Document::Types v1.0.2 - ElasticSearchX::Model::Index v1.0.2 - ElasticSearchX::Model::Role v1.0.2 - ElasticSearchX::Model::Scroll v1.0.2 - ElasticSearchX::Model::Trait::Class v1.0.2 - ElasticSearchX::Model::Tutorial v1.0.2 - ElasticSearchX::Model::Util v1.0.2 + ElasticSearchX-Model-2.0.1 + pathname: O/OA/OALDERS/ElasticSearchX-Model-2.0.1.tar.gz + provides: + ElasticSearchX::Model v2.0.1 + ElasticSearchX::Model::Bulk v2.0.1 + ElasticSearchX::Model::Document v2.0.1 + ElasticSearchX::Model::Document::EmbeddedRole v2.0.1 + ElasticSearchX::Model::Document::Mapping v2.0.1 + ElasticSearchX::Model::Document::Role v2.0.1 + ElasticSearchX::Model::Document::Set v2.0.1 + ElasticSearchX::Model::Document::Trait::Attribute v2.0.1 + ElasticSearchX::Model::Document::Trait::Class v2.0.1 + ElasticSearchX::Model::Document::Trait::Class::ID v2.0.1 + ElasticSearchX::Model::Document::Trait::Class::Timestamp v2.0.1 + ElasticSearchX::Model::Document::Trait::Class::Version v2.0.1 + ElasticSearchX::Model::Document::Trait::Field::ID v2.0.1 + ElasticSearchX::Model::Document::Trait::Field::TTL v2.0.1 + ElasticSearchX::Model::Document::Trait::Field::Timestamp v2.0.1 + ElasticSearchX::Model::Document::Trait::Field::Version v2.0.1 + ElasticSearchX::Model::Document::Types v2.0.1 + ElasticSearchX::Model::Index v2.0.1 + ElasticSearchX::Model::Role v2.0.1 + ElasticSearchX::Model::Scroll v2.0.1 + ElasticSearchX::Model::Trait::Class v2.0.1 + ElasticSearchX::Model::Tutorial v2.0.1 + ElasticSearchX::Model::Util v2.0.1 requirements: Carp 0 Class::Load 0 DateTime 0 DateTime::Format::Epoch::Unix 0 DateTime::Format::ISO8601 0 - Digest::SHA1 0 + Digest::SHA 0 Eval::Closure 0 + ExtUtils::MakeMaker 0 JSON::MaybeXS 0 List::MoreUtils 0 List::Util 0 - Module::Build 0.3601 Module::Find 0 Moose 2.02 Moose::Exporter 0 @@ -2513,84 +2066,88 @@ DISTRIBUTIONS MooseX::Types::Structured 0 Scalar::Util 0 Search::Elasticsearch 2.02 - Search::Elasticsearch::Bulk 0 - Search::Elasticsearch::Scroll 0 Sub::Exporter 0 + perl 5.006 strict 0 version 0 warnings 0 - Email-Abstract-3.008 - pathname: R/RJ/RJBS/Email-Abstract-3.008.tar.gz + Email-Abstract-3.010 + pathname: R/RJ/RJBS/Email-Abstract-3.010.tar.gz provides: - Email::Abstract 3.008 - Email::Abstract::EmailMIME 3.008 - Email::Abstract::EmailSimple 3.008 - Email::Abstract::MIMEEntity 3.008 - Email::Abstract::MailInternet 3.008 - Email::Abstract::MailMessage 3.008 - Email::Abstract::Plugin 3.008 + Email::Abstract 3.010 + Email::Abstract::EmailMIME 3.010 + Email::Abstract::EmailSimple 3.010 + Email::Abstract::MIMEEntity 3.010 + Email::Abstract::MailInternet 3.010 + Email::Abstract::MailMessage 3.010 + Email::Abstract::Plugin 3.010 requirements: Carp 0 Email::Simple 1.998 - ExtUtils::MakeMaker 0 + ExtUtils::MakeMaker 6.78 MRO::Compat 0 Module::Pluggable 1.5 Scalar::Util 0 perl 5.006 strict 0 warnings 0 - Email-Address-1.908 - pathname: R/RJ/RJBS/Email-Address-1.908.tar.gz + Email-Address-XS-1.05 + pathname: P/PA/PALI/Email-Address-XS-1.05.tar.gz provides: - Email::Address 1.908 + Email::Address::XS 1.05 requirements: + Carp 0 + Exporter 0 ExtUtils::MakeMaker 0 + XSLoader 0 + base 0 overload 0 + perl 5.006000 strict 0 warnings 0 - Email-Date-Format-1.005 - pathname: R/RJ/RJBS/Email-Date-Format-1.005.tar.gz + Email-Date-Format-1.008 + pathname: R/RJ/RJBS/Email-Date-Format-1.008.tar.gz provides: - Email::Date::Format 1.005 + Email::Date::Format 1.008 requirements: Exporter 5.57 - ExtUtils::MakeMaker 0 - Time::Local 0 - strict 0 - warnings 0 - Email-Sender-1.300031 - pathname: R/RJ/RJBS/Email-Sender-1.300031.tar.gz - provides: - Email::Sender 1.300031 - Email::Sender::Failure 1.300031 - Email::Sender::Failure::Multi 1.300031 - Email::Sender::Failure::Permanent 1.300031 - Email::Sender::Failure::Temporary 1.300031 - Email::Sender::Manual 1.300031 - Email::Sender::Manual::QuickStart 1.300031 - Email::Sender::Role::CommonSending 1.300031 - Email::Sender::Role::HasMessage 1.300031 - Email::Sender::Simple 1.300031 - Email::Sender::Success 1.300031 - Email::Sender::Success::Partial 1.300031 - Email::Sender::Transport 1.300031 - Email::Sender::Transport::DevNull 1.300031 - Email::Sender::Transport::Failable 1.300031 - Email::Sender::Transport::Maildir 1.300031 - Email::Sender::Transport::Mbox 1.300031 - Email::Sender::Transport::Print 1.300031 - Email::Sender::Transport::SMTP 1.300031 - Email::Sender::Transport::SMTP::Persistent 1.300031 - Email::Sender::Transport::Sendmail 1.300031 - Email::Sender::Transport::Test 1.300031 - Email::Sender::Transport::Wrapper 1.300031 - Email::Sender::Util 1.300031 + ExtUtils::MakeMaker 6.78 + Time::Local 1.27 + perl 5.012 + warnings 0 + Email-Sender-2.601 + pathname: R/RJ/RJBS/Email-Sender-2.601.tar.gz + provides: + Email::Sender 2.601 + Email::Sender::Failure 2.601 + Email::Sender::Failure::Multi 2.601 + Email::Sender::Failure::Permanent 2.601 + Email::Sender::Failure::Temporary 2.601 + Email::Sender::Manual 2.601 + Email::Sender::Manual::QuickStart 2.601 + Email::Sender::Role::CommonSending 2.601 + Email::Sender::Role::HasMessage 2.601 + Email::Sender::Simple 2.601 + Email::Sender::Success 2.601 + Email::Sender::Success::Partial 2.601 + Email::Sender::Transport 2.601 + Email::Sender::Transport::DevNull 2.601 + Email::Sender::Transport::Failable 2.601 + Email::Sender::Transport::Maildir 2.601 + Email::Sender::Transport::Mbox 2.601 + Email::Sender::Transport::Print 2.601 + Email::Sender::Transport::SMTP 2.601 + Email::Sender::Transport::SMTP::Persistent 2.601 + Email::Sender::Transport::Sendmail 2.601 + Email::Sender::Transport::Test 2.601 + Email::Sender::Transport::Wrapper 2.601 + Email::Sender::Util 2.601 requirements: Carp 0 Email::Abstract 3.006 - Email::Address 0 + Email::Address::XS 0 Email::Simple 1.998 - ExtUtils::MakeMaker 0 + ExtUtils::MakeMaker 6.78 Fcntl 0 File::Basename 0 File::Path 2.06 @@ -2610,26 +2167,27 @@ DISTRIBUTIONS Sys::Hostname 0 Throwable::Error 0.200003 Try::Tiny 0 + perl 5.012 strict 0 utf8 0 warnings 0 - Email-Simple-2.214 - pathname: R/RJ/RJBS/Email-Simple-2.214.tar.gz + Email-Simple-2.218 + pathname: R/RJ/RJBS/Email-Simple-2.218.tar.gz provides: - Email::Simple 2.214 - Email::Simple::Creator 2.214 - Email::Simple::Header 2.214 + Email::Simple 2.218 + Email::Simple::Creator 2.218 + Email::Simple::Header 2.218 requirements: Carp 0 Email::Date::Format 0 - ExtUtils::MakeMaker 0 - perl 5.008 + ExtUtils::MakeMaker 6.78 + perl 5.012 strict 0 warnings 0 - Email-Valid-1.202 - pathname: R/RJ/RJBS/Email-Valid-1.202.tar.gz + Email-Valid-1.204 + pathname: R/RJ/RJBS/Email-Valid-1.204.tar.gz provides: - Email::Valid 1.202 + Email::Valid 1.204 requirements: ExtUtils::MakeMaker 0 Mail::Address 0 @@ -2637,6 +2195,42 @@ DISTRIBUTIONS Scalar::Util 0 Test::More 0 perl 5.006 + Encode-3.21 + pathname: D/DA/DANKOGAI/Encode-3.21.tar.gz + provides: + Encode 3.21 + Encode::Alias 2.25 + Encode::Byte 2.04 + Encode::CJKConstants 2.02 + Encode::CN 2.03 + Encode::CN::HZ 2.10 + Encode::Config 2.05 + Encode::EBCDIC 2.02 + Encode::Encoder 2.03 + Encode::Encoding 2.08 + Encode::GSM0338 2.10 + Encode::Guess 2.08 + Encode::JP 2.05 + Encode::JP::H2Z 2.02 + Encode::JP::JIS7 2.08 + Encode::KR 2.03 + Encode::KR::2022_KR 2.04 + Encode::MIME::Header 2.29 + Encode::MIME::Header::ISO_2022_JP 1.09 + Encode::MIME::Name 1.03 + Encode::Symbol 2.02 + Encode::TW 2.03 + Encode::UTF_EBCDIC 3.21 + Encode::Unicode 2.20 + Encode::Unicode::UTF7 2.10 + Encode::XS 3.21 + Encode::utf8 3.21 + encoding 3.00 + requirements: + Exporter 5.57 + ExtUtils::MakeMaker 0 + Storable 0 + parent 0.221 Encode-Locale-1.05 pathname: G/GA/GAAS/Encode-Locale-1.05.tar.gz provides: @@ -2653,27 +2247,13 @@ DISTRIBUTIONS requirements: ExtUtils::MakeMaker 6.30 Test::More 0.90 - Encoding-FixLatin-XS-1.01 - pathname: G/GR/GRANTM/Encoding-FixLatin-XS-1.01.tar.gz + Encoding-FixLatin-XS-1.02 + pathname: G/GR/GRANTM/Encoding-FixLatin-XS-1.02.tar.gz provides: - Encoding::FixLatin::XS 1.01 + Encoding::FixLatin::XS 1.02 requirements: - Encoding::FixLatin 1.03 - ExtUtils::MakeMaker 6.30 - Test::More 0.90 - Error-0.17025 - pathname: S/SH/SHLOMIF/Error-0.17025.tar.gz - provides: - Error 0.17025 - Error::Simple 0.17025 - Error::WarnDie undef - Error::subs undef - requirements: - Module::Build 0.280801 - Scalar::Util 0 - perl v5.6.0 - strict 0 - warnings 0 + ExtUtils::MakeMaker 0 + perl 5.014 Eval-Closure-0.14 pathname: D/DO/DOY/Eval-Closure-0.14.tar.gz provides: @@ -2687,12 +2267,13 @@ DISTRIBUTIONS overload 0 strict 0 warnings 0 - Exception-Class-1.43 - pathname: D/DR/DROLSKY/Exception-Class-1.43.tar.gz + Exception-Class-1.45 + pathname: D/DR/DROLSKY/Exception-Class-1.45.tar.gz provides: - Exception::Class 1.43 - Exception::Class::Base 1.43 + Exception::Class 1.45 + Exception::Class::Base 1.45 requirements: + Carp 0 Class::Data::Inheritable 0.02 Devel::StackTrace 2.00 ExtUtils::MakeMaker 0 @@ -2702,87 +2283,51 @@ DISTRIBUTIONS perl 5.008001 strict 0 warnings 0 - Exporter-Declare-0.114 - pathname: E/EX/EXODIST/Exporter-Declare-0.114.tar.gz - provides: - Exporter::Declare 0.114 - Exporter::Declare::Export undef - Exporter::Declare::Export::Alias undef - Exporter::Declare::Export::Generator undef - Exporter::Declare::Export::Sub undef - Exporter::Declare::Export::Variable undef - Exporter::Declare::Meta undef - Exporter::Declare::Specs undef - requirements: - Carp 0 - Fennec::Lite 0.004 - Meta::Builder 0.003 - Scalar::Util 0 - Test::Exception 0.29 - Test::Simple 0.88 - aliased 0 - perl v5.8.0 - Exporter-Lite-0.08 - pathname: N/NE/NEILB/Exporter-Lite-0.08.tar.gz + Exporter-5.78 + pathname: T/TO/TODDR/Exporter-5.78.tar.gz provides: - Exporter::Lite 0.08 + Exporter 5.78 + Exporter::Heavy 5.78 requirements: - Carp 0 - ExtUtils::MakeMaker 6.3 - perl 5.006 - strict 0 - warnings 0 - Exporter-Tiny-1.000000 - pathname: T/TO/TOBYINK/Exporter-Tiny-1.000000.tar.gz + Carp 1.05 + ExtUtils::MakeMaker 0 + Exporter-Tiny-1.006002 + pathname: T/TO/TOBYINK/Exporter-Tiny-1.006002.tar.gz provides: - Exporter::Shiny 1.000000 - Exporter::Tiny 1.000000 + Exporter::Shiny 1.006002 + Exporter::Tiny 1.006002 requirements: ExtUtils::MakeMaker 6.17 perl 5.006001 - ExtUtils-Config-0.008 - pathname: L/LE/LEONT/ExtUtils-Config-0.008.tar.gz + ExtUtils-Config-0.010 + pathname: L/LE/LEONT/ExtUtils-Config-0.010.tar.gz provides: - ExtUtils::Config 0.008 + ExtUtils::Config 0.010 + ExtUtils::Config::MakeMaker 0.010 requirements: Data::Dumper 0 - ExtUtils::MakeMaker 6.30 + ExtUtils::MakeMaker 0 + ExtUtils::MakeMaker::Config 0 + perl 5.006 strict 0 warnings 0 - ExtUtils-Depends-0.405 - pathname: X/XA/XAOC/ExtUtils-Depends-0.405.tar.gz + ExtUtils-Depends-0.8002 + pathname: E/ET/ETJ/ExtUtils-Depends-0.8002.tar.gz provides: - ExtUtils::Depends 0.405 + ExtUtils::Depends 0.8002 requirements: Data::Dumper 0 - ExtUtils::MakeMaker 0 + ExtUtils::MakeMaker 7.44 File::Spec 0 IO::File 0 perl 5.006 - ExtUtils-HasCompiler-0.021 - pathname: L/LE/LEONT/ExtUtils-HasCompiler-0.021.tar.gz - provides: - ExtUtils::HasCompiler 0.021 - requirements: - Carp 0 - DynaLoader 0 - Exporter 0 - ExtUtils::MakeMaker 0 - ExtUtils::Mksymlists 0 - File::Basename 0 - File::Spec::Functions 0 - File::Temp 0 - base 0 - perl 5.006 - strict 0 - warnings 0 - ExtUtils-Helpers-0.026 - pathname: L/LE/LEONT/ExtUtils-Helpers-0.026.tar.gz + ExtUtils-Helpers-0.028 + pathname: L/LE/LEONT/ExtUtils-Helpers-0.028.tar.gz provides: - ExtUtils::Helpers 0.026 - ExtUtils::Helpers::Unix 0.026 - ExtUtils::Helpers::VMS 0.026 - ExtUtils::Helpers::Windows 0.026 + ExtUtils::Helpers 0.028 + ExtUtils::Helpers::Unix 0.028 + ExtUtils::Helpers::VMS 0.028 + ExtUtils::Helpers::Windows 0.028 requirements: Carp 0 Exporter 5.57 @@ -2791,59 +2336,59 @@ DISTRIBUTIONS File::Copy 0 File::Spec::Functions 0 Text::ParseWords 3.24 - perl 5.006 strict 0 warnings 0 - ExtUtils-InstallPaths-0.011 - pathname: L/LE/LEONT/ExtUtils-InstallPaths-0.011.tar.gz + ExtUtils-InstallPaths-0.014 + pathname: L/LE/LEONT/ExtUtils-InstallPaths-0.014.tar.gz provides: - ExtUtils::InstallPaths 0.011 + ExtUtils::InstallPaths 0.014 requirements: Carp 0 - ExtUtils::Config 0.002 + ExtUtils::Config 0.009 ExtUtils::MakeMaker 0 File::Spec 0 - perl 5.006 + perl 5.008 strict 0 warnings 0 - ExtUtils-MakeMaker-7.30 - pathname: B/BI/BINGOS/ExtUtils-MakeMaker-7.30.tar.gz - provides: - ExtUtils::Command 7.30 - ExtUtils::Command::MM 7.30 - ExtUtils::Liblist 7.30 - ExtUtils::Liblist::Kid 7.30 - ExtUtils::MM 7.30 - ExtUtils::MM_AIX 7.30 - ExtUtils::MM_Any 7.30 - ExtUtils::MM_BeOS 7.30 - ExtUtils::MM_Cygwin 7.30 - ExtUtils::MM_DOS 7.30 - ExtUtils::MM_Darwin 7.30 - ExtUtils::MM_MacOS 7.30 - ExtUtils::MM_NW5 7.30 - ExtUtils::MM_OS2 7.30 - ExtUtils::MM_QNX 7.30 - ExtUtils::MM_UWIN 7.30 - ExtUtils::MM_Unix 7.30 - ExtUtils::MM_VMS 7.30 - ExtUtils::MM_VOS 7.30 - ExtUtils::MM_Win32 7.30 - ExtUtils::MM_Win95 7.30 - ExtUtils::MY 7.30 - ExtUtils::MakeMaker 7.30 - ExtUtils::MakeMaker::Config 7.30 - ExtUtils::MakeMaker::Locale 7.30 - ExtUtils::MakeMaker::_version 7.30 - ExtUtils::MakeMaker::charstar 7.30 - ExtUtils::MakeMaker::version 7.30 - ExtUtils::MakeMaker::version::regex 7.30 - ExtUtils::MakeMaker::version::vpp 7.30 - ExtUtils::Mkbootstrap 7.30 - ExtUtils::Mksymlists 7.30 - ExtUtils::testlib 7.30 - MM 7.30 - MY 7.30 + ExtUtils-MakeMaker-7.74 + pathname: B/BI/BINGOS/ExtUtils-MakeMaker-7.74.tar.gz + provides: + ExtUtils::Command 7.74 + ExtUtils::Command::MM 7.74 + ExtUtils::Liblist 7.74 + ExtUtils::Liblist::Kid 7.74 + ExtUtils::MM 7.74 + ExtUtils::MM_AIX 7.74 + ExtUtils::MM_Any 7.74 + ExtUtils::MM_BeOS 7.74 + ExtUtils::MM_Cygwin 7.74 + ExtUtils::MM_DOS 7.74 + ExtUtils::MM_Darwin 7.74 + ExtUtils::MM_MacOS 7.74 + ExtUtils::MM_NW5 7.74 + ExtUtils::MM_OS2 7.74 + ExtUtils::MM_OS390 7.74 + ExtUtils::MM_QNX 7.74 + ExtUtils::MM_UWIN 7.74 + ExtUtils::MM_Unix 7.74 + ExtUtils::MM_VMS 7.74 + ExtUtils::MM_VOS 7.74 + ExtUtils::MM_Win32 7.74 + ExtUtils::MM_Win95 7.74 + ExtUtils::MY 7.74 + ExtUtils::MakeMaker 7.74 + ExtUtils::MakeMaker::Config 7.74 + ExtUtils::MakeMaker::Locale 7.74 + ExtUtils::MakeMaker::_version 7.74 + ExtUtils::MakeMaker::charstar 7.74 + ExtUtils::MakeMaker::version 7.74 + ExtUtils::MakeMaker::version::regex 7.74 + ExtUtils::MakeMaker::version::vpp 7.74 + ExtUtils::Mkbootstrap 7.74 + ExtUtils::Mksymlists 7.74 + ExtUtils::testlib 7.74 + MM 7.74 + MY 7.74 requirements: Data::Dumper 0 Encode 0 @@ -2851,10 +2396,10 @@ DISTRIBUTIONS File::Spec 0.8 Pod::Man 0 perl 5.006 - ExtUtils-MakeMaker-CPANfile-0.08 - pathname: I/IS/ISHIGAKI/ExtUtils-MakeMaker-CPANfile-0.08.tar.gz + ExtUtils-MakeMaker-CPANfile-0.09 + pathname: I/IS/ISHIGAKI/ExtUtils-MakeMaker-CPANfile-0.09.tar.gz provides: - ExtUtils::MakeMaker::CPANfile 0.08 + ExtUtils::MakeMaker::CPANfile 0.09 requirements: CPAN::Meta::Converter 2.141170 Cwd 0 @@ -2863,60 +2408,15 @@ DISTRIBUTIONS Module::CPANfile 0 Test::More 0.88 version 0.76 - Facebook-Graph-1.1204 - pathname: R/RI/RIZEN/Facebook-Graph-1.1204.tar.gz - provides: - Facebook::Graph 1.1204 - Facebook::Graph::AccessToken 1.1204 - Facebook::Graph::AccessToken::Response 1.1204 - Facebook::Graph::Authorize 1.1204 - Facebook::Graph::BatchRequests 1.1204 - Facebook::Graph::Page::Feed 1.1204 - Facebook::Graph::Picture 1.1204 - Facebook::Graph::Publish 1.1204 - Facebook::Graph::Publish::Checkin 1.1204 - Facebook::Graph::Publish::Comment 1.1204 - Facebook::Graph::Publish::PageTab 1.1204 - Facebook::Graph::Publish::Photo 1.1204 - Facebook::Graph::Publish::Post 1.1204 - Facebook::Graph::Publish::RSVPAttending 1.1204 - Facebook::Graph::Publish::RSVPDeclined 1.1204 - Facebook::Graph::Publish::RSVPMaybe 1.1204 - Facebook::Graph::Query 1.1204 - Facebook::Graph::Request 1.1204 - Facebook::Graph::Response 1.1204 - Facebook::Graph::Role::Uri 1.1204 - Facebook::Graph::Session 1.1204 - requirements: - DateTime 0.61 - DateTime::Format::Strptime 1.4000 - ExtUtils::MakeMaker 0 - JSON 2.16 - LWP::Protocol::https 6.06 - LWP::UserAgent 6.13 - MIME::Base64::URLSafe 0.01 - Moo 0 - Ouch 0.0400 - Test::More 0 - URI 1.54 - Fennec-Lite-0.004 - pathname: E/EX/EXODIST/Fennec-Lite-0.004.tar.gz - provides: - Fennec::Lite 0.004 - requirements: - List::Util 0 - Test::Builder 0 - Test::More 0 - perl 5.006 - File-Find-Object-v0.3.2 - pathname: S/SH/SHLOMIF/File-Find-Object-v0.3.2.tar.gz + File-Find-Object-0.3.9 + pathname: S/SH/SHLOMIF/File-Find-Object-0.3.9.tar.gz provides: - File::Find::Object v0.3.2 - File::Find::Object::Base v0.3.2 - File::Find::Object::DeepPath v0.3.2 - File::Find::Object::PathComp v0.3.2 - File::Find::Object::Result v0.3.2 - File::Find::Object::TopPath v0.3.2 + File::Find::Object v0.3.9 + File::Find::Object::Base v0.3.9 + File::Find::Object::DeepPath v0.3.9 + File::Find::Object::PathComp v0.3.9 + File::Find::Object::Result v0.3.9 + File::Find::Object::TopPath v0.3.9 requirements: Carp 0 Class::XSAccessor 0 @@ -2942,10 +2442,10 @@ DISTRIBUTIONS Number::Compare 0 Test::More 0 Text::Glob 0.07 - File-Find-Rule-Perl-1.15 - pathname: E/ET/ETHER/File-Find-Rule-Perl-1.15.tar.gz + File-Find-Rule-Perl-1.16 + pathname: E/ET/ETHER/File-Find-Rule-Perl-1.16.tar.gz provides: - File::Find::Rule::Perl 1.15 + File::Find::Rule::Perl 1.16 requirements: ExtUtils::MakeMaker 0 File::Find::Rule 0.20 @@ -2953,20 +2453,19 @@ DISTRIBUTIONS Params::Util 0.38 Parse::CPAN::Meta 1.38 perl 5.006 - File-HomeDir-1.002 - pathname: R/RE/REHSACK/File-HomeDir-1.002.tar.gz - provides: - File::HomeDir 1.002 - File::HomeDir::Darwin 1.002 - File::HomeDir::Darwin::Carbon 1.002 - File::HomeDir::Darwin::Cocoa 1.002 - File::HomeDir::Driver 1.002 - File::HomeDir::FreeDesktop 1.002 - File::HomeDir::MacOS9 1.002 - File::HomeDir::TIE 1.002 - File::HomeDir::Test 1.002 - File::HomeDir::Unix 1.002 - File::HomeDir::Windows 1.002 + File-HomeDir-1.006 + pathname: R/RE/REHSACK/File-HomeDir-1.006.tar.gz + provides: + File::HomeDir 1.006 + File::HomeDir::Darwin 1.006 + File::HomeDir::Darwin::Carbon 1.006 + File::HomeDir::Darwin::Cocoa 1.006 + File::HomeDir::Driver 1.006 + File::HomeDir::FreeDesktop 1.006 + File::HomeDir::MacOS9 1.006 + File::HomeDir::Test 1.006 + File::HomeDir::Unix 1.006 + File::HomeDir::Windows 1.006 requirements: Carp 0 Cwd 3.12 @@ -2977,86 +2476,62 @@ DISTRIBUTIONS File::Temp 0.19 File::Which 0.05 POSIX 0 - perl 5.005003 - File-Listing-6.04 - pathname: G/GA/GAAS/File-Listing-6.04.tar.gz + perl 5.008003 + File-Listing-6.16 + pathname: P/PL/PLICEASE/File-Listing-6.16.tar.gz provides: - File::Listing 6.04 - File::Listing::apache 6.04 - File::Listing::dosftp 6.04 - File::Listing::netware 6.04 - File::Listing::unix 6.04 - File::Listing::vms 6.04 + File::Listing 6.16 + File::Listing::apache 6.16 + File::Listing::dosftp 6.16 + File::Listing::netware 6.16 + File::Listing::unix 6.16 + File::Listing::vms 6.16 requirements: + Exporter 5.57 ExtUtils::MakeMaker 0 - HTTP::Date 6 - perl 5.006002 + HTTP::Date 0 + perl 5.006 File-MMagic-1.30 pathname: K/KN/KNOK/File-MMagic-1.30.tar.gz provides: File::MMagic 1.30 requirements: ExtUtils::MakeMaker 0 - File-Next-1.16 - pathname: P/PE/PETDANCE/File-Next-1.16.tar.gz + File-Next-1.18 + pathname: P/PE/PETDANCE/File-Next-1.18.tar.gz provides: - File::Next 1.16 + File::Next 1.18 requirements: ExtUtils::MakeMaker 0 + File::Copy 0 File::Spec 0 + File::Temp 0.22 Test::More 0.88 - File-Remove-1.57 - pathname: S/SH/SHLOMIF/File-Remove-1.57.tar.gz + File-ShareDir-1.118 + pathname: R/RE/REHSACK/File-ShareDir-1.118.tar.gz provides: - File::Remove 1.57 - requirements: - Cwd 3.29 - ExtUtils::MakeMaker 0 - File::Glob 0 - File::Path 0 - File::Spec 3.29 - constant 0 - perl 5.006 - strict 0 - vars 0 - warnings 0 - File-ShareDir-1.104 - pathname: R/RE/REHSACK/File-ShareDir-1.104.tar.gz - provides: - File::ShareDir 1.104 + File::ShareDir 1.118 requirements: Carp 0 Class::Inspector 1.12 ExtUtils::MakeMaker 0 - File::ShareDir::Install 0.03 + File::ShareDir::Install 0.13 File::Spec 0.80 perl 5.008001 warnings 0 - File-ShareDir-Install-0.11 - pathname: E/ET/ETHER/File-ShareDir-Install-0.11.tar.gz + File-ShareDir-Install-0.14 + pathname: E/ET/ETHER/File-ShareDir-Install-0.14.tar.gz provides: - File::ShareDir::Install 0.11 + File::ShareDir::Install 0.14 requirements: Carp 0 Exporter 0 + ExtUtils::MakeMaker 0 File::Spec 0 IO::Dir 0 - Module::Build::Tiny 0.034 - perl 5.008 + perl 5.006 strict 0 warnings 0 - File-Slurp-9999.19 - pathname: U/UR/URI/File-Slurp-9999.19.tar.gz - provides: - File::Slurp 9999.19 - FileSlurp_12 9999.13 - requirements: - Carp 0 - Exporter 0 - ExtUtils::MakeMaker 0 - Fcntl 0 - POSIX 0 - perl 5.004 File-Spec-Native-1.004 pathname: R/RW/RWSTAUNER/File-Spec-Native-1.004.tar.gz provides: @@ -3067,31 +2542,28 @@ DISTRIBUTIONS perl 5.006 strict 0 warnings 0 - File-Sync-0.11 - pathname: B/BR/BRIANSKI/File-Sync-0.11.tar.gz + File-Which-1.27 + pathname: P/PL/PLICEASE/File-Which-1.27.tar.gz provides: - File::Sync 0.11 + File::Which 1.27 requirements: ExtUtils::MakeMaker 0 - File-Which-1.22 - pathname: P/PL/PLICEASE/File-Which-1.22.tar.gz + base 0 + perl 5.006 + File-XDG-1.03 + pathname: P/PL/PLICEASE/File-XDG-1.03.tar.gz provides: - File::Which 1.22 + File::XDG 1.03 requirements: ExtUtils::MakeMaker 0 + File::Path 2.07 + Path::Tiny 0 + Ref::Util 0 perl 5.006 - File-Zglob-0.11 - pathname: T/TO/TOKUHIROM/File-Zglob-0.11.tar.gz - provides: - File::Zglob 0.11 - requirements: - ExtUtils::MakeMaker 6.59 - Test::More 0.96 - perl 5.008008 - File-pushd-1.014 - pathname: D/DA/DAGOLDEN/File-pushd-1.014.tar.gz + File-pushd-1.016 + pathname: D/DA/DAGOLDEN/File-pushd-1.016.tar.gz provides: - File::pushd 1.014 + File::pushd 1.016 requirements: Carp 0 Cwd 0 @@ -3104,137 +2576,41 @@ DISTRIBUTIONS perl 5.006 strict 0 warnings 0 - Filesys-Notify-Simple-0.12 - pathname: M/MI/MIYAGAWA/Filesys-Notify-Simple-0.12.tar.gz + Filesys-Notify-Simple-0.14 + pathname: M/MI/MIYAGAWA/Filesys-Notify-Simple-0.14.tar.gz provides: - Filesys::Notify::Simple 0.12 + Filesys::Notify::Simple 0.14 requirements: - ExtUtils::MakeMaker 6.30 - Find-Lib-1.04 - pathname: Y/YA/YANNK/Find-Lib-1.04.tar.gz + ExtUtils::MakeMaker 0 + perl 5.008001 + Getopt-Long-2.58 + pathname: J/JV/JV/Getopt-Long-2.58.tar.gz provides: - Find::Lib 1.04 + Getopt::Long 2.58 + Getopt::Long::Parser 2.58 requirements: ExtUtils::MakeMaker 0 - File::Spec 0 - Test::More 0 - Gazelle-0.46 - pathname: K/KA/KAZEBURO/Gazelle-0.46.tar.gz - provides: - Gazelle 0.46 - Plack::Handler::Gazelle 0.46 - requirements: - Devel::CheckCompiler 0.04 - Guard 0 - Module::Build 0.38 - Parallel::Prefork 0.18 - Plack 1.0037 - Server::Starter 0 - Stream::Buffered 0 - Try::Tiny 0 - perl 5.008001 - Getopt-Long-Descriptive-0.100 - pathname: R/RJ/RJBS/Getopt-Long-Descriptive-0.100.tar.gz + Pod::Usage 1.14 + Getopt-Long-Descriptive-0.116 + pathname: R/RJ/RJBS/Getopt-Long-Descriptive-0.116.tar.gz provides: - Getopt::Long::Descriptive 0.100 - Getopt::Long::Descriptive::Opts 0.100 - Getopt::Long::Descriptive::Usage 0.100 + Getopt::Long::Descriptive 0.116 + Getopt::Long::Descriptive::Opts 0.116 + Getopt::Long::Descriptive::Usage 0.116 requirements: Carp 0 - ExtUtils::MakeMaker 0 + ExtUtils::MakeMaker 6.78 File::Basename 0 - Getopt::Long 2.33 + Getopt::Long 2.55 List::Util 0 Params::Validate 0.97 Scalar::Util 0 Sub::Exporter 0.972 Sub::Exporter::Util 0 overload 0 + perl 5.012 strict 0 warnings 0 - Git-Helpers-0.000013 - pathname: O/OA/OALDERS/Git-Helpers-0.000013.tar.gz - provides: - Git::Helpers 0.000013 - Git::Helpers::CPAN 0.000013 - requirements: - Browser::Open 0 - Capture::Tiny 0 - Carp 0 - ExtUtils::MakeMaker 0 - File::pushd 0 - Getopt::Long 0 - Git::Sub 0 - MetaCPAN::Client 0 - Moo 0 - MooX::Options 0 - String::Trim 0 - Sub::Exporter 0 - Term::ReadLine 0 - Term::UI 0 - Try::Tiny 0 - Types::Standard 0 - URI 0 - URI::FromHash 0 - URI::Heuristic 0 - URI::git 0 - perl 5.006 - strict 0 - warnings 0 - Git-Sub-0.163320 - pathname: D/DO/DOLMEN/Git-Sub-0.163320.tar.gz - provides: - Git::Sub 0.163320 - requirements: - Carp 0 - ExtUtils::MakeMaker 0 - File::Which 0 - System::Sub 0.162800 - perl 5.006 - strict 0 - subs 0 - warnings 0 - Graph-0.9704 - pathname: J/JH/JHI/Graph-0.9704.tar.gz - provides: - Graph 0.9704 - Graph::AdjacencyMap undef - Graph::AdjacencyMap::Heavy undef - Graph::AdjacencyMap::Light undef - Graph::AdjacencyMap::Vertex undef - Graph::AdjacencyMatrix undef - Graph::Attribute undef - Graph::BitMatrix undef - Graph::Directed undef - Graph::MSTHeapElem undef - Graph::Matrix undef - Graph::SPTHeapElem undef - Graph::TransitiveClosure undef - Graph::TransitiveClosure::Matrix undef - Graph::Traversal undef - Graph::Traversal::BFS undef - Graph::Traversal::DFS undef - Graph::Undirected undef - Graph::UnionFind undef - Heap071::Elem undef - Heap071::Fibonacci undef - requirements: - ExtUtils::MakeMaker 0 - List::Util 0 - Math::Complex 0 - Safe 0 - Scalar::Util 0 - Storable 2.05 - Test::More 0 - perl 5.006 - Graph-Centrality-Pagerank-1.05 - pathname: K/KU/KUBINA/Graph-Centrality-Pagerank-1.05.tar.gz - provides: - Graph::Centrality::Pagerank 1.05 - requirements: - Data::Dump 1.14 - ExtUtils::MakeMaker 0 - Graph 0.91 Gravatar-URL-1.07 pathname: M/MS/MSCHWERN/Gravatar-URL-1.07.tar.gz provides: @@ -3252,129 +2628,43 @@ DISTRIBUTIONS URI::Escape 0 parent 0 perl v5.6.0 - Guard-1.023 - pathname: M/ML/MLEHMANN/Guard-1.023.tar.gz - provides: - Guard 1.023 - requirements: - ExtUtils::MakeMaker 0 - HTML-Form-6.03 - pathname: G/GA/GAAS/HTML-Form-6.03.tar.gz + HTML-Parser-3.83 + pathname: O/OA/OALDERS/HTML-Parser-3.83.tar.gz provides: - HTML::Form 6.03 - HTML::Form::FileInput 6.03 - HTML::Form::IgnoreInput 6.03 - HTML::Form::ImageInput 6.03 - HTML::Form::Input 6.03 - HTML::Form::KeygenInput 6.03 - HTML::Form::ListInput 6.03 - HTML::Form::SubmitInput 6.03 - HTML::Form::TextInput 6.03 - requirements: - Encode 2 - ExtUtils::MakeMaker 0 - HTML::TokeParser 0 - HTTP::Request 6 - HTTP::Request::Common 6.03 - URI 1.10 - perl 5.008001 - HTML-Parser-3.72 - pathname: G/GA/GAAS/HTML-Parser-3.72.tar.gz - provides: - HTML::Entities 3.69 - HTML::Filter 3.72 - HTML::HeadParser 3.71 - HTML::LinkExtor 3.69 - HTML::Parser 3.72 - HTML::PullParser 3.57 - HTML::TokeParser 3.69 - requirements: - ExtUtils::MakeMaker 0 - HTML::Tagset 3 - XSLoader 0 - perl 5.008 - HTML-Restrict-2.2.4 - pathname: O/OA/OALDERS/HTML-Restrict-2.2.4.tar.gz - provides: - HTML::Restrict 2.002004 + HTML::Entities 3.83 + HTML::Filter 3.83 + HTML::HeadParser 3.83 + HTML::LinkExtor 3.83 + HTML::Parser 3.83 + HTML::PullParser 3.83 + HTML::TokeParser 3.83 requirements: Carp 0 - Data::Dump 0 - ExtUtils::MakeMaker 0 - HTML::Entities 0 - HTML::Parser 0 - List::Util 1.33 - Moo 1.002000 - Scalar::Util 0 - Sub::Quote 0 - Types::Standard 1.000001 + Exporter 0 + ExtUtils::MakeMaker 6.52 + HTML::Tagset 0 + HTTP::Headers 0 + IO::File 0 URI 0 - namespace::clean 0 - perl 5.006 + URI::URL 0 + XSLoader 0 strict 0 - HTML-Tagset-3.20 - pathname: P/PE/PETDANCE/HTML-Tagset-3.20.tar.gz - provides: - HTML::Tagset 3.20 - requirements: - ExtUtils::MakeMaker 0 - HTML-Tiny-1.05 - pathname: A/AN/ANDYA/HTML-Tiny-1.05.tar.gz - provides: - HTML::Tiny 1.05 - requirements: - ExtUtils::MakeMaker 0 - Test::More 0 - HTML-TokeParser-Simple-3.16 - pathname: O/OV/OVID/HTML-TokeParser-Simple-3.16.tar.gz - provides: - HTML::TokeParser::Simple 3.16 - HTML::TokeParser::Simple::Token 3.16 - HTML::TokeParser::Simple::Token::Comment 3.16 - HTML::TokeParser::Simple::Token::Declaration 3.15 - HTML::TokeParser::Simple::Token::ProcessInstruction 3.16 - HTML::TokeParser::Simple::Token::Tag 3.16 - HTML::TokeParser::Simple::Token::Tag::End 3.16 - HTML::TokeParser::Simple::Token::Tag::Start 3.16 - HTML::TokeParser::Simple::Token::Text 3.16 - requirements: - HTML::Parser 3.25 - HTML::TokeParser 2.24 - Sub::Override 0 - Test::More 0 - perl 5.006 - HTML-Tree-5.07 - pathname: K/KE/KENTNL/HTML-Tree-5.07.tar.gz + HTML-Tagset-3.24 + pathname: P/PE/PETDANCE/HTML-Tagset-3.24.tar.gz provides: - HTML::AsSubs 5.07 - HTML::Element 5.07 - HTML::Element::traverse 5.07 - HTML::Parse 5.07 - HTML::Tree 5.07 - HTML::TreeBuilder 5.07 + HTML::Tagset 3.24 requirements: - Carp 0 - Encode 0 - Exporter 0 - HTML::Entities 0 - HTML::Parser 3.46 - HTML::Tagset 3.02 - Module::Build 0.2808 - Scalar::Util 0 - Test::Fatal 0 - Test::More 0 - base 0 - integer 0 - perl 5.008 - HTTP-Body-1.22 - pathname: G/GE/GETTY/HTTP-Body-1.22.tar.gz + ExtUtils::MakeMaker 6.46 + perl 5.010001 + HTTP-Body-1.23 + pathname: G/GE/GETTY/HTTP-Body-1.23.tar.gz provides: - HTTP::Body 1.22 - HTTP::Body::MultiPart 1.22 - HTTP::Body::OctetStream 1.22 - HTTP::Body::UrlEncoded 1.22 - HTTP::Body::XForms 1.22 - HTTP::Body::XFormsMultipart 1.22 + HTTP::Body 1.23 + HTTP::Body::MultiPart 1.23 + HTTP::Body::OctetStream 1.23 + HTTP::Body::UrlEncoded 1.23 + HTTP::Body::XForms 1.23 + HTTP::Body::XFormsMultipart 1.23 requirements: Carp 0 Digest::MD5 0 @@ -3382,68 +2672,36 @@ DISTRIBUTIONS File::Temp 0.14 HTTP::Headers 0 IO::File 1.14 - HTTP-CookieMonster-0.09 - pathname: O/OA/OALDERS/HTTP-CookieMonster-0.09.tar.gz - provides: - HTTP::CookieMonster 0.09 - HTTP::CookieMonster::Cookie 0.09 - requirements: - Carp 0 - ExtUtils::MakeMaker 0 - HTTP::Cookies 0 - Module::Build 0.28 - Moo 1.000003 - Safe::Isa 0 - Scalar::Util 0 - Sub::Exporter 0 - URI::Escape 0 - perl 5.006 - strict 0 - warnings 0 - HTTP-Cookies-6.04 - pathname: O/OA/OALDERS/HTTP-Cookies-6.04.tar.gz + HTTP-Cookies-6.11 + pathname: O/OA/OALDERS/HTTP-Cookies-6.11.tar.gz provides: - HTTP::Cookies 6.04 - HTTP::Cookies::Microsoft 6.04 - HTTP::Cookies::Netscape 6.04 + HTTP::Cookies 6.11 + HTTP::Cookies::Microsoft 6.11 + HTTP::Cookies::Netscape 6.11 requirements: Carp 0 ExtUtils::MakeMaker 0 HTTP::Date 6 HTTP::Headers::Util 6 HTTP::Request 0 - Time::Local 0 locale 0 perl 5.008001 strict 0 - vars 0 - HTTP-Daemon-6.01 - pathname: G/GA/GAAS/HTTP-Daemon-6.01.tar.gz - provides: - HTTP::Daemon 6.01 - HTTP::Daemon::ClientConn 6.01 - requirements: - ExtUtils::MakeMaker 0 - HTTP::Date 6 - HTTP::Request 6 - HTTP::Response 6 - HTTP::Status 6 - IO::Socket 0 - LWP::MediaTypes 6 - Sys::Hostname 0 - perl 5.008001 - HTTP-Date-6.02 - pathname: G/GA/GAAS/HTTP-Date-6.02.tar.gz + HTTP-Date-6.06 + pathname: O/OA/OALDERS/HTTP-Date-6.06.tar.gz provides: - HTTP::Date 6.02 + HTTP::Date 6.06 requirements: + Exporter 0 ExtUtils::MakeMaker 0 - Time::Local 0 + Time::Local 1.28 + Time::Zone 0 perl 5.006002 - HTTP-Entity-Parser-0.20 - pathname: K/KA/KAZEBURO/HTTP-Entity-Parser-0.20.tar.gz + strict 0 + HTTP-Entity-Parser-0.25 + pathname: K/KA/KAZEBURO/HTTP-Entity-Parser-0.25.tar.gz provides: - HTTP::Entity::Parser 0.20 + HTTP::Entity::Parser 0.25 HTTP::Entity::Parser::JSON undef HTTP::Entity::Parser::MultiPart undef HTTP::Entity::Parser::OctetStream undef @@ -3458,50 +2716,50 @@ DISTRIBUTIONS Module::Load 0 Stream::Buffered 0 WWW::Form::UrlEncoded 0.23 - perl 5.008005 - HTTP-Headers-Fast-0.21 - pathname: T/TO/TOKUHIROM/HTTP-Headers-Fast-0.21.tar.gz + perl 5.008001 + HTTP-Headers-Fast-0.22 + pathname: T/TO/TOKUHIROM/HTTP-Headers-Fast-0.22.tar.gz provides: - HTTP::Headers::Fast 0.21 + HTTP::Headers::Fast 0.22 requirements: HTTP::Date 0 Module::Build::Tiny 0.035 perl 5.008001 - HTTP-Message-6.13 - pathname: O/OA/OALDERS/HTTP-Message-6.13.tar.gz - provides: - HTTP::Config 6.13 - HTTP::Headers 6.13 - HTTP::Headers::Auth 6.13 - HTTP::Headers::ETag 6.13 - HTTP::Headers::Util 6.13 - HTTP::Message 6.13 - HTTP::Request 6.13 - HTTP::Request::Common 6.13 - HTTP::Response 6.13 - HTTP::Status 6.13 - requirements: - Carp 0 - Compress::Raw::Zlib 0 - Encode 2.21 + HTTP-Message-7.00 + pathname: O/OA/OALDERS/HTTP-Message-7.00.tar.gz + provides: + HTTP::Config 7.00 + HTTP::Headers 7.00 + HTTP::Headers::Auth 7.00 + HTTP::Headers::ETag 7.00 + HTTP::Headers::Util 7.00 + HTTP::Message 7.00 + HTTP::Request 7.00 + HTTP::Request::Common 7.00 + HTTP::Response 7.00 + HTTP::Status 7.00 + requirements: + Carp 0 + Clone 0.46 + Compress::Raw::Bzip2 0 + Compress::Raw::Zlib 2.062 + Encode 3.01 Encode::Locale 1 Exporter 5.57 ExtUtils::MakeMaker 0 + File::Spec 0 HTTP::Date 6 IO::Compress::Bzip2 2.021 IO::Compress::Deflate 0 IO::Compress::Gzip 0 IO::HTML 0 - IO::Uncompress::Bunzip2 2.021 - IO::Uncompress::Gunzip 0 IO::Uncompress::Inflate 0 IO::Uncompress::RawInflate 0 LWP::MediaTypes 6 MIME::Base64 2.1 MIME::QuotedPrint 0 - Storable 0 URI 1.10 - base 0 + parent 0 perl 5.008001 strict 0 warnings 0 @@ -3524,42 +2782,23 @@ DISTRIBUTIONS ExtUtils::MakeMaker 0 HTTP::Headers 6 perl 5.008001 - HTTP-Parser-XS-0.17 - pathname: K/KA/KAZUHO/HTTP-Parser-XS-0.17.tar.gz - provides: - HTTP::Parser::XS 0.17 - HTTP::Parser::XS::PP undef - requirements: - ExtUtils::MakeMaker 6.36 - Test::More 0.96 - HTTP-Request-AsCGI-1.2 - pathname: F/FL/FLORA/HTTP-Request-AsCGI-1.2.tar.gz - provides: - HTTP::Request::AsCGI 1.2 - requirements: - Carp 0 - Class::Accessor 0 - ExtUtils::MakeMaker 0 - HTTP::Request 0 - HTTP::Response 1.53 - IO::File 0 - Test::More 0 - URI::Escape 0 - HTTP-Server-Simple-0.52 - pathname: B/BP/BPS/HTTP-Server-Simple-0.52.tar.gz + HTTP-Thin-0.006 + pathname: P/PE/PERIGRIN/HTTP-Thin-0.006.tar.gz provides: - HTTP::Server::Simple 0.52 - HTTP::Server::Simple::CGI undef - HTTP::Server::Simple::CGI::Environment undef + HTTP::Thin 0.006 requirements: - CGI 0 - ExtUtils::MakeMaker 6.36 - Socket 1.94 - Test::More 0 - HTTP-Tiny-0.070 - pathname: D/DA/DAGOLDEN/HTTP-Tiny-0.070.tar.gz + Class::Method::Modifiers 0 + ExtUtils::MakeMaker 6.30 + HTTP::Response 0 + HTTP::Tiny 0 + Hash::MultiValue 0 + Safe::Isa 0 + parent 0 + warnings 0 + HTTP-Tiny-0.090 + pathname: H/HA/HAARG/HTTP-Tiny-0.090.tar.gz provides: - HTTP::Tiny 0.070 + HTTP::Tiny 0.090 requirements: Carp 0 ExtUtils::MakeMaker 6.17 @@ -3572,30 +2811,31 @@ DISTRIBUTIONS perl 5.006 strict 0 warnings 0 - Hash-Merge-0.298 - pathname: H/HE/HERMES/Hash-Merge-0.298.tar.gz + Hash-Merge-0.302 + pathname: H/HE/HERMES/Hash-Merge-0.302.tar.gz provides: - Hash::Merge 0.298 + Hash::Merge 0.302 requirements: Clone::Choose 0.008 - ExtUtils::MakeMaker 0 + ExtUtils::MakeMaker 6.64 Scalar::Util 0 perl 5.008001 - Hash-Merge-Simple-0.051 - pathname: R/RO/ROKR/Hash-Merge-Simple-0.051.tar.gz + Hash-Merge-Simple-0.052 + pathname: H/HA/HAARG/Hash-Merge-Simple-0.052.tar.gz provides: - Hash::Merge::Simple 0.051 + Hash::Merge::Simple 0.052 requirements: Clone 0 - ExtUtils::MakeMaker 6.31 + ExtUtils::MakeMaker 0 Storable 0 - Test::Most 0 - Hash-MoreUtils-0.05 - pathname: R/RE/REHSACK/Hash-MoreUtils-0.05.tar.gz + perl 5.006000 + Hash-MoreUtils-0.06 + pathname: R/RE/REHSACK/Hash-MoreUtils-0.06.tar.gz provides: - Hash::MoreUtils 0.05 + Hash::MoreUtils 0.06 requirements: - Test::More 0.90 + ExtUtils::MakeMaker 0 + perl 5.008001 Hash-MultiValue-0.16 pathname: A/AR/ARISTOTLE/Hash-MultiValue-0.16.tar.gz provides: @@ -3603,172 +2843,147 @@ DISTRIBUTIONS requirements: ExtUtils::MakeMaker 0 perl 5.008001 - Hook-LexWrap-0.26 - pathname: E/ET/ETHER/Hook-LexWrap-0.26.tar.gz - provides: - Hook::LexWrap 0.26 + IO-1.55 + pathname: T/TO/TODDR/IO-1.55.tar.gz + provides: + IO 1.55 + IO::Dir 1.55 + IO::File 1.55 + IO::Handle 1.55 + IO::Pipe 1.55 + IO::Pipe::End 1.55 + IO::Poll 1.55 + IO::Seekable 1.55 + IO::Select 1.55 + IO::Socket 1.55 + IO::Socket::INET 1.55 + IO::Socket::UNIX 1.55 requirements: - Carp 0 ExtUtils::MakeMaker 0 - overload 0 - perl 5.006 - strict 0 - warnings 0 - IO-All-0.87 - pathname: F/FR/FREW/IO-All-0.87.tar.gz - provides: - IO::All 0.87 - IO::All::Base undef - IO::All::DBM undef - IO::All::Dir undef - IO::All::File undef - IO::All::Filesys undef - IO::All::Link undef - IO::All::MLDBM undef - IO::All::Pipe undef - IO::All::STDIO undef - IO::All::Socket undef - IO::All::String undef - IO::All::Temp undef - requirements: - Cwd 0 + File::Temp 0.15 + Test::More 0 + IO-Compress-2.213 + pathname: P/PM/PMQS/IO-Compress-2.213.tar.gz + provides: + Compress::Zlib 2.213 + File::GlobMapper 1.001 + IO::Compress 2.213 + IO::Compress::Adapter::Bzip2 2.213 + IO::Compress::Adapter::Deflate 2.213 + IO::Compress::Adapter::Identity 2.213 + IO::Compress::Base 2.213 + IO::Compress::Base::Common 2.213 + IO::Compress::Bzip2 2.213 + IO::Compress::Deflate 2.213 + IO::Compress::Gzip 2.213 + IO::Compress::Gzip::Constants 2.213 + IO::Compress::RawDeflate 2.213 + IO::Compress::Zip 2.213 + IO::Compress::Zip::Constants 2.213 + IO::Compress::Zlib::Constants 2.213 + IO::Compress::Zlib::Extra 2.213 + IO::Uncompress::Adapter::Bunzip2 2.213 + IO::Uncompress::Adapter::Identity 2.213 + IO::Uncompress::Adapter::Inflate 2.213 + IO::Uncompress::AnyInflate 2.213 + IO::Uncompress::AnyUncompress 2.213 + IO::Uncompress::Base 2.213 + IO::Uncompress::Bunzip2 2.213 + IO::Uncompress::Gunzip 2.213 + IO::Uncompress::Inflate 2.213 + IO::Uncompress::RawInflate 2.213 + IO::Uncompress::Unzip 2.213 + U64 2.213 + Zlib::OldDeflate 2.213 + Zlib::OldInflate 2.213 + requirements: + Compress::Raw::Bzip2 2.213 + Compress::Raw::Zlib 2.213 + Encode 0 ExtUtils::MakeMaker 0 Scalar::Util 0 - perl 5.008001 - IO-CaptureOutput-1.1104 - pathname: D/DA/DAGOLDEN/IO-CaptureOutput-1.1104.tar.gz - provides: - IO::CaptureOutput 1.1104 - requirements: - Carp 0 - Exporter 0 - ExtUtils::MakeMaker 6.17 - File::Basename 0 - File::Temp 0.16 - Symbol 0 - perl 5.006 - strict 0 - vars 0 - warnings 0 - IO-File-AtomicChange-0.05 - pathname: H/HI/HIROSE/IO-File-AtomicChange-0.05.tar.gz + Time::Local 0 + IO-File-AtomicChange-0.08 + pathname: H/HI/HIROSE/IO-File-AtomicChange-0.08.tar.gz provides: - IO::File::AtomicChange 0.05 + IO::File::AtomicChange 0.08 requirements: - CPAN::Meta 0 - ExtUtils::MakeMaker 6.36 File::Copy 0 - File::Sync 0 File::Temp 0 - IO::File 0 + IO 1.39 + Module::Build::Tiny 0.039 POSIX 0 Path::Class 0 Time::HiRes 0 - IO-HTML-1.001 - pathname: C/CJ/CJM/IO-HTML-1.001.tar.gz + perl 5.008005 + IO-HTML-1.004 + pathname: C/CJ/CJM/IO-HTML-1.004.tar.gz provides: - IO::HTML 1.001 + IO::HTML 1.004 requirements: Carp 0 Encode 2.10 Exporter 5.57 - ExtUtils::MakeMaker 6.30 - IO-Interactive-1.022 - pathname: B/BD/BDFOY/IO-Interactive-1.022.tar.gz + ExtUtils::MakeMaker 0 + perl 5.008 + IO-Prompt-Tiny-0.003 + pathname: D/DA/DAGOLDEN/IO-Prompt-Tiny-0.003.tar.gz provides: - IO::Interactive 1.022 + IO::Prompt::Tiny 0.003 requirements: - ExtUtils::MakeMaker 6.64 - File::Spec::Functions 0 - perl 5.008 - IO-Prompt-0.997004 - pathname: D/DC/DCONWAY/IO-Prompt-0.997004.tar.gz + Carp 0 + Exporter 0 + ExtUtils::MakeMaker 6.17 + perl 5.006 + strict 0 + warnings 0 + IO-Socket-IP-0.43 + pathname: P/PE/PEVANS/IO-Socket-IP-0.43.tar.gz provides: - IO::Prompt 0.997004 - IO::Prompt::ReturnVal 0.997004 + IO::Socket::IP 0.43 requirements: - IO::Handle 0 - Term::ReadKey 0 - Test::More 0 - Want 0 - IO-Socket-SSL-2.052 - pathname: S/SU/SULLR/IO-Socket-SSL-2.052.tar.gz - provides: - IO::Socket::SSL 2.052 - IO::Socket::SSL::Intercept 2.014 - IO::Socket::SSL::OCSP_Cache 2.052 - IO::Socket::SSL::OCSP_Resolver 2.052 + IO::Socket 0 + Module::Build 0.4004 + Socket 1.97 + perl 5.014 + IO-Socket-SSL-2.089 + pathname: S/SU/SULLR/IO-Socket-SSL-2.089.tar.gz + provides: + IO::Socket::SSL 2.089 + IO::Socket::SSL::Intercept 2.056 + IO::Socket::SSL::OCSP_Cache 2.089 + IO::Socket::SSL::OCSP_Resolver 2.089 IO::Socket::SSL::PublicSuffix undef - IO::Socket::SSL::SSL_Context 2.052 - IO::Socket::SSL::SSL_HANDLE 2.052 - IO::Socket::SSL::Session_Cache 2.052 - IO::Socket::SSL::Utils 2.014 + IO::Socket::SSL::SSL_Context 2.089 + IO::Socket::SSL::SSL_HANDLE 2.089 + IO::Socket::SSL::Session_Cache 2.089 + IO::Socket::SSL::Trace 2.089 + IO::Socket::SSL::Utils 2.015 requirements: ExtUtils::MakeMaker 0 - Mozilla::CA 0 Net::SSLeay 1.46 Scalar::Util 0 - IO-String-1.08 - pathname: G/GA/GAAS/IO-String-1.08.tar.gz - provides: - IO::String 1.08 - requirements: - ExtUtils::MakeMaker 0 - IO-stringy-2.111 - pathname: D/DS/DSKOLL/IO-stringy-2.111.tar.gz - provides: - IO::AtomicFile 2.111 - IO::Clever 1.01 - IO::InnerFile 2.111 - IO::Lines 2.111 - IO::Scalar 2.111 - IO::ScalarArray 2.111 - IO::Stringy 2.111 - IO::Wrap 2.111 - IO::WrapTie 2.111 - IO::WrapTie::Master 2.111 - IO::WrapTie::Slave 2.111 - requirements: - ExtUtils::MakeMaker 0 - IPC-Run-0.96 - pathname: T/TO/TODDR/IPC-Run-0.96.tar.gz - provides: - IPC::Run 0.96 - IPC::Run::Debug 0.96 - IPC::Run::IO 0.96 - IPC::Run::Timer 0.96 - IPC::Run::Win32Helper 0.96 - IPC::Run::Win32IO 0.96 - IPC::Run::Win32Pump 0.96 - requirements: - ExtUtils::MakeMaker 0 - Test::More 0.47 - IPC-Run3-0.048 - pathname: R/RJ/RJBS/IPC-Run3-0.048.tar.gz + IPC-Run3-0.049 + pathname: R/RJ/RJBS/IPC-Run3-0.049.tar.gz provides: - IPC::Run3 0.048 + IPC::Run3 0.049 requirements: ExtUtils::MakeMaker 0 Test::More 0.31 Time::HiRes 0 - IPC-Signal-1.00 - pathname: R/RO/ROSCH/IPC-Signal-1.00.tar.gz - provides: - IPC::Signal 1.00 - requirements: - ExtUtils::MakeMaker 0 - IPC-System-Simple-1.25 - pathname: P/PJ/PJF/IPC-System-Simple-1.25.tar.gz + IPC-System-Simple-1.30 + pathname: J/JK/JKEENAN/IPC-System-Simple-1.30.tar.gz provides: - IPC::System::Simple 1.25 + IPC::System::Simple 1.30 requirements: Carp 0 Exporter 0 - ExtUtils::MakeMaker 6.30 + ExtUtils::MakeMaker 0 List::Util 0 POSIX 0 Scalar::Util 0 constant 0 + perl 5.006 re 0 strict 0 warnings 0 @@ -3782,193 +2997,115 @@ DISTRIBUTIONS perl 5.006 strict 0 warnings 0 - Iterator-0.03 - pathname: R/RO/ROODE/Iterator-0.03.tar.gz - provides: - Iterator 0.03 - requirements: - Exception::Class 1.21 - ExtUtils::MakeMaker 0 - Test::Simple 0.40 - Iterator-Util-0.02 - pathname: R/RO/ROODE/Iterator-Util-0.02.tar.gz + JSON-4.10 + pathname: I/IS/ISHIGAKI/JSON-4.10.tar.gz provides: - Iterator::Util 0.02 - requirements: - Exception::Class 1.21 - ExtUtils::MakeMaker 0 - Iterator 0.01 - Test::Simple 0.40 - JSON-2.94 - pathname: I/IS/ISHIGAKI/JSON-2.94.tar.gz - provides: - JSON 2.94 - JSON::Backend::PP 2.94 + JSON 4.10 + JSON::Backend::PP 4.10 requirements: ExtUtils::MakeMaker 0 Test::More 0 - JSON-MaybeXS-1.003009 - pathname: E/ET/ETHER/JSON-MaybeXS-1.003009.tar.gz + JSON-MaybeXS-1.004008 + pathname: E/ET/ETHER/JSON-MaybeXS-1.004008.tar.gz provides: - JSON::MaybeXS 1.003009 + JSON::MaybeXS 1.004008 requirements: Carp 0 Cpanel::JSON::XS 2.3310 - ExtUtils::CBuilder 0.27 ExtUtils::MakeMaker 0 - File::Spec 0 - File::Temp 0 JSON::PP 2.27300 Scalar::Util 0 perl 5.006 - JSON-XS-3.04 - pathname: M/ML/MLEHMANN/JSON-XS-3.04.tar.gz + JSON-Validator-5.15 + pathname: J/JH/JHTHORSEN/JSON-Validator-5.15.tar.gz + provides: + JSON::Validator 5.15 + JSON::Validator::Error undef + JSON::Validator::Formats undef + JSON::Validator::Joi undef + JSON::Validator::Schema undef + JSON::Validator::Schema::Draft201909 undef + JSON::Validator::Schema::Draft4 undef + JSON::Validator::Schema::Draft6 undef + JSON::Validator::Schema::Draft7 undef + JSON::Validator::Schema::OpenAPIv2 undef + JSON::Validator::Schema::OpenAPIv3 undef + JSON::Validator::Store undef + JSON::Validator::URI undef + JSON::Validator::Util undef + requirements: + ExtUtils::MakeMaker 0 + List::Util 1.45 + Mojolicious 7.28 + YAML::XS 0.67 + perl 5.016 + JSON-XS-4.03 + pathname: M/ML/MLEHMANN/JSON-XS-4.03.tar.gz provides: - JSON::XS 3.04 + JSON::XS 4.03 requirements: Canary::Stability 0 ExtUtils::MakeMaker 6.52 Types::Serialiser 0 common::sense 0 - LWP-ConsoleLogger-0.000036 - pathname: O/OA/OALDERS/LWP-ConsoleLogger-0.000036.tar.gz - provides: - LWP::ConsoleLogger 0.000036 - LWP::ConsoleLogger::Easy 0.000036 - LWP::ConsoleLogger::Everywhere 0.000036 - requirements: - Class::Method::Modifiers 0 - Data::Printer 0.36 - DateTime 0 - ExtUtils::MakeMaker 0 - HTML::Restrict 0 - HTTP::Body 0 - HTTP::CookieMonster 0 - JSON::MaybeXS 1.003005 - LWP::UserAgent 0 - List::AllUtils 0 - Log::Dispatch 2.56 - Module::Load::Conditional 0 - Moo 0 - MooX::StrictConstructor 0 - Parse::MIME 0 - String::Trim 0 - Sub::Exporter 0 - Term::Size::Any 0 - Text::SimpleTable::AutoWidth 0.09 - Try::Tiny 0 - Types::Common::Numeric 0 - Types::Standard 0 - URI::Query 0 - URI::QueryParam 0 - XML::Simple 0 - perl 5.013010 - strict 0 - warnings 0 - LWP-MediaTypes-6.02 - pathname: G/GA/GAAS/LWP-MediaTypes-6.02.tar.gz + LWP-MediaTypes-6.04 + pathname: O/OA/OALDERS/LWP-MediaTypes-6.04.tar.gz provides: - LWP::MediaTypes 6.02 + LWP::MediaTypes 6.04 requirements: + Carp 0 + Exporter 0 ExtUtils::MakeMaker 0 + File::Basename 0 + Scalar::Util 0 perl 5.006002 - LWP-Protocol-https-6.07 - pathname: O/OA/OALDERS/LWP-Protocol-https-6.07.tar.gz + strict 0 + LWP-Protocol-https-6.14 + pathname: O/OA/OALDERS/LWP-Protocol-https-6.14.tar.gz provides: - LWP::Protocol::https 6.07 - LWP::Protocol::https::Socket 6.07 + LWP::Protocol::https 6.14 + LWP::Protocol::https::Socket 6.14 requirements: ExtUtils::MakeMaker 0 - IO::Socket::SSL 1.54 + IO::Socket::SSL 1.970 + LWP::Protocol::http 0 LWP::UserAgent 6.06 - Mozilla::CA 20110101 Net::HTTPS 6 + base 0 perl 5.008001 - LWP-UserAgent-Paranoid-0.97 - pathname: T/TS/TSIBLEY/LWP-UserAgent-Paranoid-0.97.tar.gz - provides: - LWP::UserAgent::Paranoid 0.97 - LWP::UserAgent::Paranoid::Compat undef - LWP::UserAgent::Paranoid::Test undef - requirements: - ExtUtils::MakeMaker 6.36 - HTTP::Server::PSGI 0 - LWP::UserAgent 0 - LWPx::ParanoidHandler 0 - Net::DNS::Paranoid 0 - Scalar::Util 0 - Test::Requires 0 - Test::TCP 0 - Time::HiRes 1.9716 - LWPx-ParanoidHandler-0.07 - pathname: T/TO/TOKUHIROM/LWPx-ParanoidHandler-0.07.tar.gz - provides: - LWPx::ParanoidHandler 0.07 - requirements: - CPAN::Meta 0 - CPAN::Meta::Prereqs 0 - Exporter 0 - ExtUtils::CBuilder 0 - LWP 6 - Module::Build 0.38 - Net::DNS::Paranoid 0.07 - parent 0 - perl 5.008008 - Lexical-SealRequireHints-0.011 - pathname: Z/ZE/ZEFRAM/Lexical-SealRequireHints-0.011.tar.gz - provides: - Lexical::SealRequireHints 0.011 - requirements: - Module::Build 0 - Test::More 0.41 - perl 5.006 strict 0 - warnings 0 - Lingua-EN-Inflect-1.903 - pathname: D/DC/DCONWAY/Lingua-EN-Inflect-1.903.tar.gz + Lingua-EN-Inflect-1.905 + pathname: D/DC/DCONWAY/Lingua-EN-Inflect-1.905.tar.gz provides: - Lingua::EN::Inflect 1.903 + Lingua::EN::Inflect 1.905 requirements: ExtUtils::MakeMaker 0 Test::More 0 - List-AllUtils-0.14 - pathname: D/DR/DROLSKY/List-AllUtils-0.14.tar.gz - provides: - List::AllUtils 0.14 - requirements: - Exporter 0 - ExtUtils::MakeMaker 0 - List::SomeUtils 0.50 - List::Util 1.45 - List::UtilsBy 0.10 - base 0 - strict 0 - warnings 0 - List-Compare-0.53 - pathname: J/JK/JKEENAN/List-Compare-0.53.tar.gz + List-Compare-0.55 + pathname: J/JK/JKEENAN/List-Compare-0.55.tar.gz provides: - List::Compare 0.53 - List::Compare::Accelerated 0.53 - List::Compare::Base::_Auxiliary 0.53 - List::Compare::Base::_Engine 0.53 - List::Compare::Functional 0.53 - List::Compare::Multiple 0.53 - List::Compare::Multiple::Accelerated 0.53 + List::Compare 0.55 + List::Compare::Accelerated 0.55 + List::Compare::Base::_Auxiliary 0.55 + List::Compare::Base::_Engine 0.55 + List::Compare::Functional 0.55 + List::Compare::Multiple 0.55 + List::Compare::Multiple::Accelerated 0.55 requirements: ExtUtils::MakeMaker 0 - List-MoreUtils-0.426 - pathname: R/RE/REHSACK/List-MoreUtils-0.426.tar.gz + List-MoreUtils-0.430 + pathname: R/RE/REHSACK/List-MoreUtils-0.430.tar.gz provides: - List::MoreUtils 0.426 - List::MoreUtils::PP 0.426 + List::MoreUtils 0.430 + List::MoreUtils::PP 0.430 requirements: Exporter::Tiny 0.038 ExtUtils::MakeMaker 0 - List::MoreUtils::XS 0.426 - List-MoreUtils-XS-0.426 - pathname: R/RE/REHSACK/List-MoreUtils-XS-0.426.tar.gz + List::MoreUtils::XS 0.430 + List-MoreUtils-XS-0.430 + pathname: R/RE/REHSACK/List-MoreUtils-XS-0.430.tar.gz provides: - List::MoreUtils::XS 0.426 + List::MoreUtils::XS 0.430 requirements: Carp 0 ExtUtils::MakeMaker 0 @@ -3979,116 +3116,110 @@ DISTRIBUTIONS IPC::Cmd 0 XSLoader 0.22 base 0 - List-SomeUtils-0.56 - pathname: D/DR/DROLSKY/List-SomeUtils-0.56.tar.gz + List-SomeUtils-0.59 + pathname: D/DR/DROLSKY/List-SomeUtils-0.59.tar.gz provides: - List::SomeUtils 0.56 - List::SomeUtils::PP 0.56 + List::SomeUtils 0.59 + List::SomeUtils::PP 0.59 requirements: Carp 0 Exporter 0 ExtUtils::MakeMaker 0 List::SomeUtils::XS 0.54 List::Util 0 - Module::Implementation 0 + Module::Implementation 0.04 Text::ParseWords 0 perl 5.006 strict 0 vars 0 warnings 0 - List-SomeUtils-XS-0.55 - pathname: D/DR/DROLSKY/List-SomeUtils-XS-0.55.tar.gz + List-SomeUtils-XS-0.58 + pathname: D/DR/DROLSKY/List-SomeUtils-XS-0.58.tar.gz provides: - List::SomeUtils::XS 0.55 + List::SomeUtils::XS 0.58 requirements: ExtUtils::MakeMaker 0 XSLoader 0 - perl 5.006 strict 0 warnings 0 - List-UtilsBy-0.10 - pathname: P/PE/PEVANS/List-UtilsBy-0.10.tar.gz + Log-Any-1.717 + pathname: P/PR/PREACTION/Log-Any-1.717.tar.gz provides: - List::UtilsBy 0.10 - requirements: - Exporter 5.57 - Module::Build 0.4004 - Log-Any-1.701 - pathname: P/PR/PREACTION/Log-Any-1.701.tar.gz - provides: - Log::Any 1.701 - Log::Any::Adapter 1.701 - Log::Any::Adapter::Base 1.701 - Log::Any::Adapter::File 1.701 - Log::Any::Adapter::Null 1.701 - Log::Any::Adapter::Stderr 1.701 - Log::Any::Adapter::Stdout 1.701 - Log::Any::Adapter::Syslog 1.701 - Log::Any::Adapter::Test 1.701 - Log::Any::Adapter::Util 1.701 - Log::Any::Manager 1.701 - Log::Any::Proxy 1.701 - Log::Any::Proxy::Null 1.701 - Log::Any::Proxy::Test 1.701 - Log::Any::Test 1.701 + Log::Any 1.717 + Log::Any::Adapter 1.717 + Log::Any::Adapter::Base 1.717 + Log::Any::Adapter::Capture 1.717 + Log::Any::Adapter::File 1.717 + Log::Any::Adapter::Multiplex 1.717 + Log::Any::Adapter::Null 1.717 + Log::Any::Adapter::Stderr 1.717 + Log::Any::Adapter::Stdout 1.717 + Log::Any::Adapter::Syslog 1.717 + Log::Any::Adapter::Test 1.717 + Log::Any::Adapter::Util 1.717 + Log::Any::Manager 1.717 + Log::Any::Proxy 1.717 + Log::Any::Proxy::Null 1.717 + Log::Any::Proxy::Test 1.717 + Log::Any::Proxy::WithStackTrace 1.717 + Log::Any::Test 1.717 requirements: - B 0 - Carp 0 - Data::Dumper 0 - Exporter 0 ExtUtils::MakeMaker 0 - Fcntl 0 - File::Basename 0 - FindBin 0 - IO::File 0 - Storable 0 - Sys::Syslog 0 - Test::Builder 0 - constant 0 + Log-Any-Adapter-Log4perl-0.09 + pathname: P/PR/PREACTION/Log-Any-Adapter-Log4perl-0.09.tar.gz + provides: + Log::Any::Adapter::Log4perl 0.09 + requirements: + ExtUtils::MakeMaker 6.17 + Log::Any::Adapter::Base 0 + Log::Any::Adapter::Util 1.03 + Log::Log4perl 1.32 + base 0 + perl 5.006 strict 0 warnings 0 - Log-Contextual-0.007001 - pathname: F/FR/FREW/Log-Contextual-0.007001.tar.gz + Log-Contextual-0.009001 + pathname: H/HA/HAARG/Log-Contextual-0.009001.tar.gz provides: - Log::Contextual 0.007001 - Log::Contextual::Easy::Default 0.007001 - Log::Contextual::Easy::Package 0.007001 - Log::Contextual::Role::Router 0.007001 - Log::Contextual::Role::Router::HasLogger 0.007001 - Log::Contextual::Role::Router::SetLogger 0.007001 - Log::Contextual::Role::Router::WithLogger 0.007001 - Log::Contextual::Router 0.007001 - Log::Contextual::SimpleLogger 0.007001 - Log::Contextual::TeeLogger 0.007001 - Log::Contextual::WarnLogger 0.007001 + Log::Contextual 0.009001 + Log::Contextual::Easy::Default 0.009001 + Log::Contextual::Easy::Package 0.009001 + Log::Contextual::Role::Router 0.009001 + Log::Contextual::Role::Router::HasLogger 0.009001 + Log::Contextual::Role::Router::SetLogger 0.009001 + Log::Contextual::Role::Router::WithLogger 0.009001 + Log::Contextual::Router 0.009001 + Log::Contextual::SimpleLogger 0.009001 + Log::Contextual::TeeLogger 0.009001 + Log::Contextual::WarnLogger 0.009001 requirements: Carp 0 Data::Dumper::Concise 0 - Exporter::Declare 0.111 ExtUtils::MakeMaker 0 - Moo 1.003 + Moo 1.003000 Scalar::Util 0 - Log-Dispatch-2.67 - pathname: D/DR/DROLSKY/Log-Dispatch-2.67.tar.gz - provides: - Log::Dispatch 2.67 - Log::Dispatch::ApacheLog 2.67 - Log::Dispatch::Base 2.67 - Log::Dispatch::Code 2.67 - Log::Dispatch::Email 2.67 - Log::Dispatch::Email::MIMELite 2.67 - Log::Dispatch::Email::MailSend 2.67 - Log::Dispatch::Email::MailSender 2.67 - Log::Dispatch::Email::MailSendmail 2.67 - Log::Dispatch::File 2.67 - Log::Dispatch::File::Locked 2.67 - Log::Dispatch::Handle 2.67 - Log::Dispatch::Null 2.67 - Log::Dispatch::Output 2.67 - Log::Dispatch::Screen 2.67 - Log::Dispatch::Syslog 2.67 - Log::Dispatch::Types 2.67 - Log::Dispatch::Vars 2.67 + perl 5.008001 + Log-Dispatch-2.71 + pathname: D/DR/DROLSKY/Log-Dispatch-2.71.tar.gz + provides: + Log::Dispatch 2.71 + Log::Dispatch::ApacheLog 2.71 + Log::Dispatch::Base 2.71 + Log::Dispatch::Code 2.71 + Log::Dispatch::Email 2.71 + Log::Dispatch::Email::MIMELite 2.71 + Log::Dispatch::Email::MailSend 2.71 + Log::Dispatch::Email::MailSender 2.71 + Log::Dispatch::Email::MailSendmail 2.71 + Log::Dispatch::File 2.71 + Log::Dispatch::File::Locked 2.71 + Log::Dispatch::Handle 2.71 + Log::Dispatch::Null 2.71 + Log::Dispatch::Output 2.71 + Log::Dispatch::Screen 2.71 + Log::Dispatch::Syslog 2.71 + Log::Dispatch::Types 2.71 + Log::Dispatch::Vars 2.71 requirements: Carp 0 Devel::GlobalDestruction 0 @@ -4115,26 +3246,26 @@ DISTRIBUTIONS perl 5.006 strict 0 warnings 0 - Log-Log4perl-1.49 - pathname: M/MS/MSCHILLI/Log-Log4perl-1.49.tar.gz + Log-Log4perl-1.57 + pathname: E/ET/ETJ/Log-Log4perl-1.57.tar.gz provides: L4pResurrectable 0.01 - Log::Log4perl 1.49 + Log::Log4perl 1.57 Log::Log4perl::Appender undef - Log::Log4perl::Appender::Buffer undef + Log::Log4perl::Appender::Buffer 1.53 Log::Log4perl::Appender::DBI undef Log::Log4perl::Appender::File undef - Log::Log4perl::Appender::Limit undef + Log::Log4perl::Appender::Limit 1.53 Log::Log4perl::Appender::RRDs undef Log::Log4perl::Appender::Screen undef Log::Log4perl::Appender::ScreenColoredLevels undef Log::Log4perl::Appender::Socket undef Log::Log4perl::Appender::String undef - Log::Log4perl::Appender::Synchronized undef + Log::Log4perl::Appender::Synchronized 1.53 Log::Log4perl::Appender::TestArrayBuffer undef Log::Log4perl::Appender::TestBuffer undef Log::Log4perl::Appender::TestFileCreeper undef - Log::Log4perl::Catalyst undef + Log::Log4perl::Catalyst 1.53 Log::Log4perl::Config undef Log::Log4perl::Config::BaseConfigurator undef Log::Log4perl::Config::DOMConfigurator 0.03 @@ -4171,64 +3302,67 @@ DISTRIBUTIONS Log::Log4perl::Util::TimeTracker undef requirements: ExtUtils::MakeMaker 0 - File::Path 2.0606 + File::Path 2.07 File::Spec 0.82 - Test::More 0.45 - Log-Message-0.08 - pathname: B/BI/BINGOS/Log-Message-0.08.tar.gz + perl 5.006 + Log-Log4perl-Layout-JSON-0.61 + pathname: M/MS/MSCHOUT/Log-Log4perl-Layout-JSON-0.61.tar.gz provides: - Log::Message 0.08 - Log::Message::Config 0.08 - Log::Message::Handlers 0.08 - Log::Message::Item 0.08 + Log::Log4perl::Layout::JSON 0.61 requirements: + Carp 0 + Class::Tiny 0 ExtUtils::MakeMaker 0 - File::Spec 0 - Locale::Maketext::Simple 0 - Module::Load 0 - Params::Check 0 - Test::More 0 - if 0 - Log-Message-Simple-0.10 - pathname: B/BI/BINGOS/Log-Message-Simple-0.10.tar.gz - provides: - Log::Message::Handlers 0.10 - Log::Message::Simple 0.10 - requirements: - Carp 0 - ExtUtils::MakeMaker 0 - Log::Message 0 - Test::More 0 - if 0 - MCE-1.831 - pathname: M/MA/MARIOROY/MCE-1.831.tar.gz - provides: - MCE 1.831 - MCE::Candy 1.831 - MCE::Core::Input::Generator 1.831 - MCE::Core::Input::Handle 1.831 - MCE::Core::Input::Iterator 1.831 - MCE::Core::Input::Request 1.831 - MCE::Core::Input::Sequence 1.831 - MCE::Core::Manager 1.831 - MCE::Core::Validation 1.831 - MCE::Core::Worker 1.831 - MCE::Flow 1.831 - MCE::Grep 1.831 - MCE::Loop 1.831 - MCE::Map 1.831 - MCE::Mutex 1.831 - MCE::Mutex::Channel 1.831 - MCE::Mutex::Flock 1.831 - MCE::Queue 1.831 - MCE::Relay 1.831 - MCE::Signal 1.831 - MCE::Step 1.831 - MCE::Stream 1.831 - MCE::Subs 1.831 - MCE::Util 1.831 + JSON::MaybeXS 0 + Log::Log4perl 0 + Log::Log4perl::Layout 0 + Log::Log4perl::Layout::PatternLayout 0 + Log::Log4perl::Level 0 + Scalar::Util 0 + parent 0 + perl 5.010 + strict 0 + warnings 0 + MCE-1.901 + pathname: M/MA/MARIOROY/MCE-1.901.tar.gz + provides: + MCE 1.901 + MCE::Candy 1.901 + MCE::Channel 1.901 + MCE::Channel::Mutex 1.901 + MCE::Channel::MutexFast 1.901 + MCE::Channel::Simple 1.901 + MCE::Channel::SimpleFast 1.901 + MCE::Channel::Threads 1.901 + MCE::Channel::ThreadsFast 1.901 + MCE::Child 1.901 + MCE::Core 1.901 + MCE::Core::Input::Generator 1.901 + MCE::Core::Input::Handle 1.901 + MCE::Core::Input::Iterator 1.901 + MCE::Core::Input::Request 1.901 + MCE::Core::Input::Sequence 1.901 + MCE::Core::Manager 1.901 + MCE::Core::Validation 1.901 + MCE::Core::Worker 1.901 + MCE::Flow 1.901 + MCE::Grep 1.901 + MCE::Loop 1.901 + MCE::Map 1.901 + MCE::Mutex 1.901 + MCE::Mutex::Channel 1.901 + MCE::Mutex::Channel2 1.901 + MCE::Mutex::Flock 1.901 + MCE::Queue 1.901 + MCE::Relay 1.901 + MCE::Signal 1.901 + MCE::Step 1.901 + MCE::Stream 1.901 + MCE::Subs 1.901 + MCE::Util 1.901 requirements: Carp 0 + Errno 0 ExtUtils::MakeMaker 0 Fcntl 0 File::Path 0 @@ -4237,116 +3371,122 @@ DISTRIBUTIONS Scalar::Util 0 Socket 0 Storable 2.04 - Symbol 0 Time::HiRes 0 base 0 bytes 0 constant 0 - perl 5.008 + open 0 + perl 5.008001 strict 0 warnings 0 - MIME-Base64-URLSafe-0.01 - pathname: K/KA/KAZUHO/MIME-Base64-URLSafe-0.01.tar.gz + MIME-Base32-1.303 + pathname: R/RE/REHSACK/MIME-Base32-1.303.tar.gz provides: - MIME::Base64::URLSafe 0.01 + MIME::Base32 1.303 requirements: + Exporter 0 ExtUtils::MakeMaker 0 - MIME::Base64 0 - MIME-Charset-1.012.2 - pathname: N/NE/NEZUMI/MIME-Charset-1.012.2.tar.gz + perl 5.008001 + utf8 0 + MIME-Charset-1.013.1 + pathname: N/NE/NEZUMI/MIME-Charset-1.013.1.tar.gz provides: - MIME::Charset v1.12.2 + MIME::Charset v1.13.1 requirements: CPAN 0 Encode 1.98 ExtUtils::MakeMaker 6.42 Test::More 0 perl 5.005 - MIME-Types-2.14 - pathname: M/MA/MARKOV/MIME-Types-2.14.tar.gz + MIME-Types-2.28 + pathname: M/MA/MARKOV/MIME-Types-2.28.tar.gz provides: - MIME::Type 2.14 - MIME::Types 2.14 - MojoX::MIME::Types 2.14 + MIME::Type 2.28 + MIME::Types 2.28 + MojoX::MIME::Types 2.28 requirements: ExtUtils::MakeMaker 0 File::Basename 0 File::Spec 0 List::Util 0 Test::More 0.47 - MRO-Compat-0.13 - pathname: H/HA/HAARG/MRO-Compat-0.13.tar.gz + MRO-Compat-0.15 + pathname: H/HA/HAARG/MRO-Compat-0.15.tar.gz provides: - MRO::Compat 0.13 + MRO::Compat 0.15 requirements: ExtUtils::MakeMaker 0 perl 5.006 - MailTools-2.19 - pathname: M/MA/MARKOV/MailTools-2.19.tar.gz - provides: - Mail::Address 2.19 - Mail::Cap 2.19 - Mail::Field 2.19 - Mail::Field::AddrList 2.19 - Mail::Field::Date 2.19 - Mail::Field::Generic 2.19 - Mail::Filter 2.19 - Mail::Header 2.19 - Mail::Internet 2.19 - Mail::Mailer 2.19 - Mail::Mailer::qmail 2.19 - Mail::Mailer::rfc822 2.19 - Mail::Mailer::sendmail 2.19 - Mail::Mailer::smtp 2.19 - Mail::Mailer::smtp::pipe 2.19 - Mail::Mailer::smtps 2.19 - Mail::Mailer::smtps::pipe 2.19 - Mail::Mailer::testfile 2.19 - Mail::Mailer::testfile::pipe 2.19 - Mail::Send 2.19 - Mail::Util 2.19 - MailTools 2.19 + MailTools-2.22 + pathname: M/MA/MARKOV/MailTools-2.22.tar.gz + provides: + Mail::Address 2.22 + Mail::Cap 2.22 + Mail::Field 2.22 + Mail::Field::AddrList 2.22 + Mail::Field::Date 2.22 + Mail::Field::Generic 2.22 + Mail::Filter 2.22 + Mail::Header 2.22 + Mail::Internet 2.22 + Mail::Mailer 2.22 + Mail::Mailer::qmail 2.22 + Mail::Mailer::rfc822 2.22 + Mail::Mailer::sendmail 2.22 + Mail::Mailer::smtp 2.22 + Mail::Mailer::smtp::pipe 2.22 + Mail::Mailer::smtps 2.22 + Mail::Mailer::smtps::pipe 2.22 + Mail::Mailer::testfile 2.22 + Mail::Mailer::testfile::pipe 2.22 + Mail::Send 2.22 + Mail::Util 2.22 + MailTools 2.22 requirements: Date::Format 0 Date::Parse 0 ExtUtils::MakeMaker 0 IO::Handle 0 Net::Domain 1.05 - Net::SMTP 1.03 + Net::SMTP 1.28 Test::More 0 - Meta-Builder-0.003 - pathname: E/EX/EXODIST/Meta-Builder-0.003.tar.gz + Math-BigInt-2.005003 + pathname: P/PJ/PJACKLAM/Math-BigInt-2.005003.tar.gz provides: - Meta::Builder 0.003 - Meta::Builder::Base undef - Meta::Builder::Util undef + Math::BigFloat 2.005003 + Math::BigInt 2.005003 + Math::BigInt::Calc 2.005003 + Math::BigInt::Lib 2.005003 + Math::BigRat 2.005003 requirements: - Carp 0 - Fennec::Lite 0 - Test::Exception 0 - Test::More 0 - MetaCPAN-Client-2.019000 - pathname: M/MI/MICKEY/MetaCPAN-Client-2.019000.tar.gz - provides: - MetaCPAN::Client 2.019000 - MetaCPAN::Client::Author 2.019000 - MetaCPAN::Client::Distribution 2.019000 - MetaCPAN::Client::DownloadURL 2.019000 - MetaCPAN::Client::Favorite 2.019000 - MetaCPAN::Client::File 2.019000 - MetaCPAN::Client::Mirror 2.019000 - MetaCPAN::Client::Module 2.019000 - MetaCPAN::Client::Package 2.019000 - MetaCPAN::Client::Permission 2.019000 - MetaCPAN::Client::Pod 2.019000 - MetaCPAN::Client::Rating 2.019000 - MetaCPAN::Client::Release 2.019000 - MetaCPAN::Client::Request 2.019000 - MetaCPAN::Client::ResultSet 2.019000 - MetaCPAN::Client::Role::Entity 2.019000 - MetaCPAN::Client::Role::HasUA 2.019000 - MetaCPAN::Client::Scroll 2.019000 - MetaCPAN::Client::Types 2.019000 + Carp 1.22 + ExtUtils::MakeMaker 6.58 + Math::Complex 1.36 + Scalar::Util 0 + perl 5.006001 + MetaCPAN-Client-2.033000 + pathname: M/MI/MICKEY/MetaCPAN-Client-2.033000.tar.gz + provides: + MetaCPAN::Client 2.033000 + MetaCPAN::Client::Author 2.033000 + MetaCPAN::Client::Cover 2.033000 + MetaCPAN::Client::Distribution 2.033000 + MetaCPAN::Client::DownloadURL 2.033000 + MetaCPAN::Client::Favorite 2.033000 + MetaCPAN::Client::File 2.033000 + MetaCPAN::Client::Mirror 2.033000 + MetaCPAN::Client::Module 2.033000 + MetaCPAN::Client::Package 2.033000 + MetaCPAN::Client::Permission 2.033000 + MetaCPAN::Client::Pod 2.033000 + MetaCPAN::Client::Rating 2.033000 + MetaCPAN::Client::Release 2.033000 + MetaCPAN::Client::Request 2.033000 + MetaCPAN::Client::ResultSet 2.033000 + MetaCPAN::Client::Role::Entity 2.033000 + MetaCPAN::Client::Role::HasUA 2.033000 + MetaCPAN::Client::Scroll 2.033000 + MetaCPAN::Client::Types 2.033000 requirements: Carp 0 ExtUtils::MakeMaker 7.1101 @@ -4377,108 +3517,116 @@ DISTRIBUTIONS perl 5.006 strict 0 warnings 0 - MetaCPAN-Pod-XHTML-0.001001 - pathname: H/HA/HAARG/MetaCPAN-Pod-XHTML-0.001001.tar.gz + MetaCPAN-Pod-HTML-0.004000 + pathname: H/HA/HAARG/MetaCPAN-Pod-HTML-0.004000.tar.gz provides: - MetaCPAN::Pod::XHTML 0.001001 + MetaCPAN::Pod::HTML 0.004000 + MetaCPAN::Pod::XHTML 0.004000 + Pod::Simple::Role::StripVerbatimIndent 0.004000 + Pod::Simple::Role::WithHighlightConfig 0.004000 + Pod::Simple::Role::XHTML::HTML5 0.004000 + Pod::Simple::Role::XHTML::RepairLinkEncoding 0.004000 + Pod::Simple::Role::XHTML::WithAccurateTargets 0.004000 + Pod::Simple::Role::XHTML::WithErrata 0.004000 + Pod::Simple::Role::XHTML::WithExtraTargets 0.004000 + Pod::Simple::Role::XHTML::WithHighlightConfig 0.004000 + Pod::Simple::Role::XHTML::WithLinkMappings 0.004000 + Pod::Simple::Role::XHTML::WithPostProcess 0.004000 requirements: ExtUtils::MakeMaker 0 - Pod::Simple::XHTML 0 - MetaCPAN-Role-0.06 - pathname: L/LL/LLAP/MetaCPAN-Role-0.06.tar.gz + HTML::Entities 3.69 + Moo 2.003000 + Moo::Role 2.003000 + Pod::Simple::XHTML 3.45 + URL::Encode 0.03 + namespace::clean 0.27 + MetaCPAN-Role-1.00 + pathname: L/LL/LLAP/MetaCPAN-Role-1.00.tar.gz provides: - MetaCPAN::Role 0.06 - MetaCPAN::Role::Fastly 0.06 - MetaCPAN::Role::Fastly::Catalyst 0.06 + MetaCPAN::Role 1.00 + MetaCPAN::Role::Fastly 1.00 + MetaCPAN::Role::Fastly::Catalyst 1.00 requirements: Carp 0 - CatalystX::Fastly::Role::Response 0.04 + CatalystX::Fastly::Role::Response 0.07 ExtUtils::MakeMaker 0 Moose::Role 0 - MooseX::Fastly::Role 0.01 + MooseX::Fastly::Role 0.04 Net::Fastly 1.05 - Minion-9.03 - pathname: S/SR/SRI/Minion-9.03.tar.gz + Minion-10.31 + pathname: S/SR/SRI/Minion-10.31.tar.gz provides: LinkCheck undef LinkCheck::Controller::Links undef LinkCheck::Task::CheckLinks undef - Minion 9.03 + Minion 10.31 Minion::Backend undef Minion::Backend::Pg undef Minion::Command::minion undef Minion::Command::minion::job undef Minion::Command::minion::worker undef + Minion::Iterator undef Minion::Job undef Minion::Worker undef - Minion::_Guard 9.03 Mojolicious::Plugin::Minion undef Mojolicious::Plugin::Minion::Admin undef requirements: ExtUtils::MakeMaker 0 - Mojolicious 7.56 - perl 5.010001 - Minion-Backend-SQLite-2.004 - pathname: D/DB/DBOOK/Minion-Backend-SQLite-2.004.tar.gz + Mojolicious 9.0 + YAML::XS 0.67 + perl 5.016 + Minion-Backend-SQLite-v5.0.7 + pathname: D/DB/DBOOK/Minion-Backend-SQLite-v5.0.7.tar.gz provides: - Minion::Backend::SQLite 2.004 + Minion::Backend::SQLite v5.0.7 requirements: List::Util 0 - Minion 7.05 + Minion 10.13 Module::Build::Tiny 0.034 Mojo::SQLite 3.000 - Mojolicious 7.29 + Mojolicious 7.49 Sys::Hostname 0 Time::HiRes 0 perl 5.010001 - Mixin-Linewise-0.108 - pathname: R/RJ/RJBS/Mixin-Linewise-0.108.tar.gz + Mixin-Linewise-0.111 + pathname: R/RJ/RJBS/Mixin-Linewise-0.111.tar.gz provides: - Mixin::Linewise 0.108 - Mixin::Linewise::Readers 0.108 - Mixin::Linewise::Writers 0.108 + Mixin::Linewise 0.111 + Mixin::Linewise::Readers 0.111 + Mixin::Linewise::Writers 0.111 requirements: Carp 0 - ExtUtils::MakeMaker 0 + ExtUtils::MakeMaker 6.78 IO::File 0 PerlIO::utf8_strict 0 Sub::Exporter 0 - perl 5.008001 - strict 0 - warnings 0 - Mock-Config-0.03 - pathname: R/RU/RURBAN/Mock-Config-0.03.tar.gz - provides: - Mock::Config 0.03 - requirements: - ExtUtils::MakeMaker 0 - Test::More 0 - perl 5.006 - Module-Build-0.4224 - pathname: L/LE/LEONT/Module-Build-0.4224.tar.gz - provides: - Module::Build 0.4224 - Module::Build::Base 0.4224 - Module::Build::Compat 0.4224 - Module::Build::Config 0.4224 - Module::Build::Cookbook 0.4224 - Module::Build::Dumper 0.4224 - Module::Build::Notes 0.4224 - Module::Build::PPMMaker 0.4224 - Module::Build::Platform::Default 0.4224 - Module::Build::Platform::MacOS 0.4224 - Module::Build::Platform::Unix 0.4224 - Module::Build::Platform::VMS 0.4224 - Module::Build::Platform::VOS 0.4224 - Module::Build::Platform::Windows 0.4224 - Module::Build::Platform::aix 0.4224 - Module::Build::Platform::cygwin 0.4224 - Module::Build::Platform::darwin 0.4224 - Module::Build::Platform::os2 0.4224 - Module::Build::PodParser 0.4224 + perl 5.012 + strict 0 + warnings 0 + Module-Build-0.4234 + pathname: L/LE/LEONT/Module-Build-0.4234.tar.gz + provides: + Module::Build 0.4234 + Module::Build::Base 0.4234 + Module::Build::Compat 0.4234 + Module::Build::Config 0.4234 + Module::Build::Cookbook 0.4234 + Module::Build::Dumper 0.4234 + Module::Build::Notes 0.4234 + Module::Build::PPMMaker 0.4234 + Module::Build::Platform::Default 0.4234 + Module::Build::Platform::MacOS 0.4234 + Module::Build::Platform::Unix 0.4234 + Module::Build::Platform::VMS 0.4234 + Module::Build::Platform::VOS 0.4234 + Module::Build::Platform::Windows 0.4234 + Module::Build::Platform::aix 0.4234 + Module::Build::Platform::cygwin 0.4234 + Module::Build::Platform::darwin 0.4234 + Module::Build::Platform::os2 0.4234 + Module::Build::PodParser 0.4234 requirements: CPAN::Meta 2.142060 - CPAN::Meta::YAML 0.003 Cwd 0 Data::Dumper 0 ExtUtils::CBuilder 0.27 @@ -4492,22 +3640,18 @@ DISTRIBUTIONS File::Find 0 File::Path 0 File::Spec 0.82 - File::Temp 0.15 Getopt::Long 0 Module::Metadata 1.000002 - Parse::CPAN::Meta 1.4401 Perl::OSType 1 - Pod::Man 2.17 TAP::Harness 3.29 - Test::More 0.49 Text::Abbrev 0 Text::ParseWords 0 perl 5.006001 version 0.87 - Module-Build-Tiny-0.039 - pathname: L/LE/LEONT/Module-Build-Tiny-0.039.tar.gz + Module-Build-Tiny-0.051 + pathname: L/LE/LEONT/Module-Build-Tiny-0.051.tar.gz provides: - Module::Build::Tiny 0.039 + Module::Build::Tiny 0.051 requirements: CPAN::Meta 0 DynaLoader 0 @@ -4529,25 +3673,10 @@ DISTRIBUTIONS perl 5.006 strict 0 warnings 0 - Module-Build-XSUtil-0.18 - pathname: H/HI/HIDEAKIO/Module-Build-XSUtil-0.18.tar.gz + Module-CPANfile-1.1004 + pathname: M/MI/MIYAGAWA/Module-CPANfile-1.1004.tar.gz provides: - Module::Build::XSUtil 0.18 - requirements: - Devel::CheckCompiler 0 - Devel::PPPort 0 - Exporter 0 - ExtUtils::CBuilder 0 - File::Basename 0 - File::Path 0 - Module::Build 0.4005 - XSLoader 0 - parent 0 - perl 5.008005 - Module-CPANfile-1.1002 - pathname: M/MI/MIYAGAWA/Module-CPANfile-1.1002.tar.gz - provides: - Module::CPANfile 1.1002 + Module::CPANfile 1.1004 Module::CPANfile::Environment undef Module::CPANfile::Prereq undef Module::CPANfile::Prereqs undef @@ -4556,17 +3685,7 @@ DISTRIBUTIONS CPAN::Meta 2.12091 CPAN::Meta::Prereqs 2.12091 ExtUtils::MakeMaker 0 - JSON::PP 2.27300 parent 0 - Module-Extract-Namespaces-1.02 - pathname: B/BD/BDFOY/Module-Extract-Namespaces-1.02.tar.gz - provides: - Module::Extract::Namespaces 1.02 - PPI::Lexer 1.02 - requirements: - ExtUtils::MakeMaker 0 - PPI 0 - Test::More 0 Module-Faker-0.017 pathname: R/RJ/RJBS/Module-Faker-0.017.tar.gz provides: @@ -4596,19 +3715,16 @@ DISTRIBUTIONS Text::Template 0 strict 0 warnings 0 - Module-Find-0.13 - pathname: C/CR/CRENZ/Module-Find-0.13.tar.gz + Module-Find-0.17 + pathname: C/CR/CRENZ/Module-Find-0.17.tar.gz provides: - Module::Find 0.13 - ModuleFindTest undef - ModuleFindTest::SubMod undef - ModuleFindTest::SubMod::SubSubMod undef + Module::Find 0.17 requirements: ExtUtils::MakeMaker 0 File::Find 0 File::Spec 0 Test::More 0 - perl 5.006001 + perl 5.008001 Module-Implementation-0.09 pathname: D/DR/DROLSKY/Module-Implementation-0.09.tar.gz provides: @@ -4620,10 +3736,10 @@ DISTRIBUTIONS Try::Tiny 0 strict 0 warnings 0 - Module-Load-Conditional-0.68 - pathname: B/BI/BINGOS/Module-Load-Conditional-0.68.tar.gz + Module-Load-Conditional-0.74 + pathname: B/BI/BINGOS/Module-Load-Conditional-0.74.tar.gz provides: - Module::Load::Conditional 0.68 + Module::Load::Conditional 0.74 requirements: ExtUtils::MakeMaker 0 Locale::Maketext::Simple 0 @@ -4633,11 +3749,26 @@ DISTRIBUTIONS Params::Check 0 Test::More 0 version 0.69 - Module-Pluggable-5.2 - pathname: S/SI/SIMONW/Module-Pluggable-5.2.tar.gz + Module-Metadata-1.000038 + pathname: E/ET/ETHER/Module-Metadata-1.000038.tar.gz + provides: + Module::Metadata 1.000038 + requirements: + Carp 0 + Encode 0 + ExtUtils::MakeMaker 0 + Fcntl 0 + File::Find 0 + File::Spec 0 + perl 5.006 + strict 0 + version 0.87 + warnings 0 + Module-Pluggable-6.3 + pathname: S/SI/SIMONW/Module-Pluggable-6.3.tar.gz provides: Devel::InnerPackage 0.4 - Module::Pluggable 5.2 + Module::Pluggable 6.3 Module::Pluggable::Object 5.2 requirements: Exporter 5.57 @@ -4646,19 +3777,17 @@ DISTRIBUTIONS File::Find 0 File::Spec 3.00 File::Spec::Functions 0 + Scalar::Util 0 if 0 - perl 5.00503 + perl 5.006 strict 0 - Module-Runtime-0.016 - pathname: Z/ZE/ZEFRAM/Module-Runtime-0.016.tar.gz + Module-Runtime-0.018 + pathname: H/HA/HAARG/Module-Runtime-0.018.tar.gz provides: - Module::Runtime 0.016 + Module::Runtime 0.018 requirements: - Module::Build 0 - Test::More 0.41 - perl 5.006 - strict 0 - warnings 0 + ExtUtils::MakeMaker 0 + perl 5.006000 Module-Runtime-Conflicts-0.003 pathname: E/ET/ETHER/Module-Runtime-Conflicts-0.003.tar.gz provides: @@ -4670,53 +3799,53 @@ DISTRIBUTIONS perl 5.006 strict 0 warnings 0 - Mojo-Pg-4.08 - pathname: S/SR/SRI/Mojo-Pg-4.08.tar.gz + Mojo-Pg-4.27 + pathname: S/SR/SRI/Mojo-Pg-4.27.tar.gz provides: - Mojo::Pg 4.08 + Mojo::Pg 4.27 Mojo::Pg::Database undef Mojo::Pg::Migrations undef Mojo::Pg::PubSub undef Mojo::Pg::Results undef Mojo::Pg::Transaction undef - SQL::Abstract::Pg undef requirements: - DBD::Pg 3.005001 + DBD::Pg 3.007004 ExtUtils::MakeMaker 0 - Mojolicious 7.53 - SQL::Abstract 1.85 - perl 5.010001 - Mojo-SQLite-3.000 - pathname: D/DB/DBOOK/Mojo-SQLite-3.000.tar.gz + Mojolicious 8.50 + SQL::Abstract::Pg 1.0 + perl 5.016 + Mojo-SQLite-3.009 + pathname: D/DB/DBOOK/Mojo-SQLite-3.009.tar.gz provides: - Mojo::SQLite 3.000 - Mojo::SQLite::Database 3.000 - Mojo::SQLite::Migrations 3.000 - Mojo::SQLite::PubSub 3.000 - Mojo::SQLite::Results 3.000 - Mojo::SQLite::Transaction 3.000 + Mojo::SQLite 3.009 + Mojo::SQLite::Database 3.009 + Mojo::SQLite::Migrations 3.009 + Mojo::SQLite::PubSub 3.009 + Mojo::SQLite::Results 3.009 + Mojo::SQLite::Transaction 3.009 requirements: Carp 0 - DBD::SQLite 1.50 + DBD::SQLite 1.68 DBI 1.627 File::Spec::Functions 0 File::Temp 0 Module::Build::Tiny 0.034 - Mojolicious 7.32 - SQL::Abstract 1.81 + Mojolicious 8.03 + SQL::Abstract::Pg 1.0 Scalar::Util 0 URI 1.69 URI::db 0.15 URI::file 4.21 perl 5.010001 - Mojolicious-7.56 - pathname: S/SR/SRI/Mojolicious-7.56.tar.gz + Mojolicious-9.39 + pathname: S/SR/SRI/Mojolicious-9.39.tar.gz provides: Mojo undef Mojo::Asset undef Mojo::Asset::File undef Mojo::Asset::Memory undef Mojo::Base undef + Mojo::BaseUtil undef Mojo::ByteStream undef Mojo::Cache undef Mojo::Collection undef @@ -4730,6 +3859,7 @@ DISTRIBUTIONS Mojo::DOM::CSS undef Mojo::DOM::HTML undef Mojo::Date undef + Mojo::DynamicMethods undef Mojo::EventEmitter undef Mojo::Exception undef Mojo::File undef @@ -4738,7 +3868,6 @@ DISTRIBUTIONS Mojo::Home undef Mojo::IOLoop undef Mojo::IOLoop::Client undef - Mojo::IOLoop::Delay undef Mojo::IOLoop::Server undef Mojo::IOLoop::Stream undef Mojo::IOLoop::Subprocess undef @@ -4764,7 +3893,6 @@ DISTRIBUTIONS Mojo::Server::Morbo::Backend undef Mojo::Server::Morbo::Backend::Poll undef Mojo::Server::PSGI undef - Mojo::Server::PSGI::_IO undef Mojo::Server::Prefork undef Mojo::Template undef Mojo::Transaction undef @@ -4779,37 +3907,36 @@ DISTRIBUTIONS Mojo::UserAgent::Transactor undef Mojo::Util undef Mojo::WebSocket undef - Mojolicious 7.56 + Mojolicious 9.39 Mojolicious::Command undef + Mojolicious::Command::Author::cpanify undef + Mojolicious::Command::Author::generate undef + Mojolicious::Command::Author::generate::app undef + Mojolicious::Command::Author::generate::dockerfile undef + Mojolicious::Command::Author::generate::lite_app undef + Mojolicious::Command::Author::generate::makefile undef + Mojolicious::Command::Author::generate::plugin undef + Mojolicious::Command::Author::inflate undef Mojolicious::Command::cgi undef - Mojolicious::Command::cpanify undef Mojolicious::Command::daemon undef Mojolicious::Command::eval undef - Mojolicious::Command::generate undef - Mojolicious::Command::generate::app undef - Mojolicious::Command::generate::lite_app undef - Mojolicious::Command::generate::makefile undef - Mojolicious::Command::generate::plugin undef Mojolicious::Command::get undef - Mojolicious::Command::inflate undef Mojolicious::Command::prefork undef Mojolicious::Command::psgi undef Mojolicious::Command::routes undef - Mojolicious::Command::test undef Mojolicious::Command::version undef Mojolicious::Commands undef Mojolicious::Controller undef Mojolicious::Lite undef Mojolicious::Plugin undef Mojolicious::Plugin::Config undef - Mojolicious::Plugin::Config::Sandbox undef Mojolicious::Plugin::DefaultHelpers undef Mojolicious::Plugin::EPLRenderer undef Mojolicious::Plugin::EPRenderer undef Mojolicious::Plugin::HeaderCondition undef Mojolicious::Plugin::JSONConfig undef Mojolicious::Plugin::Mount undef - Mojolicious::Plugin::PODRenderer undef + Mojolicious::Plugin::NotYAMLConfig undef Mojolicious::Plugin::TagHelpers undef Mojolicious::Plugins undef Mojolicious::Renderer undef @@ -4827,40 +3954,86 @@ DISTRIBUTIONS requirements: ExtUtils::MakeMaker 0 IO::Socket::IP 0.37 - JSON::PP 2.27103 - Pod::Simple 3.09 - Time::Local 1.2 + Sub::Util 1.41 + perl 5.016 + Mojolicious-Plugin-MountPSGI-0.15 + pathname: J/JB/JBERGER/Mojolicious-Plugin-MountPSGI-0.15.tar.gz + provides: + Mojolicious::Plugin::MountPSGI 0.15 + Mojolicious::Plugin::MountPSGI::Proxy undef + requirements: + ExtUtils::MakeMaker 0 + Mojolicious 7.70 + Plack 0 + Mojolicious-Plugin-OpenAPI-5.11 + pathname: J/JH/JHTHORSEN/Mojolicious-Plugin-OpenAPI-5.11.tar.gz + provides: + Mojolicious::Plugin::OpenAPI 5.11 + Mojolicious::Plugin::OpenAPI::Cors undef + Mojolicious::Plugin::OpenAPI::Parameters undef + Mojolicious::Plugin::OpenAPI::Security undef + Mojolicious::Plugin::OpenAPI::SpecRenderer undef + requirements: + ExtUtils::MakeMaker 0 + JSON::Validator 5.13 + Mojolicious 9.00 + perl 5.016 + Mojolicious-Plugin-Web-Auth-0.17 + pathname: H/HA/HAYAJO/Mojolicious-Plugin-Web-Auth-0.17.tar.gz + provides: + Mojolicious::Plugin::Web::Auth 0.17 + Mojolicious::Plugin::Web::Auth::Base undef + Mojolicious::Plugin::Web::Auth::OAuth undef + Mojolicious::Plugin::Web::Auth::OAuth2 undef + Mojolicious::Plugin::Web::Auth::Site::Dropbox undef + Mojolicious::Plugin::Web::Auth::Site::Facebook undef + Mojolicious::Plugin::Web::Auth::Site::Github undef + Mojolicious::Plugin::Web::Auth::Site::Google undef + Mojolicious::Plugin::Web::Auth::Site::Instagram undef + Mojolicious::Plugin::Web::Auth::Site::Twitter undef + Mojolicious::Plugin::Web::Auth::Site::Yandex undef + requirements: + IO::Socket::SSL 1.77 + Module::Build::Tiny 0.035 + Mojolicious 7.13 + Net::OAuth 0.28 perl 5.010001 - Moo-2.003003 - pathname: H/HA/HAARG/Moo-2.003003.tar.gz + Moo-2.005005 + pathname: H/HA/HAARG/Moo-2.005005.tar.gz provides: Method::Generate::Accessor undef Method::Generate::BuildAll undef Method::Generate::Constructor undef Method::Generate::DemolishAll undef - Moo 2.003003 + Moo 2.005005 Moo::HandleMoose undef Moo::HandleMoose::FakeConstructor undef Moo::HandleMoose::FakeMetaClass undef Moo::HandleMoose::_TypeMap undef Moo::Object undef - Moo::Role 2.003003 + Moo::Role 2.005005 Moo::_Utils undef - Moo::_mro undef - Moo::_strictures undef Moo::sification undef oo undef requirements: - Class::Method::Modifiers 1.1 - Devel::GlobalDestruction 0.11 - Exporter 5.57 + Carp 0 + Class::Method::Modifiers 1.10 + Exporter 0 ExtUtils::MakeMaker 0 - Module::Runtime 0.014 - Role::Tiny 2.000004 - Scalar::Util 0 - Sub::Defer 2.003001 - Sub::Quote 2.003001 + Role::Tiny 2.002003 + Scalar::Util 1.00 + Sub::Defer 2.006006 + Sub::Quote 2.006006 + perl 5.006 + MooX-Aliases-0.001006 + pathname: H/HA/HAARG/MooX-Aliases-0.001006.tar.gz + provides: + MooX::Aliases 0.001006 + requirements: + Class::Method::Modifiers 1.05 + Moo 1.001 perl 5.006 + strictures 1 MooX-Locale-Passthrough-0.001 pathname: R/RE/REHSACK/MooX-Locale-Passthrough-0.001.tar.gz provides: @@ -4889,25 +4062,31 @@ DISTRIBUTIONS Text::LineFold 0 perl 5.008001 strictures 2 - MooX-StrictConstructor-0.008 - pathname: H/HA/HARTZELL/MooX-StrictConstructor-0.008.tar.gz + MooX-StrictConstructor-0.013 + pathname: H/HA/HAARG/MooX-StrictConstructor-0.013.tar.gz provides: - Method::Generate::Constructor::Role::StrictConstructor 0.008 - MooX::StrictConstructor 0.008 + MooX::StrictConstructor 0.013 + MooX::StrictConstructor::Role::BuildAll 0.013 + MooX::StrictConstructor::Role::Constructor 0.013 + MooX::StrictConstructor::Role::Constructor::Base 0.013 + MooX::StrictConstructor::Role::Constructor::Late 0.013 requirements: - B 0 - Class::Method::Modifiers 0 ExtUtils::MakeMaker 0 - Module::Build 0.28 - Moo 1.001000 + Moo 2.004000 Moo::Role 0 - bareword::filehandles 0 - constant 0 - indirect 0 - multidimensional 0 - perl 5.006 - strict 0 - strictures 1 + perl 5.008 + MooX-Traits-0.005 + pathname: T/TO/TOBYINK/MooX-Traits-0.005.tar.gz + provides: + MooX::Traits 0.005 + MooX::Traits::Util 0.005 + requirements: + Exporter::Shiny 0 + ExtUtils::MakeMaker 6.17 + Module::Runtime 0 + Role::Tiny 1.000000 + Scalar::Util 0 + perl 5.006000 MooX-Types-MooseLike-0.29 pathname: M/MA/MATEU/MooX-Types-MooseLike-0.29.tar.gz provides: @@ -4926,368 +4105,458 @@ DISTRIBUTIONS MooX::Types::MooseLike 0.23 Test::Fatal 0.003 Test::More 0.96 - Moose-2.2007 - pathname: E/ET/ETHER/Moose-2.2007.tar.gz - provides: - Class::MOP 2.2007 - Class::MOP::Attribute 2.2007 - Class::MOP::Class 2.2007 - Class::MOP::Instance 2.2007 - Class::MOP::Method 2.2007 - Class::MOP::Method::Accessor 2.2007 - Class::MOP::Method::Constructor 2.2007 - Class::MOP::Method::Generated 2.2007 - Class::MOP::Method::Inlined 2.2007 - Class::MOP::Method::Meta 2.2007 - Class::MOP::Method::Wrapped 2.2007 - Class::MOP::Module 2.2007 - Class::MOP::Object 2.2007 - Class::MOP::Overload 2.2007 - Class::MOP::Package 2.2007 - Moose 2.2007 - Moose::Cookbook 2.2007 - Moose::Cookbook::Basics::BankAccount_MethodModifiersAndSubclassing 2.2007 - Moose::Cookbook::Basics::BinaryTree_AttributeFeatures 2.2007 - Moose::Cookbook::Basics::BinaryTree_BuilderAndLazyBuild 2.2007 - Moose::Cookbook::Basics::Company_Subtypes 2.2007 - Moose::Cookbook::Basics::DateTime_ExtendingNonMooseParent 2.2007 - Moose::Cookbook::Basics::Document_AugmentAndInner 2.2007 - Moose::Cookbook::Basics::Genome_OverloadingSubtypesAndCoercion 2.2007 - Moose::Cookbook::Basics::HTTP_SubtypesAndCoercion 2.2007 - Moose::Cookbook::Basics::Immutable 2.2007 - Moose::Cookbook::Basics::Person_BUILDARGSAndBUILD 2.2007 - Moose::Cookbook::Basics::Point_AttributesAndSubclassing 2.2007 - Moose::Cookbook::Extending::Debugging_BaseClassRole 2.2007 - Moose::Cookbook::Extending::ExtensionOverview 2.2007 - Moose::Cookbook::Extending::Mooseish_MooseSugar 2.2007 - Moose::Cookbook::Legacy::Debugging_BaseClassReplacement 2.2007 - Moose::Cookbook::Legacy::Labeled_AttributeMetaclass 2.2007 - Moose::Cookbook::Legacy::Table_ClassMetaclass 2.2007 - Moose::Cookbook::Meta::GlobRef_InstanceMetaclass 2.2007 - Moose::Cookbook::Meta::Labeled_AttributeTrait 2.2007 - Moose::Cookbook::Meta::PrivateOrPublic_MethodMetaclass 2.2007 - Moose::Cookbook::Meta::Table_MetaclassTrait 2.2007 - Moose::Cookbook::Meta::WhyMeta 2.2007 - Moose::Cookbook::Roles::ApplicationToInstance 2.2007 - Moose::Cookbook::Roles::Comparable_CodeReuse 2.2007 - Moose::Cookbook::Roles::Restartable_AdvancedComposition 2.2007 - Moose::Cookbook::Snack::Keywords 2.2007 - Moose::Cookbook::Snack::Types 2.2007 - Moose::Cookbook::Style 2.2007 - Moose::Exception 2.2007 - Moose::Exception::AccessorMustReadWrite 2.2007 - Moose::Exception::AddParameterizableTypeTakesParameterizableType 2.2007 - Moose::Exception::AddRoleTakesAMooseMetaRoleInstance 2.2007 - Moose::Exception::AddRoleToARoleTakesAMooseMetaRole 2.2007 - Moose::Exception::ApplyTakesABlessedInstance 2.2007 - Moose::Exception::AttachToClassNeedsAClassMOPClassInstanceOrASubclass 2.2007 - Moose::Exception::AttributeConflictInRoles 2.2007 - Moose::Exception::AttributeConflictInSummation 2.2007 - Moose::Exception::AttributeExtensionIsNotSupportedInRoles 2.2007 - Moose::Exception::AttributeIsRequired 2.2007 - Moose::Exception::AttributeMustBeAnClassMOPMixinAttributeCoreOrSubclass 2.2007 - Moose::Exception::AttributeNamesDoNotMatch 2.2007 - Moose::Exception::AttributeValueIsNotAnObject 2.2007 - Moose::Exception::AttributeValueIsNotDefined 2.2007 - Moose::Exception::AutoDeRefNeedsArrayRefOrHashRef 2.2007 - Moose::Exception::BadOptionFormat 2.2007 - Moose::Exception::BothBuilderAndDefaultAreNotAllowed 2.2007 - Moose::Exception::BuilderDoesNotExist 2.2007 - Moose::Exception::BuilderMethodNotSupportedForAttribute 2.2007 - Moose::Exception::BuilderMethodNotSupportedForInlineAttribute 2.2007 - Moose::Exception::BuilderMustBeAMethodName 2.2007 - Moose::Exception::CallingMethodOnAnImmutableInstance 2.2007 - Moose::Exception::CallingReadOnlyMethodOnAnImmutableInstance 2.2007 - Moose::Exception::CanExtendOnlyClasses 2.2007 - Moose::Exception::CanOnlyConsumeRole 2.2007 - Moose::Exception::CanOnlyWrapBlessedCode 2.2007 - Moose::Exception::CanReblessOnlyIntoASubclass 2.2007 - Moose::Exception::CanReblessOnlyIntoASuperclass 2.2007 - Moose::Exception::CannotAddAdditionalTypeCoercionsToUnion 2.2007 - Moose::Exception::CannotAddAsAnAttributeToARole 2.2007 - Moose::Exception::CannotApplyBaseClassRolesToRole 2.2007 - Moose::Exception::CannotAssignValueToReadOnlyAccessor 2.2007 - Moose::Exception::CannotAugmentIfLocalMethodPresent 2.2007 - Moose::Exception::CannotAugmentNoSuperMethod 2.2007 - Moose::Exception::CannotAutoDerefWithoutIsa 2.2007 - Moose::Exception::CannotAutoDereferenceTypeConstraint 2.2007 - Moose::Exception::CannotCalculateNativeType 2.2007 - Moose::Exception::CannotCallAnAbstractBaseMethod 2.2007 - Moose::Exception::CannotCallAnAbstractMethod 2.2007 - Moose::Exception::CannotCoerceAWeakRef 2.2007 - Moose::Exception::CannotCoerceAttributeWhichHasNoCoercion 2.2007 - Moose::Exception::CannotCreateHigherOrderTypeWithoutATypeParameter 2.2007 - Moose::Exception::CannotCreateMethodAliasLocalMethodIsPresent 2.2007 - Moose::Exception::CannotCreateMethodAliasLocalMethodIsPresentInClass 2.2007 - Moose::Exception::CannotDelegateLocalMethodIsPresent 2.2007 - Moose::Exception::CannotDelegateWithoutIsa 2.2007 - Moose::Exception::CannotFindDelegateMetaclass 2.2007 - Moose::Exception::CannotFindType 2.2007 - Moose::Exception::CannotFindTypeGivenToMatchOnType 2.2007 - Moose::Exception::CannotFixMetaclassCompatibility 2.2007 - Moose::Exception::CannotGenerateInlineConstraint 2.2007 - Moose::Exception::CannotInitializeMooseMetaRoleComposite 2.2007 - Moose::Exception::CannotInlineTypeConstraintCheck 2.2007 - Moose::Exception::CannotLocatePackageInINC 2.2007 - Moose::Exception::CannotMakeMetaclassCompatible 2.2007 - Moose::Exception::CannotOverrideALocalMethod 2.2007 - Moose::Exception::CannotOverrideBodyOfMetaMethods 2.2007 - Moose::Exception::CannotOverrideLocalMethodIsPresent 2.2007 - Moose::Exception::CannotOverrideNoSuperMethod 2.2007 - Moose::Exception::CannotRegisterUnnamedTypeConstraint 2.2007 - Moose::Exception::CannotUseLazyBuildAndDefaultSimultaneously 2.2007 - Moose::Exception::CircularReferenceInAlso 2.2007 - Moose::Exception::ClassDoesNotHaveInitMeta 2.2007 - Moose::Exception::ClassDoesTheExcludedRole 2.2007 - Moose::Exception::ClassNamesDoNotMatch 2.2007 - Moose::Exception::CloneObjectExpectsAnInstanceOfMetaclass 2.2007 - Moose::Exception::CodeBlockMustBeACodeRef 2.2007 - Moose::Exception::CoercingWithoutCoercions 2.2007 - Moose::Exception::CoercionAlreadyExists 2.2007 - Moose::Exception::CoercionNeedsTypeConstraint 2.2007 - Moose::Exception::ConflictDetectedInCheckRoleExclusions 2.2007 - Moose::Exception::ConflictDetectedInCheckRoleExclusionsInToClass 2.2007 - Moose::Exception::ConstructClassInstanceTakesPackageName 2.2007 - Moose::Exception::CouldNotCreateMethod 2.2007 - Moose::Exception::CouldNotCreateWriter 2.2007 - Moose::Exception::CouldNotEvalConstructor 2.2007 - Moose::Exception::CouldNotEvalDestructor 2.2007 - Moose::Exception::CouldNotFindTypeConstraintToCoerceFrom 2.2007 - Moose::Exception::CouldNotGenerateInlineAttributeMethod 2.2007 - Moose::Exception::CouldNotLocateTypeConstraintForUnion 2.2007 - Moose::Exception::CouldNotParseType 2.2007 - Moose::Exception::CreateMOPClassTakesArrayRefOfAttributes 2.2007 - Moose::Exception::CreateMOPClassTakesArrayRefOfSuperclasses 2.2007 - Moose::Exception::CreateMOPClassTakesHashRefOfMethods 2.2007 - Moose::Exception::CreateTakesArrayRefOfRoles 2.2007 - Moose::Exception::CreateTakesHashRefOfAttributes 2.2007 - Moose::Exception::CreateTakesHashRefOfMethods 2.2007 - Moose::Exception::DefaultToMatchOnTypeMustBeCodeRef 2.2007 - Moose::Exception::DelegationToAClassWhichIsNotLoaded 2.2007 - Moose::Exception::DelegationToARoleWhichIsNotLoaded 2.2007 - Moose::Exception::DelegationToATypeWhichIsNotAClass 2.2007 - Moose::Exception::DoesRequiresRoleName 2.2007 - Moose::Exception::EnumCalledWithAnArrayRefAndAdditionalArgs 2.2007 - Moose::Exception::EnumValuesMustBeString 2.2007 - Moose::Exception::ExtendsMissingArgs 2.2007 - Moose::Exception::HandlesMustBeAHashRef 2.2007 - Moose::Exception::IllegalInheritedOptions 2.2007 - Moose::Exception::IllegalMethodTypeToAddMethodModifier 2.2007 - Moose::Exception::IncompatibleMetaclassOfSuperclass 2.2007 - Moose::Exception::InitMetaRequiresClass 2.2007 - Moose::Exception::InitializeTakesUnBlessedPackageName 2.2007 - Moose::Exception::InstanceBlessedIntoWrongClass 2.2007 - Moose::Exception::InstanceMustBeABlessedReference 2.2007 - Moose::Exception::InvalidArgPassedToMooseUtilMetaRole 2.2007 - Moose::Exception::InvalidArgumentToMethod 2.2007 - Moose::Exception::InvalidArgumentsToTraitAliases 2.2007 - Moose::Exception::InvalidBaseTypeGivenToCreateParameterizedTypeConstraint 2.2007 - Moose::Exception::InvalidHandleValue 2.2007 - Moose::Exception::InvalidHasProvidedInARole 2.2007 - Moose::Exception::InvalidNameForType 2.2007 - Moose::Exception::InvalidOverloadOperator 2.2007 - Moose::Exception::InvalidRoleApplication 2.2007 - Moose::Exception::InvalidTypeConstraint 2.2007 - Moose::Exception::InvalidTypeGivenToCreateParameterizedTypeConstraint 2.2007 - Moose::Exception::InvalidValueForIs 2.2007 - Moose::Exception::IsaDoesNotDoTheRole 2.2007 - Moose::Exception::IsaLacksDoesMethod 2.2007 - Moose::Exception::LazyAttributeNeedsADefault 2.2007 - Moose::Exception::Legacy 2.2007 - Moose::Exception::MOPAttributeNewNeedsAttributeName 2.2007 - Moose::Exception::MatchActionMustBeACodeRef 2.2007 - Moose::Exception::MessageParameterMustBeCodeRef 2.2007 - Moose::Exception::MetaclassIsAClassNotASubclassOfGivenMetaclass 2.2007 - Moose::Exception::MetaclassIsARoleNotASubclassOfGivenMetaclass 2.2007 - Moose::Exception::MetaclassIsNotASubclassOfGivenMetaclass 2.2007 - Moose::Exception::MetaclassMustBeASubclassOfMooseMetaClass 2.2007 - Moose::Exception::MetaclassMustBeASubclassOfMooseMetaRole 2.2007 - Moose::Exception::MetaclassMustBeDerivedFromClassMOPClass 2.2007 - Moose::Exception::MetaclassNotLoaded 2.2007 - Moose::Exception::MetaclassTypeIncompatible 2.2007 - Moose::Exception::MethodExpectedAMetaclassObject 2.2007 - Moose::Exception::MethodExpectsFewerArgs 2.2007 - Moose::Exception::MethodExpectsMoreArgs 2.2007 - Moose::Exception::MethodModifierNeedsMethodName 2.2007 - Moose::Exception::MethodNameConflictInRoles 2.2007 - Moose::Exception::MethodNameNotFoundInInheritanceHierarchy 2.2007 - Moose::Exception::MethodNameNotGiven 2.2007 - Moose::Exception::MustDefineAMethodName 2.2007 - Moose::Exception::MustDefineAnAttributeName 2.2007 - Moose::Exception::MustDefineAnOverloadOperator 2.2007 - Moose::Exception::MustHaveAtLeastOneValueToEnumerate 2.2007 - Moose::Exception::MustPassAHashOfOptions 2.2007 - Moose::Exception::MustPassAMooseMetaRoleInstanceOrSubclass 2.2007 - Moose::Exception::MustPassAPackageNameOrAnExistingClassMOPPackageInstance 2.2007 - Moose::Exception::MustPassEvenNumberOfArguments 2.2007 - Moose::Exception::MustPassEvenNumberOfAttributeOptions 2.2007 - Moose::Exception::MustProvideANameForTheAttribute 2.2007 - Moose::Exception::MustSpecifyAtleastOneMethod 2.2007 - Moose::Exception::MustSpecifyAtleastOneRole 2.2007 - Moose::Exception::MustSpecifyAtleastOneRoleToApplicant 2.2007 - Moose::Exception::MustSupplyAClassMOPAttributeInstance 2.2007 - Moose::Exception::MustSupplyADelegateToMethod 2.2007 - Moose::Exception::MustSupplyAMetaclass 2.2007 - Moose::Exception::MustSupplyAMooseMetaAttributeInstance 2.2007 - Moose::Exception::MustSupplyAnAccessorTypeToConstructWith 2.2007 - Moose::Exception::MustSupplyAnAttributeToConstructWith 2.2007 - Moose::Exception::MustSupplyArrayRefAsCurriedArguments 2.2007 - Moose::Exception::MustSupplyPackageNameAndName 2.2007 - Moose::Exception::NeedsTypeConstraintUnionForTypeCoercionUnion 2.2007 - Moose::Exception::NeitherAttributeNorAttributeNameIsGiven 2.2007 - Moose::Exception::NeitherClassNorClassNameIsGiven 2.2007 - Moose::Exception::NeitherRoleNorRoleNameIsGiven 2.2007 - Moose::Exception::NeitherTypeNorTypeNameIsGiven 2.2007 - Moose::Exception::NoAttributeFoundInSuperClass 2.2007 - Moose::Exception::NoBodyToInitializeInAnAbstractBaseClass 2.2007 - Moose::Exception::NoCasesMatched 2.2007 - Moose::Exception::NoConstraintCheckForTypeConstraint 2.2007 - Moose::Exception::NoDestructorClassSpecified 2.2007 - Moose::Exception::NoImmutableTraitSpecifiedForClass 2.2007 - Moose::Exception::NoParentGivenToSubtype 2.2007 - Moose::Exception::OnlyInstancesCanBeCloned 2.2007 - Moose::Exception::OperatorIsRequired 2.2007 - Moose::Exception::OverloadConflictInSummation 2.2007 - Moose::Exception::OverloadRequiresAMetaClass 2.2007 - Moose::Exception::OverloadRequiresAMetaMethod 2.2007 - Moose::Exception::OverloadRequiresAMetaOverload 2.2007 - Moose::Exception::OverloadRequiresAMethodNameOrCoderef 2.2007 - Moose::Exception::OverloadRequiresAnOperator 2.2007 - Moose::Exception::OverloadRequiresNamesForCoderef 2.2007 - Moose::Exception::OverrideConflictInComposition 2.2007 - Moose::Exception::OverrideConflictInSummation 2.2007 - Moose::Exception::PackageDoesNotUseMooseExporter 2.2007 - Moose::Exception::PackageNameAndNameParamsNotGivenToWrap 2.2007 - Moose::Exception::PackagesAndModulesAreNotCachable 2.2007 - Moose::Exception::ParameterIsNotSubtypeOfParent 2.2007 - Moose::Exception::ReferencesAreNotAllowedAsDefault 2.2007 - Moose::Exception::RequiredAttributeLacksInitialization 2.2007 - Moose::Exception::RequiredAttributeNeedsADefault 2.2007 - Moose::Exception::RequiredMethodsImportedByClass 2.2007 - Moose::Exception::RequiredMethodsNotImplementedByClass 2.2007 - Moose::Exception::Role::Attribute 2.2007 - Moose::Exception::Role::AttributeName 2.2007 - Moose::Exception::Role::Class 2.2007 - Moose::Exception::Role::EitherAttributeOrAttributeName 2.2007 - Moose::Exception::Role::Instance 2.2007 - Moose::Exception::Role::InstanceClass 2.2007 - Moose::Exception::Role::InvalidAttributeOptions 2.2007 - Moose::Exception::Role::Method 2.2007 - Moose::Exception::Role::ParamsHash 2.2007 - Moose::Exception::Role::Role 2.2007 - Moose::Exception::Role::RoleForCreate 2.2007 - Moose::Exception::Role::RoleForCreateMOPClass 2.2007 - Moose::Exception::Role::TypeConstraint 2.2007 - Moose::Exception::RoleDoesTheExcludedRole 2.2007 - Moose::Exception::RoleExclusionConflict 2.2007 - Moose::Exception::RoleNameRequired 2.2007 - Moose::Exception::RoleNameRequiredForMooseMetaRole 2.2007 - Moose::Exception::RolesDoNotSupportAugment 2.2007 - Moose::Exception::RolesDoNotSupportExtends 2.2007 - Moose::Exception::RolesDoNotSupportInner 2.2007 - Moose::Exception::RolesDoNotSupportRegexReferencesForMethodModifiers 2.2007 - Moose::Exception::RolesInCreateTakesAnArrayRef 2.2007 - Moose::Exception::RolesListMustBeInstancesOfMooseMetaRole 2.2007 - Moose::Exception::SingleParamsToNewMustBeHashRef 2.2007 - Moose::Exception::TriggerMustBeACodeRef 2.2007 - Moose::Exception::TypeConstraintCannotBeUsedForAParameterizableType 2.2007 - Moose::Exception::TypeConstraintIsAlreadyCreated 2.2007 - Moose::Exception::TypeParameterMustBeMooseMetaType 2.2007 - Moose::Exception::UnableToCanonicalizeHandles 2.2007 - Moose::Exception::UnableToCanonicalizeNonRolePackage 2.2007 - Moose::Exception::UnableToRecognizeDelegateMetaclass 2.2007 - Moose::Exception::UndefinedHashKeysPassedToMethod 2.2007 - Moose::Exception::UnionCalledWithAnArrayRefAndAdditionalArgs 2.2007 - Moose::Exception::UnionTakesAtleastTwoTypeNames 2.2007 - Moose::Exception::ValidationFailedForInlineTypeConstraint 2.2007 - Moose::Exception::ValidationFailedForTypeConstraint 2.2007 - Moose::Exception::WrapTakesACodeRefToBless 2.2007 - Moose::Exception::WrongTypeConstraintGiven 2.2007 - Moose::Exporter 2.2007 - Moose::Intro 2.2007 - Moose::Manual 2.2007 - Moose::Manual::Attributes 2.2007 - Moose::Manual::BestPractices 2.2007 - Moose::Manual::Classes 2.2007 - Moose::Manual::Concepts 2.2007 - Moose::Manual::Construction 2.2007 - Moose::Manual::Contributing 2.2007 - Moose::Manual::Delegation 2.2007 - Moose::Manual::Delta 2.2007 - Moose::Manual::Exceptions 2.2007 - Moose::Manual::Exceptions::Manifest 2.2007 - Moose::Manual::FAQ 2.2007 - Moose::Manual::MOP 2.2007 - Moose::Manual::MethodModifiers 2.2007 - Moose::Manual::MooseX 2.2007 - Moose::Manual::Resources 2.2007 - Moose::Manual::Roles 2.2007 - Moose::Manual::Support 2.2007 - Moose::Manual::Types 2.2007 - Moose::Manual::Unsweetened 2.2007 - Moose::Meta::Attribute 2.2007 - Moose::Meta::Attribute::Native 2.2007 - Moose::Meta::Attribute::Native::Trait::Array 2.2007 - Moose::Meta::Attribute::Native::Trait::Bool 2.2007 - Moose::Meta::Attribute::Native::Trait::Code 2.2007 - Moose::Meta::Attribute::Native::Trait::Counter 2.2007 - Moose::Meta::Attribute::Native::Trait::Hash 2.2007 - Moose::Meta::Attribute::Native::Trait::Number 2.2007 - Moose::Meta::Attribute::Native::Trait::String 2.2007 - Moose::Meta::Class 2.2007 - Moose::Meta::Instance 2.2007 - Moose::Meta::Method 2.2007 - Moose::Meta::Method::Accessor 2.2007 - Moose::Meta::Method::Augmented 2.2007 - Moose::Meta::Method::Constructor 2.2007 - Moose::Meta::Method::Delegation 2.2007 - Moose::Meta::Method::Destructor 2.2007 - Moose::Meta::Method::Meta 2.2007 - Moose::Meta::Method::Overridden 2.2007 - Moose::Meta::Role 2.2007 - Moose::Meta::Role::Application 2.2007 - Moose::Meta::Role::Application::RoleSummation 2.2007 - Moose::Meta::Role::Application::ToClass 2.2007 - Moose::Meta::Role::Application::ToInstance 2.2007 - Moose::Meta::Role::Application::ToRole 2.2007 - Moose::Meta::Role::Attribute 2.2007 - Moose::Meta::Role::Composite 2.2007 - Moose::Meta::Role::Method 2.2007 - Moose::Meta::Role::Method::Conflicting 2.2007 - Moose::Meta::Role::Method::Required 2.2007 - Moose::Meta::TypeCoercion 2.2007 - Moose::Meta::TypeCoercion::Union 2.2007 - Moose::Meta::TypeConstraint 2.2007 - Moose::Meta::TypeConstraint::Class 2.2007 - Moose::Meta::TypeConstraint::DuckType 2.2007 - Moose::Meta::TypeConstraint::Enum 2.2007 - Moose::Meta::TypeConstraint::Parameterizable 2.2007 - Moose::Meta::TypeConstraint::Parameterized 2.2007 - Moose::Meta::TypeConstraint::Registry 2.2007 - Moose::Meta::TypeConstraint::Role 2.2007 - Moose::Meta::TypeConstraint::Union 2.2007 - Moose::Object 2.2007 - Moose::Role 2.2007 - Moose::Spec::Role 2.2007 - Moose::Unsweetened 2.2007 - Moose::Util 2.2007 - Moose::Util::MetaRole 2.2007 - Moose::Util::TypeConstraints 2.2007 - Test::Moose 2.2007 - metaclass 2.2007 - oose 2.2007 + Moose-2.2207 + pathname: E/ET/ETHER/Moose-2.2207.tar.gz + provides: + Class::MOP 2.2207 + Class::MOP::Attribute 2.2207 + Class::MOP::Class 2.2207 + Class::MOP::Class::Immutable::Trait 2.2207 + Class::MOP::Deprecated 2.2207 + Class::MOP::Instance 2.2207 + Class::MOP::Method 2.2207 + Class::MOP::Method::Accessor 2.2207 + Class::MOP::Method::Constructor 2.2207 + Class::MOP::Method::Generated 2.2207 + Class::MOP::Method::Inlined 2.2207 + Class::MOP::Method::Meta 2.2207 + Class::MOP::Method::Wrapped 2.2207 + Class::MOP::MiniTrait 2.2207 + Class::MOP::Mixin 2.2207 + Class::MOP::Mixin::AttributeCore 2.2207 + Class::MOP::Mixin::HasAttributes 2.2207 + Class::MOP::Mixin::HasMethods 2.2207 + Class::MOP::Mixin::HasOverloads 2.2207 + Class::MOP::Module 2.2207 + Class::MOP::Object 2.2207 + Class::MOP::Overload 2.2207 + Class::MOP::Package 2.2207 + Moose 2.2207 + Moose::Cookbook 2.2207 + Moose::Cookbook::Basics::BankAccount_MethodModifiersAndSubclassing 2.2207 + Moose::Cookbook::Basics::BinaryTree_AttributeFeatures 2.2207 + Moose::Cookbook::Basics::BinaryTree_BuilderAndLazyBuild 2.2207 + Moose::Cookbook::Basics::Company_Subtypes 2.2207 + Moose::Cookbook::Basics::DateTime_ExtendingNonMooseParent 2.2207 + Moose::Cookbook::Basics::Document_AugmentAndInner 2.2207 + Moose::Cookbook::Basics::Genome_OverloadingSubtypesAndCoercion 2.2207 + Moose::Cookbook::Basics::HTTP_SubtypesAndCoercion 2.2207 + Moose::Cookbook::Basics::Immutable 2.2207 + Moose::Cookbook::Basics::Person_BUILDARGSAndBUILD 2.2207 + Moose::Cookbook::Basics::Point_AttributesAndSubclassing 2.2207 + Moose::Cookbook::Extending::Debugging_BaseClassRole 2.2207 + Moose::Cookbook::Extending::ExtensionOverview 2.2207 + Moose::Cookbook::Extending::Mooseish_MooseSugar 2.2207 + Moose::Cookbook::Legacy::Debugging_BaseClassReplacement 2.2207 + Moose::Cookbook::Legacy::Labeled_AttributeMetaclass 2.2207 + Moose::Cookbook::Legacy::Table_ClassMetaclass 2.2207 + Moose::Cookbook::Meta::GlobRef_InstanceMetaclass 2.2207 + Moose::Cookbook::Meta::Labeled_AttributeTrait 2.2207 + Moose::Cookbook::Meta::PrivateOrPublic_MethodMetaclass 2.2207 + Moose::Cookbook::Meta::Table_MetaclassTrait 2.2207 + Moose::Cookbook::Meta::WhyMeta 2.2207 + Moose::Cookbook::Roles::ApplicationToInstance 2.2207 + Moose::Cookbook::Roles::Comparable_CodeReuse 2.2207 + Moose::Cookbook::Roles::Restartable_AdvancedComposition 2.2207 + Moose::Cookbook::Snack::Keywords 2.2207 + Moose::Cookbook::Snack::Types 2.2207 + Moose::Cookbook::Style 2.2207 + Moose::Deprecated 2.2207 + Moose::Exception 2.2207 + Moose::Exception::AccessorMustReadWrite 2.2207 + Moose::Exception::AddParameterizableTypeTakesParameterizableType 2.2207 + Moose::Exception::AddRoleTakesAMooseMetaRoleInstance 2.2207 + Moose::Exception::AddRoleToARoleTakesAMooseMetaRole 2.2207 + Moose::Exception::ApplyTakesABlessedInstance 2.2207 + Moose::Exception::AttachToClassNeedsAClassMOPClassInstanceOrASubclass 2.2207 + Moose::Exception::AttributeConflictInRoles 2.2207 + Moose::Exception::AttributeConflictInSummation 2.2207 + Moose::Exception::AttributeExtensionIsNotSupportedInRoles 2.2207 + Moose::Exception::AttributeIsRequired 2.2207 + Moose::Exception::AttributeMustBeAnClassMOPMixinAttributeCoreOrSubclass 2.2207 + Moose::Exception::AttributeNamesDoNotMatch 2.2207 + Moose::Exception::AttributeValueIsNotAnObject 2.2207 + Moose::Exception::AttributeValueIsNotDefined 2.2207 + Moose::Exception::AutoDeRefNeedsArrayRefOrHashRef 2.2207 + Moose::Exception::BadOptionFormat 2.2207 + Moose::Exception::BothBuilderAndDefaultAreNotAllowed 2.2207 + Moose::Exception::BuilderDoesNotExist 2.2207 + Moose::Exception::BuilderMethodNotSupportedForAttribute 2.2207 + Moose::Exception::BuilderMethodNotSupportedForInlineAttribute 2.2207 + Moose::Exception::BuilderMustBeAMethodName 2.2207 + Moose::Exception::CallingMethodOnAnImmutableInstance 2.2207 + Moose::Exception::CallingReadOnlyMethodOnAnImmutableInstance 2.2207 + Moose::Exception::CanExtendOnlyClasses 2.2207 + Moose::Exception::CanOnlyConsumeRole 2.2207 + Moose::Exception::CanOnlyWrapBlessedCode 2.2207 + Moose::Exception::CanReblessOnlyIntoASubclass 2.2207 + Moose::Exception::CanReblessOnlyIntoASuperclass 2.2207 + Moose::Exception::CannotAddAdditionalTypeCoercionsToUnion 2.2207 + Moose::Exception::CannotAddAsAnAttributeToARole 2.2207 + Moose::Exception::CannotApplyBaseClassRolesToRole 2.2207 + Moose::Exception::CannotAssignValueToReadOnlyAccessor 2.2207 + Moose::Exception::CannotAugmentIfLocalMethodPresent 2.2207 + Moose::Exception::CannotAugmentNoSuperMethod 2.2207 + Moose::Exception::CannotAutoDerefWithoutIsa 2.2207 + Moose::Exception::CannotAutoDereferenceTypeConstraint 2.2207 + Moose::Exception::CannotCalculateNativeType 2.2207 + Moose::Exception::CannotCallAnAbstractBaseMethod 2.2207 + Moose::Exception::CannotCallAnAbstractMethod 2.2207 + Moose::Exception::CannotCoerceAWeakRef 2.2207 + Moose::Exception::CannotCoerceAttributeWhichHasNoCoercion 2.2207 + Moose::Exception::CannotCreateHigherOrderTypeWithoutATypeParameter 2.2207 + Moose::Exception::CannotCreateMethodAliasLocalMethodIsPresent 2.2207 + Moose::Exception::CannotCreateMethodAliasLocalMethodIsPresentInClass 2.2207 + Moose::Exception::CannotDelegateLocalMethodIsPresent 2.2207 + Moose::Exception::CannotDelegateWithoutIsa 2.2207 + Moose::Exception::CannotFindDelegateMetaclass 2.2207 + Moose::Exception::CannotFindType 2.2207 + Moose::Exception::CannotFindTypeGivenToMatchOnType 2.2207 + Moose::Exception::CannotFixMetaclassCompatibility 2.2207 + Moose::Exception::CannotGenerateInlineConstraint 2.2207 + Moose::Exception::CannotInitializeMooseMetaRoleComposite 2.2207 + Moose::Exception::CannotInlineTypeConstraintCheck 2.2207 + Moose::Exception::CannotLocatePackageInINC 2.2207 + Moose::Exception::CannotMakeMetaclassCompatible 2.2207 + Moose::Exception::CannotOverrideALocalMethod 2.2207 + Moose::Exception::CannotOverrideBodyOfMetaMethods 2.2207 + Moose::Exception::CannotOverrideLocalMethodIsPresent 2.2207 + Moose::Exception::CannotOverrideNoSuperMethod 2.2207 + Moose::Exception::CannotRegisterUnnamedTypeConstraint 2.2207 + Moose::Exception::CannotUseLazyBuildAndDefaultSimultaneously 2.2207 + Moose::Exception::CircularReferenceInAlso 2.2207 + Moose::Exception::ClassDoesNotHaveInitMeta 2.2207 + Moose::Exception::ClassDoesTheExcludedRole 2.2207 + Moose::Exception::ClassNamesDoNotMatch 2.2207 + Moose::Exception::CloneObjectExpectsAnInstanceOfMetaclass 2.2207 + Moose::Exception::CodeBlockMustBeACodeRef 2.2207 + Moose::Exception::CoercingWithoutCoercions 2.2207 + Moose::Exception::CoercionAlreadyExists 2.2207 + Moose::Exception::CoercionNeedsTypeConstraint 2.2207 + Moose::Exception::ConflictDetectedInCheckRoleExclusions 2.2207 + Moose::Exception::ConflictDetectedInCheckRoleExclusionsInToClass 2.2207 + Moose::Exception::ConstructClassInstanceTakesPackageName 2.2207 + Moose::Exception::CouldNotCreateMethod 2.2207 + Moose::Exception::CouldNotCreateWriter 2.2207 + Moose::Exception::CouldNotEvalConstructor 2.2207 + Moose::Exception::CouldNotEvalDestructor 2.2207 + Moose::Exception::CouldNotFindTypeConstraintToCoerceFrom 2.2207 + Moose::Exception::CouldNotGenerateInlineAttributeMethod 2.2207 + Moose::Exception::CouldNotLocateTypeConstraintForUnion 2.2207 + Moose::Exception::CouldNotParseType 2.2207 + Moose::Exception::CreateMOPClassTakesArrayRefOfAttributes 2.2207 + Moose::Exception::CreateMOPClassTakesArrayRefOfSuperclasses 2.2207 + Moose::Exception::CreateMOPClassTakesHashRefOfMethods 2.2207 + Moose::Exception::CreateTakesArrayRefOfRoles 2.2207 + Moose::Exception::CreateTakesHashRefOfAttributes 2.2207 + Moose::Exception::CreateTakesHashRefOfMethods 2.2207 + Moose::Exception::DefaultToMatchOnTypeMustBeCodeRef 2.2207 + Moose::Exception::DelegationToAClassWhichIsNotLoaded 2.2207 + Moose::Exception::DelegationToARoleWhichIsNotLoaded 2.2207 + Moose::Exception::DelegationToATypeWhichIsNotAClass 2.2207 + Moose::Exception::DoesRequiresRoleName 2.2207 + Moose::Exception::EnumCalledWithAnArrayRefAndAdditionalArgs 2.2207 + Moose::Exception::EnumValuesMustBeString 2.2207 + Moose::Exception::ExtendsMissingArgs 2.2207 + Moose::Exception::HandlesMustBeAHashRef 2.2207 + Moose::Exception::IllegalInheritedOptions 2.2207 + Moose::Exception::IllegalMethodTypeToAddMethodModifier 2.2207 + Moose::Exception::IncompatibleMetaclassOfSuperclass 2.2207 + Moose::Exception::InitMetaRequiresClass 2.2207 + Moose::Exception::InitializeTakesUnBlessedPackageName 2.2207 + Moose::Exception::InstanceBlessedIntoWrongClass 2.2207 + Moose::Exception::InstanceMustBeABlessedReference 2.2207 + Moose::Exception::InvalidArgPassedToMooseUtilMetaRole 2.2207 + Moose::Exception::InvalidArgumentToMethod 2.2207 + Moose::Exception::InvalidArgumentsToTraitAliases 2.2207 + Moose::Exception::InvalidBaseTypeGivenToCreateParameterizedTypeConstraint 2.2207 + Moose::Exception::InvalidHandleValue 2.2207 + Moose::Exception::InvalidHasProvidedInARole 2.2207 + Moose::Exception::InvalidNameForType 2.2207 + Moose::Exception::InvalidOverloadOperator 2.2207 + Moose::Exception::InvalidRoleApplication 2.2207 + Moose::Exception::InvalidTypeConstraint 2.2207 + Moose::Exception::InvalidTypeGivenToCreateParameterizedTypeConstraint 2.2207 + Moose::Exception::InvalidValueForIs 2.2207 + Moose::Exception::IsaDoesNotDoTheRole 2.2207 + Moose::Exception::IsaLacksDoesMethod 2.2207 + Moose::Exception::LazyAttributeNeedsADefault 2.2207 + Moose::Exception::Legacy 2.2207 + Moose::Exception::MOPAttributeNewNeedsAttributeName 2.2207 + Moose::Exception::MatchActionMustBeACodeRef 2.2207 + Moose::Exception::MessageParameterMustBeCodeRef 2.2207 + Moose::Exception::MetaclassIsAClassNotASubclassOfGivenMetaclass 2.2207 + Moose::Exception::MetaclassIsARoleNotASubclassOfGivenMetaclass 2.2207 + Moose::Exception::MetaclassIsNotASubclassOfGivenMetaclass 2.2207 + Moose::Exception::MetaclassMustBeASubclassOfMooseMetaClass 2.2207 + Moose::Exception::MetaclassMustBeASubclassOfMooseMetaRole 2.2207 + Moose::Exception::MetaclassMustBeDerivedFromClassMOPClass 2.2207 + Moose::Exception::MetaclassNotLoaded 2.2207 + Moose::Exception::MetaclassTypeIncompatible 2.2207 + Moose::Exception::MethodExpectedAMetaclassObject 2.2207 + Moose::Exception::MethodExpectsFewerArgs 2.2207 + Moose::Exception::MethodExpectsMoreArgs 2.2207 + Moose::Exception::MethodModifierNeedsMethodName 2.2207 + Moose::Exception::MethodNameConflictInRoles 2.2207 + Moose::Exception::MethodNameNotFoundInInheritanceHierarchy 2.2207 + Moose::Exception::MethodNameNotGiven 2.2207 + Moose::Exception::MustDefineAMethodName 2.2207 + Moose::Exception::MustDefineAnAttributeName 2.2207 + Moose::Exception::MustDefineAnOverloadOperator 2.2207 + Moose::Exception::MustHaveAtLeastOneValueToEnumerate 2.2207 + Moose::Exception::MustPassAHashOfOptions 2.2207 + Moose::Exception::MustPassAMooseMetaRoleInstanceOrSubclass 2.2207 + Moose::Exception::MustPassAPackageNameOrAnExistingClassMOPPackageInstance 2.2207 + Moose::Exception::MustPassEvenNumberOfArguments 2.2207 + Moose::Exception::MustPassEvenNumberOfAttributeOptions 2.2207 + Moose::Exception::MustProvideANameForTheAttribute 2.2207 + Moose::Exception::MustSpecifyAtleastOneMethod 2.2207 + Moose::Exception::MustSpecifyAtleastOneRole 2.2207 + Moose::Exception::MustSpecifyAtleastOneRoleToApplicant 2.2207 + Moose::Exception::MustSupplyAClassMOPAttributeInstance 2.2207 + Moose::Exception::MustSupplyADelegateToMethod 2.2207 + Moose::Exception::MustSupplyAMetaclass 2.2207 + Moose::Exception::MustSupplyAMooseMetaAttributeInstance 2.2207 + Moose::Exception::MustSupplyAnAccessorTypeToConstructWith 2.2207 + Moose::Exception::MustSupplyAnAttributeToConstructWith 2.2207 + Moose::Exception::MustSupplyArrayRefAsCurriedArguments 2.2207 + Moose::Exception::MustSupplyPackageNameAndName 2.2207 + Moose::Exception::NeedsTypeConstraintUnionForTypeCoercionUnion 2.2207 + Moose::Exception::NeitherAttributeNorAttributeNameIsGiven 2.2207 + Moose::Exception::NeitherClassNorClassNameIsGiven 2.2207 + Moose::Exception::NeitherRoleNorRoleNameIsGiven 2.2207 + Moose::Exception::NeitherTypeNorTypeNameIsGiven 2.2207 + Moose::Exception::NoAttributeFoundInSuperClass 2.2207 + Moose::Exception::NoBodyToInitializeInAnAbstractBaseClass 2.2207 + Moose::Exception::NoCasesMatched 2.2207 + Moose::Exception::NoConstraintCheckForTypeConstraint 2.2207 + Moose::Exception::NoDestructorClassSpecified 2.2207 + Moose::Exception::NoImmutableTraitSpecifiedForClass 2.2207 + Moose::Exception::NoParentGivenToSubtype 2.2207 + Moose::Exception::OnlyInstancesCanBeCloned 2.2207 + Moose::Exception::OperatorIsRequired 2.2207 + Moose::Exception::OverloadConflictInSummation 2.2207 + Moose::Exception::OverloadRequiresAMetaClass 2.2207 + Moose::Exception::OverloadRequiresAMetaMethod 2.2207 + Moose::Exception::OverloadRequiresAMetaOverload 2.2207 + Moose::Exception::OverloadRequiresAMethodNameOrCoderef 2.2207 + Moose::Exception::OverloadRequiresAnOperator 2.2207 + Moose::Exception::OverloadRequiresNamesForCoderef 2.2207 + Moose::Exception::OverrideConflictInComposition 2.2207 + Moose::Exception::OverrideConflictInSummation 2.2207 + Moose::Exception::PackageDoesNotUseMooseExporter 2.2207 + Moose::Exception::PackageNameAndNameParamsNotGivenToWrap 2.2207 + Moose::Exception::PackagesAndModulesAreNotCachable 2.2207 + Moose::Exception::ParameterIsNotSubtypeOfParent 2.2207 + Moose::Exception::ReferencesAreNotAllowedAsDefault 2.2207 + Moose::Exception::RequiredAttributeLacksInitialization 2.2207 + Moose::Exception::RequiredAttributeNeedsADefault 2.2207 + Moose::Exception::RequiredMethodsImportedByClass 2.2207 + Moose::Exception::RequiredMethodsNotImplementedByClass 2.2207 + Moose::Exception::Role::Attribute 2.2207 + Moose::Exception::Role::AttributeName 2.2207 + Moose::Exception::Role::Class 2.2207 + Moose::Exception::Role::EitherAttributeOrAttributeName 2.2207 + Moose::Exception::Role::Instance 2.2207 + Moose::Exception::Role::InstanceClass 2.2207 + Moose::Exception::Role::InvalidAttributeOptions 2.2207 + Moose::Exception::Role::Method 2.2207 + Moose::Exception::Role::ParamsHash 2.2207 + Moose::Exception::Role::Role 2.2207 + Moose::Exception::Role::RoleForCreate 2.2207 + Moose::Exception::Role::RoleForCreateMOPClass 2.2207 + Moose::Exception::Role::TypeConstraint 2.2207 + Moose::Exception::RoleDoesTheExcludedRole 2.2207 + Moose::Exception::RoleExclusionConflict 2.2207 + Moose::Exception::RoleNameRequired 2.2207 + Moose::Exception::RoleNameRequiredForMooseMetaRole 2.2207 + Moose::Exception::RolesDoNotSupportAugment 2.2207 + Moose::Exception::RolesDoNotSupportExtends 2.2207 + Moose::Exception::RolesDoNotSupportInner 2.2207 + Moose::Exception::RolesDoNotSupportRegexReferencesForMethodModifiers 2.2207 + Moose::Exception::RolesInCreateTakesAnArrayRef 2.2207 + Moose::Exception::RolesListMustBeInstancesOfMooseMetaRole 2.2207 + Moose::Exception::SingleParamsToNewMustBeHashRef 2.2207 + Moose::Exception::TriggerMustBeACodeRef 2.2207 + Moose::Exception::TypeConstraintCannotBeUsedForAParameterizableType 2.2207 + Moose::Exception::TypeConstraintIsAlreadyCreated 2.2207 + Moose::Exception::TypeParameterMustBeMooseMetaType 2.2207 + Moose::Exception::UnableToCanonicalizeHandles 2.2207 + Moose::Exception::UnableToCanonicalizeNonRolePackage 2.2207 + Moose::Exception::UnableToRecognizeDelegateMetaclass 2.2207 + Moose::Exception::UndefinedHashKeysPassedToMethod 2.2207 + Moose::Exception::UnionCalledWithAnArrayRefAndAdditionalArgs 2.2207 + Moose::Exception::UnionTakesAtleastTwoTypeNames 2.2207 + Moose::Exception::ValidationFailedForInlineTypeConstraint 2.2207 + Moose::Exception::ValidationFailedForTypeConstraint 2.2207 + Moose::Exception::WrapTakesACodeRefToBless 2.2207 + Moose::Exception::WrongTypeConstraintGiven 2.2207 + Moose::Exporter 2.2207 + Moose::Intro 2.2207 + Moose::Manual 2.2207 + Moose::Manual::Attributes 2.2207 + Moose::Manual::BestPractices 2.2207 + Moose::Manual::Classes 2.2207 + Moose::Manual::Concepts 2.2207 + Moose::Manual::Construction 2.2207 + Moose::Manual::Contributing 2.2207 + Moose::Manual::Delegation 2.2207 + Moose::Manual::Delta 2.2207 + Moose::Manual::Exceptions 2.2207 + Moose::Manual::Exceptions::Manifest 2.2207 + Moose::Manual::FAQ 2.2207 + Moose::Manual::MOP 2.2207 + Moose::Manual::MethodModifiers 2.2207 + Moose::Manual::MooseX 2.2207 + Moose::Manual::Resources 2.2207 + Moose::Manual::Roles 2.2207 + Moose::Manual::Support 2.2207 + Moose::Manual::Types 2.2207 + Moose::Manual::Unsweetened 2.2207 + Moose::Meta::Attribute 2.2207 + Moose::Meta::Attribute::Native 2.2207 + Moose::Meta::Attribute::Native::Trait 2.2207 + Moose::Meta::Attribute::Native::Trait::Array 2.2207 + Moose::Meta::Attribute::Native::Trait::Bool 2.2207 + Moose::Meta::Attribute::Native::Trait::Code 2.2207 + Moose::Meta::Attribute::Native::Trait::Counter 2.2207 + Moose::Meta::Attribute::Native::Trait::Hash 2.2207 + Moose::Meta::Attribute::Native::Trait::Number 2.2207 + Moose::Meta::Attribute::Native::Trait::String 2.2207 + Moose::Meta::Class 2.2207 + Moose::Meta::Class::Immutable::Trait 2.2207 + Moose::Meta::Instance 2.2207 + Moose::Meta::Method 2.2207 + Moose::Meta::Method::Accessor 2.2207 + Moose::Meta::Method::Accessor::Native 2.2207 + Moose::Meta::Method::Accessor::Native::Array 2.2207 + Moose::Meta::Method::Accessor::Native::Array::Writer 2.2207 + Moose::Meta::Method::Accessor::Native::Array::accessor 2.2207 + Moose::Meta::Method::Accessor::Native::Array::clear 2.2207 + Moose::Meta::Method::Accessor::Native::Array::count 2.2207 + Moose::Meta::Method::Accessor::Native::Array::delete 2.2207 + Moose::Meta::Method::Accessor::Native::Array::elements 2.2207 + Moose::Meta::Method::Accessor::Native::Array::first 2.2207 + Moose::Meta::Method::Accessor::Native::Array::first_index 2.2207 + Moose::Meta::Method::Accessor::Native::Array::get 2.2207 + Moose::Meta::Method::Accessor::Native::Array::grep 2.2207 + Moose::Meta::Method::Accessor::Native::Array::insert 2.2207 + Moose::Meta::Method::Accessor::Native::Array::is_empty 2.2207 + Moose::Meta::Method::Accessor::Native::Array::join 2.2207 + Moose::Meta::Method::Accessor::Native::Array::map 2.2207 + Moose::Meta::Method::Accessor::Native::Array::natatime 2.2207 + Moose::Meta::Method::Accessor::Native::Array::pop 2.2207 + Moose::Meta::Method::Accessor::Native::Array::push 2.2207 + Moose::Meta::Method::Accessor::Native::Array::reduce 2.2207 + Moose::Meta::Method::Accessor::Native::Array::set 2.2207 + Moose::Meta::Method::Accessor::Native::Array::shallow_clone 2.2207 + Moose::Meta::Method::Accessor::Native::Array::shift 2.2207 + Moose::Meta::Method::Accessor::Native::Array::shuffle 2.2207 + Moose::Meta::Method::Accessor::Native::Array::sort 2.2207 + Moose::Meta::Method::Accessor::Native::Array::sort_in_place 2.2207 + Moose::Meta::Method::Accessor::Native::Array::splice 2.2207 + Moose::Meta::Method::Accessor::Native::Array::uniq 2.2207 + Moose::Meta::Method::Accessor::Native::Array::unshift 2.2207 + Moose::Meta::Method::Accessor::Native::Bool::not 2.2207 + Moose::Meta::Method::Accessor::Native::Bool::set 2.2207 + Moose::Meta::Method::Accessor::Native::Bool::toggle 2.2207 + Moose::Meta::Method::Accessor::Native::Bool::unset 2.2207 + Moose::Meta::Method::Accessor::Native::Code::execute 2.2207 + Moose::Meta::Method::Accessor::Native::Code::execute_method 2.2207 + Moose::Meta::Method::Accessor::Native::Collection 2.2207 + Moose::Meta::Method::Accessor::Native::Counter::Writer 2.2207 + Moose::Meta::Method::Accessor::Native::Counter::dec 2.2207 + Moose::Meta::Method::Accessor::Native::Counter::inc 2.2207 + Moose::Meta::Method::Accessor::Native::Counter::reset 2.2207 + Moose::Meta::Method::Accessor::Native::Counter::set 2.2207 + Moose::Meta::Method::Accessor::Native::Hash 2.2207 + Moose::Meta::Method::Accessor::Native::Hash::Writer 2.2207 + Moose::Meta::Method::Accessor::Native::Hash::accessor 2.2207 + Moose::Meta::Method::Accessor::Native::Hash::clear 2.2207 + Moose::Meta::Method::Accessor::Native::Hash::count 2.2207 + Moose::Meta::Method::Accessor::Native::Hash::defined 2.2207 + Moose::Meta::Method::Accessor::Native::Hash::delete 2.2207 + Moose::Meta::Method::Accessor::Native::Hash::elements 2.2207 + Moose::Meta::Method::Accessor::Native::Hash::exists 2.2207 + Moose::Meta::Method::Accessor::Native::Hash::get 2.2207 + Moose::Meta::Method::Accessor::Native::Hash::is_empty 2.2207 + Moose::Meta::Method::Accessor::Native::Hash::keys 2.2207 + Moose::Meta::Method::Accessor::Native::Hash::kv 2.2207 + Moose::Meta::Method::Accessor::Native::Hash::set 2.2207 + Moose::Meta::Method::Accessor::Native::Hash::shallow_clone 2.2207 + Moose::Meta::Method::Accessor::Native::Hash::values 2.2207 + Moose::Meta::Method::Accessor::Native::Number::abs 2.2207 + Moose::Meta::Method::Accessor::Native::Number::add 2.2207 + Moose::Meta::Method::Accessor::Native::Number::div 2.2207 + Moose::Meta::Method::Accessor::Native::Number::mod 2.2207 + Moose::Meta::Method::Accessor::Native::Number::mul 2.2207 + Moose::Meta::Method::Accessor::Native::Number::set 2.2207 + Moose::Meta::Method::Accessor::Native::Number::sub 2.2207 + Moose::Meta::Method::Accessor::Native::Reader 2.2207 + Moose::Meta::Method::Accessor::Native::String::append 2.2207 + Moose::Meta::Method::Accessor::Native::String::chomp 2.2207 + Moose::Meta::Method::Accessor::Native::String::chop 2.2207 + Moose::Meta::Method::Accessor::Native::String::clear 2.2207 + Moose::Meta::Method::Accessor::Native::String::inc 2.2207 + Moose::Meta::Method::Accessor::Native::String::length 2.2207 + Moose::Meta::Method::Accessor::Native::String::match 2.2207 + Moose::Meta::Method::Accessor::Native::String::prepend 2.2207 + Moose::Meta::Method::Accessor::Native::String::replace 2.2207 + Moose::Meta::Method::Accessor::Native::String::substr 2.2207 + Moose::Meta::Method::Accessor::Native::Writer 2.2207 + Moose::Meta::Method::Augmented 2.2207 + Moose::Meta::Method::Constructor 2.2207 + Moose::Meta::Method::Delegation 2.2207 + Moose::Meta::Method::Destructor 2.2207 + Moose::Meta::Method::Meta 2.2207 + Moose::Meta::Method::Overridden 2.2207 + Moose::Meta::Mixin::AttributeCore 2.2207 + Moose::Meta::Object::Trait 2.2207 + Moose::Meta::Role 2.2207 + Moose::Meta::Role::Application 2.2207 + Moose::Meta::Role::Application::RoleSummation 2.2207 + Moose::Meta::Role::Application::ToClass 2.2207 + Moose::Meta::Role::Application::ToInstance 2.2207 + Moose::Meta::Role::Application::ToRole 2.2207 + Moose::Meta::Role::Attribute 2.2207 + Moose::Meta::Role::Composite 2.2207 + Moose::Meta::Role::Method 2.2207 + Moose::Meta::Role::Method::Conflicting 2.2207 + Moose::Meta::Role::Method::Required 2.2207 + Moose::Meta::TypeCoercion 2.2207 + Moose::Meta::TypeCoercion::Union 2.2207 + Moose::Meta::TypeConstraint 2.2207 + Moose::Meta::TypeConstraint::Class 2.2207 + Moose::Meta::TypeConstraint::DuckType 2.2207 + Moose::Meta::TypeConstraint::Enum 2.2207 + Moose::Meta::TypeConstraint::Parameterizable 2.2207 + Moose::Meta::TypeConstraint::Parameterized 2.2207 + Moose::Meta::TypeConstraint::Registry 2.2207 + Moose::Meta::TypeConstraint::Role 2.2207 + Moose::Meta::TypeConstraint::Union 2.2207 + Moose::Object 2.2207 + Moose::Role 2.2207 + Moose::Spec::Role 2.2207 + Moose::Unsweetened 2.2207 + Moose::Util 2.2207 + Moose::Util::MetaRole 2.2207 + Moose::Util::TypeConstraints 2.2207 + Moose::Util::TypeConstraints::Builtins 2.2207 + Test::Moose 2.2207 + metaclass 2.2207 + oose 2.2207 requirements: Carp 1.22 Class::Load 0.09 Class::Load::XS 0.01 Data::OptList 0.107 Devel::GlobalDestruction 0 - Devel::OverloadInfo 0.004 - Devel::StackTrace 1.33 + Devel::OverloadInfo 0.005 + Devel::StackTrace 2.03 Dist::CheckConflicts 0.02 Eval::Closure 0.04 ExtUtils::MakeMaker 0 - List::Util 1.45 + List::Util 1.56 MRO::Compat 0.05 Module::Runtime 0.014 Module::Runtime::Conflicts 0.002 @@ -5297,23 +4566,11 @@ DISTRIBUTIONS Params::Util 1.00 Scalar::Util 1.19 Sub::Exporter 0.980 - Sub::Identify 0 - Sub::Name 0.20 + Sub::Util 1.40 Try::Tiny 0.17 parent 0.223 strict 1.03 warnings 1.03 - MooseX-Aliases-0.11 - pathname: D/DO/DOY/MooseX-Aliases-0.11.tar.gz - provides: - MooseX::Aliases 0.11 - requirements: - ExtUtils::MakeMaker 6.30 - Moose 2.0000 - Moose::Exporter 0 - Moose::Role 0 - Moose::Util::TypeConstraints 0 - Scalar::Util 0 MooseX-Attribute-Chained-1.0.3 pathname: T/TO/TOMHUKINS/MooseX-Attribute-Chained-1.0.3.tar.gz provides: @@ -5362,45 +4619,16 @@ DISTRIBUTIONS MooseX::Types::Structured 0 Test::More 0.88 Try::Tiny 0 - MooseX-ClassAttribute-0.29 - pathname: D/DR/DROLSKY/MooseX-ClassAttribute-0.29.tar.gz - provides: - MooseX::ClassAttribute 0.29 - MooseX::ClassAttribute::Meta::Role::Attribute 0.29 - MooseX::ClassAttribute::Trait::Application 0.29 - MooseX::ClassAttribute::Trait::Application::ToClass 0.29 - MooseX::ClassAttribute::Trait::Application::ToRole 0.29 - MooseX::ClassAttribute::Trait::Attribute 0.29 - MooseX::ClassAttribute::Trait::Class 0.29 - MooseX::ClassAttribute::Trait::Mixin::HasClassAttributes 0.29 - MooseX::ClassAttribute::Trait::Role 0.29 - MooseX::ClassAttribute::Trait::Role::Composite 0.29 - requirements: - ExtUtils::MakeMaker 0 - List::Util 1.45 - Moose 2.00 - Moose::Exporter 0 - Moose::Meta::Role::Attribute 0 - Moose::Role 0 - Moose::Util 0 - Moose::Util::MetaRole 0 - Scalar::Util 0 - namespace::autoclean 0.11 - namespace::clean 0.20 - strict 0 - warnings 0 - MooseX-Emulate-Class-Accessor-Fast-0.00903 - pathname: F/FL/FLORA/MooseX-Emulate-Class-Accessor-Fast-0.00903.tar.gz + MooseX-Emulate-Class-Accessor-Fast-0.009032 + pathname: H/HA/HAARG/MooseX-Emulate-Class-Accessor-Fast-0.009032.tar.gz provides: - MooseX::Adopt::Class::Accessor::Fast 0.00200 - MooseX::Emulate::Class::Accessor::Fast 0.00903 + MooseX::Adopt::Class::Accessor::Fast 0.009032 + MooseX::Emulate::Class::Accessor::Fast 0.009032 MooseX::Emulate::Class::Accessor::Fast::Meta::Accessor undef MooseX::Emulate::Class::Accessor::Fast::Meta::Role::Attribute undef requirements: - ExtUtils::MakeMaker 6.42 + ExtUtils::MakeMaker 0 Moose 0.84 - Test::Exception 0 - Test::More 0 namespace::clean 0 MooseX-Fastly-Role-0.04 pathname: L/LL/LLAP/MooseX-Fastly-Role-0.04.tar.gz @@ -5412,20 +4640,20 @@ DISTRIBUTIONS HTTP::Tiny 0 Moose::Role 0 Net::Fastly 1.08 - MooseX-Getopt-0.71 - pathname: E/ET/ETHER/MooseX-Getopt-0.71.tar.gz - provides: - MooseX::Getopt 0.71 - MooseX::Getopt::Basic 0.71 - MooseX::Getopt::Dashes 0.71 - MooseX::Getopt::GLD 0.71 - MooseX::Getopt::Meta::Attribute 0.71 - MooseX::Getopt::Meta::Attribute::NoGetopt 0.71 - MooseX::Getopt::Meta::Attribute::Trait 0.71 - MooseX::Getopt::Meta::Attribute::Trait::NoGetopt 0.71 - MooseX::Getopt::OptionTypeMap 0.71 - MooseX::Getopt::ProcessedArgv 0.71 - MooseX::Getopt::Strict 0.71 + MooseX-Getopt-0.78 + pathname: E/ET/ETHER/MooseX-Getopt-0.78.tar.gz + provides: + MooseX::Getopt 0.78 + MooseX::Getopt::Basic 0.78 + MooseX::Getopt::Dashes 0.78 + MooseX::Getopt::GLD 0.78 + MooseX::Getopt::Meta::Attribute 0.78 + MooseX::Getopt::Meta::Attribute::NoGetopt 0.78 + MooseX::Getopt::Meta::Attribute::Trait 0.78 + MooseX::Getopt::Meta::Attribute::Trait::NoGetopt 0.78 + MooseX::Getopt::OptionTypeMap 0.78 + MooseX::Getopt::ProcessedArgv 0.78 + MooseX::Getopt::Strict 0.78 requirements: Carp 0 Getopt::Long 2.37 @@ -5442,22 +4670,22 @@ DISTRIBUTIONS perl 5.006 strict 0 warnings 0 - MooseX-MethodAttributes-0.31 - pathname: E/ET/ETHER/MooseX-MethodAttributes-0.31.tar.gz + MooseX-MethodAttributes-0.32 + pathname: E/ET/ETHER/MooseX-MethodAttributes-0.32.tar.gz provides: - MooseX::MethodAttributes 0.31 - MooseX::MethodAttributes::Inheritable 0.31 - MooseX::MethodAttributes::Role 0.31 - MooseX::MethodAttributes::Role::AttrContainer 0.31 - MooseX::MethodAttributes::Role::AttrContainer::Inheritable 0.31 - MooseX::MethodAttributes::Role::Meta::Class 0.31 - MooseX::MethodAttributes::Role::Meta::Map 0.31 - MooseX::MethodAttributes::Role::Meta::Method 0.31 - MooseX::MethodAttributes::Role::Meta::Method::MaybeWrapped 0.31 - MooseX::MethodAttributes::Role::Meta::Method::Wrapped 0.31 - MooseX::MethodAttributes::Role::Meta::Role 0.31 - MooseX::MethodAttributes::Role::Meta::Role::Application 0.31 - MooseX::MethodAttributes::Role::Meta::Role::Application::Summation 0.31 + MooseX::MethodAttributes 0.32 + MooseX::MethodAttributes::Inheritable 0.32 + MooseX::MethodAttributes::Role 0.32 + MooseX::MethodAttributes::Role::AttrContainer 0.32 + MooseX::MethodAttributes::Role::AttrContainer::Inheritable 0.32 + MooseX::MethodAttributes::Role::Meta::Class 0.32 + MooseX::MethodAttributes::Role::Meta::Map 0.32 + MooseX::MethodAttributes::Role::Meta::Method 0.32 + MooseX::MethodAttributes::Role::Meta::Method::MaybeWrapped 0.32 + MooseX::MethodAttributes::Role::Meta::Method::Wrapped 0.32 + MooseX::MethodAttributes::Role::Meta::Role 0.32 + MooseX::MethodAttributes::Role::Meta::Role::Application 0.32 + MooseX::MethodAttributes::Role::Meta::Role::Application::Summation 0.32 requirements: Carp 0 ExtUtils::MakeMaker 0 @@ -5466,29 +4694,20 @@ DISTRIBUTIONS Moose::Role 0 Moose::Util 0 Moose::Util::MetaRole 0 - MooseX::Types::Moose 0.21 namespace::autoclean 0.08 perl 5.006 - MooseX-RelatedClassRoles-0.004 - pathname: H/HD/HDP/MooseX-RelatedClassRoles-0.004.tar.gz - provides: - MooseX::RelatedClassRoles 0.004 - requirements: - Class::MOP 0.80 - ExtUtils::MakeMaker 0 - Moose 0.73 - MooseX::Role::Parameterized 0.04 - MooseX-Role-Parameterized-1.10 - pathname: E/ET/ETHER/MooseX-Role-Parameterized-1.10.tar.gz + MooseX-Role-Parameterized-1.11 + pathname: E/ET/ETHER/MooseX-Role-Parameterized-1.11.tar.gz provides: - MooseX::Role::Parameterised 1.10 - MooseX::Role::Parameterized 1.10 - MooseX::Role::Parameterized::Meta::Role::Parameterized 1.10 - MooseX::Role::Parameterized::Meta::Trait::Parameterizable 1.10 - MooseX::Role::Parameterized::Meta::Trait::Parameterized 1.10 - MooseX::Role::Parameterized::Parameters 1.10 + MooseX::Role::Parameterised 1.11 + MooseX::Role::Parameterized 1.11 + MooseX::Role::Parameterized::Meta::Role::Parameterized 1.11 + MooseX::Role::Parameterized::Meta::Trait::Parameterizable 1.11 + MooseX::Role::Parameterized::Meta::Trait::Parameterized 1.11 + MooseX::Role::Parameterized::Parameters 1.11 requirements: Carp 0 + ExtUtils::MakeMaker 0 Module::Build::Tiny 0.034 Module::Runtime 0 Moose 2.0300 @@ -5517,31 +4736,18 @@ DISTRIBUTIONS namespace::autoclean 0 strict 0 warnings 0 - MooseX-Traits-Pluggable-0.12 - pathname: R/RK/RKITOVER/MooseX-Traits-Pluggable-0.12.tar.gz + MooseX-Types-0.51 + pathname: E/ET/ETHER/MooseX-Types-0.51.tar.gz provides: - MooseX::Traits::Pluggable 0.12 - requirements: - Carp 0 - Class::Load 0 - ExtUtils::MakeMaker 6.30 - List::MoreUtils 0 - Moose::Role 0 - Moose::Util 0 - Scalar::Util 0 - namespace::autoclean 0 - MooseX-Types-0.50 - pathname: E/ET/ETHER/MooseX-Types-0.50.tar.gz - provides: - MooseX::Types 0.50 - MooseX::Types::Base 0.50 - MooseX::Types::CheckedUtilExports 0.50 - MooseX::Types::Combine 0.50 - MooseX::Types::Moose 0.50 - MooseX::Types::TypeDecorator 0.50 - MooseX::Types::UndefinedType 0.50 - MooseX::Types::Util 0.50 - MooseX::Types::Wrapper 0.50 + MooseX::Types 0.51 + MooseX::Types::Base 0.51 + MooseX::Types::CheckedUtilExports 0.51 + MooseX::Types::Combine 0.51 + MooseX::Types::Moose 0.51 + MooseX::Types::TypeDecorator 0.51 + MooseX::Types::UndefinedType 0.51 + MooseX::Types::Util 0.51 + MooseX::Types::Wrapper 0.51 requirements: Carp 0 Carp::Clan 6.00 @@ -5556,25 +4762,11 @@ DISTRIBUTIONS Sub::Exporter 0 Sub::Exporter::ForMethods 0.100052 Sub::Install 0 - Sub::Name 0 + Sub::Util 0 base 0 namespace::autoclean 0.16 overload 0 - perl 5.008 - strict 0 - warnings 0 - MooseX-Types-Common-0.001014 - pathname: E/ET/ETHER/MooseX-Types-Common-0.001014.tar.gz - provides: - MooseX::Types::Common 0.001014 - MooseX::Types::Common::Numeric 0.001014 - MooseX::Types::Common::String 0.001014 - requirements: - Carp 0 - Module::Build::Tiny 0.034 - MooseX::Types 0 - MooseX::Types::Moose 0 - if 0 + parent 0 perl 5.008 strict 0 warnings 0 @@ -5588,47 +4780,6 @@ DISTRIBUTIONS Module::Build 0.3601 MooseX::Types 0 Search::Elasticsearch 0 - MooseX-Types-Path-Class-0.09 - pathname: E/ET/ETHER/MooseX-Types-Path-Class-0.09.tar.gz - provides: - MooseX::Types::Path::Class 0.09 - requirements: - Module::Build::Tiny 0.034 - MooseX::Types 0 - MooseX::Types::Moose 0 - Path::Class 0.16 - if 0 - perl 5.006 - strict 0 - warnings 0 - MooseX-Types-Path-Class-MoreCoercions-0.003 - pathname: D/DA/DAGOLDEN/MooseX-Types-Path-Class-MoreCoercions-0.003.tar.gz - provides: - MooseX::Types::Path::Class::MoreCoercions 0.003 - requirements: - ExtUtils::MakeMaker 6.30 - File::Find 0 - File::Temp 0 - File::pushd 0 - Moose 0 - MooseX::Types 0 - MooseX::Types::Path::Class 0 - MooseX::Types::Stringlike 0 - Path::Class 0 - Test::More 0.96 - strict 0 - warnings 0 - MooseX-Types-Stringlike-0.003 - pathname: D/DA/DAGOLDEN/MooseX-Types-Stringlike-0.003.tar.gz - provides: - MooseX::Types::Stringlike 0.003 - requirements: - ExtUtils::MakeMaker 6.17 - MooseX::Types 0 - MooseX::Types::Moose 0 - overload 0 - strict 0 - warnings 0 MooseX-Types-Structured-0.36 pathname: E/ET/ETHER/MooseX-Types-Structured-0.36.tar.gz provides: @@ -5648,207 +4799,154 @@ DISTRIBUTIONS namespace::clean 0.19 overload 0 perl 5.008 - MooseX-Types-URI-0.08 - pathname: E/ET/ETHER/MooseX-Types-URI-0.08.tar.gz - provides: - MooseX::Types::URI 0.08 - requirements: - Module::Build::Tiny 0.007 - MooseX::Types 0.40 - MooseX::Types::Moose 0 - MooseX::Types::Path::Class 0 - Scalar::Util 0 - URI 0 - URI::FromHash 0 - URI::QueryParam 0 - URI::WithBase 0 - URI::data 0 - URI::file 0 - if 0 - namespace::autoclean 0 - perl 5.006 - strict 0 - warnings 0 - Mouse-v2.4.10 - pathname: G/GF/GFUJI/Mouse-v2.4.10.tar.gz - provides: - Mouse v2.4.10 - Mouse::Exporter undef - Mouse::Meta::Attribute undef - Mouse::Meta::Class undef - Mouse::Meta::Method undef - Mouse::Meta::Method::Accessor undef - Mouse::Meta::Method::Constructor undef - Mouse::Meta::Method::Delegation undef - Mouse::Meta::Method::Destructor undef - Mouse::Meta::Module undef - Mouse::Meta::Role undef - Mouse::Meta::Role::Application undef - Mouse::Meta::Role::Application::RoleSummation undef - Mouse::Meta::Role::Composite undef - Mouse::Meta::Role::Method undef - Mouse::Meta::TypeConstraint undef - Mouse::Object undef - Mouse::PurePerl undef - Mouse::Role v2.4.10 - Mouse::Spec v2.4.10 - Mouse::TypeRegistry undef - Mouse::Util v2.4.10 - Mouse::Util::MetaRole undef - Mouse::Util::TypeConstraints undef - Squirrel undef - Squirrel::Role undef - Test::Mouse undef - ouse undef - requirements: - ExtUtils::CBuilder 0 - Module::Build 0.4005 - Module::Build::XSUtil 0.18 - Scalar::Util 1.14 - XSLoader 0.02 - perl 5.008005 - Mozilla-CA-20160104 - pathname: A/AB/ABH/Mozilla-CA-20160104.tar.gz - provides: - Mozilla::CA 20160104 - requirements: - ExtUtils::MakeMaker 0 - Test 0 - perl 5.006 - Net-CIDR-Lite-0.21 - pathname: D/DO/DOUGW/Net-CIDR-Lite-0.21.tar.gz - provides: - Net::CIDR::Lite 0.21 - Net::CIDR::Lite::Span 0.21 - requirements: - ExtUtils::MakeMaker 0 - Net-DNS-1.13 - pathname: N/NL/NLNETLABS/Net-DNS-1.13.tar.gz - provides: - Net::DNS 1.13 - Net::DNS::Domain 1603 - Net::DNS::DomainName 1558 - Net::DNS::DomainName1035 1558 - Net::DNS::DomainName2535 1558 - Net::DNS::Header 1527 - Net::DNS::Mailbox 1527 - Net::DNS::Mailbox1035 1527 - Net::DNS::Mailbox2535 1527 - Net::DNS::Nameserver 1593 - Net::DNS::Packet 1584 - Net::DNS::Parameters 1598 - Net::DNS::Question 1530 - Net::DNS::RR 1597 - Net::DNS::RR::A 1597 - Net::DNS::RR::AAAA 1597 - Net::DNS::RR::AFSDB 1597 - Net::DNS::RR::APL 1597 - Net::DNS::RR::APL::Item 1597 - Net::DNS::RR::CAA 1597 - Net::DNS::RR::CDNSKEY 1586 - Net::DNS::RR::CDS 1586 - Net::DNS::RR::CERT 1597 - Net::DNS::RR::CNAME 1597 - Net::DNS::RR::CSYNC 1597 - Net::DNS::RR::DHCID 1597 - Net::DNS::RR::DLV 1528 - Net::DNS::RR::DNAME 1597 - Net::DNS::RR::DNSKEY 1597 - Net::DNS::RR::DS 1597 - Net::DNS::RR::EUI48 1597 - Net::DNS::RR::EUI64 1597 - Net::DNS::RR::GPOS 1528 - Net::DNS::RR::HINFO 1597 - Net::DNS::RR::HIP 1597 - Net::DNS::RR::IPSECKEY 1597 - Net::DNS::RR::ISDN 1597 - Net::DNS::RR::KEY 1528 - Net::DNS::RR::KX 1597 - Net::DNS::RR::L32 1597 - Net::DNS::RR::L64 1597 - Net::DNS::RR::LOC 1597 - Net::DNS::RR::LP 1597 - Net::DNS::RR::MB 1528 - Net::DNS::RR::MG 1528 - Net::DNS::RR::MINFO 1597 - Net::DNS::RR::MR 1528 - Net::DNS::RR::MX 1597 - Net::DNS::RR::NAPTR 1597 - Net::DNS::RR::NID 1597 - Net::DNS::RR::NS 1597 - Net::DNS::RR::NSEC 1597 - Net::DNS::RR::NSEC3 1597 - Net::DNS::RR::NSEC3PARAM 1597 - Net::DNS::RR::NULL 1528 - Net::DNS::RR::OPENPGPKEY 1597 - Net::DNS::RR::OPT 1578 - Net::DNS::RR::OPT::CHAIN 1578 - Net::DNS::RR::OPT::CLIENT_SUBNET 1578 - Net::DNS::RR::OPT::COOKIE 1578 - Net::DNS::RR::OPT::DAU 1578 - Net::DNS::RR::OPT::DHU 1578 - Net::DNS::RR::OPT::EXPIRE 1578 - Net::DNS::RR::OPT::KEY_TAG 1578 - Net::DNS::RR::OPT::N3U 1578 - Net::DNS::RR::OPT::PADDING 1578 - Net::DNS::RR::OPT::TCP_KEEPALIVE 1578 - Net::DNS::RR::PTR 1597 - Net::DNS::RR::PX 1597 - Net::DNS::RR::RP 1597 - Net::DNS::RR::RRSIG 1597 - Net::DNS::RR::RT 1597 - Net::DNS::RR::SIG 1597 - Net::DNS::RR::SMIMEA 1597 - Net::DNS::RR::SOA 1597 - Net::DNS::RR::SPF 1593 - Net::DNS::RR::SRV 1597 - Net::DNS::RR::SSHFP 1597 - Net::DNS::RR::TKEY 1528 - Net::DNS::RR::TLSA 1597 - Net::DNS::RR::TSIG 1597 - Net::DNS::RR::TXT 1597 - Net::DNS::RR::URI 1597 - Net::DNS::RR::X25 1597 - Net::DNS::Resolver 1598 - Net::DNS::Resolver::Base 1595 - Net::DNS::Resolver::MSWin32 1568 - Net::DNS::Resolver::Recurse 1555 - Net::DNS::Resolver::UNIX 1573 - Net::DNS::Resolver::android 1568 - Net::DNS::Resolver::cygwin 1568 - Net::DNS::Resolver::os2 1568 - Net::DNS::Resolver::os390 1579 - Net::DNS::Text 1601 - Net::DNS::Update 1571 - Net::DNS::ZoneFile 1526 - Net::DNS::ZoneFile::Generator 1526 - Net::DNS::ZoneFile::Text 1526 - requirements: + Mozilla-CA-20250202 + pathname: L/LW/LWP/Mozilla-CA-20250202.tar.gz + provides: + Mozilla::CA 20250202 + requirements: + ExtUtils::MakeMaker 0 + Net-DNS-1.50 + pathname: N/NL/NLNETLABS/Net-DNS-1.50.tar.gz + provides: + Net::DNS 1.50 + Net::DNS::Domain 2002 + Net::DNS::DomainName 2005 + Net::DNS::DomainName1035 2005 + Net::DNS::DomainName2535 2005 + Net::DNS::Header 2002 + Net::DNS::Mailbox 2002 + Net::DNS::Mailbox1035 2002 + Net::DNS::Mailbox2535 2002 + Net::DNS::Nameserver 2002 + Net::DNS::Packet 2003 + Net::DNS::Parameters 2002 + Net::DNS::Question 2002 + Net::DNS::RR 2003 + Net::DNS::RR::A 2003 + Net::DNS::RR::AAAA 2003 + Net::DNS::RR::AFSDB 2002 + Net::DNS::RR::AMTRELAY 2003 + Net::DNS::RR::APL 2003 + Net::DNS::RR::APL::Item 2003 + Net::DNS::RR::CAA 2003 + Net::DNS::RR::CDNSKEY 2003 + Net::DNS::RR::CDS 2003 + Net::DNS::RR::CERT 2002 + Net::DNS::RR::CNAME 2003 + Net::DNS::RR::CSYNC 2003 + Net::DNS::RR::DELEG 2003 + Net::DNS::RR::DHCID 2003 + Net::DNS::RR::DNAME 2003 + Net::DNS::RR::DNSKEY 2003 + Net::DNS::RR::DS 2003 + Net::DNS::RR::DSYNC 2003 + Net::DNS::RR::EUI48 2003 + Net::DNS::RR::EUI64 2003 + Net::DNS::RR::GPOS 2003 + Net::DNS::RR::HINFO 2003 + Net::DNS::RR::HIP 2003 + Net::DNS::RR::HTTPS 2002 + Net::DNS::RR::IPSECKEY 2003 + Net::DNS::RR::ISDN 2002 + Net::DNS::RR::KEY 2002 + Net::DNS::RR::KX 2003 + Net::DNS::RR::L32 2003 + Net::DNS::RR::L64 2003 + Net::DNS::RR::LOC 2003 + Net::DNS::RR::LP 2003 + Net::DNS::RR::MB 2002 + Net::DNS::RR::MG 2002 + Net::DNS::RR::MINFO 2002 + Net::DNS::RR::MR 2002 + Net::DNS::RR::MX 2002 + Net::DNS::RR::NAPTR 2003 + Net::DNS::RR::NID 2003 + Net::DNS::RR::NS 2003 + Net::DNS::RR::NSEC 2002 + Net::DNS::RR::NSEC3 2003 + Net::DNS::RR::NSEC3PARAM 2003 + Net::DNS::RR::NULL 2002 + Net::DNS::RR::OPENPGPKEY 2003 + Net::DNS::RR::OPT 2005 + Net::DNS::RR::OPT::CHAIN 2005 + Net::DNS::RR::OPT::CLIENT_SUBNET 2005 + Net::DNS::RR::OPT::COOKIE 2005 + Net::DNS::RR::OPT::DAU 2005 + Net::DNS::RR::OPT::DHU 2005 + Net::DNS::RR::OPT::EXPIRE 2005 + Net::DNS::RR::OPT::EXTENDED_ERROR 2005 + Net::DNS::RR::OPT::KEY_TAG 2005 + Net::DNS::RR::OPT::N3U 2005 + Net::DNS::RR::OPT::NSID 2005 + Net::DNS::RR::OPT::PADDING 2005 + Net::DNS::RR::OPT::REPORT_CHANNEL 2005 + Net::DNS::RR::OPT::TCP_KEEPALIVE 2005 + Net::DNS::RR::OPT::ZONEVERSION 2005 + Net::DNS::RR::PTR 2002 + Net::DNS::RR::PX 2003 + Net::DNS::RR::RESINFO 2003 + Net::DNS::RR::RP 2002 + Net::DNS::RR::RRSIG 2003 + Net::DNS::RR::RT 2003 + Net::DNS::RR::SIG 2003 + Net::DNS::RR::SMIMEA 2003 + Net::DNS::RR::SOA 2002 + Net::DNS::RR::SPF 2003 + Net::DNS::RR::SRV 2003 + Net::DNS::RR::SSHFP 2003 + Net::DNS::RR::SVCB 2003 + Net::DNS::RR::TKEY 2003 + Net::DNS::RR::TLSA 2003 + Net::DNS::RR::TSIG 2003 + Net::DNS::RR::TXT 2003 + Net::DNS::RR::URI 2003 + Net::DNS::RR::X25 2002 + Net::DNS::RR::ZONEMD 2003 + Net::DNS::Resolver 2009 + Net::DNS::Resolver::Base 2011 + Net::DNS::Resolver::MSWin32 2002 + Net::DNS::Resolver::Recurse 2002 + Net::DNS::Resolver::UNIX 2007 + Net::DNS::Resolver::android 2007 + Net::DNS::Resolver::cygwin 2002 + Net::DNS::Resolver::os2 2007 + Net::DNS::Resolver::os390 2007 + Net::DNS::Text 2002 + Net::DNS::Update 2003 + Net::DNS::ZoneFile 2002 + Net::DNS::ZoneFile::Generator 2002 + Net::DNS::ZoneFile::Text 2002 + requirements: + Carp 1.1 + Config 0 Digest::HMAC 1.03 - Digest::MD5 2.13 + Digest::MD5 2.37 Digest::SHA 5.23 - ExtUtils::MakeMaker 0 - File::Spec 0.86 - IO::Socket 1.16 - MIME::Base64 2.11 - Test::More 0.52 + Encode 2.26 + Exporter 5.63 + ExtUtils::MakeMaker 6.48 + File::Spec 3.29 + Getopt::Long 2.43 + IO::File 1.14 + IO::Select 1.17 + IO::Socket 1.3 + IO::Socket::IP 0.38 + MIME::Base64 3.07 + PerlIO 1.05 + Scalar::Util 1.19 + Socket 1.81 Time::Local 1.19 - perl 5.006 - Net-DNS-Paranoid-0.08 - pathname: T/TO/TOKUHIROM/Net-DNS-Paranoid-0.08.tar.gz - provides: - Net::DNS::Paranoid 0.08 - requirements: - Class::Accessor::Lite 0.05 - Module::Build 0.38 - Net::DNS 0.68 - Test::More 0.98 - parent 0 - perl 5.008008 - Net-Fastly-1.09 - pathname: F/FA/FASTLY/Net-Fastly-1.09.tar.gz + base 2.13 + constant 1.17 + integer 1 + overload 1.06 + perl 5.008009 + strict 1.03 + warnings 1.0501 + Net-Fastly-1.12 + pathname: F/FA/FASTLY/Net-Fastly-1.12.tar.gz provides: - Net::Fastly 1.09 + Net::Fastly 1.12 Net::Fastly::Backend undef Net::Fastly::BelongsToServiceAndVersion undef Net::Fastly::Client undef @@ -5884,13 +4982,45 @@ DISTRIBUTIONS URI 0 URI::Escape 0 YAML 0 - Net-HTTP-6.17 - pathname: O/OA/OALDERS/Net-HTTP-6.17.tar.gz + Net-GitHub-1.05 + pathname: F/FA/FAYLAND/Net-GitHub-1.05.tar.gz + provides: + Net::GitHub 1.05 + Net::GitHub::V3 1.05 + Net::GitHub::V3::Actions 1.05 + Net::GitHub::V3::Events 1.05 + Net::GitHub::V3::Gists 1.05 + Net::GitHub::V3::GitData 1.05 + Net::GitHub::V3::Gitignore 1.05 + Net::GitHub::V3::Issues 1.05 + Net::GitHub::V3::OAuth 1.05 + Net::GitHub::V3::Orgs 0.60 + Net::GitHub::V3::PullRequests 1.05 + Net::GitHub::V3::Query 1.05 + Net::GitHub::V3::Repos 1.05 + Net::GitHub::V3::ResultSet 1.05 + Net::GitHub::V3::Search 0.68 + Net::GitHub::V3::Users 1.05 + Net::GitHub::V4 1.05 + requirements: + Cache::LRU 0 + ExtUtils::MakeMaker 0 + HTTP::Request 0 + JSON::MaybeXS 0 + LWP::Protocol::https 0 + LWP::UserAgent 0 + MIME::Base64 0 + Moo 0 + Types::Standard 0 + URI 0 + URI::Escape 0 + Net-HTTP-6.23 + pathname: O/OA/OALDERS/Net-HTTP-6.23.tar.gz provides: - Net::HTTP 6.17 - Net::HTTP::Methods 6.17 - Net::HTTP::NB 6.17 - Net::HTTPS 6.17 + Net::HTTP 6.23 + Net::HTTP::Methods 6.23 + Net::HTTP::NB 6.23 + Net::HTTPS 6.23 requirements: Carp 0 Compress::Raw::Zlib 0 @@ -5901,20 +5031,25 @@ DISTRIBUTIONS base 0 perl 5.006002 strict 0 - vars 0 warnings 0 - Net-OAuth-0.28 - pathname: K/KG/KGRENNAN/Net-OAuth-0.28.tar.gz + Net-IP-1.26 + pathname: M/MA/MANU/Net-IP-1.26.tar.gz provides: - Net::OAuth 0.28 + Net::IP 1.26 + requirements: + ExtUtils::MakeMaker 0 + Net-OAuth-0.31 + pathname: R/RR/RRWO/Net-OAuth-0.31.tar.gz + provides: + Net::OAuth 0.31 Net::OAuth::AccessToken undef Net::OAuth::AccessTokenRequest undef Net::OAuth::AccessTokenResponse undef - Net::OAuth::Client undef + Net::OAuth::Client 0.31 Net::OAuth::ConsumerRequest undef Net::OAuth::Message undef Net::OAuth::ProtectedResourceRequest undef - Net::OAuth::Request 0.28 + Net::OAuth::Request 0.31 Net::OAuth::RequestTokenRequest undef Net::OAuth::RequestTokenResponse undef Net::OAuth::Response undef @@ -5933,178 +5068,26 @@ DISTRIBUTIONS requirements: Class::Accessor 0.31 Class::Data::Inheritable 0.06 - Digest::HMAC_SHA1 1.01 + Crypt::URandom 0.37 Digest::SHA 5.47 - Digest::SHA1 2.12 Encode 2.35 + ExtUtils::MakeMaker 0 LWP::UserAgent 1 Test::More 0.66 Test::Warn 0.21 - URI::Escape 3.28 - Net-OpenID-Common-1.20 - pathname: W/WR/WROG/Net-OpenID-Common-1.20.tar.gz - provides: - Net::OpenID::Common 1.20 - Net::OpenID::Extension 1.20 - Net::OpenID::Extension::SimpleRegistration 1.20 - Net::OpenID::Extension::SimpleRegistration::Request 1.20 - Net::OpenID::Extension::SimpleRegistration::Response 1.20 - Net::OpenID::ExtensionMessage 1.20 - Net::OpenID::IndirectMessage 1.20 - Net::OpenID::URIFetch 1.20 - Net::OpenID::URIFetch::Response 1.20 - Net::OpenID::Yadis 1.20 - Net::OpenID::Yadis::Service 1.20 - OpenID::util 1.20 - requirements: - Crypt::DH::GMP 0.00011 - Encode 0 - ExtUtils::MakeMaker 0 - HTML::Parser 3.40 - HTTP::Headers::Util 0 - HTTP::Message 5.814 - HTTP::Request 0 - HTTP::Status 0 - MIME::Base64 0 - Math::BigInt 0 - Time::Local 0 - XML::Simple 0 - Net-OpenID-Consumer-1.18 - pathname: W/WR/WROG/Net-OpenID-Consumer-1.18.tar.gz + URI 5.15 + Net-SSLeay-1.94 + pathname: C/CH/CHRISN/Net-SSLeay-1.94.tar.gz provides: - Net::OpenID::Association 1.18 - Net::OpenID::ClaimedIdentity 1.18 - Net::OpenID::Consumer 1.18 - Net::OpenID::VerifiedIdentity 1.18 + Net::SSLeay 1.94 + Net::SSLeay::Handle 1.94 requirements: - Digest::SHA 0 + English 0 ExtUtils::MakeMaker 0 - HTTP::Request 0 - JSON 0 - LWP::UserAgent 0 - MIME::Base64 0 - Net::OpenID::Common 1.19 - Storable 0 - Time::Local 0 - URI 0 - Net-OpenID-Server-1.09 - pathname: R/RO/ROBN/Net-OpenID-Server-1.09.tar.gz - provides: - Net::OpenID::Server 1.09 - requirements: - Digest::SHA 0 - ExtUtils::MakeMaker 6.31 - MIME::Base64 0 - Net::OpenID::Common 1.11 - Test::More 0 - URI 0 - Net-SSLeay-1.82 - pathname: M/MI/MIKEM/Net-SSLeay-1.82.tar.gz - provides: - Net::SSLeay 1.82 - Net::SSLeay::Handle 0.61 - requirements: - ExtUtils::MakeMaker 6.36 + File::Spec::Functions 0 MIME::Base64 0 - Test::More 0.60_01 - perl 5.005 - Net-Server-2.009 - pathname: R/RH/RHANDOM/Net-Server-2.009.tar.gz - provides: - Net::Server 2.009 - Net::Server::Daemonize 0.06 - Net::Server::Fork undef - Net::Server::HTTP undef - Net::Server::INET undef - Net::Server::INET::Handle undef - Net::Server::Log::Log::Log4perl undef - Net::Server::Log::Sys::Syslog undef - Net::Server::MultiType undef - Net::Server::Multiplex undef - Net::Server::Multiplex::MUX undef - Net::Server::PSGI undef - Net::Server::PreFork undef - Net::Server::PreForkSimple undef - Net::Server::Proto undef - Net::Server::Proto::SSL undef - Net::Server::Proto::SSLEAY undef - Net::Server::Proto::TCP undef - Net::Server::Proto::UDP undef - Net::Server::Proto::UNIX undef - Net::Server::Proto::UNIXDGRAM undef - Net::Server::SIG 0.03 - Net::Server::Single undef - Net::Server::TiedHandle 2.009 - requirements: - ExtUtils::MakeMaker 6.30 - File::Temp 0 - IO::Socket 0 - POSIX 0 - Socket 0 - Time::HiRes 0 - Net-Twitter-4.01042 - pathname: M/MM/MMIMS/Net-Twitter-4.01042.tar.gz - provides: - Net::Identica 4.01042 - Net::Twitter 4.01042 - Net::Twitter::API 4.01042 - Net::Twitter::Core 4.01042 - Net::Twitter::Error 4.01042 - Net::Twitter::Meta::Method 4.01042 - Net::Twitter::OAuth 4.01042 - Net::Twitter::Role::API::Lists 4.01042 - Net::Twitter::Role::API::REST 4.01042 - Net::Twitter::Role::API::RESTv1_1 4.01042 - Net::Twitter::Role::API::Search 4.01042 - Net::Twitter::Role::API::Search::Trends 4.01042 - Net::Twitter::Role::API::TwitterVision 4.01042 - Net::Twitter::Role::API::Upload 4.01042 - Net::Twitter::Role::API::UploadMedia 4.01042 - Net::Twitter::Role::AppAuth 4.01042 - Net::Twitter::Role::AutoCursor 4.01042 - Net::Twitter::Role::InflateObjects 4.01042 - Net::Twitter::Role::Legacy 4.01042 - Net::Twitter::Role::OAuth 4.01042 - Net::Twitter::Role::RateLimit 4.01042 - Net::Twitter::Role::RetryOnError 4.01042 - Net::Twitter::Role::SimulateCursors 4.01042 - Net::Twitter::Role::WrapError 4.01042 - Net::Twitter::Role::WrapResult 4.01042 - Net::Twitter::Search 4.01042 - Net::Twitter::Types 4.01042 - Net::Twitter::WrappedResult 4.01042 - requirements: - Carp::Clan 0 - Class::Load 0 - Data::Visitor::Callback 0 - DateTime 0 - DateTime::Format::Strptime 0 - Devel::StackTrace 0 - Digest::SHA 0 - Encode 0 - ExtUtils::MakeMaker 7.1101 - HTML::Entities 0 - HTTP::Request::Common 0 - IO::Socket::SSL 2.005 - JSON::MaybeXS 0 - LWP::Protocol::https 0 - List::Util 0 - Moose 0 - Moose::Exporter 0 - Moose::Meta::Method 0 - Moose::Role 0 - Moose::Util::TypeConstraints 0 - MooseX::Role::Parameterized 0 - Net::HTTP >= 0, != 6.04, != 6.05 - Net::Netrc 0 - Net::OAuth 0 - Scalar::Util 0 - Time::HiRes 0 - Try::Tiny 0 - URI 0 - URI::Escape 0 - namespace::autoclean 0 - overload 0 + Text::Wrap 0 + constant 0 perl 5.008001 Number-Compare-0.03 pathname: R/RC/RCLAMP/Number-Compare-0.03.tar.gz @@ -6113,21 +5096,23 @@ DISTRIBUTIONS requirements: ExtUtils::MakeMaker 0 Test::More 0 - Object-Signature-1.07 - pathname: A/AD/ADAMK/Object-Signature-1.07.tar.gz + Object-Signature-1.08 + pathname: E/ET/ETHER/Object-Signature-1.08.tar.gz provides: - Object::Signature 1.07 - Object::Signature::File 1.07 + Object::Signature 1.08 + Object::Signature::File 1.08 requirements: Digest::MD5 2.00 - ExtUtils::MakeMaker 6.42 + ExtUtils::MakeMaker 0 Storable 2.11 - Test::More 0.47 - perl 5.005 - OrePAN2-0.46 - pathname: O/OA/OALDERS/OrePAN2-0.46.tar.gz + base 0 + perl 5.006 + strict 0 + warnings 0 + OrePAN2-0.52 + pathname: O/OA/OALDERS/OrePAN2-0.52.tar.gz provides: - OrePAN2 0.46 + OrePAN2 0.52 OrePAN2::Auditor undef OrePAN2::CLI::Indexer undef OrePAN2::CLI::Inject undef @@ -6138,13 +5123,15 @@ DISTRIBUTIONS OrePAN2::Repository::Cache undef requirements: Archive::Extract 0.72 - Archive::Tar 0 - CPAN::Meta 2.13156 - Class::Accessor::Lite 0.05 + Archive::Tar 1.46 + CPAN::Meta 2.131560 Digest::MD5 0 + ExtUtils::MakeMaker 7.06 File::Path 0 + File::Spec 0 File::Temp 0 File::pushd 0 + File::stat 0 Getopt::Long 2.39 HTTP::Tiny 0 IO::File::AtomicChange 0 @@ -6158,31 +5145,23 @@ DISTRIBUTIONS Module::Build::Tiny 0.035 Moo 1.007000 MooX::Options 0 + MooX::StrictConstructor 0 Parse::CPAN::Meta 1.4414 - Parse::CPAN::Packages 2.39 + Parse::CPAN::Packages::Fast 0.09 Parse::LocalDistribution 0.14 - Parse::PMFile 0.29 Path::Tiny 0 Pod::Usage 0 - Ref::Util 0 Try::Tiny 0 - Type::Params 0 + Type::Tiny 2.000000 + Types::Path::Tiny 0 + Types::Self 0 Types::URI 0 autodie 0 + feature 0 + namespace::clean 0 parent 0 - perl 5.008005 + perl 5.012000 version 0.9912 - Ouch-0.0500 - pathname: R/RI/RIZEN/Ouch-0.0500.tar.gz - provides: - Ouch 0.0500 - requirements: - Carp 0 - ExtUtils::MakeMaker 0 - Test::More 0 - Test::Trap 0 - overload 0 - parent 0 PAUSE-Permissions-0.17 pathname: N/NE/NEILB/PAUSE-Permissions-0.17.tar.gz provides: @@ -6207,237 +5186,271 @@ DISTRIBUTIONS perl 5.010000 strict 0 warnings 0 - POSIX-strftime-Compiler-0.42 - pathname: K/KA/KAZEBURO/POSIX-strftime-Compiler-0.42.tar.gz + POSIX-strftime-Compiler-0.46 + pathname: K/KA/KAZEBURO/POSIX-strftime-Compiler-0.46.tar.gz provides: - POSIX::strftime::Compiler 0.42 + POSIX::strftime::Compiler 0.46 requirements: Carp 0 Exporter 0 - Module::Build 0.38 + Module::Build::Tiny 0.035 POSIX 0 Time::Local 0 perl 5.008001 - PPI-1.236 - pathname: M/MI/MITHALDU/PPI-1.236.tar.gz - provides: - PPI 1.236 - PPI::Cache 1.236 - PPI::Document 1.236 - PPI::Document::File 1.236 - PPI::Document::Fragment 1.236 - PPI::Document::Normalized 1.236 - PPI::Dumper 1.236 - PPI::Element 1.236 - PPI::Exception 1.236 - PPI::Exception::ParserRejection 1.236 - PPI::Find 1.236 - PPI::Lexer 1.236 - PPI::Node 1.236 - PPI::Normal 1.236 - PPI::Normal::Standard 1.236 - PPI::Statement 1.236 - PPI::Statement::Break 1.236 - PPI::Statement::Compound 1.236 - PPI::Statement::Data 1.236 - PPI::Statement::End 1.236 - PPI::Statement::Expression 1.236 - PPI::Statement::Given 1.236 - PPI::Statement::Include 1.236 - PPI::Statement::Include::Perl6 1.236 - PPI::Statement::Null 1.236 - PPI::Statement::Package 1.236 - PPI::Statement::Scheduled 1.236 - PPI::Statement::Sub 1.236 - PPI::Statement::Unknown 1.236 - PPI::Statement::UnmatchedBrace 1.236 - PPI::Statement::Variable 1.236 - PPI::Statement::When 1.236 - PPI::Structure 1.236 - PPI::Structure::Block 1.236 - PPI::Structure::Condition 1.236 - PPI::Structure::Constructor 1.236 - PPI::Structure::For 1.236 - PPI::Structure::Given 1.236 - PPI::Structure::List 1.236 - PPI::Structure::Subscript 1.236 - PPI::Structure::Unknown 1.236 - PPI::Structure::When 1.236 - PPI::Token 1.236 - PPI::Token::ArrayIndex 1.236 - PPI::Token::Attribute 1.236 - PPI::Token::BOM 1.236 - PPI::Token::Cast 1.236 - PPI::Token::Comment 1.236 - PPI::Token::DashedWord 1.236 - PPI::Token::Data 1.236 - PPI::Token::End 1.236 - PPI::Token::HereDoc 1.236 - PPI::Token::Label 1.236 - PPI::Token::Magic 1.236 - PPI::Token::Number 1.236 - PPI::Token::Number::Binary 1.236 - PPI::Token::Number::Exp 1.236 - PPI::Token::Number::Float 1.236 - PPI::Token::Number::Hex 1.236 - PPI::Token::Number::Octal 1.236 - PPI::Token::Number::Version 1.236 - PPI::Token::Operator 1.236 - PPI::Token::Pod 1.236 - PPI::Token::Prototype 1.236 - PPI::Token::Quote 1.236 - PPI::Token::Quote::Double 1.236 - PPI::Token::Quote::Interpolate 1.236 - PPI::Token::Quote::Literal 1.236 - PPI::Token::Quote::Single 1.236 - PPI::Token::QuoteLike 1.236 - PPI::Token::QuoteLike::Backtick 1.236 - PPI::Token::QuoteLike::Command 1.236 - PPI::Token::QuoteLike::Readline 1.236 - PPI::Token::QuoteLike::Regexp 1.236 - PPI::Token::QuoteLike::Words 1.236 - PPI::Token::Regexp 1.236 - PPI::Token::Regexp::Match 1.236 - PPI::Token::Regexp::Substitute 1.236 - PPI::Token::Regexp::Transliterate 1.236 - PPI::Token::Separator 1.236 - PPI::Token::Structure 1.236 - PPI::Token::Symbol 1.236 - PPI::Token::Unknown 1.236 - PPI::Token::Whitespace 1.236 - PPI::Token::Word 1.236 - PPI::Token::_QuoteEngine 1.236 - PPI::Token::_QuoteEngine::Full 1.236 - PPI::Token::_QuoteEngine::Simple 1.236 - PPI::Tokenizer 1.236 - PPI::Transform 1.236 - PPI::Transform::UpdateCopyright 1.236 - PPI::Util 1.236 - PPI::XSAccessor 1.236 - requirements: - Class::Inspector 1.22 + PPI-1.281 + pathname: M/MI/MITHALDU/PPI-1.281.tar.gz + provides: + PPI 1.281 + PPI::Cache 1.281 + PPI::Document 1.281 + PPI::Document::File 1.281 + PPI::Document::Fragment 1.281 + PPI::Document::Normalized 1.281 + PPI::Dumper 1.281 + PPI::Element 1.281 + PPI::Exception 1.281 + PPI::Exception::ParserRejection 1.281 + PPI::Find 1.281 + PPI::Lexer 1.281 + PPI::Node 1.281 + PPI::Normal 1.281 + PPI::Normal::Standard 1.281 + PPI::Singletons 1.281 + PPI::Statement 1.281 + PPI::Statement::Break 1.281 + PPI::Statement::Compound 1.281 + PPI::Statement::Data 1.281 + PPI::Statement::End 1.281 + PPI::Statement::Expression 1.281 + PPI::Statement::Given 1.281 + PPI::Statement::Include 1.281 + PPI::Statement::Include::Perl6 1.281 + PPI::Statement::Null 1.281 + PPI::Statement::Package 1.281 + PPI::Statement::Scheduled 1.281 + PPI::Statement::Sub 1.281 + PPI::Statement::Unknown 1.281 + PPI::Statement::UnmatchedBrace 1.281 + PPI::Statement::Variable 1.281 + PPI::Statement::When 1.281 + PPI::Structure 1.281 + PPI::Structure::Block 1.281 + PPI::Structure::Condition 1.281 + PPI::Structure::Constructor 1.281 + PPI::Structure::For 1.281 + PPI::Structure::Given 1.281 + PPI::Structure::List 1.281 + PPI::Structure::Signature 1.281 + PPI::Structure::Subscript 1.281 + PPI::Structure::Unknown 1.281 + PPI::Structure::When 1.281 + PPI::Token 1.281 + PPI::Token::ArrayIndex 1.281 + PPI::Token::Attribute 1.281 + PPI::Token::BOM 1.281 + PPI::Token::Cast 1.281 + PPI::Token::Comment 1.281 + PPI::Token::DashedWord 1.281 + PPI::Token::Data 1.281 + PPI::Token::End 1.281 + PPI::Token::HereDoc 1.281 + PPI::Token::Label 1.281 + PPI::Token::Magic 1.281 + PPI::Token::Number 1.281 + PPI::Token::Number::Binary 1.281 + PPI::Token::Number::Exp 1.281 + PPI::Token::Number::Float 1.281 + PPI::Token::Number::Hex 1.281 + PPI::Token::Number::Octal 1.281 + PPI::Token::Number::Version 1.281 + PPI::Token::Operator 1.281 + PPI::Token::Pod 1.281 + PPI::Token::Prototype 1.281 + PPI::Token::Quote 1.281 + PPI::Token::Quote::Double 1.281 + PPI::Token::Quote::Interpolate 1.281 + PPI::Token::Quote::Literal 1.281 + PPI::Token::Quote::Single 1.281 + PPI::Token::QuoteLike 1.281 + PPI::Token::QuoteLike::Backtick 1.281 + PPI::Token::QuoteLike::Command 1.281 + PPI::Token::QuoteLike::Readline 1.281 + PPI::Token::QuoteLike::Regexp 1.281 + PPI::Token::QuoteLike::Words 1.281 + PPI::Token::Regexp 1.281 + PPI::Token::Regexp::Match 1.281 + PPI::Token::Regexp::Substitute 1.281 + PPI::Token::Regexp::Transliterate 1.281 + PPI::Token::Separator 1.281 + PPI::Token::Structure 1.281 + PPI::Token::Symbol 1.281 + PPI::Token::Unknown 1.281 + PPI::Token::Whitespace 1.281 + PPI::Token::Word 1.281 + PPI::Tokenizer 1.281 + PPI::Transform 1.281 + PPI::Transform::UpdateCopyright 1.281 + PPI::Util 1.281 + PPI::XSAccessor 1.281 + requirements: + Carp 0 Clone 0.30 Digest::MD5 2.35 - ExtUtils::MakeMaker 6.59 - File::Remove 1.42 + Exporter 0 + ExtUtils::MakeMaker 0 + File::Path 0 File::Spec 0.84 - IO::String 1.07 - List::MoreUtils 0.16 List::Util 1.33 Params::Util 1.00 + Safe::Isa 0 + Scalar::Util 0 Storable 2.17 Task::Weaken 0 - Test::Deep 0 - Test::More 0.86 - Test::Object 0.07 - Test::SubCalls 1.07 + YAML::PP 0 + constant 0 + if 0 + overload 0 perl 5.006 - PPIx-Regexp-0.053 - pathname: W/WY/WYANT/PPIx-Regexp-0.053.tar.gz - provides: - PPIx::Regexp 0.053 - PPIx::Regexp::Constant 0.053 - PPIx::Regexp::Dumper 0.053 - PPIx::Regexp::Element 0.053 - PPIx::Regexp::Lexer 0.053 - PPIx::Regexp::Node 0.053 - PPIx::Regexp::Node::Range 0.053 - PPIx::Regexp::Node::Unknown 0.053 - PPIx::Regexp::StringTokenizer 0.053 - PPIx::Regexp::Structure 0.053 - PPIx::Regexp::Structure::Assertion 0.053 - PPIx::Regexp::Structure::BranchReset 0.053 - PPIx::Regexp::Structure::Capture 0.053 - PPIx::Regexp::Structure::CharClass 0.053 - PPIx::Regexp::Structure::Code 0.053 - PPIx::Regexp::Structure::Main 0.053 - PPIx::Regexp::Structure::Modifier 0.053 - PPIx::Regexp::Structure::NamedCapture 0.053 - PPIx::Regexp::Structure::Quantifier 0.053 - PPIx::Regexp::Structure::RegexSet 0.053 - PPIx::Regexp::Structure::Regexp 0.053 - PPIx::Regexp::Structure::Replacement 0.053 - PPIx::Regexp::Structure::Subexpression 0.053 - PPIx::Regexp::Structure::Switch 0.053 - PPIx::Regexp::Structure::Unknown 0.053 - PPIx::Regexp::Support 0.053 - PPIx::Regexp::Token 0.053 - PPIx::Regexp::Token::Assertion 0.053 - PPIx::Regexp::Token::Backreference 0.053 - PPIx::Regexp::Token::Backtrack 0.053 - PPIx::Regexp::Token::CharClass 0.053 - PPIx::Regexp::Token::CharClass::POSIX 0.053 - PPIx::Regexp::Token::CharClass::POSIX::Unknown 0.053 - PPIx::Regexp::Token::CharClass::Simple 0.053 - PPIx::Regexp::Token::Code 0.053 - PPIx::Regexp::Token::Comment 0.053 - PPIx::Regexp::Token::Condition 0.053 - PPIx::Regexp::Token::Control 0.053 - PPIx::Regexp::Token::Delimiter 0.053 - PPIx::Regexp::Token::Greediness 0.053 - PPIx::Regexp::Token::GroupType 0.053 - PPIx::Regexp::Token::GroupType::Assertion 0.053 - PPIx::Regexp::Token::GroupType::BranchReset 0.053 - PPIx::Regexp::Token::GroupType::Code 0.053 - PPIx::Regexp::Token::GroupType::Modifier 0.053 - PPIx::Regexp::Token::GroupType::NamedCapture 0.053 - PPIx::Regexp::Token::GroupType::Subexpression 0.053 - PPIx::Regexp::Token::GroupType::Switch 0.053 - PPIx::Regexp::Token::Interpolation 0.053 - PPIx::Regexp::Token::Literal 0.053 - PPIx::Regexp::Token::Modifier 0.053 - PPIx::Regexp::Token::NoOp 0.053 - PPIx::Regexp::Token::Operator 0.053 - PPIx::Regexp::Token::Quantifier 0.053 - PPIx::Regexp::Token::Recursion 0.053 - PPIx::Regexp::Token::Reference 0.053 - PPIx::Regexp::Token::Structure 0.053 - PPIx::Regexp::Token::Unknown 0.053 - PPIx::Regexp::Token::Unmatched 0.053 - PPIx::Regexp::Token::Whitespace 0.053 - PPIx::Regexp::Tokenizer 0.053 - PPIx::Regexp::Util 0.053 + strict 0 + version 0.77 + PPIx-QuoteLike-0.023 + pathname: W/WY/WYANT/PPIx-QuoteLike-0.023.tar.gz + provides: + PPIx::QuoteLike 0.023 + PPIx::QuoteLike::Constant 0.023 + PPIx::QuoteLike::Dumper 0.023 + PPIx::QuoteLike::Token 0.023 + PPIx::QuoteLike::Token::Control 0.023 + PPIx::QuoteLike::Token::Delimiter 0.023 + PPIx::QuoteLike::Token::Interpolation 0.023 + PPIx::QuoteLike::Token::String 0.023 + PPIx::QuoteLike::Token::Structure 0.023 + PPIx::QuoteLike::Token::Unknown 0.023 + PPIx::QuoteLike::Token::Whitespace 0.023 + PPIx::QuoteLike::Utils 0.023 requirements: Carp 0 + Encode 0 Exporter 0 - List::MoreUtils 0 List::Util 0 - PPI::Document 1.117 + PPI::Document 1.238 + PPI::Dumper 1.238 + Readonly 0 Scalar::Util 0 - Task::Weaken 0 Test::More 0.88 base 0 + charnames 0 constant 0 + lib 0 perl 5.006 + re 0 strict 0 warnings 0 - PPIx-Utilities-1.001000 - pathname: E/EL/ELLIOTJS/PPIx-Utilities-1.001000.tar.gz - provides: - PPIx::Utilities 1.001000 - PPIx::Utilities::Exception::Bug 1.001000 - PPIx::Utilities::Node 1.001000 - PPIx::Utilities::Statement 1.001000 + PPIx-Regexp-0.088 + pathname: W/WY/WYANT/PPIx-Regexp-0.088.tar.gz + provides: + PPIx::Regexp 0.088 + PPIx::Regexp::Constant 0.085_04 + PPIx::Regexp::Constant::Inf 0.088 + PPIx::Regexp::Dumper 0.088 + PPIx::Regexp::Element 0.088 + PPIx::Regexp::Lexer 0.088 + PPIx::Regexp::Node 0.088 + PPIx::Regexp::Node::Range 0.088 + PPIx::Regexp::Node::Unknown 0.088 + PPIx::Regexp::Structure 0.088 + PPIx::Regexp::Structure::Assertion 0.088 + PPIx::Regexp::Structure::Atomic_Script_Run 0.088 + PPIx::Regexp::Structure::BranchReset 0.088 + PPIx::Regexp::Structure::Capture 0.088 + PPIx::Regexp::Structure::CharClass 0.088 + PPIx::Regexp::Structure::Code 0.088 + PPIx::Regexp::Structure::Main 0.088 + PPIx::Regexp::Structure::Modifier 0.088 + PPIx::Regexp::Structure::NamedCapture 0.088 + PPIx::Regexp::Structure::Quantifier 0.088 + PPIx::Regexp::Structure::RegexSet 0.088 + PPIx::Regexp::Structure::Regexp 0.088 + PPIx::Regexp::Structure::Replacement 0.088 + PPIx::Regexp::Structure::Script_Run 0.088 + PPIx::Regexp::Structure::Subexpression 0.088 + PPIx::Regexp::Structure::Switch 0.088 + PPIx::Regexp::Structure::Unknown 0.088 + PPIx::Regexp::Support 0.088 + PPIx::Regexp::Token 0.088 + PPIx::Regexp::Token::Assertion 0.088 + PPIx::Regexp::Token::Backreference 0.088 + PPIx::Regexp::Token::Backtrack 0.088 + PPIx::Regexp::Token::CharClass 0.088 + PPIx::Regexp::Token::CharClass::POSIX 0.088 + PPIx::Regexp::Token::CharClass::POSIX::Unknown 0.088 + PPIx::Regexp::Token::CharClass::Simple 0.088 + PPIx::Regexp::Token::Code 0.088 + PPIx::Regexp::Token::Comment 0.088 + PPIx::Regexp::Token::Condition 0.088 + PPIx::Regexp::Token::Control 0.088 + PPIx::Regexp::Token::Delimiter 0.088 + PPIx::Regexp::Token::Greediness 0.088 + PPIx::Regexp::Token::GroupType 0.088 + PPIx::Regexp::Token::GroupType::Assertion 0.088 + PPIx::Regexp::Token::GroupType::Atomic_Script_Run 0.088 + PPIx::Regexp::Token::GroupType::BranchReset 0.088 + PPIx::Regexp::Token::GroupType::Code 0.088 + PPIx::Regexp::Token::GroupType::Modifier 0.088 + PPIx::Regexp::Token::GroupType::NamedCapture 0.088 + PPIx::Regexp::Token::GroupType::Script_Run 0.088 + PPIx::Regexp::Token::GroupType::Subexpression 0.088 + PPIx::Regexp::Token::GroupType::Switch 0.088 + PPIx::Regexp::Token::Interpolation 0.088 + PPIx::Regexp::Token::Literal 0.088 + PPIx::Regexp::Token::Modifier 0.088 + PPIx::Regexp::Token::NoOp 0.088 + PPIx::Regexp::Token::Operator 0.088 + PPIx::Regexp::Token::Quantifier 0.088 + PPIx::Regexp::Token::Recursion 0.088 + PPIx::Regexp::Token::Reference 0.088 + PPIx::Regexp::Token::Structure 0.088 + PPIx::Regexp::Token::Unknown 0.088 + PPIx::Regexp::Token::Unmatched 0.088 + PPIx::Regexp::Token::Whitespace 0.088 + PPIx::Regexp::Tokenizer 0.088 + PPIx::Regexp::Util 0.088 requirements: - Data::Dumper 0 - Exception::Class 0 + Carp 0 + Encode 0 Exporter 0 - PPI 1.208 - PPI::Document 1.208 - PPI::Document::Fragment 1.208 - PPI::Dumper 1.208 - Readonly 0 + List::Util 0 + PPI::Document 1.238 + PPI::Dumper 1.238 Scalar::Util 0 Task::Weaken 0 - Test::Deep 0 - Test::More 0 + Test::More 0.88 base 0 + charnames 0 + constant 0 + lib 0 + overload 0 + perl 5.006 strict 0 warnings 0 - Package-DeprecationManager-0.17 - pathname: D/DR/DROLSKY/Package-DeprecationManager-0.17.tar.gz + PPIx-Utils-0.003 + pathname: D/DB/DBOOK/PPIx-Utils-0.003.tar.gz + provides: + PPIx::Utils 0.003 + PPIx::Utils::Classification 0.003 + PPIx::Utils::Language 0.003 + PPIx::Utils::Traversal 0.003 + requirements: + B::Keywords 1.09 + Exporter 0 + ExtUtils::MakeMaker 0 + PPI 1.250 + Scalar::Util 0 + perl 5.006 + Package-DeprecationManager-0.18 + pathname: D/DR/DROLSKY/Package-DeprecationManager-0.18.tar.gz provides: - Package::DeprecationManager 0.17 + Package::DeprecationManager 0.18 requirements: Carp 0 ExtUtils::MakeMaker 0 @@ -6445,21 +5458,19 @@ DISTRIBUTIONS Package::Stash 0 Params::Util 0 Sub::Install 0 - Sub::Name 0 + Sub::Util 0 strict 0 warnings 0 - Package-Stash-0.37 - pathname: D/DO/DOY/Package-Stash-0.37.tar.gz + Package-Stash-0.40 + pathname: E/ET/ETHER/Package-Stash-0.40.tar.gz provides: - Package::Stash 0.37 - Package::Stash::PP 0.37 + Package::Stash 0.40 + Package::Stash::PP 0.40 requirements: B 0 Carp 0 - Config 0 Dist::CheckConflicts 0.02 ExtUtils::MakeMaker 0 - File::Spec 0 Getopt::Long 0 Module::Implementation 0.06 Package::Stash::XS 0.26 @@ -6467,77 +5478,65 @@ DISTRIBUTIONS Symbol 0 Text::ParseWords 0 constant 0 + perl 5.008001 strict 0 warnings 0 - Package-Stash-XS-0.28 - pathname: D/DO/DOY/Package-Stash-XS-0.28.tar.gz + Package-Stash-XS-0.30 + pathname: E/ET/ETHER/Package-Stash-XS-0.30.tar.gz provides: - Package::Stash::XS 0.28 + Package::Stash::XS 0.30 requirements: - ExtUtils::MakeMaker 6.30 + ExtUtils::MakeMaker 0 XSLoader 0 + perl 5.008001 strict 0 warnings 0 - PadWalker-2.3 - pathname: R/RO/ROBIN/PadWalker-2.3.tar.gz + Parallel-ForkManager-2.03 + pathname: Y/YA/YANICK/Parallel-ForkManager-2.03.tar.gz provides: - PadWalker 2.3 + Parallel::ForkManager 2.03 + Parallel::ForkManager::Child 2.03 requirements: + Carp 0 ExtUtils::MakeMaker 0 - perl 5.008001 - Parallel-Prefork-0.18 - pathname: K/KA/KAZUHO/Parallel-Prefork-0.18.tar.gz - provides: - Parallel::Prefork 0.18 - Parallel::Prefork::SpareWorkers undef - Parallel::Prefork::SpareWorkers::Scoreboard undef - requirements: - Class::Accessor::Lite 0.04 - ExtUtils::MakeMaker 6.59 - List::MoreUtils 0 - Proc::Wait3 0.03 - Scope::Guard 0 - Signal::Mask 0 - Test::Requires 0 - Test::SharedFork 0 - perl 5.008001 - Parallel-Scoreboard-0.08 - pathname: K/KA/KAZUHO/Parallel-Scoreboard-0.08.tar.gz - provides: - Parallel::Scoreboard 0.08 - Parallel::Scoreboard::PSGI::App undef - Parallel::Scoreboard::PSGI::App::JSON undef - requirements: - Class::Accessor::Lite 0.05 - ExtUtils::MakeMaker 6.36 + File::Path 0 + File::Spec 0 File::Temp 0 - HTML::Entities 0 - JSON 0 - Test::More 0 - Test::Warn 0 - Params-Util-1.07 - pathname: A/AD/ADAMK/Params-Util-1.07.tar.gz + Moo 1.001000 + Moo::Role 0 + POSIX 0 + Storable 0 + perl 5.006 + strict 0 + warnings 0 + Params-Util-1.102 + pathname: R/RE/REHSACK/Params-Util-1.102.tar.gz provides: - Params::Util 1.07 + Params::Util 1.102 + Params::Util::PP 1.102 requirements: - ExtUtils::CBuilder 0.27 - ExtUtils::MakeMaker 6.52 - File::Spec 0.80 + Carp 0 + ExtUtils::MakeMaker 0 + File::Basename 0 + File::Copy 0 + File::Path 0 + File::Spec 0 + IPC::Cmd 0 Scalar::Util 1.18 - Test::More 0.42 - perl 5.00503 - Params-Validate-1.29 - pathname: D/DR/DROLSKY/Params-Validate-1.29.tar.gz + XSLoader 0.22 + parent 0 + Params-Validate-1.31 + pathname: D/DR/DROLSKY/Params-Validate-1.31.tar.gz provides: - Params::Validate 1.29 - Params::Validate::Constants 1.29 - Params::Validate::PP 1.29 - Params::Validate::XS 1.29 + Params::Validate 1.31 + Params::Validate::Constants 1.31 + Params::Validate::PP 1.31 + Params::Validate::XS 1.31 requirements: Carp 0 Exporter 0 ExtUtils::CBuilder 0 - Module::Build 0.28 + Module::Build 0.4227 Module::Implementation 0 Scalar::Util 1.10 XSLoader 0 @@ -6545,12 +5544,12 @@ DISTRIBUTIONS strict 0 vars 0 warnings 0 - Params-ValidationCompiler-0.24 - pathname: D/DR/DROLSKY/Params-ValidationCompiler-0.24.tar.gz + Params-ValidationCompiler-0.31 + pathname: D/DR/DROLSKY/Params-ValidationCompiler-0.31.tar.gz provides: - Params::ValidationCompiler 0.24 - Params::ValidationCompiler::Compiler 0.24 - Params::ValidationCompiler::Exceptions 0.24 + Params::ValidationCompiler 0.31 + Params::ValidationCompiler::Compiler 0.31 + Params::ValidationCompiler::Exceptions 0.31 requirements: B 0 Carp 0 @@ -6563,26 +5562,6 @@ DISTRIBUTIONS overload 0 strict 0 warnings 0 - Parse-CPAN-Packages-2.40 - pathname: M/MI/MITHALDU/Parse-CPAN-Packages-2.40.tar.gz - provides: - Parse::CPAN::Packages 2.40 - Parse::CPAN::Packages::Distribution undef - Parse::CPAN::Packages::Package undef - requirements: - Archive::Peek 0 - CPAN::DistnameInfo 0 - Compress::Zlib 0 - ExtUtils::MakeMaker 0 - File::Slurp 0 - Moo 0 - PPI 0 - Path::Class 0 - Test::InDistDir 0 - Test::More 0 - Type::Utils 0 - Types::Standard 0 - version 0 Parse-CPAN-Packages-Fast-0.09 pathname: S/SR/SREZIC/Parse-CPAN-Packages-Fast-0.09.tar.gz provides: @@ -6594,49 +5573,26 @@ DISTRIBUTIONS CPAN::Version 0 ExtUtils::MakeMaker 0 IO::Uncompress::Gunzip 0 - Parse-CSV-2.04 - pathname: K/KW/KWILLIAMS/Parse-CSV-2.04.tar.gz + Parse-LocalDistribution-0.20 + pathname: I/IS/ISHIGAKI/Parse-LocalDistribution-0.20.tar.gz provides: - Parse::CSV 2.04 - requirements: - Carp 0 - ExtUtils::MakeMaker 6.30 - IO::File 1.13 - Module::Build 0.3601 - Params::Util 1.00 - Text::CSV_XS 0.80 - perl 5.005 - strict 0 - Parse-LocalDistribution-0.19 - pathname: I/IS/ISHIGAKI/Parse-LocalDistribution-0.19.tar.gz - provides: - Parse::LocalDistribution 0.19 + Parse::LocalDistribution 0.20 requirements: ExtUtils::MakeMaker 0 - ExtUtils::MakeMaker::CPANfile 0.08 - File::Find 0 - File::Spec 0 - List::Util 0 - Parse::CPAN::Meta 0 - Parse::PMFile 0.37 - Parse-MIME-1.003 - pathname: A/AR/ARISTOTLE/Parse-MIME-1.003.tar.gz - provides: - Parse::MIME 1.003 - requirements: - Exporter 0 - ExtUtils::MakeMaker 0 - perl 5.006 - strict 0 - warnings 0 - Parse-PMFile-0.41 - pathname: I/IS/ISHIGAKI/Parse-PMFile-0.41.tar.gz + ExtUtils::MakeMaker::CPANfile 0.09 + File::Find 0 + File::Spec 0 + List::Util 0 + Parse::CPAN::Meta 0 + Parse::PMFile 0.37 + Parse-PMFile-0.47 + pathname: I/IS/ISHIGAKI/Parse-PMFile-0.47.tar.gz provides: - Parse::PMFile 0.41 + Parse::PMFile 0.47 requirements: Dumpvalue 0 ExtUtils::MakeMaker 0 - ExtUtils::MakeMaker::CPANfile 0.08 + ExtUtils::MakeMaker::CPANfile 0.09 File::Spec 0 JSON::PP 2.00 Safe 0 @@ -6666,11 +5622,11 @@ DISTRIBUTIONS overload 0 parent 0 strict 0 - Path-Iterator-Rule-1.012 - pathname: D/DA/DAGOLDEN/Path-Iterator-Rule-1.012.tar.gz + Path-Iterator-Rule-1.015 + pathname: D/DA/DAGOLDEN/Path-Iterator-Rule-1.015.tar.gz provides: - PIR 1.012 - Path::Iterator::Rule 1.012 + PIR 1.015 + Path::Iterator::Rule 1.015 requirements: Carp 0 ExtUtils::MakeMaker 6.17 @@ -6686,19 +5642,21 @@ DISTRIBUTIONS strict 0 warnings 0 warnings::register 0 - Path-Tiny-0.104 - pathname: D/DA/DAGOLDEN/Path-Tiny-0.104.tar.gz + Path-Tiny-0.148 + pathname: D/DA/DAGOLDEN/Path-Tiny-0.148.tar.gz provides: - Path::Tiny 0.104 - Path::Tiny::Error 0.104 + Path::Tiny 0.148 + Path::Tiny::Error 0.148 requirements: Carp 0 Cwd 0 Digest 1.03 Digest::SHA 5.45 + Encode 0 Exporter 5.57 ExtUtils::MakeMaker 6.17 Fcntl 0 + File::Compare 0 File::Copy 0 File::Glob 0 File::Path 2.07 @@ -6706,365 +5664,299 @@ DISTRIBUTIONS File::Temp 0.19 File::stat 0 constant 0 - if 0 overload 0 perl 5.008001 strict 0 warnings 0 - Perl-Critic-1.130 - pathname: P/PE/PETDANCE/Perl-Critic-1.130.tar.gz - provides: - Perl::Critic 1.130 - Perl::Critic::Annotation 1.130 - Perl::Critic::Command 1.130 - Perl::Critic::Config 1.130 - Perl::Critic::Document 1.130 - Perl::Critic::Exception 1.130 - Perl::Critic::Exception::AggregateConfiguration 1.130 - Perl::Critic::Exception::Configuration 1.130 - Perl::Critic::Exception::Configuration::Generic 1.130 - Perl::Critic::Exception::Configuration::NonExistentPolicy 1.130 - Perl::Critic::Exception::Configuration::Option 1.130 - Perl::Critic::Exception::Configuration::Option::Global 1.130 - Perl::Critic::Exception::Configuration::Option::Global::ExtraParameter 1.130 - Perl::Critic::Exception::Configuration::Option::Global::ParameterValue 1.130 - Perl::Critic::Exception::Configuration::Option::Policy 1.130 - Perl::Critic::Exception::Configuration::Option::Policy::ExtraParameter 1.130 - Perl::Critic::Exception::Configuration::Option::Policy::ParameterValue 1.130 - Perl::Critic::Exception::Fatal 1.130 - Perl::Critic::Exception::Fatal::Generic 1.130 - Perl::Critic::Exception::Fatal::Internal 1.130 - Perl::Critic::Exception::Fatal::PolicyDefinition 1.130 - Perl::Critic::Exception::IO 1.130 - Perl::Critic::Exception::Parse 1.130 - Perl::Critic::OptionsProcessor 1.130 - Perl::Critic::Policy 1.130 - Perl::Critic::Policy::BuiltinFunctions::ProhibitBooleanGrep 1.130 - Perl::Critic::Policy::BuiltinFunctions::ProhibitComplexMappings 1.130 - Perl::Critic::Policy::BuiltinFunctions::ProhibitLvalueSubstr 1.130 - Perl::Critic::Policy::BuiltinFunctions::ProhibitReverseSortBlock 1.130 - Perl::Critic::Policy::BuiltinFunctions::ProhibitSleepViaSelect 1.130 - Perl::Critic::Policy::BuiltinFunctions::ProhibitStringyEval 1.130 - Perl::Critic::Policy::BuiltinFunctions::ProhibitStringySplit 1.130 - Perl::Critic::Policy::BuiltinFunctions::ProhibitUniversalCan 1.130 - Perl::Critic::Policy::BuiltinFunctions::ProhibitUniversalIsa 1.130 - Perl::Critic::Policy::BuiltinFunctions::ProhibitUselessTopic 1.130 - Perl::Critic::Policy::BuiltinFunctions::ProhibitVoidGrep 1.130 - Perl::Critic::Policy::BuiltinFunctions::ProhibitVoidMap 1.130 - Perl::Critic::Policy::BuiltinFunctions::RequireBlockGrep 1.130 - Perl::Critic::Policy::BuiltinFunctions::RequireBlockMap 1.130 - Perl::Critic::Policy::BuiltinFunctions::RequireGlobFunction 1.130 - Perl::Critic::Policy::BuiltinFunctions::RequireSimpleSortBlock 1.130 - Perl::Critic::Policy::ClassHierarchies::ProhibitAutoloading 1.130 - Perl::Critic::Policy::ClassHierarchies::ProhibitExplicitISA 1.130 - Perl::Critic::Policy::ClassHierarchies::ProhibitOneArgBless 1.130 - Perl::Critic::Policy::CodeLayout::ProhibitHardTabs 1.130 - Perl::Critic::Policy::CodeLayout::ProhibitParensWithBuiltins 1.130 - Perl::Critic::Policy::CodeLayout::ProhibitQuotedWordLists 1.130 - Perl::Critic::Policy::CodeLayout::ProhibitTrailingWhitespace 1.130 - Perl::Critic::Policy::CodeLayout::RequireConsistentNewlines 1.130 - Perl::Critic::Policy::CodeLayout::RequireTidyCode 1.130 - Perl::Critic::Policy::CodeLayout::RequireTrailingCommas 1.130 - Perl::Critic::Policy::ControlStructures::ProhibitCStyleForLoops 1.130 - Perl::Critic::Policy::ControlStructures::ProhibitCascadingIfElse 1.130 - Perl::Critic::Policy::ControlStructures::ProhibitDeepNests 1.130 - Perl::Critic::Policy::ControlStructures::ProhibitLabelsWithSpecialBlockNames 1.130 - Perl::Critic::Policy::ControlStructures::ProhibitMutatingListFunctions 1.130 - Perl::Critic::Policy::ControlStructures::ProhibitNegativeExpressionsInUnlessAndUntilConditions 1.130 - Perl::Critic::Policy::ControlStructures::ProhibitPostfixControls 1.130 - Perl::Critic::Policy::ControlStructures::ProhibitUnlessBlocks 1.130 - Perl::Critic::Policy::ControlStructures::ProhibitUnreachableCode 1.130 - Perl::Critic::Policy::ControlStructures::ProhibitUntilBlocks 1.130 - Perl::Critic::Policy::ControlStructures::ProhibitYadaOperator 1.130 - Perl::Critic::Policy::Documentation::PodSpelling 1.130 - Perl::Critic::Policy::Documentation::RequirePackageMatchesPodName 1.130 - Perl::Critic::Policy::Documentation::RequirePodAtEnd 1.130 - Perl::Critic::Policy::Documentation::RequirePodLinksIncludeText 1.130 - Perl::Critic::Policy::Documentation::RequirePodSections 1.130 - Perl::Critic::Policy::ErrorHandling::RequireCarping 1.130 - Perl::Critic::Policy::ErrorHandling::RequireCheckingReturnValueOfEval 1.130 - Perl::Critic::Policy::InputOutput::ProhibitBacktickOperators 1.130 - Perl::Critic::Policy::InputOutput::ProhibitBarewordFileHandles 1.130 - Perl::Critic::Policy::InputOutput::ProhibitExplicitStdin 1.130 - Perl::Critic::Policy::InputOutput::ProhibitInteractiveTest 1.130 - Perl::Critic::Policy::InputOutput::ProhibitJoinedReadline 1.130 - Perl::Critic::Policy::InputOutput::ProhibitOneArgSelect 1.130 - Perl::Critic::Policy::InputOutput::ProhibitReadlineInForLoop 1.130 - Perl::Critic::Policy::InputOutput::ProhibitTwoArgOpen 1.130 - Perl::Critic::Policy::InputOutput::RequireBracedFileHandleWithPrint 1.130 - Perl::Critic::Policy::InputOutput::RequireBriefOpen 1.130 - Perl::Critic::Policy::InputOutput::RequireCheckedClose 1.130 - Perl::Critic::Policy::InputOutput::RequireCheckedOpen 1.130 - Perl::Critic::Policy::InputOutput::RequireCheckedSyscalls 1.130 - Perl::Critic::Policy::InputOutput::RequireEncodingWithUTF8Layer 1.130 - Perl::Critic::Policy::Miscellanea::ProhibitFormats 1.130 - Perl::Critic::Policy::Miscellanea::ProhibitTies 1.130 - Perl::Critic::Policy::Miscellanea::ProhibitUnrestrictedNoCritic 1.130 - Perl::Critic::Policy::Miscellanea::ProhibitUselessNoCritic 1.130 - Perl::Critic::Policy::Modules::ProhibitAutomaticExportation 1.130 - Perl::Critic::Policy::Modules::ProhibitConditionalUseStatements 1.130 - Perl::Critic::Policy::Modules::ProhibitEvilModules 1.130 - Perl::Critic::Policy::Modules::ProhibitExcessMainComplexity 1.130 - Perl::Critic::Policy::Modules::ProhibitMultiplePackages 1.130 - Perl::Critic::Policy::Modules::RequireBarewordIncludes 1.130 - Perl::Critic::Policy::Modules::RequireEndWithOne 1.130 - Perl::Critic::Policy::Modules::RequireExplicitPackage 1.130 - Perl::Critic::Policy::Modules::RequireFilenameMatchesPackage 1.130 - Perl::Critic::Policy::Modules::RequireNoMatchVarsWithUseEnglish 1.130 - Perl::Critic::Policy::Modules::RequireVersionVar 1.130 - Perl::Critic::Policy::NamingConventions::Capitalization 1.130 - Perl::Critic::Policy::NamingConventions::ProhibitAmbiguousNames 1.130 - Perl::Critic::Policy::Objects::ProhibitIndirectSyntax 1.130 - Perl::Critic::Policy::References::ProhibitDoubleSigils 1.130 - Perl::Critic::Policy::RegularExpressions::ProhibitCaptureWithoutTest 1.130 - Perl::Critic::Policy::RegularExpressions::ProhibitComplexRegexes 1.130 - Perl::Critic::Policy::RegularExpressions::ProhibitEnumeratedClasses 1.130 - Perl::Critic::Policy::RegularExpressions::ProhibitEscapedMetacharacters 1.130 - Perl::Critic::Policy::RegularExpressions::ProhibitFixedStringMatches 1.130 - Perl::Critic::Policy::RegularExpressions::ProhibitSingleCharAlternation 1.130 - Perl::Critic::Policy::RegularExpressions::ProhibitUnusedCapture 1.130 - Perl::Critic::Policy::RegularExpressions::ProhibitUnusualDelimiters 1.130 - Perl::Critic::Policy::RegularExpressions::ProhibitUselessTopic 1.130 - Perl::Critic::Policy::RegularExpressions::RequireBracesForMultiline 1.130 - Perl::Critic::Policy::RegularExpressions::RequireDotMatchAnything 1.130 - Perl::Critic::Policy::RegularExpressions::RequireExtendedFormatting 1.130 - Perl::Critic::Policy::RegularExpressions::RequireLineBoundaryMatching 1.130 - Perl::Critic::Policy::Subroutines::ProhibitAmpersandSigils 1.130 - Perl::Critic::Policy::Subroutines::ProhibitBuiltinHomonyms 1.130 - Perl::Critic::Policy::Subroutines::ProhibitExcessComplexity 1.130 - Perl::Critic::Policy::Subroutines::ProhibitExplicitReturnUndef 1.130 - Perl::Critic::Policy::Subroutines::ProhibitManyArgs 1.130 - Perl::Critic::Policy::Subroutines::ProhibitNestedSubs 1.130 - Perl::Critic::Policy::Subroutines::ProhibitReturnSort 1.130 - Perl::Critic::Policy::Subroutines::ProhibitSubroutinePrototypes 1.130 - Perl::Critic::Policy::Subroutines::ProhibitUnusedPrivateSubroutines 1.130 - Perl::Critic::Policy::Subroutines::ProtectPrivateSubs 1.130 - Perl::Critic::Policy::Subroutines::RequireArgUnpacking 1.130 - Perl::Critic::Policy::Subroutines::RequireFinalReturn 1.130 - Perl::Critic::Policy::TestingAndDebugging::ProhibitNoStrict 1.130 - Perl::Critic::Policy::TestingAndDebugging::ProhibitNoWarnings 1.130 - Perl::Critic::Policy::TestingAndDebugging::ProhibitProlongedStrictureOverride 1.130 - Perl::Critic::Policy::TestingAndDebugging::RequireTestLabels 1.130 - Perl::Critic::Policy::TestingAndDebugging::RequireUseStrict 1.130 - Perl::Critic::Policy::TestingAndDebugging::RequireUseWarnings 1.130 - Perl::Critic::Policy::ValuesAndExpressions::ProhibitCommaSeparatedStatements 1.130 - Perl::Critic::Policy::ValuesAndExpressions::ProhibitComplexVersion 1.130 - Perl::Critic::Policy::ValuesAndExpressions::ProhibitConstantPragma 1.130 - Perl::Critic::Policy::ValuesAndExpressions::ProhibitEmptyQuotes 1.130 - Perl::Critic::Policy::ValuesAndExpressions::ProhibitEscapedCharacters 1.130 - Perl::Critic::Policy::ValuesAndExpressions::ProhibitImplicitNewlines 1.130 - Perl::Critic::Policy::ValuesAndExpressions::ProhibitInterpolationOfLiterals 1.130 - Perl::Critic::Policy::ValuesAndExpressions::ProhibitLeadingZeros 1.130 - Perl::Critic::Policy::ValuesAndExpressions::ProhibitLongChainsOfMethodCalls 1.130 - Perl::Critic::Policy::ValuesAndExpressions::ProhibitMagicNumbers 1.130 - Perl::Critic::Policy::ValuesAndExpressions::ProhibitMismatchedOperators 1.130 - Perl::Critic::Policy::ValuesAndExpressions::ProhibitMixedBooleanOperators 1.130 - Perl::Critic::Policy::ValuesAndExpressions::ProhibitNoisyQuotes 1.130 - Perl::Critic::Policy::ValuesAndExpressions::ProhibitQuotesAsQuotelikeOperatorDelimiters 1.130 - Perl::Critic::Policy::ValuesAndExpressions::ProhibitSpecialLiteralHeredocTerminator 1.130 - Perl::Critic::Policy::ValuesAndExpressions::ProhibitVersionStrings 1.130 - Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion 1.130 - Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars 1.130 - Perl::Critic::Policy::ValuesAndExpressions::RequireNumberSeparators 1.130 - Perl::Critic::Policy::ValuesAndExpressions::RequireQuotedHeredocTerminator 1.130 - Perl::Critic::Policy::ValuesAndExpressions::RequireUpperCaseHeredocTerminator 1.130 - Perl::Critic::Policy::Variables::ProhibitAugmentedAssignmentInDeclaration 1.130 - Perl::Critic::Policy::Variables::ProhibitConditionalDeclarations 1.130 - Perl::Critic::Policy::Variables::ProhibitEvilVariables 1.130 - Perl::Critic::Policy::Variables::ProhibitLocalVars 1.130 - Perl::Critic::Policy::Variables::ProhibitMatchVars 1.130 - Perl::Critic::Policy::Variables::ProhibitPackageVars 1.130 - Perl::Critic::Policy::Variables::ProhibitPerl4PackageNames 1.130 - Perl::Critic::Policy::Variables::ProhibitPunctuationVars 1.130 - Perl::Critic::Policy::Variables::ProhibitReusedNames 1.130 - Perl::Critic::Policy::Variables::ProhibitUnusedVariables 1.130 - Perl::Critic::Policy::Variables::ProtectPrivateVars 1.130 - Perl::Critic::Policy::Variables::RequireInitializationForLocalVars 1.130 - Perl::Critic::Policy::Variables::RequireLexicalLoopIterators 1.130 - Perl::Critic::Policy::Variables::RequireLocalizedPunctuationVars 1.130 - Perl::Critic::Policy::Variables::RequireNegativeIndices 1.130 - Perl::Critic::PolicyConfig 1.130 - Perl::Critic::PolicyFactory 1.130 - Perl::Critic::PolicyListing 1.130 - Perl::Critic::PolicyParameter 1.130 - Perl::Critic::PolicyParameter::Behavior 1.130 - Perl::Critic::PolicyParameter::Behavior::Boolean 1.130 - Perl::Critic::PolicyParameter::Behavior::Enumeration 1.130 - Perl::Critic::PolicyParameter::Behavior::Integer 1.130 - Perl::Critic::PolicyParameter::Behavior::String 1.130 - Perl::Critic::PolicyParameter::Behavior::StringList 1.130 - Perl::Critic::ProfilePrototype 1.130 - Perl::Critic::Statistics 1.130 - Perl::Critic::TestUtils 1.130 - Perl::Critic::Theme 1.130 - Perl::Critic::ThemeListing 1.130 - Perl::Critic::UserProfile 1.130 - Perl::Critic::Utils 1.130 - Perl::Critic::Utils::Constants 1.130 - Perl::Critic::Utils::DataConversion 1.130 - Perl::Critic::Utils::McCabe 1.130 - Perl::Critic::Utils::POD 1.130 - Perl::Critic::Utils::POD::ParseInteriorSequence 1.130 - Perl::Critic::Utils::PPI 1.130 - Perl::Critic::Utils::Perl 1.130 - Perl::Critic::Violation 1.130 - Test::Perl::Critic::Policy 1.130 - requirements: - B::Keywords 1.05 + warnings::register 0 + Perl-Critic-1.156 + pathname: P/PE/PETDANCE/Perl-Critic-1.156.tar.gz + provides: + Perl::Critic 1.156 + Perl::Critic::Annotation 1.156 + Perl::Critic::Command 1.156 + Perl::Critic::Config 1.156 + Perl::Critic::Document 1.156 + Perl::Critic::Exception 1.156 + Perl::Critic::Exception::AggregateConfiguration 1.156 + Perl::Critic::Exception::Configuration 1.156 + Perl::Critic::Exception::Configuration::Generic 1.156 + Perl::Critic::Exception::Configuration::NonExistentPolicy 1.156 + Perl::Critic::Exception::Configuration::Option 1.156 + Perl::Critic::Exception::Configuration::Option::Global 1.156 + Perl::Critic::Exception::Configuration::Option::Global::ExtraParameter 1.156 + Perl::Critic::Exception::Configuration::Option::Global::ParameterValue 1.156 + Perl::Critic::Exception::Configuration::Option::Policy 1.156 + Perl::Critic::Exception::Configuration::Option::Policy::ExtraParameter 1.156 + Perl::Critic::Exception::Configuration::Option::Policy::ParameterValue 1.156 + Perl::Critic::Exception::Fatal 1.156 + Perl::Critic::Exception::Fatal::Generic 1.156 + Perl::Critic::Exception::Fatal::Internal 1.156 + Perl::Critic::Exception::Fatal::PolicyDefinition 1.156 + Perl::Critic::Exception::IO 1.156 + Perl::Critic::Exception::Parse 1.156 + Perl::Critic::OptionsProcessor 1.156 + Perl::Critic::Policy 1.156 + Perl::Critic::Policy::BuiltinFunctions::ProhibitBooleanGrep 1.156 + Perl::Critic::Policy::BuiltinFunctions::ProhibitComplexMappings 1.156 + Perl::Critic::Policy::BuiltinFunctions::ProhibitLvalueSubstr 1.156 + Perl::Critic::Policy::BuiltinFunctions::ProhibitReverseSortBlock 1.156 + Perl::Critic::Policy::BuiltinFunctions::ProhibitShiftRef 1.156 + Perl::Critic::Policy::BuiltinFunctions::ProhibitSleepViaSelect 1.156 + Perl::Critic::Policy::BuiltinFunctions::ProhibitStringyEval 1.156 + Perl::Critic::Policy::BuiltinFunctions::ProhibitStringySplit 1.156 + Perl::Critic::Policy::BuiltinFunctions::ProhibitUniversalCan 1.156 + Perl::Critic::Policy::BuiltinFunctions::ProhibitUniversalIsa 1.156 + Perl::Critic::Policy::BuiltinFunctions::ProhibitUselessTopic 1.156 + Perl::Critic::Policy::BuiltinFunctions::ProhibitVoidGrep 1.156 + Perl::Critic::Policy::BuiltinFunctions::ProhibitVoidMap 1.156 + Perl::Critic::Policy::BuiltinFunctions::RequireBlockGrep 1.156 + Perl::Critic::Policy::BuiltinFunctions::RequireBlockMap 1.156 + Perl::Critic::Policy::BuiltinFunctions::RequireGlobFunction 1.156 + Perl::Critic::Policy::BuiltinFunctions::RequireSimpleSortBlock 1.156 + Perl::Critic::Policy::ClassHierarchies::ProhibitAutoloading 1.156 + Perl::Critic::Policy::ClassHierarchies::ProhibitExplicitISA 1.156 + Perl::Critic::Policy::ClassHierarchies::ProhibitOneArgBless 1.156 + Perl::Critic::Policy::CodeLayout::ProhibitHardTabs 1.156 + Perl::Critic::Policy::CodeLayout::ProhibitParensWithBuiltins 1.156 + Perl::Critic::Policy::CodeLayout::ProhibitQuotedWordLists 1.156 + Perl::Critic::Policy::CodeLayout::ProhibitTrailingWhitespace 1.156 + Perl::Critic::Policy::CodeLayout::RequireConsistentNewlines 1.156 + Perl::Critic::Policy::CodeLayout::RequireTidyCode 1.156 + Perl::Critic::Policy::CodeLayout::RequireTrailingCommas 1.156 + Perl::Critic::Policy::ControlStructures::ProhibitCStyleForLoops 1.156 + Perl::Critic::Policy::ControlStructures::ProhibitCascadingIfElse 1.156 + Perl::Critic::Policy::ControlStructures::ProhibitDeepNests 1.156 + Perl::Critic::Policy::ControlStructures::ProhibitLabelsWithSpecialBlockNames 1.156 + Perl::Critic::Policy::ControlStructures::ProhibitMutatingListFunctions 1.156 + Perl::Critic::Policy::ControlStructures::ProhibitNegativeExpressionsInUnlessAndUntilConditions 1.156 + Perl::Critic::Policy::ControlStructures::ProhibitPostfixControls 1.156 + Perl::Critic::Policy::ControlStructures::ProhibitUnlessBlocks 1.156 + Perl::Critic::Policy::ControlStructures::ProhibitUnreachableCode 1.156 + Perl::Critic::Policy::ControlStructures::ProhibitUntilBlocks 1.156 + Perl::Critic::Policy::ControlStructures::ProhibitYadaOperator 1.156 + Perl::Critic::Policy::Documentation::PodSpelling 1.156 + Perl::Critic::Policy::Documentation::RequirePackageMatchesPodName 1.156 + Perl::Critic::Policy::Documentation::RequirePodAtEnd 1.156 + Perl::Critic::Policy::Documentation::RequirePodSections 1.156 + Perl::Critic::Policy::ErrorHandling::RequireCarping 1.156 + Perl::Critic::Policy::ErrorHandling::RequireCheckingReturnValueOfEval 1.156 + Perl::Critic::Policy::InputOutput::ProhibitBacktickOperators 1.156 + Perl::Critic::Policy::InputOutput::ProhibitBarewordDirHandles 1.156 + Perl::Critic::Policy::InputOutput::ProhibitBarewordFileHandles 1.156 + Perl::Critic::Policy::InputOutput::ProhibitExplicitStdin 1.156 + Perl::Critic::Policy::InputOutput::ProhibitInteractiveTest 1.156 + Perl::Critic::Policy::InputOutput::ProhibitJoinedReadline 1.156 + Perl::Critic::Policy::InputOutput::ProhibitOneArgSelect 1.156 + Perl::Critic::Policy::InputOutput::ProhibitReadlineInForLoop 1.156 + Perl::Critic::Policy::InputOutput::ProhibitTwoArgOpen 1.156 + Perl::Critic::Policy::InputOutput::RequireBracedFileHandleWithPrint 1.156 + Perl::Critic::Policy::InputOutput::RequireBriefOpen 1.156 + Perl::Critic::Policy::InputOutput::RequireCheckedClose 1.156 + Perl::Critic::Policy::InputOutput::RequireCheckedOpen 1.156 + Perl::Critic::Policy::InputOutput::RequireCheckedSyscalls 1.156 + Perl::Critic::Policy::InputOutput::RequireEncodingWithUTF8Layer 1.156 + Perl::Critic::Policy::Miscellanea::ProhibitFormats 1.156 + Perl::Critic::Policy::Miscellanea::ProhibitTies 1.156 + Perl::Critic::Policy::Miscellanea::ProhibitUnrestrictedNoCritic 1.156 + Perl::Critic::Policy::Miscellanea::ProhibitUselessNoCritic 1.156 + Perl::Critic::Policy::Modules::ProhibitAutomaticExportation 1.156 + Perl::Critic::Policy::Modules::ProhibitConditionalUseStatements 1.156 + Perl::Critic::Policy::Modules::ProhibitEvilModules 1.156 + Perl::Critic::Policy::Modules::ProhibitExcessMainComplexity 1.156 + Perl::Critic::Policy::Modules::ProhibitMultiplePackages 1.156 + Perl::Critic::Policy::Modules::RequireBarewordIncludes 1.156 + Perl::Critic::Policy::Modules::RequireEndWithOne 1.156 + Perl::Critic::Policy::Modules::RequireExplicitPackage 1.156 + Perl::Critic::Policy::Modules::RequireFilenameMatchesPackage 1.156 + Perl::Critic::Policy::Modules::RequireNoMatchVarsWithUseEnglish 1.156 + Perl::Critic::Policy::Modules::RequireVersionVar 1.156 + Perl::Critic::Policy::NamingConventions::Capitalization 1.156 + Perl::Critic::Policy::NamingConventions::ProhibitAmbiguousNames 1.156 + Perl::Critic::Policy::Objects::ProhibitIndirectSyntax 1.156 + Perl::Critic::Policy::References::ProhibitDoubleSigils 1.156 + Perl::Critic::Policy::RegularExpressions::ProhibitCaptureWithoutTest 1.156 + Perl::Critic::Policy::RegularExpressions::ProhibitComplexRegexes 1.156 + Perl::Critic::Policy::RegularExpressions::ProhibitEnumeratedClasses 1.156 + Perl::Critic::Policy::RegularExpressions::ProhibitEscapedMetacharacters 1.156 + Perl::Critic::Policy::RegularExpressions::ProhibitFixedStringMatches 1.156 + Perl::Critic::Policy::RegularExpressions::ProhibitSingleCharAlternation 1.156 + Perl::Critic::Policy::RegularExpressions::ProhibitUnusedCapture 1.156 + Perl::Critic::Policy::RegularExpressions::ProhibitUnusualDelimiters 1.156 + Perl::Critic::Policy::RegularExpressions::ProhibitUselessTopic 1.156 + Perl::Critic::Policy::RegularExpressions::RequireBracesForMultiline 1.156 + Perl::Critic::Policy::RegularExpressions::RequireDotMatchAnything 1.156 + Perl::Critic::Policy::RegularExpressions::RequireExtendedFormatting 1.156 + Perl::Critic::Policy::RegularExpressions::RequireLineBoundaryMatching 1.156 + Perl::Critic::Policy::Subroutines::ProhibitAmpersandSigils 1.156 + Perl::Critic::Policy::Subroutines::ProhibitBuiltinHomonyms 1.156 + Perl::Critic::Policy::Subroutines::ProhibitExcessComplexity 1.156 + Perl::Critic::Policy::Subroutines::ProhibitExplicitReturnUndef 1.156 + Perl::Critic::Policy::Subroutines::ProhibitManyArgs 1.156 + Perl::Critic::Policy::Subroutines::ProhibitNestedSubs 1.156 + Perl::Critic::Policy::Subroutines::ProhibitReturnSort 1.156 + Perl::Critic::Policy::Subroutines::ProhibitSubroutinePrototypes 1.156 + Perl::Critic::Policy::Subroutines::ProhibitUnusedPrivateSubroutines 1.156 + Perl::Critic::Policy::Subroutines::ProtectPrivateSubs 1.156 + Perl::Critic::Policy::Subroutines::RequireArgUnpacking 1.156 + Perl::Critic::Policy::Subroutines::RequireFinalReturn 1.156 + Perl::Critic::Policy::TestingAndDebugging::ProhibitNoStrict 1.156 + Perl::Critic::Policy::TestingAndDebugging::ProhibitNoWarnings 1.156 + Perl::Critic::Policy::TestingAndDebugging::ProhibitProlongedStrictureOverride 1.156 + Perl::Critic::Policy::TestingAndDebugging::RequireTestLabels 1.156 + Perl::Critic::Policy::TestingAndDebugging::RequireUseStrict 1.156 + Perl::Critic::Policy::TestingAndDebugging::RequireUseWarnings 1.156 + Perl::Critic::Policy::ValuesAndExpressions::ProhibitCommaSeparatedStatements 1.156 + Perl::Critic::Policy::ValuesAndExpressions::ProhibitComplexVersion 1.156 + Perl::Critic::Policy::ValuesAndExpressions::ProhibitConstantPragma 1.156 + Perl::Critic::Policy::ValuesAndExpressions::ProhibitEmptyQuotes 1.156 + Perl::Critic::Policy::ValuesAndExpressions::ProhibitEscapedCharacters 1.156 + Perl::Critic::Policy::ValuesAndExpressions::ProhibitImplicitNewlines 1.156 + Perl::Critic::Policy::ValuesAndExpressions::ProhibitInterpolationOfLiterals 1.156 + Perl::Critic::Policy::ValuesAndExpressions::ProhibitLeadingZeros 1.156 + Perl::Critic::Policy::ValuesAndExpressions::ProhibitLongChainsOfMethodCalls 1.156 + Perl::Critic::Policy::ValuesAndExpressions::ProhibitMagicNumbers 1.156 + Perl::Critic::Policy::ValuesAndExpressions::ProhibitMismatchedOperators 1.156 + Perl::Critic::Policy::ValuesAndExpressions::ProhibitMixedBooleanOperators 1.156 + Perl::Critic::Policy::ValuesAndExpressions::ProhibitNoisyQuotes 1.156 + Perl::Critic::Policy::ValuesAndExpressions::ProhibitQuotesAsQuotelikeOperatorDelimiters 1.156 + Perl::Critic::Policy::ValuesAndExpressions::ProhibitSpecialLiteralHeredocTerminator 1.156 + Perl::Critic::Policy::ValuesAndExpressions::ProhibitVersionStrings 1.156 + Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion 1.156 + Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars 1.156 + Perl::Critic::Policy::ValuesAndExpressions::RequireNumberSeparators 1.156 + Perl::Critic::Policy::ValuesAndExpressions::RequireQuotedHeredocTerminator 1.156 + Perl::Critic::Policy::ValuesAndExpressions::RequireUpperCaseHeredocTerminator 1.156 + Perl::Critic::Policy::Variables::ProhibitAugmentedAssignmentInDeclaration 1.156 + Perl::Critic::Policy::Variables::ProhibitConditionalDeclarations 1.156 + Perl::Critic::Policy::Variables::ProhibitEvilVariables 1.156 + Perl::Critic::Policy::Variables::ProhibitLocalVars 1.156 + Perl::Critic::Policy::Variables::ProhibitMatchVars 1.156 + Perl::Critic::Policy::Variables::ProhibitPackageVars 1.156 + Perl::Critic::Policy::Variables::ProhibitPerl4PackageNames 1.156 + Perl::Critic::Policy::Variables::ProhibitPunctuationVars 1.156 + Perl::Critic::Policy::Variables::ProhibitReusedNames 1.156 + Perl::Critic::Policy::Variables::ProhibitUnusedVariables 1.156 + Perl::Critic::Policy::Variables::ProtectPrivateVars 1.156 + Perl::Critic::Policy::Variables::RequireInitializationForLocalVars 1.156 + Perl::Critic::Policy::Variables::RequireLexicalLoopIterators 1.156 + Perl::Critic::Policy::Variables::RequireLocalizedPunctuationVars 1.156 + Perl::Critic::Policy::Variables::RequireNegativeIndices 1.156 + Perl::Critic::PolicyConfig 1.156 + Perl::Critic::PolicyFactory 1.156 + Perl::Critic::PolicyListing 1.156 + Perl::Critic::PolicyParameter 1.156 + Perl::Critic::PolicyParameter::Behavior 1.156 + Perl::Critic::PolicyParameter::Behavior::Boolean 1.156 + Perl::Critic::PolicyParameter::Behavior::Enumeration 1.156 + Perl::Critic::PolicyParameter::Behavior::Integer 1.156 + Perl::Critic::PolicyParameter::Behavior::String 1.156 + Perl::Critic::PolicyParameter::Behavior::StringList 1.156 + Perl::Critic::ProfilePrototype 1.156 + Perl::Critic::Statistics 1.156 + Perl::Critic::TestUtils 1.156 + Perl::Critic::Theme 1.156 + Perl::Critic::ThemeListing 1.156 + Perl::Critic::UserProfile 1.156 + Perl::Critic::Utils 1.156 + Perl::Critic::Utils::Constants 1.156 + Perl::Critic::Utils::McCabe 1.156 + Perl::Critic::Utils::POD 1.156 + Perl::Critic::Utils::PPI 1.156 + Perl::Critic::Utils::Perl 1.156 + Perl::Critic::Violation 1.156 + Test::Perl::Critic::Policy 1.156 + requirements: + B::Keywords 1.23 Carp 0 Config::Tiny 2 - Email::Address 1.889 English 0 Exception::Class 1.23 Exporter 5.63 File::Basename 0 File::Find 0 - File::HomeDir 0 File::Path 0 File::Spec 0 File::Spec::Unix 0 File::Temp 0 File::Which 0 Getopt::Long 0 - IO::String 0 - IPC::Open2 1 - List::MoreUtils 0.19 + List::SomeUtils 0.55 List::Util 0 - Module::Build 0.4024 + Module::Build 0.4204 Module::Pluggable 3.1 - PPI 1.224 - PPI::Document 1.224 - PPI::Document::File 1.224 - PPI::Node 1.224 - PPI::Token::Quote::Single 1.224 - PPI::Token::Whitespace 1.224 + PPI 1.277 + PPI::Document 1.277 + PPI::Document::File 1.277 + PPI::Node 1.277 + PPI::Token::Quote::Single 1.277 + PPI::Token::Whitespace 1.277 + PPIx::QuoteLike 0 PPIx::Regexp 0.027 - PPIx::Utilities::Node 1.001 - PPIx::Utilities::Statement 1.001 + PPIx::Regexp::Util 0.068 + PPIx::Utils::Traversal 0.003 Perl::Tidy 0 - Pod::Parser 0 Pod::PlainText 0 Pod::Select 0 Pod::Spell 1 Pod::Usage 0 Readonly 2 Scalar::Util 0 - String::Format 1.13 - Task::Weaken 0 + String::Format 1.18 Term::ANSIColor 2.02 Test::Builder 0.92 - Test::Deep 0 - Test::More 0 Text::ParseWords 3 base 0 charnames 0 lib 0 overload 0 - perl 5.006001 + parent 0 + perl 5.010001 strict 0 version 0.77 warnings 0 - Perl-Tidy-20180220 - pathname: S/SH/SHANCOCK/Perl-Tidy-20180220.tar.gz - provides: - Perl::Tidy 20180220 - Perl::Tidy::Debugger 20180220 - Perl::Tidy::DevNull 20180220 - Perl::Tidy::Diagnostics 20180220 - Perl::Tidy::FileWriter 20180220 - Perl::Tidy::Formatter 20180220 - Perl::Tidy::HtmlWriter 20180220 - Perl::Tidy::IOScalar 20180220 - Perl::Tidy::IOScalarArray 20180220 - Perl::Tidy::IndentationItem 20180220 - Perl::Tidy::LineBuffer 20180220 - Perl::Tidy::LineSink 20180220 - Perl::Tidy::LineSource 20180220 - Perl::Tidy::Logger 20180220 - Perl::Tidy::Tokenizer 20180220 - Perl::Tidy::VerticalAligner 20180220 - Perl::Tidy::VerticalAligner::Alignment 20180220 - Perl::Tidy::VerticalAligner::Line 20180220 + Perl-Tidy-20240511 + pathname: S/SH/SHANCOCK/Perl-Tidy-20240511.tar.gz + provides: + Perl::Tidy 20240511 + Perl::Tidy::Debugger 20240511 + Perl::Tidy::Diagnostics 20240511 + Perl::Tidy::FileWriter 20240511 + Perl::Tidy::Formatter 20240511 + Perl::Tidy::HtmlWriter 20240511 + Perl::Tidy::IOScalar 20240511 + Perl::Tidy::IOScalarArray 20240511 + Perl::Tidy::IndentationItem 20240511 + Perl::Tidy::Logger 20240511 + Perl::Tidy::Tokenizer 20240511 + Perl::Tidy::VerticalAligner 20240511 + Perl::Tidy::VerticalAligner::Alignment 20240511 + Perl::Tidy::VerticalAligner::Line 20240511 requirements: ExtUtils::MakeMaker 0 + perl 5.008 PerlIO-gzip-0.20 pathname: N/NW/NWCLARK/PerlIO-gzip-0.20.tar.gz provides: PerlIO::gzip 0.20 requirements: ExtUtils::MakeMaker 0 - PerlIO-utf8_strict-0.007 - pathname: L/LE/LEONT/PerlIO-utf8_strict-0.007.tar.gz + PerlIO-utf8_strict-0.010 + pathname: L/LE/LEONT/PerlIO-utf8_strict-0.010.tar.gz provides: - PerlIO::utf8_strict 0.007 + PerlIO::utf8_strict 0.010 requirements: ExtUtils::MakeMaker 0 XSLoader 0 perl 5.008 strict 0 warnings 0 - Pithub-0.01033 - pathname: O/OA/OALDERS/Pithub-0.01033.tar.gz - provides: - Pithub 0.01033 - Pithub::Base 0.01033 - Pithub::Events 0.01033 - Pithub::Gists 0.01033 - Pithub::Gists::Comments 0.01033 - Pithub::GitData 0.01033 - Pithub::GitData::Blobs 0.01033 - Pithub::GitData::Commits 0.01033 - Pithub::GitData::References 0.01033 - Pithub::GitData::Tags 0.01033 - Pithub::GitData::Trees 0.01033 - Pithub::Issues 0.01033 - Pithub::Issues::Assignees 0.01033 - Pithub::Issues::Comments 0.01033 - Pithub::Issues::Events 0.01033 - Pithub::Issues::Labels 0.01033 - Pithub::Issues::Milestones 0.01033 - Pithub::Orgs 0.01033 - Pithub::Orgs::Members 0.01033 - Pithub::Orgs::Teams 0.01033 - Pithub::PullRequests 0.01033 - Pithub::PullRequests::Comments 0.01033 - Pithub::Repos 0.01033 - Pithub::Repos::Collaborators 0.01033 - Pithub::Repos::Commits 0.01033 - Pithub::Repos::Contents 0.01033 - Pithub::Repos::Downloads 0.01033 - Pithub::Repos::Forks 0.01033 - Pithub::Repos::Hooks 0.01033 - Pithub::Repos::Keys 0.01033 - Pithub::Repos::Releases 0.01033 - Pithub::Repos::Releases::Assets 0.01033 - Pithub::Repos::Starring 0.01033 - Pithub::Repos::Stats 0.01033 - Pithub::Repos::Statuses 0.01033 - Pithub::Repos::Watching 0.01033 - Pithub::Result 0.01033 - Pithub::Result::SharedCache 0.01033 - Pithub::Search 0.01033 - Pithub::SearchV3 0.01033 - Pithub::Users 0.01033 - Pithub::Users::Emails 0.01033 - Pithub::Users::Followers 0.01033 - Pithub::Users::Keys 0.01033 - requirements: - Array::Iterator 0 - Cache::LRU 0.04 - ExtUtils::MakeMaker 0 - HTTP::Message 0 - JSON::MaybeXS 1.003003 - LWP::Protocol::https 0 - LWP::UserAgent 0 - Moo 1.001000 - Plack-1.0044 - pathname: M/MI/MIYAGAWA/Plack-1.0044.tar.gz + Plack-1.0051 + pathname: M/MI/MIYAGAWA/Plack-1.0051.tar.gz provides: HTTP::Message::PSGI undef HTTP::Server::PSGI undef - Plack 1.0044 + Plack 1.0051 Plack::App::CGIBin undef Plack::App::Cascade undef Plack::App::Directory undef @@ -7123,9 +6015,9 @@ DISTRIBUTIONS Plack::Middleware::XFramework undef Plack::Middleware::XSendfile undef Plack::Recursive::ForwardRequest undef - Plack::Request 1.0044 + Plack::Request 1.0051 Plack::Request::Upload undef - Plack::Response 1.0044 + Plack::Response 1.0051 Plack::Runner undef Plack::TempBuffer undef Plack::Test undef @@ -7145,7 +6037,7 @@ DISTRIBUTIONS File::ShareDir 1.00 File::ShareDir::Install 0.06 Filesys::Notify::Simple 0 - HTTP::Entity::Parser 0.17 + HTTP::Entity::Parser 0.25 HTTP::Headers::Fast 0.18 HTTP::Message 5.814 HTTP::Tiny 0.034 @@ -7157,7 +6049,7 @@ DISTRIBUTIONS URI 1.59 WWW::Form::UrlEncoded 0.23 parent 0 - perl 5.008001 + perl 5.012000 Plack-Middleware-FixMissingBodyInRedirect-0.12 pathname: S/SW/SWEETKID/Plack-Middleware-FixMissingBodyInRedirect-0.12.tar.gz provides: @@ -7171,21 +6063,10 @@ DISTRIBUTIONS parent 0 strict 0 warnings 0 - Plack-Middleware-Header-0.04 - pathname: C/CH/CHIBA/Plack-Middleware-Header-0.04.tar.gz + Plack-Middleware-MethodOverride-0.20 + pathname: M/MI/MIYAGAWA/Plack-Middleware-MethodOverride-0.20.tar.gz provides: - Plack::Middleware::Header 0.04 - requirements: - ExtUtils::MakeMaker 6.42 - Filter::Util::Call 0 - Plack::Middleware 0 - Test::More 0 - parent 0 - perl 5.008001 - Plack-Middleware-MethodOverride-0.15 - pathname: D/DW/DWHEELER/Plack-Middleware-MethodOverride-0.15.tar.gz - provides: - Plack::Middleware::MethodOverride 0.15 + Plack::Middleware::MethodOverride 0.20 requirements: ExtUtils::MakeMaker 0 Plack::Middleware 0 @@ -7195,10 +6076,10 @@ DISTRIBUTIONS perl 5.008001 strict 0 warnings 0 - Plack-Middleware-RemoveRedundantBody-0.06 - pathname: S/SW/SWEETKID/Plack-Middleware-RemoveRedundantBody-0.06.tar.gz + Plack-Middleware-RemoveRedundantBody-0.09 + pathname: S/SW/SWEETKID/Plack-Middleware-RemoveRedundantBody-0.09.tar.gz provides: - Plack::Middleware::RemoveRedundantBody 0.06 + Plack::Middleware::RemoveRedundantBody 0.09 requirements: ExtUtils::MakeMaker 0 Plack::Middleware 0 @@ -7206,10 +6087,10 @@ DISTRIBUTIONS parent 0 strict 0 warnings 0 - Plack-Middleware-ReverseProxy-0.15 - pathname: M/MI/MIYAGAWA/Plack-Middleware-ReverseProxy-0.15.tar.gz + Plack-Middleware-ReverseProxy-0.16 + pathname: M/MI/MIYAGAWA/Plack-Middleware-ReverseProxy-0.16.tar.gz provides: - Plack::Middleware::ReverseProxy 0.15 + Plack::Middleware::ReverseProxy 0.16 requirements: ExtUtils::MakeMaker 6.59 Plack 0.9988 @@ -7218,73 +6099,26 @@ DISTRIBUTIONS Test::More 0 parent 0 perl 5.008001 - Plack-Middleware-Rewrite-2.000 - pathname: A/AR/ARISTOTLE/Plack-Middleware-Rewrite-2.000.tar.gz - provides: - Plack::Middleware::Rewrite 2.000 - requirements: - ExtUtils::MakeMaker 0 - Plack 0.9942 - Plack::Middleware 0 - Plack::Request 0 - Plack::Util 0 - Plack::Util::Accessor 0 - overload 0 - parent 0 - perl 5.006 - strict 0 - warnings 0 - Plack-Middleware-ServerStatus-Lite-0.36 - pathname: K/KA/KAZEBURO/Plack-Middleware-ServerStatus-Lite-0.36.tar.gz - provides: - Plack::Middleware::ServerStatus::Lite 0.36 - requirements: - Getopt::Long 2.38 - JSON 2.53 - Module::Build 0.38 - Net::CIDR::Lite 0 - Parallel::Scoreboard 0.03 - Plack::Middleware 0 - Pod::Usage 0 - Try::Tiny 0.09 - parent 0 - Plack-Middleware-Session-0.30 - pathname: M/MI/MIYAGAWA/Plack-Middleware-Session-0.30.tar.gz + Plack-Middleware-Session-0.34 + pathname: M/MI/MIYAGAWA/Plack-Middleware-Session-0.34.tar.gz provides: - Plack::Middleware::Session 0.30 + Plack::Middleware::Session 0.34 Plack::Middleware::Session::Cookie undef - Plack::Session 0.30 - Plack::Session::Cleanup 0.30 - Plack::Session::State 0.30 - Plack::Session::State::Cookie 0.30 - Plack::Session::Store 0.30 - Plack::Session::Store::Cache 0.30 - Plack::Session::Store::DBI 0.30 - Plack::Session::Store::File 0.30 - Plack::Session::Store::Null 0.30 - requirements: - Cookie::Baker 0 + Plack::Session 0.34 + Plack::Session::Cleanup 0.34 + Plack::Session::State 0.34 + Plack::Session::State::Cookie 0.34 + Plack::Session::Store 0.34 + Plack::Session::Store::Cache 0.34 + Plack::Session::Store::DBI 0.34 + Plack::Session::Store::File 0.34 + Plack::Session::Store::Null 0.34 + requirements: + Cookie::Baker 0.12 Digest::HMAC_SHA1 1.03 - Digest::SHA1 0 - Module::Build::Tiny 0.039 + Digest::SHA 0 + Module::Build::Tiny 0.034 Plack 0.9910 - Plack-Test-Agent-1.4 - pathname: O/OA/OALDERS/Plack-Test-Agent-1.4.tar.gz - provides: - Plack::Test::Agent 1.4 - requirements: - ExtUtils::MakeMaker 0 - HTTP::Message::PSGI 0 - HTTP::Request::Common 0 - HTTP::Response 0 - Plack::Loader 0 - Plack::Util::Accessor 0 - Test::TCP 0 - Test::WWW::Mechanize 0 - parent 0 - perl 5.008 - strict 0 - warnings 0 Plack-Test-ExternalServer-0.02 pathname: E/ET/ETHER/Plack-Test-ExternalServer-0.02.tar.gz provides: @@ -7297,37 +6131,11 @@ DISTRIBUTIONS perl 5.006 strict 0 warnings 0 - Pod-Coverage-0.23 - pathname: R/RC/RCLAMP/Pod-Coverage-0.23.tar.gz - provides: - Pod::Coverage 0.23 - Pod::Coverage::CountParents undef - Pod::Coverage::ExportOnly undef - Pod::Coverage::Extractor 0.23 - Pod::Coverage::Overloader undef - requirements: - Devel::Symdump 2.01 - ExtUtils::MakeMaker 0 - Pod::Find 0.21 - Pod::Parser 1.13 - Test::More 0 - Pod-Coverage-Moose-0.07 - pathname: E/ET/ETHER/Pod-Coverage-Moose-0.07.tar.gz - provides: - Pod::Coverage::Moose 0.07 - requirements: - Carp 0 - Class::Load 0 - Module::Build::Tiny 0.034 - Moose 2.1300 - Pod::Coverage 0 - namespace::autoclean 0.08 - perl 5.006 - Pod-Markdown-3.005 - pathname: R/RW/RWSTAUNER/Pod-Markdown-3.005.tar.gz + Pod-Markdown-3.400 + pathname: R/RW/RWSTAUNER/Pod-Markdown-3.400.tar.gz provides: - Pod::Markdown 3.005 - Pod::Perldoc::ToMarkdown 3.005 + Pod::Markdown 3.400 + Pod::Perldoc::ToMarkdown 3.400 requirements: Encode 0 ExtUtils::MakeMaker 0 @@ -7335,58 +6143,63 @@ DISTRIBUTIONS Pod::Simple 3.27 Pod::Simple::Methody 0 Pod::Usage 0 + URI::Escape 0 parent 0 perl 5.008 strict 0 warnings 0 - Pod-POM-2.01 - pathname: N/NE/NEILB/Pod-POM-2.01.tar.gz - provides: - Pod::POM 2.01 - Pod::POM::Constants 2.01 - Pod::POM::Node 2.01 - Pod::POM::Node::Begin 2.01 - Pod::POM::Node::Code 2.01 - Pod::POM::Node::Content 2.01 - Pod::POM::Node::For 2.01 - Pod::POM::Node::Head1 2.01 - Pod::POM::Node::Head2 2.01 - Pod::POM::Node::Head3 2.01 - Pod::POM::Node::Head4 2.01 - Pod::POM::Node::Item 2.01 - Pod::POM::Node::Over 2.01 - Pod::POM::Node::Pod 2.01 - Pod::POM::Node::Sequence 2.01 - Pod::POM::Node::Text 2.01 - Pod::POM::Node::Verbatim 2.01 - Pod::POM::Nodes 2.01 - Pod::POM::Test 2.01 - Pod::POM::View 2.01 - Pod::POM::View::HTML 2.01 - Pod::POM::View::Pod 2.01 - Pod::POM::View::Text 2.01 + Pod-Simple-3.45 + pathname: K/KH/KHW/Pod-Simple-3.45.tar.gz + provides: + Pod::Simple 3.45 + Pod::Simple::BlackBox 3.45 + Pod::Simple::Checker 3.45 + Pod::Simple::Debug 3.45 + Pod::Simple::DumpAsText 3.45 + Pod::Simple::DumpAsXML 3.45 + Pod::Simple::HTML 3.45 + Pod::Simple::HTMLBatch 3.45 + Pod::Simple::HTMLLegacy 5.01 + Pod::Simple::JustPod undef + Pod::Simple::LinkSection 3.45 + Pod::Simple::Methody 3.45 + Pod::Simple::Progress 3.45 + Pod::Simple::PullParser 3.45 + Pod::Simple::PullParserEndToken 3.45 + Pod::Simple::PullParserStartToken 3.45 + Pod::Simple::PullParserTextToken 3.45 + Pod::Simple::PullParserToken 3.45 + Pod::Simple::RTF 3.45 + Pod::Simple::Search 3.45 + Pod::Simple::SimpleTree 3.45 + Pod::Simple::Text 3.45 + Pod::Simple::TextContent 3.45 + Pod::Simple::TiedOutFH 3.45 + Pod::Simple::Transcode 3.45 + Pod::Simple::TranscodeDumb 3.45 + Pod::Simple::TranscodeSmart 3.45 + Pod::Simple::XHTML 3.45 + Pod::Simple::XMLOutStream 3.45 requirements: - Encode 0 - Exporter 0 + Carp 0 + Config 0 + Cwd 0 ExtUtils::MakeMaker 0 File::Basename 0 - FindBin 0 - Getopt::Long 0 - Getopt::Std 0 - Text::Wrap 0 - constant 0 - lib 0 + File::Find 0 + File::Spec 0 + Pod::Escapes 1.04 + Symbol 0 + Text::Wrap 98.112902 + if 0 + integer 0 overload 0 - parent 0 - perl 5.006 strict 0 - vars 0 - warnings 0 - Pod-Spell-1.20 - pathname: D/DO/DOLMEN/Pod-Spell-1.20.tar.gz + Pod-Spell-1.27 + pathname: H/HA/HAARG/Pod-Spell-1.27.tar.gz provides: - Pod::Spell 1.20 - Pod::Wordlist 1.20 + Pod::Spell 1.27 + Pod::Wordlist 1.27 requirements: Carp 0 Class::Tiny 0 @@ -7395,22 +6208,13 @@ DISTRIBUTIONS File::ShareDir::Install 0.06 Lingua::EN::Inflect 0 POSIX 0 - Path::Tiny 0 Pod::Escapes 0 - Pod::Parser 0 + Pod::Simple 3.27 Text::Wrap 0 constant 0 locale 0 parent 0 - perl 5.008 - strict 0 - warnings 0 - Proc-Wait3-0.05 - pathname: C/CT/CTILMES/Proc-Wait3-0.05.tar.gz - provides: - Proc::Wait3 0.05 - requirements: - ExtUtils::MakeMaker 0 + perl 5.008001 Readonly-2.05 pathname: S/SA/SANKO/Readonly-2.05.tar.gz provides: @@ -7421,91 +6225,55 @@ DISTRIBUTIONS requirements: Module::Build::Tiny 0.035 perl 5.005 - Ref-Util-0.203 - pathname: A/AR/ARC/Ref-Util-0.203.tar.gz + Ref-Util-0.204 + pathname: A/AR/ARC/Ref-Util-0.204.tar.gz provides: - Ref::Util 0.203 - Ref::Util::PP 0.203 + Ref::Util 0.204 + Ref::Util::PP 0.204 requirements: Exporter 5.57 ExtUtils::MakeMaker 0 Ref::Util::XS 0 Text::ParseWords 0 perl 5.006 - Ref-Util-XS-0.116 - pathname: X/XS/XSAWYERX/Ref-Util-XS-0.116.tar.gz + Ref-Util-XS-0.117 + pathname: X/XS/XSAWYERX/Ref-Util-XS-0.117.tar.gz provides: - Ref::Util::XS 0.116 + Ref::Util::XS 0.117 requirements: Exporter 5.57 ExtUtils::MakeMaker 0 XSLoader 0 perl 5.006 - Regexp-Common-2017060201 - pathname: A/AB/ABIGAIL/Regexp-Common-2017060201.tar.gz - provides: - Regexp::Common 2017060201 - Regexp::Common::CC 2017060201 - Regexp::Common::Entry 2017060201 - Regexp::Common::SEN 2017060201 - Regexp::Common::URI 2017060201 - Regexp::Common::URI::RFC1035 2017060201 - Regexp::Common::URI::RFC1738 2017060201 - Regexp::Common::URI::RFC1808 2017060201 - Regexp::Common::URI::RFC2384 2017060201 - Regexp::Common::URI::RFC2396 2017060201 - Regexp::Common::URI::RFC2806 2017060201 - Regexp::Common::URI::fax 2017060201 - Regexp::Common::URI::file 2017060201 - Regexp::Common::URI::ftp 2017060201 - Regexp::Common::URI::gopher 2017060201 - Regexp::Common::URI::http 2017060201 - Regexp::Common::URI::news 2017060201 - Regexp::Common::URI::pop 2017060201 - Regexp::Common::URI::prospero 2017060201 - Regexp::Common::URI::tel 2017060201 - Regexp::Common::URI::telnet 2017060201 - Regexp::Common::URI::tv 2017060201 - Regexp::Common::URI::wais 2017060201 - Regexp::Common::_support 2017060201 - Regexp::Common::balanced 2017060201 - Regexp::Common::comment 2017060201 - Regexp::Common::delimited 2017060201 - Regexp::Common::lingua 2017060201 - Regexp::Common::list 2017060201 - Regexp::Common::net 2017060201 - Regexp::Common::number 2017060201 - Regexp::Common::profanity 2017060201 - Regexp::Common::whitespace 2017060201 - Regexp::Common::zip 2017060201 - requirements: - Config 0 - ExtUtils::MakeMaker 0 - perl 5.01 - strict 0 - vars 0 - warnings 0 - Regexp-Common-time-0.14 - pathname: M/MA/MANWAR/Regexp-Common-time-0.14.tar.gz + Role-Hooks-0.008 + pathname: T/TO/TOBYINK/Role-Hooks-0.008.tar.gz provides: - Regexp::Common::time 0.14 + Role::Hooks 0.008 requirements: - ExtUtils::MakeMaker 0 - Regexp::Common 0 - Test::More 0.40 - perl 5.006 - Role-Tiny-2.000006 - pathname: H/HA/HAARG/Role-Tiny-2.000006.tar.gz + Class::Method::Modifiers 0 + ExtUtils::MakeMaker 6.17 + List::Util 1.45 + perl 5.008001 + Role-Tiny-2.002004 + pathname: H/HA/HAARG/Role-Tiny-2.002004.tar.gz provides: - Role::Tiny 2.000006 - Role::Tiny::With 2.000006 + Role::Tiny 2.002004 + Role::Tiny::With 2.002004 requirements: Exporter 5.57 perl 5.006 - SQL-Abstract-1.85 - pathname: I/IL/ILMARI/SQL-Abstract-1.85.tar.gz - provides: - SQL::Abstract 1.85 + SQL-Abstract-2.000001 + pathname: M/MS/MSTROUT/SQL-Abstract-2.000001.tar.gz + provides: + Chunkstrumenter undef + DBIx::Class::SQLMaker::Role::SQLA2Passthrough undef + SQL::Abstract 2.000001 + SQL::Abstract::Formatter undef + SQL::Abstract::Parts undef + SQL::Abstract::Plugin::BangOverrides undef + SQL::Abstract::Plugin::ExtraClauses undef + SQL::Abstract::Reference undef + SQL::Abstract::Role::Plugin undef SQL::Abstract::Test undef SQL::Abstract::Tree undef requirements: @@ -7517,27 +6285,37 @@ DISTRIBUTIONS Moo 2.000001 Scalar::Util 0 Sub::Quote 2.000001 + Test::Builder::Module 0.84 + Test::Deep 0.101 Text::Balanced 2.00 perl 5.006 - Safe-Isa-1.000008 - pathname: E/ET/ETHER/Safe-Isa-1.000008.tar.gz + SQL-Abstract-Pg-1.0 + pathname: S/SR/SRI/SQL-Abstract-Pg-1.0.tar.gz + provides: + SQL::Abstract::Pg 1.0 + requirements: + ExtUtils::MakeMaker 0 + SQL::Abstract 2.0 + perl 5.016 + Safe-Isa-1.000010 + pathname: E/ET/ETHER/Safe-Isa-1.000010.tar.gz provides: - Safe::Isa 1.000008 + Safe::Isa 1.000010 requirements: Exporter 5.57 ExtUtils::MakeMaker 0 Scalar::Util 0 perl 5.006 - Scalar-List-Utils-1.49 - pathname: P/PE/PEVANS/Scalar-List-Utils-1.49.tar.gz + Scalar-List-Utils-1.69 + pathname: P/PE/PEVANS/Scalar-List-Utils-1.69.tar.gz provides: - List::Util 1.49 - List::Util::XS 1.49 - Scalar::Util 1.49 - Sub::Util 1.49 + List::Util 1.69 + List::Util::XS 1.69 + Scalar::List::Utils 1.69 + Scalar::Util 1.69 + Sub::Util 1.69 requirements: ExtUtils::MakeMaker 0 - Test::More 0 perl 5.006 Scope-Guard-0.21 pathname: C/CH/CHOCOLATE/Scope-Guard-0.21.tar.gz @@ -7547,65 +6325,87 @@ DISTRIBUTIONS ExtUtils::MakeMaker 0 Test::More 0 perl 5.006001 - Search-Elasticsearch-2.03 - pathname: D/DR/DRTECH/Search-Elasticsearch-2.03.tar.gz - provides: - Search::Elasticsearch 2.03 - Search::Elasticsearch::Bulk 2.03 - Search::Elasticsearch::Client::0_90::Direct 2.03 - Search::Elasticsearch::Client::0_90::Direct::Cluster 2.03 - Search::Elasticsearch::Client::0_90::Direct::Indices 2.03 - Search::Elasticsearch::Client::1_0::Direct 2.03 - Search::Elasticsearch::Client::1_0::Direct::Cat 2.03 - Search::Elasticsearch::Client::1_0::Direct::Cluster 2.03 - Search::Elasticsearch::Client::1_0::Direct::Indices 2.03 - Search::Elasticsearch::Client::1_0::Direct::Nodes 2.03 - Search::Elasticsearch::Client::1_0::Direct::Snapshot 2.03 - Search::Elasticsearch::Client::2_0::Direct 2.03 - Search::Elasticsearch::Client::2_0::Direct::Cat 2.03 - Search::Elasticsearch::Client::2_0::Direct::Cluster 2.03 - Search::Elasticsearch::Client::2_0::Direct::Indices 2.03 - Search::Elasticsearch::Client::2_0::Direct::Nodes 2.03 - Search::Elasticsearch::Client::2_0::Direct::Snapshot 2.03 - Search::Elasticsearch::Client::2_0::Direct::Tasks 2.03 - Search::Elasticsearch::Cxn::Factory 2.03 - Search::Elasticsearch::Cxn::HTTPTiny 2.03 - Search::Elasticsearch::Cxn::Hijk 2.03 - Search::Elasticsearch::Cxn::LWP 2.03 - Search::Elasticsearch::CxnPool::Sniff 2.03 - Search::Elasticsearch::CxnPool::Static 2.03 - Search::Elasticsearch::CxnPool::Static::NoPing 2.03 - Search::Elasticsearch::Error 2.03 - Search::Elasticsearch::Logger::LogAny 2.03 - Search::Elasticsearch::Role::API::0_90 2.03 - Search::Elasticsearch::Role::API::1_0 2.03 - Search::Elasticsearch::Role::API::2_0 2.03 - Search::Elasticsearch::Role::Bulk 2.03 - Search::Elasticsearch::Role::Client 2.03 - Search::Elasticsearch::Role::Client::Direct 2.03 - Search::Elasticsearch::Role::Client::Direct::Main 2.03 - Search::Elasticsearch::Role::Cxn 2.03 - Search::Elasticsearch::Role::Cxn::HTTP 2.03 - Search::Elasticsearch::Role::CxnPool 2.03 - Search::Elasticsearch::Role::CxnPool::Sniff 2.03 - Search::Elasticsearch::Role::CxnPool::Static 2.03 - Search::Elasticsearch::Role::CxnPool::Static::NoPing 2.03 - Search::Elasticsearch::Role::Is_Sync 2.03 - Search::Elasticsearch::Role::Logger 2.03 - Search::Elasticsearch::Role::Scroll 2.03 - Search::Elasticsearch::Role::Serializer 2.03 - Search::Elasticsearch::Role::Serializer::JSON 2.03 - Search::Elasticsearch::Role::Transport 2.03 - Search::Elasticsearch::Scroll 2.03 - Search::Elasticsearch::Serializer::JSON 2.03 - Search::Elasticsearch::Serializer::JSON::Cpanel 2.03 - Search::Elasticsearch::Serializer::JSON::PP 2.03 - Search::Elasticsearch::Serializer::JSON::XS 2.03 - Search::Elasticsearch::TestServer 2.03 - Search::Elasticsearch::Transport 2.03 - Search::Elasticsearch::Util 2.03 - Search::Elasticsearch::Util::API::Path 2.03 - Search::Elasticsearch::Util::API::QS 2.03 + Search-Elasticsearch-8.12 + pathname: E/EZ/EZIMUEL/Search-Elasticsearch-8.12.tar.gz + provides: + Search::Elasticsearch 8.12 + Search::Elasticsearch::Client::8_0 8.12 + Search::Elasticsearch::Client::8_0::Bulk 8.12 + Search::Elasticsearch::Client::8_0::Direct 8.12 + Search::Elasticsearch::Client::8_0::Direct::Autoscaling 8.12 + Search::Elasticsearch::Client::8_0::Direct::CCR 8.12 + Search::Elasticsearch::Client::8_0::Direct::Cat 8.12 + Search::Elasticsearch::Client::8_0::Direct::Cluster 8.12 + Search::Elasticsearch::Client::8_0::Direct::Connector 8.12 + Search::Elasticsearch::Client::8_0::Direct::ConnectorSyncJob 8.12 + Search::Elasticsearch::Client::8_0::Direct::DanglingIndices 8.12 + Search::Elasticsearch::Client::8_0::Direct::Enrich 8.12 + Search::Elasticsearch::Client::8_0::Direct::Eql 8.12 + Search::Elasticsearch::Client::8_0::Direct::Esql 8.12 + Search::Elasticsearch::Client::8_0::Direct::Features 8.12 + Search::Elasticsearch::Client::8_0::Direct::Fleet 8.12 + Search::Elasticsearch::Client::8_0::Direct::Graph 8.12 + Search::Elasticsearch::Client::8_0::Direct::ILM 8.12 + Search::Elasticsearch::Client::8_0::Direct::Indices 8.12 + Search::Elasticsearch::Client::8_0::Direct::Inference 8.12 + Search::Elasticsearch::Client::8_0::Direct::Ingest 8.12 + Search::Elasticsearch::Client::8_0::Direct::License 8.12 + Search::Elasticsearch::Client::8_0::Direct::Logstash 8.12 + Search::Elasticsearch::Client::8_0::Direct::ML 8.12 + Search::Elasticsearch::Client::8_0::Direct::Migration 8.12 + Search::Elasticsearch::Client::8_0::Direct::Monitoring 8.12 + Search::Elasticsearch::Client::8_0::Direct::Nodes 8.12 + Search::Elasticsearch::Client::8_0::Direct::Profiling 8.12 + Search::Elasticsearch::Client::8_0::Direct::QueryRuleset 8.12 + Search::Elasticsearch::Client::8_0::Direct::Rollup 8.12 + Search::Elasticsearch::Client::8_0::Direct::SQL 8.12 + Search::Elasticsearch::Client::8_0::Direct::SSL 8.12 + Search::Elasticsearch::Client::8_0::Direct::SearchApplication 8.12 + Search::Elasticsearch::Client::8_0::Direct::SearchableSnapshots 8.12 + Search::Elasticsearch::Client::8_0::Direct::Security 8.12 + Search::Elasticsearch::Client::8_0::Direct::Shutdown 8.12 + Search::Elasticsearch::Client::8_0::Direct::Simulate 8.12 + Search::Elasticsearch::Client::8_0::Direct::Slm 8.12 + Search::Elasticsearch::Client::8_0::Direct::Snapshot 8.12 + Search::Elasticsearch::Client::8_0::Direct::Synonyms 8.12 + Search::Elasticsearch::Client::8_0::Direct::Tasks 8.12 + Search::Elasticsearch::Client::8_0::Direct::TextStructure 8.12 + Search::Elasticsearch::Client::8_0::Direct::Transform 8.12 + Search::Elasticsearch::Client::8_0::Direct::Watcher 8.12 + Search::Elasticsearch::Client::8_0::Direct::XPack 8.12 + Search::Elasticsearch::Client::8_0::Role::API 8.12 + Search::Elasticsearch::Client::8_0::Role::Bulk 8.12 + Search::Elasticsearch::Client::8_0::Role::Scroll 8.12 + Search::Elasticsearch::Client::8_0::Scroll 8.12 + Search::Elasticsearch::Client::8_0::TestServer 8.12 + Search::Elasticsearch::Cxn::Factory 8.12 + Search::Elasticsearch::Cxn::HTTPTiny 8.12 + Search::Elasticsearch::Cxn::LWP 8.12 + Search::Elasticsearch::CxnPool::Sniff 8.12 + Search::Elasticsearch::CxnPool::Static 8.12 + Search::Elasticsearch::CxnPool::Static::NoPing 8.12 + Search::Elasticsearch::Error 8.12 + Search::Elasticsearch::Logger::LogAny 8.12 + Search::Elasticsearch::Role::API 8.12 + Search::Elasticsearch::Role::Client 8.12 + Search::Elasticsearch::Role::Client::Direct 8.12 + Search::Elasticsearch::Role::Cxn 8.12 + Search::Elasticsearch::Role::CxnPool 8.12 + Search::Elasticsearch::Role::CxnPool::Sniff 8.12 + Search::Elasticsearch::Role::CxnPool::Static 8.12 + Search::Elasticsearch::Role::CxnPool::Static::NoPing 8.12 + Search::Elasticsearch::Role::Is_Sync 8.12 + Search::Elasticsearch::Role::Logger 8.12 + Search::Elasticsearch::Role::Serializer 8.12 + Search::Elasticsearch::Role::Serializer::JSON 8.12 + Search::Elasticsearch::Role::Transport 8.12 + Search::Elasticsearch::Serializer::JSON 8.12 + Search::Elasticsearch::Serializer::JSON::Cpanel 8.12 + Search::Elasticsearch::Serializer::JSON::PP 8.12 + Search::Elasticsearch::Serializer::JSON::XS 8.12 + Search::Elasticsearch::TestServer 8.12 + Search::Elasticsearch::Transport 8.12 + Search::Elasticsearch::Util 8.12 requirements: Any::URI::Escape 0 Data::Dumper 0 @@ -7615,9 +6415,12 @@ DISTRIBUTIONS File::Temp 0 HTTP::Headers 0 HTTP::Request 0 - HTTP::Tiny 0.043 + HTTP::Tiny 0.076 + IO::Compress::Deflate 0 + IO::Compress::Gzip 0 IO::Select 0 IO::Socket 0 + IO::Uncompress::Gunzip 0 IO::Uncompress::Inflate 0 JSON::MaybeXS 1.002002 JSON::PP 0 @@ -7627,8 +6430,9 @@ DISTRIBUTIONS Log::Any::Adapter 0 MIME::Base64 0 Module::Runtime 0 - Moo 1.003 + Moo 2.001000 Moo::Role 0 + Net::IP 0 POSIX 0 Package::Stash 0.34 Scalar::Util 0 @@ -7640,34 +6444,82 @@ DISTRIBUTIONS overload 0 strict 0 warnings 0 - Server-Starter-0.33 - pathname: K/KA/KAZUHO/Server-Starter-0.33.tar.gz - provides: - Server::Starter 0.33 - Server::Starter::Guard undef - requirements: - ExtUtils::CBuilder 0 - Module::Build 0.4005 - perl 5.008 - Signal-Mask-0.008 - pathname: L/LE/LEONT/Signal-Mask-0.008.tar.gz - provides: - Signal::Mask 0.008 - Signal::Pending 0.008 + Search-Elasticsearch-Client-2_0-6.81 + pathname: E/EZ/EZIMUEL/Search-Elasticsearch-Client-2_0-6.81.tar.gz + provides: + Search::Elasticsearch::Client::2_0 6.81 + Search::Elasticsearch::Client::2_0::Bulk 6.81 + Search::Elasticsearch::Client::2_0::Direct 6.81 + Search::Elasticsearch::Client::2_0::Direct::Cat 6.81 + Search::Elasticsearch::Client::2_0::Direct::Cluster 6.81 + Search::Elasticsearch::Client::2_0::Direct::Indices 6.81 + Search::Elasticsearch::Client::2_0::Direct::Nodes 6.81 + Search::Elasticsearch::Client::2_0::Direct::Snapshot 6.81 + Search::Elasticsearch::Client::2_0::Direct::Tasks 6.81 + Search::Elasticsearch::Client::2_0::Role::API 6.81 + Search::Elasticsearch::Client::2_0::Role::Bulk 6.81 + Search::Elasticsearch::Client::2_0::Role::Scroll 6.81 + Search::Elasticsearch::Client::2_0::Scroll 6.81 + Search::Elasticsearch::Client::2_0::TestServer 6.81 requirements: - Carp 0 - ExtUtils::MakeMaker 6.30 - IPC::Signal 0 - POSIX 0 + Devel::GlobalDestruction 0 + ExtUtils::MakeMaker 0 + Moo 0 + Moo::Role 0 + Search::Elasticsearch 6.00 + Search::Elasticsearch::Role::API 0 + Search::Elasticsearch::Role::Client::Direct 0 + Search::Elasticsearch::Role::Is_Sync 0 + Search::Elasticsearch::Util 0 + Try::Tiny 0 + namespace::clean 0 strict 0 warnings 0 - Sort-Naturally-1.03 - pathname: B/BI/BINGOS/Sort-Naturally-1.03.tar.gz + Sereal-Decoder-5.004 + pathname: Y/YV/YVES/Sereal-Decoder-5.004.tar.gz provides: - Sort::Naturally 1.03 + Sereal::Decoder 5.004 + Sereal::Decoder::Constants 5.004 + Sereal::Performance undef requirements: - ExtUtils::MakeMaker 0 - perl 5 + Data::Dumper 0 + Devel::CheckLib 1.16 + ExtUtils::MakeMaker 7.0 + ExtUtils::ParseXS 2.21 + File::Find 0 + File::Path 0 + File::Spec 0 + Scalar::Util 0 + Test::Deep 0 + Test::Differences 0 + Test::LongString 0 + Test::More 0.88 + Test::Warn 0 + XSLoader 0 + perl 5.008 + Sereal-Encoder-5.004 + pathname: Y/YV/YVES/Sereal-Encoder-5.004.tar.gz + provides: + Sereal::Encoder 5.004 + Sereal::Encoder::Constants 5.004 + requirements: + Data::Dumper 0 + Devel::CheckLib 1.16 + ExtUtils::MakeMaker 7.0 + ExtUtils::ParseXS 2.21 + File::Find 0 + File::Path 0 + File::Spec 0 + Hash::Util 0 + Scalar::Util 0 + Sereal::Decoder 5.004 + Test::Deep 0 + Test::Differences 0 + Test::LongString 0 + Test::More 0.88 + Test::Warn 0 + XSLoader 0 + perl 5.008 Sort-Versions-1.62 pathname: N/NE/NEILB/Sort-Versions-1.62.tar.gz provides: @@ -7678,52 +6530,53 @@ DISTRIBUTIONS perl 5.006 strict 0 warnings 0 - Specio-0.42 - pathname: D/DR/DROLSKY/Specio-0.42.tar.gz - provides: - Specio 0.42 - Specio::Coercion 0.42 - Specio::Constraint::AnyCan 0.42 - Specio::Constraint::AnyDoes 0.42 - Specio::Constraint::AnyIsa 0.42 - Specio::Constraint::Enum 0.42 - Specio::Constraint::Intersection 0.42 - Specio::Constraint::ObjectCan 0.42 - Specio::Constraint::ObjectDoes 0.42 - Specio::Constraint::ObjectIsa 0.42 - Specio::Constraint::Parameterizable 0.42 - Specio::Constraint::Parameterized 0.42 - Specio::Constraint::Role::CanType 0.42 - Specio::Constraint::Role::DoesType 0.42 - Specio::Constraint::Role::Interface 0.42 - Specio::Constraint::Role::IsaType 0.42 - Specio::Constraint::Simple 0.42 - Specio::Constraint::Structurable 0.42 - Specio::Constraint::Structured 0.42 - Specio::Constraint::Union 0.42 - Specio::Declare 0.42 - Specio::DeclaredAt 0.42 - Specio::Exception 0.42 - Specio::Exporter 0.42 - Specio::Helpers 0.42 - Specio::Library::Builtins 0.42 - Specio::Library::Numeric 0.42 - Specio::Library::Perl 0.42 - Specio::Library::String 0.42 - Specio::Library::Structured 0.42 - Specio::Library::Structured::Dict 0.42 - Specio::Library::Structured::Map 0.42 - Specio::Library::Structured::Tuple 0.42 - Specio::OO 0.42 - Specio::PartialDump 0.42 - Specio::Registry 0.42 - Specio::Role::Inlinable 0.42 - Specio::Subs 0.42 - Specio::TypeChecks 0.42 - Test::Specio 0.42 + Specio-0.50 + pathname: D/DR/DROLSKY/Specio-0.50.tar.gz + provides: + Specio 0.50 + Specio::Coercion 0.50 + Specio::Constraint::AnyCan 0.50 + Specio::Constraint::AnyDoes 0.50 + Specio::Constraint::AnyIsa 0.50 + Specio::Constraint::Enum 0.50 + Specio::Constraint::Intersection 0.50 + Specio::Constraint::ObjectCan 0.50 + Specio::Constraint::ObjectDoes 0.50 + Specio::Constraint::ObjectIsa 0.50 + Specio::Constraint::Parameterizable 0.50 + Specio::Constraint::Parameterized 0.50 + Specio::Constraint::Role::CanType 0.50 + Specio::Constraint::Role::DoesType 0.50 + Specio::Constraint::Role::Interface 0.50 + Specio::Constraint::Role::IsaType 0.50 + Specio::Constraint::Simple 0.50 + Specio::Constraint::Structurable 0.50 + Specio::Constraint::Structured 0.50 + Specio::Constraint::Union 0.50 + Specio::Declare 0.50 + Specio::DeclaredAt 0.50 + Specio::Exception 0.50 + Specio::Exporter 0.50 + Specio::Helpers 0.50 + Specio::Library::Builtins 0.50 + Specio::Library::Numeric 0.50 + Specio::Library::Perl 0.50 + Specio::Library::String 0.50 + Specio::Library::Structured 0.50 + Specio::Library::Structured::Dict 0.50 + Specio::Library::Structured::Map 0.50 + Specio::Library::Structured::Tuple 0.50 + Specio::OO 0.50 + Specio::PartialDump 0.50 + Specio::Registry 0.50 + Specio::Role::Inlinable 0.50 + Specio::Subs 0.50 + Specio::TypeChecks 0.50 + Test::Specio 0.50 requirements: B 0 Carp 0 + Clone 0 Devel::StackTrace 0 Eval::Closure 0 Exporter 0 @@ -7735,11 +6588,11 @@ DISTRIBUTIONS Role::Tiny 1.003003 Role::Tiny::With 0 Scalar::Util 0 - Storable 0 Sub::Quote 0 Test::Fatal 0 Test::More 0.96 Try::Tiny 0 + XString 0 overload 0 parent 0 perl 5.008 @@ -7747,10 +6600,10 @@ DISTRIBUTIONS strict 0 version 0.83 warnings 0 - Specio-Library-Path-Tiny-0.04 - pathname: D/DR/DROLSKY/Specio-Library-Path-Tiny-0.04.tar.gz + Specio-Library-Path-Tiny-0.05 + pathname: D/DR/DROLSKY/Specio-Library-Path-Tiny-0.05.tar.gz provides: - Specio::Library::Path::Tiny 0.04 + Specio::Library::Path::Tiny 0.05 requirements: ExtUtils::MakeMaker 0 Path::Tiny 0.087 @@ -7764,24 +6617,6 @@ DISTRIBUTIONS parent 0 strict 0 warnings 0 - Starman-0.4014 - pathname: M/MI/MIYAGAWA/Starman-0.4014.tar.gz - provides: - HTTP::Server::PSGI::Net::Server::PreFork undef - Plack::Handler::Starman undef - Starman 0.4014 - Starman::Server undef - requirements: - Data::Dump 0 - HTTP::Date 0 - HTTP::Parser::XS 0 - HTTP::Status 0 - Module::Build::Tiny 0.039 - Net::Server 2.007 - Plack 0.9971 - Test::TCP 2.00 - parent 0 - perl 5.008001 Stream-Buffered-0.03 pathname: D/DO/DOY/Stream-Buffered-0.03.tar.gz provides: @@ -7792,57 +6627,48 @@ DISTRIBUTIONS requirements: ExtUtils::MakeMaker 6.30 IO::File 1.14 - String-Format-1.17 - pathname: D/DA/DARREN/String-Format-1.17.tar.gz + String-Format-1.18 + pathname: S/SR/SREZIC/String-Format-1.18.tar.gz provides: - String::Format 1.17 + String::Format 1.18 requirements: ExtUtils::MakeMaker 0 Test::More 0 - String-RewritePrefix-0.007 - pathname: R/RJ/RJBS/String-RewritePrefix-0.007.tar.gz + String-RewritePrefix-0.009 + pathname: R/RJ/RJBS/String-RewritePrefix-0.009.tar.gz provides: - String::RewritePrefix 0.007 + String::RewritePrefix 0.009 requirements: Carp 0 - ExtUtils::MakeMaker 6.30 + ExtUtils::MakeMaker 6.78 Sub::Exporter 0.972 + perl 5.012 strict 0 warnings 0 - String-Trim-0.005 - pathname: D/DO/DOHERTY/String-Trim-0.005.tar.gz + Sub-Exporter-0.991 + pathname: R/RJ/RJBS/Sub-Exporter-0.991.tar.gz provides: - String::Trim 0.005 - requirements: - Data::Dumper 0 - Exporter 5.57 - ExtUtils::MakeMaker 6.31 - File::Find 0 - File::Temp 0 - Test::Builder 0.94 - Test::More 0.94 - Sub-Exporter-0.987 - pathname: R/RJ/RJBS/Sub-Exporter-0.987.tar.gz - provides: - Sub::Exporter 0.987 - Sub::Exporter::Util 0.987 + Sub::Exporter 0.991 + Sub::Exporter::Util 0.991 requirements: Carp 0 Data::OptList 0.100 - ExtUtils::MakeMaker 6.30 + ExtUtils::MakeMaker 6.78 Params::Util 0.14 Sub::Install 0.92 + perl 5.012 strict 0 warnings 0 - Sub-Exporter-ForMethods-0.100052 - pathname: R/RJ/RJBS/Sub-Exporter-ForMethods-0.100052.tar.gz + Sub-Exporter-ForMethods-0.100055 + pathname: R/RJ/RJBS/Sub-Exporter-ForMethods-0.100055.tar.gz provides: - Sub::Exporter::ForMethods 0.100052 + Sub::Exporter::ForMethods 0.100055 requirements: - ExtUtils::MakeMaker 0 + ExtUtils::MakeMaker 6.78 Scalar::Util 0 Sub::Exporter 0.978 - Sub::Name 0 + Sub::Util 0 + perl 5.012 strict 0 warnings 0 Sub-Exporter-Progressive-0.001013 @@ -7851,48 +6677,64 @@ DISTRIBUTIONS Sub::Exporter::Progressive 0.001013 requirements: ExtUtils::MakeMaker 0 - Sub-Identify-0.14 - pathname: R/RG/RGARCIA/Sub-Identify-0.14.tar.gz - provides: - Sub::Identify 0.14 + Sub-HandlesVia-0.050002 + pathname: T/TO/TOBYINK/Sub-HandlesVia-0.050002.tar.gz + provides: + Sub::HandlesVia 0.050002 + Sub::HandlesVia::CodeGenerator 0.050002 + Sub::HandlesVia::Declare 0.050002 + Sub::HandlesVia::Handler 0.050002 + Sub::HandlesVia::Handler::CodeRef 0.050002 + Sub::HandlesVia::Handler::Traditional 0.050002 + Sub::HandlesVia::HandlerLibrary 0.050002 + Sub::HandlesVia::HandlerLibrary::Array 0.050002 + Sub::HandlesVia::HandlerLibrary::Blessed 0.050002 + Sub::HandlesVia::HandlerLibrary::Bool 0.050002 + Sub::HandlesVia::HandlerLibrary::Code 0.050002 + Sub::HandlesVia::HandlerLibrary::Counter 0.050002 + Sub::HandlesVia::HandlerLibrary::Enum 0.050002 + Sub::HandlesVia::HandlerLibrary::Hash 0.050002 + Sub::HandlesVia::HandlerLibrary::Number 0.050002 + Sub::HandlesVia::HandlerLibrary::Scalar 0.050002 + Sub::HandlesVia::HandlerLibrary::String 0.050002 + Sub::HandlesVia::Mite undef + Sub::HandlesVia::Toolkit 0.050002 + Sub::HandlesVia::Toolkit::Mite 0.050002 + Sub::HandlesVia::Toolkit::Moo 0.050002 + Sub::HandlesVia::Toolkit::Moose 0.050002 + Sub::HandlesVia::Toolkit::Moose::PackageTrait 0.050002 + Sub::HandlesVia::Toolkit::Moose::RoleTrait 0.050002 + Sub::HandlesVia::Toolkit::Mouse 0.050002 + Sub::HandlesVia::Toolkit::Mouse::PackageTrait 0.050002 + Sub::HandlesVia::Toolkit::Mouse::RoleTrait 0.050002 + Sub::HandlesVia::Toolkit::ObjectPad 0.050002 + Sub::HandlesVia::Toolkit::Plain 0.050002 requirements: - ExtUtils::MakeMaker 0 - Test::More 0 - Sub-Install-0.928 - pathname: R/RJ/RJBS/Sub-Install-0.928.tar.gz + Class::Method::Modifiers 0 + Exporter::Shiny 0 + ExtUtils::MakeMaker 6.17 + List::Util 1.54 + Role::Hooks 0.008 + Role::Tiny 0 + Type::Tiny 1.004 + perl 5.008001 + Sub-Install-0.929 + pathname: R/RJ/RJBS/Sub-Install-0.929.tar.gz provides: - Sub::Install 0.928 + Sub::Install 0.929 requirements: B 0 Carp 0 - ExtUtils::MakeMaker 6.30 + ExtUtils::MakeMaker 6.78 Scalar::Util 0 + perl 5.008000 strict 0 warnings 0 - Sub-Name-0.21 - pathname: E/ET/ETHER/Sub-Name-0.21.tar.gz + Sub-Quote-2.006008 + pathname: H/HA/HAARG/Sub-Quote-2.006008.tar.gz provides: - Sub::Name 0.21 - requirements: - Exporter 5.57 - ExtUtils::MakeMaker 0 - XSLoader 0 - perl 5.006 - strict 0 - warnings 0 - Sub-Override-0.09 - pathname: O/OV/OVID/Sub-Override-0.09.tar.gz - provides: - Sub::Override 0.09 - requirements: - ExtUtils::MakeMaker 0 - Test::Fatal 0.010 - Test::More 0.47 - Sub-Quote-2.004000 - pathname: H/HA/HAARG/Sub-Quote-2.004000.tar.gz - provides: - Sub::Defer 2.004000 - Sub::Quote 2.004000 + Sub::Defer 2.006008 + Sub::Quote 2.006008 requirements: ExtUtils::MakeMaker 0 Scalar::Util 0 @@ -7908,33 +6750,41 @@ DISTRIBUTIONS perl 5.006 strict 0 warnings 0 - System-Sub-0.162800 - pathname: D/DO/DOLMEN/System-Sub-0.162800.tar.gz + Symbol-Get-0.12 + pathname: F/FE/FELIPE/Symbol-Get-0.12.tar.gz provides: - System::Sub 0.162800 - System::Sub::AutoLoad 0.162800 + Symbol::Get 0.12 + requirements: + Call::Context 0 + ExtUtils::MakeMaker 0 + TOML-Tiny-0.20 + pathname: O/OA/OALDERS/TOML-Tiny-0.20.tar.gz + provides: + TOML::Tiny 0.20 + TOML::Tiny::Grammar 0.20 + TOML::Tiny::Parser 0.20 + TOML::Tiny::Tokenizer 0.20 + TOML::Tiny::Util 0.20 + TOML::Tiny::Writer 0.20 requirements: Carp 0 + Data::Dumper 0 + Encode 0 + Exporter 0 ExtUtils::MakeMaker 0 - File::Which 0 - IPC::Run 0 - Scalar::Util 1.11 - Sub::Name 0 - Symbol 0 - constant 0 - perl 5.006 - strict 0 - warnings 0 - Task-Weaken-1.04 - pathname: A/AD/ADAMK/Task-Weaken-1.04.tar.gz + Math::BigInt 1.999718 + perl 5.018 + Task-Weaken-1.06 + pathname: E/ET/ETHER/Task-Weaken-1.06.tar.gz provides: - Task::Weaken 1.04 + Task::Weaken 1.06 requirements: - ExtUtils::MakeMaker 6.42 - File::Spec 0.80 + Config 0 + ExtUtils::MakeMaker 0 + File::Spec 0 Scalar::Util 1.14 - Test::More 0.42 - perl 5.005 + perl 5.006 + strict 0 Term-Size-Any-0.002 pathname: F/FE/FERREIRA/Term-Size-Any-0.002.tar.gz provides: @@ -7945,171 +6795,178 @@ DISTRIBUTIONS Module::Load::Conditional 0 Term::Size::Perl 0 Test::More 0 - Term-Size-Perl-0.029 - pathname: F/FE/FERREIRA/Term-Size-Perl-0.029.tar.gz + Term-Size-Perl-0.031 + pathname: F/FE/FERREIRA/Term-Size-Perl-0.031.tar.gz provides: - Term::Size::Perl 0.029 + Term::Size::Perl 0.031 requirements: Exporter 0 ExtUtils::CBuilder 0 ExtUtils::MakeMaker 0 - Test::More 0 - Term-UI-0.46 - pathname: B/BI/BINGOS/Term-UI-0.46.tar.gz + Term-Table-0.024 + pathname: E/EX/EXODIST/Term-Table-0.024.tar.gz provides: - Term::UI 0.46 - Term::UI::History 0.46 + Term::Table 0.024 + Term::Table::Cell 0.024 + Term::Table::CellStack 0.024 + Term::Table::HashBase 0.024 + Term::Table::LineBreak 0.024 + Term::Table::Spacer 0.024 + Term::Table::Util 0.024 requirements: + Carp 0 ExtUtils::MakeMaker 0 - Locale::Maketext::Simple 0 - Log::Message::Simple 0 - Params::Check 0 - Term::ReadLine 0 - Test::More 0.31 - if 0 - TermReadKey-2.37 - pathname: J/JS/JSTOWE/TermReadKey-2.37.tar.gz - provides: - Term::ReadKey 2.37 - requirements: - ExtUtils::MakeMaker 6.58 - Test-Abortable-0.002 - pathname: R/RJ/RJBS/Test-Abortable-0.002.tar.gz + List::Util 0 + Scalar::Util 0 + perl 5.008001 + Test-Abortable-0.003 + pathname: R/RJ/RJBS/Test-Abortable-0.003.tar.gz provides: - Test::Abortable 0.002 + Test::Abortable 0.003 requirements: - ExtUtils::MakeMaker 0 + ExtUtils::MakeMaker 6.78 Sub::Exporter 0 Test2::API 1.302075 - strict 0 - warnings 0 - Test-Compile-v1.3.0 - pathname: E/EG/EGILES/Test-Compile-v1.3.0.tar.gz - provides: - Test::Compile v1.3.0 - Test::Compile::Internal v1.3.0 - requirements: - Module::Build 0.38 - UNIVERSAL::require 0 - perl v5.6.2 - version 0 - Test-Deep-1.127 - pathname: R/RJ/RJBS/Test-Deep-1.127.tar.gz - provides: - Test::Deep 1.127 - Test::Deep::All undef - Test::Deep::Any undef - Test::Deep::Array undef - Test::Deep::ArrayEach undef - Test::Deep::ArrayElementsOnly undef - Test::Deep::ArrayLength undef - Test::Deep::ArrayLengthOnly undef - Test::Deep::Blessed undef - Test::Deep::Boolean undef - Test::Deep::Cache undef - Test::Deep::Cache::Simple undef - Test::Deep::Class undef - Test::Deep::Cmp undef - Test::Deep::Code undef - Test::Deep::Hash undef - Test::Deep::HashEach undef - Test::Deep::HashElements undef - Test::Deep::HashKeys undef - Test::Deep::HashKeysOnly undef - Test::Deep::Ignore undef - Test::Deep::Isa undef - Test::Deep::ListMethods undef - Test::Deep::MM undef - Test::Deep::Methods undef - Test::Deep::NoTest undef - Test::Deep::None undef - Test::Deep::Number undef - Test::Deep::Obj undef - Test::Deep::Ref undef - Test::Deep::RefType undef - Test::Deep::Regexp undef - Test::Deep::RegexpMatches undef - Test::Deep::RegexpOnly undef - Test::Deep::RegexpRef undef - Test::Deep::RegexpRefOnly undef - Test::Deep::RegexpVersion undef - Test::Deep::ScalarRef undef - Test::Deep::ScalarRefOnly undef - Test::Deep::Set undef - Test::Deep::Shallow undef - Test::Deep::Stack undef - Test::Deep::String undef - Test::Deep::SubHash undef - Test::Deep::SubHashElements undef - Test::Deep::SubHashKeys undef - Test::Deep::SubHashKeysOnly undef - Test::Deep::SuperHash undef - Test::Deep::SuperHashElements undef - Test::Deep::SuperHashKeys undef - Test::Deep::SuperHashKeysOnly undef - requirements: - ExtUtils::MakeMaker 0 + perl 5.012 + strict 0 + warnings 0 + Test-Deep-1.205 + pathname: R/RJ/RJBS/Test-Deep-1.205.tar.gz + provides: + Test::Deep 1.205 + Test::Deep::All 1.205 + Test::Deep::Any 1.205 + Test::Deep::Array 1.205 + Test::Deep::ArrayEach 1.205 + Test::Deep::ArrayElementsOnly 1.205 + Test::Deep::ArrayLength 1.205 + Test::Deep::ArrayLengthOnly 1.205 + Test::Deep::Blessed 1.205 + Test::Deep::Boolean 1.205 + Test::Deep::Cache 1.205 + Test::Deep::Cache::Simple 1.205 + Test::Deep::Class 1.205 + Test::Deep::Cmp 1.205 + Test::Deep::Code 1.205 + Test::Deep::Hash 1.205 + Test::Deep::HashEach 1.205 + Test::Deep::HashElements 1.205 + Test::Deep::HashKeys 1.205 + Test::Deep::HashKeysOnly 1.205 + Test::Deep::Ignore 1.205 + Test::Deep::Isa 1.205 + Test::Deep::ListMethods 1.205 + Test::Deep::MM 1.205 + Test::Deep::Methods 1.205 + Test::Deep::NoTest 1.205 + Test::Deep::None 1.205 + Test::Deep::Number 1.205 + Test::Deep::Obj 1.205 + Test::Deep::Ref 1.205 + Test::Deep::RefType 1.205 + Test::Deep::Regexp 1.205 + Test::Deep::RegexpMatches 1.205 + Test::Deep::RegexpOnly 1.205 + Test::Deep::RegexpRef 1.205 + Test::Deep::RegexpRefOnly 1.205 + Test::Deep::RegexpVersion 1.205 + Test::Deep::ScalarRef 1.205 + Test::Deep::ScalarRefOnly 1.205 + Test::Deep::Set 1.205 + Test::Deep::Shallow 1.205 + Test::Deep::Stack 1.205 + Test::Deep::String 1.205 + Test::Deep::SubHash 1.205 + Test::Deep::SubHashElements 1.205 + Test::Deep::SubHashKeys 1.205 + Test::Deep::SubHashKeysOnly 1.205 + Test::Deep::SuperHash 1.205 + Test::Deep::SuperHashElements 1.205 + Test::Deep::SuperHashKeys 1.205 + Test::Deep::SuperHashKeysOnly 1.205 + requirements: + ExtUtils::MakeMaker 6.78 List::Util 1.09 Scalar::Util 1.09 Test::Builder 0 - Test-Differences-0.64 - pathname: D/DC/DCANTRELL/Test-Differences-0.64.tar.gz + Test::More 0.96 + perl 5.012 + Test-Differences-0.71 + pathname: D/DC/DCANTRELL/Test-Differences-0.71.tar.gz provides: - Test::Differences 0.64 + Test::Differences 0.71 requirements: Capture::Tiny 0.24 Data::Dumper 2.126 - Test::More 0.88 - Text::Diff 0.35 - Test-Exception-0.43 - pathname: E/EX/EXODIST/Test-Exception-0.43.tar.gz - provides: - Test::Exception 0.43 - requirements: - Carp 0 - Exporter 0 ExtUtils::MakeMaker 0 - Sub::Uplevel 0.18 - Test::Builder 0.7 - Test::Builder::Tester 1.07 - Test::Harness 2.03 - base 0 - perl 5.006001 - strict 0 - warnings 0 - Test-Fatal-0.014 - pathname: R/RJ/RJBS/Test-Fatal-0.014.tar.gz + Test::More 0.88 + Text::Diff 1.43 + Test-Fatal-0.017 + pathname: R/RJ/RJBS/Test-Fatal-0.017.tar.gz provides: - Test::Fatal 0.014 + Test::Fatal 0.017 requirements: Carp 0 Exporter 5.57 - ExtUtils::MakeMaker 0 + ExtUtils::MakeMaker 6.78 Test::Builder 0 Try::Tiny 0.07 strict 0 warnings 0 - Test-HTTP-Server-Simple-0.11 - pathname: A/AL/ALEXMV/Test-HTTP-Server-Simple-0.11.tar.gz - provides: - Test::HTTP::Server::Simple 0.11 + Test-Harness-3.50 + pathname: L/LE/LEONT/Test-Harness-3.50.tar.gz + provides: + App::Prove 3.50 + App::Prove::State 3.50 + App::Prove::State::Result 3.50 + App::Prove::State::Result::Test 3.50 + Harness::Hook undef + TAP::Base 3.50 + TAP::Formatter::Base 3.50 + TAP::Formatter::Color 3.50 + TAP::Formatter::Console 3.50 + TAP::Formatter::Console::ParallelSession 3.50 + TAP::Formatter::Console::Session 3.50 + TAP::Formatter::File 3.50 + TAP::Formatter::File::Session 3.50 + TAP::Formatter::Session 3.50 + TAP::Harness 3.50 + TAP::Harness::Env 3.50 + TAP::Object 3.50 + TAP::Parser 3.50 + TAP::Parser::Aggregator 3.50 + TAP::Parser::Grammar 3.50 + TAP::Parser::Iterator 3.50 + TAP::Parser::Iterator::Array 3.50 + TAP::Parser::Iterator::Process 3.50 + TAP::Parser::Iterator::Stream 3.50 + TAP::Parser::IteratorFactory 3.50 + TAP::Parser::Multiplexer 3.50 + TAP::Parser::Result 3.50 + TAP::Parser::Result::Bailout 3.50 + TAP::Parser::Result::Comment 3.50 + TAP::Parser::Result::Plan 3.50 + TAP::Parser::Result::Pragma 3.50 + TAP::Parser::Result::Test 3.50 + TAP::Parser::Result::Unknown 3.50 + TAP::Parser::Result::Version 3.50 + TAP::Parser::Result::YAML 3.50 + TAP::Parser::ResultFactory 3.50 + TAP::Parser::Scheduler 3.50 + TAP::Parser::Scheduler::Job 3.50 + TAP::Parser::Scheduler::Spinner 3.50 + TAP::Parser::Source 3.50 + TAP::Parser::SourceHandler 3.50 + TAP::Parser::SourceHandler::Executable 3.50 + TAP::Parser::SourceHandler::File 3.50 + TAP::Parser::SourceHandler::Handle 3.50 + TAP::Parser::SourceHandler::Perl 3.50 + TAP::Parser::SourceHandler::RawTAP 3.50 + TAP::Parser::YAMLish::Reader 3.50 + TAP::Parser::YAMLish::Writer 3.50 + Test::Harness 3.50 requirements: ExtUtils::MakeMaker 0 - HTTP::Server::Simple 0 - NEXT 0 - Test::Builder 0 - Test::Builder::Tester 1.04 - Test::More 0 - Test-InDistDir-1.112071 - pathname: M/MI/MITHALDU/Test-InDistDir-1.112071.tar.gz - provides: - Test::InDistDir 1.112071 - requirements: - ExtUtils::MakeMaker 6.30 - File::Find 0 - File::Spec 0 - File::Temp 0 - Test::More 0 Test-LongString-0.17 pathname: R/RG/RGARCIA/Test-LongString-0.17.tar.gz provides: @@ -8127,79 +6984,26 @@ DISTRIBUTIONS ExtUtils::MakeMaker 6.17 strict 0 warnings 0 - Test-Most-0.35 - pathname: O/OV/OVID/Test-Most-0.35.tar.gz - provides: - Test::Most 0.35 - Test::Most::Exception 0.35 - requirements: - Exception::Class 1.14 - ExtUtils::MakeMaker 0 - Test::Deep 0.119 - Test::Differences 0.64 - Test::Exception 0.43 - Test::Harness 3.35 - Test::More 1.302047 - Test::Warn 0.30 - Test-Object-0.07 - pathname: A/AD/ADAMK/Test-Object-0.07.tar.gz - provides: - Test::Object 0.07 - Test::Object::Test 0.07 - requirements: - Carp 0 - Exporter 0 - ExtUtils::MakeMaker 0 - File::Spec 0.80 - Scalar::Util 1.16 - Test::Builder 0.33 - Test::Builder::Tester 1.02 - Test::More 0.42 - overload 0 - Test-OpenID-Consumer-0.03 - pathname: T/TS/TSIBLEY/Test-OpenID-Consumer-0.03.tar.gz - provides: - Test::OpenID::Consumer 0.03 - requirements: - Cache::FileCache 0 - ExtUtils::MakeMaker 6.36 - HTTP::Server::Simple 0 - LWP::UserAgent::Paranoid 0.97 - Net::OpenID::Consumer 0 - Test::Builder 0 - Test::HTTP::Server::Simple 0 - Test-OpenID-Server-0.03 - pathname: T/TS/TSIBLEY/Test-OpenID-Server-0.03.tar.gz + Test-Perl-Critic-1.04 + pathname: P/PE/PETDANCE/Test-Perl-Critic-1.04.tar.gz provides: - Test::OpenID::Server 0.03 - requirements: - ExtUtils::MakeMaker 6.36 - HTTP::Server::Simple 0 - Net::OpenID::Server 0 - Test::HTTP::Server::Simple 0 - Test::OpenID::Consumer 0 - Test::WWW::Mechanize 0 - Test::Warnings 0.009 - Test-Perl-Critic-1.03 - pathname: T/TH/THALJEF/Test-Perl-Critic-1.03.tar.gz - provides: - Test::Perl::Critic 1.03 + Test::Perl::Critic 1.04 requirements: Carp 0 English 0 - MCE 1.52 + MCE 1.827 Module::Build 0.4 Perl::Critic 1.105 Perl::Critic::Utils 1.105 Perl::Critic::Violation 1.105 - Test::Builder 0 + Test::Builder 0.88 Test::More 0 strict 0 warnings 0 - Test-Requires-0.10 - pathname: T/TO/TOKUHIROM/Test-Requires-0.10.tar.gz + Test-Requires-0.11 + pathname: T/TO/TOKUHIROM/Test-Requires-0.11.tar.gz provides: - Test::Requires 0.10 + Test::Requires 0.11 requirements: ExtUtils::MakeMaker 6.64 Test::Builder::Module 0 @@ -8214,21 +7018,21 @@ DISTRIBUTIONS Socket 0 strict 0 warnings 0 - Test-Routine-0.025 - pathname: R/RJ/RJBS/Test-Routine-0.025.tar.gz + Test-Routine-0.031 + pathname: R/RJ/RJBS/Test-Routine-0.031.tar.gz provides: - Test::Routine 0.025 - Test::Routine::Common 0.025 - Test::Routine::Compositor 0.025 - Test::Routine::Manual::Demo 0.025 - Test::Routine::Runner 0.025 - Test::Routine::Test 0.025 - Test::Routine::Test::Role 0.025 - Test::Routine::Util 0.025 + Test::Routine 0.031 + Test::Routine::Common 0.031 + Test::Routine::Compositor 0.031 + Test::Routine::Manual::Demo 0.031 + Test::Routine::Runner 0.031 + Test::Routine::Test 0.031 + Test::Routine::Test::Role 0.031 + Test::Routine::Util 0.031 requirements: Carp 0 Class::Load 0 - ExtUtils::MakeMaker 0 + ExtUtils::MakeMaker 6.78 Moose 0 Moose::Exporter 0 Moose::Meta::Class 0 @@ -8246,6 +7050,7 @@ DISTRIBUTIONS Try::Tiny 0 namespace::autoclean 0 namespace::clean 0 + perl 5.012000 strict 0 warnings 0 Test-SharedFork-0.35 @@ -8262,95 +7067,225 @@ DISTRIBUTIONS Test::Builder::Module 0 Test::More 0.88 perl 5.008_001 - Test-Simple-1.302106 - pathname: E/EX/EXODIST/Test-Simple-1.302106.tar.gz - provides: - Test2 1.302106 - Test2::API 1.302106 - Test2::API::Breakage 1.302106 - Test2::API::Context 1.302106 - Test2::API::Instance 1.302106 - Test2::API::Stack 1.302106 - Test2::Event 1.302106 - Test2::Event::Bail 1.302106 - Test2::Event::Diag 1.302106 - Test2::Event::Encoding 1.302106 - Test2::Event::Exception 1.302106 - Test2::Event::Fail 1.302106 - Test2::Event::Generic 1.302106 - Test2::Event::Note 1.302106 - Test2::Event::Ok 1.302106 - Test2::Event::Pass 1.302106 - Test2::Event::Plan 1.302106 - Test2::Event::Skip 1.302106 - Test2::Event::Subtest 1.302106 - Test2::Event::TAP::Version 1.302106 - Test2::Event::Waiting 1.302106 - Test2::EventFacet 1.302106 - Test2::EventFacet::About 1.302106 - Test2::EventFacet::Amnesty 1.302106 - Test2::EventFacet::Assert 1.302106 - Test2::EventFacet::Control 1.302106 - Test2::EventFacet::Error 1.302106 - Test2::EventFacet::Info 1.302106 - Test2::EventFacet::Meta 1.302106 - Test2::EventFacet::Parent 1.302106 - Test2::EventFacet::Plan 1.302106 - Test2::EventFacet::Trace 1.302106 - Test2::Formatter 1.302106 - Test2::Formatter::TAP 1.302106 - Test2::Hub 1.302106 - Test2::Hub::Interceptor 1.302106 - Test2::Hub::Interceptor::Terminator 1.302106 - Test2::Hub::Subtest 1.302106 - Test2::IPC 1.302106 - Test2::IPC::Driver 1.302106 - Test2::IPC::Driver::Files 1.302106 - Test2::Tools::Tiny 1.302106 - Test2::Util 1.302106 - Test2::Util::ExternalMeta 1.302106 - Test2::Util::Facets2Legacy 1.302106 - Test2::Util::HashBase 1.302106 - Test2::Util::Trace 1.302106 - Test::Builder 1.302106 - Test::Builder::Formatter 1.302106 - Test::Builder::IO::Scalar 2.114 - Test::Builder::Module 1.302106 - Test::Builder::Tester 1.302106 - Test::Builder::Tester::Color 1.302106 - Test::Builder::Tester::Tie 1.302106 - Test::Builder::TodoDiag 1.302106 - Test::More 1.302106 - Test::Simple 1.302106 - Test::Tester 1.302106 - Test::Tester::Capture 1.302106 - Test::Tester::CaptureRunner 1.302106 - Test::Tester::Delegate 1.302106 - Test::use::ok 1.302106 - ok 1.302106 + Test-Simple-1.302210 + pathname: E/EX/EXODIST/Test-Simple-1.302210.tar.gz + provides: + Test2 1.302210 + Test2::API 1.302210 + Test2::API::Breakage 1.302210 + Test2::API::Context 1.302210 + Test2::API::Instance 1.302210 + Test2::API::InterceptResult 1.302210 + Test2::API::InterceptResult::Event 1.302210 + Test2::API::InterceptResult::Facet 1.302210 + Test2::API::InterceptResult::Hub 1.302210 + Test2::API::InterceptResult::Squasher 1.302210 + Test2::API::Stack 1.302210 + Test2::AsyncSubtest 1.302210 + Test2::AsyncSubtest::Event::Attach 1.302210 + Test2::AsyncSubtest::Event::Detach 1.302210 + Test2::AsyncSubtest::Formatter 1.302210 + Test2::AsyncSubtest::Hub 1.302210 + Test2::Bundle 1.302210 + Test2::Bundle::Extended 1.302210 + Test2::Bundle::More 1.302210 + Test2::Bundle::Simple 1.302210 + Test2::Compare 1.302210 + Test2::Compare::Array 1.302210 + Test2::Compare::Bag 1.302210 + Test2::Compare::Base 1.302210 + Test2::Compare::Bool 1.302210 + Test2::Compare::Custom 1.302210 + Test2::Compare::DeepRef 1.302210 + Test2::Compare::Delta 1.302210 + Test2::Compare::Event 1.302210 + Test2::Compare::EventMeta 1.302210 + Test2::Compare::Float 1.302210 + Test2::Compare::Hash 1.302210 + Test2::Compare::Isa 1.302210 + Test2::Compare::Meta 1.302210 + Test2::Compare::Negatable 1.302210 + Test2::Compare::Number 1.302210 + Test2::Compare::Object 1.302210 + Test2::Compare::OrderedSubset 1.302210 + Test2::Compare::Pattern 1.302210 + Test2::Compare::Ref 1.302210 + Test2::Compare::Regex 1.302210 + Test2::Compare::Scalar 1.302210 + Test2::Compare::Set 1.302210 + Test2::Compare::String 1.302210 + Test2::Compare::Undef 1.302210 + Test2::Compare::Wildcard 1.302210 + Test2::Env 1.302210 + Test2::Event 1.302210 + Test2::Event::Bail 1.302210 + Test2::Event::Diag 1.302210 + Test2::Event::Encoding 1.302210 + Test2::Event::Exception 1.302210 + Test2::Event::Fail 1.302210 + Test2::Event::Generic 1.302210 + Test2::Event::Note 1.302210 + Test2::Event::Ok 1.302210 + Test2::Event::Pass 1.302210 + Test2::Event::Plan 1.302210 + Test2::Event::Skip 1.302210 + Test2::Event::Subtest 1.302210 + Test2::Event::TAP::Version 1.302210 + Test2::Event::V2 1.302210 + Test2::Event::Waiting 1.302210 + Test2::EventFacet 1.302210 + Test2::EventFacet::About 1.302210 + Test2::EventFacet::Amnesty 1.302210 + Test2::EventFacet::Assert 1.302210 + Test2::EventFacet::Control 1.302210 + Test2::EventFacet::Error 1.302210 + Test2::EventFacet::Hub 1.302210 + Test2::EventFacet::Info 1.302210 + Test2::EventFacet::Info::Table 1.302210 + Test2::EventFacet::Meta 1.302210 + Test2::EventFacet::Parent 1.302210 + Test2::EventFacet::Plan 1.302210 + Test2::EventFacet::Render 1.302210 + Test2::EventFacet::Trace 1.302210 + Test2::Formatter 1.302210 + Test2::Formatter::TAP 1.302210 + Test2::Hub 1.302210 + Test2::Hub::Interceptor 1.302210 + Test2::Hub::Interceptor::Terminator 1.302210 + Test2::Hub::Subtest 1.302210 + Test2::IPC 1.302210 + Test2::IPC::Driver 1.302210 + Test2::IPC::Driver::Files 1.302210 + Test2::Manual 1.302210 + Test2::Manual::Anatomy 1.302210 + Test2::Manual::Anatomy::API 1.302210 + Test2::Manual::Anatomy::Context 1.302210 + Test2::Manual::Anatomy::EndToEnd 1.302210 + Test2::Manual::Anatomy::Event 1.302210 + Test2::Manual::Anatomy::Hubs 1.302210 + Test2::Manual::Anatomy::IPC 1.302210 + Test2::Manual::Anatomy::Utilities 1.302210 + Test2::Manual::Concurrency 1.302210 + Test2::Manual::Contributing 1.302210 + Test2::Manual::Testing 1.302210 + Test2::Manual::Testing::Introduction 1.302210 + Test2::Manual::Testing::Migrating 1.302210 + Test2::Manual::Testing::Planning 1.302210 + Test2::Manual::Testing::Todo 1.302210 + Test2::Manual::Tooling 1.302210 + Test2::Manual::Tooling::FirstTool 1.302210 + Test2::Manual::Tooling::Formatter 1.302210 + Test2::Manual::Tooling::Nesting 1.302210 + Test2::Manual::Tooling::Plugin::TestExit 1.302210 + Test2::Manual::Tooling::Plugin::TestingDone 1.302210 + Test2::Manual::Tooling::Plugin::ToolCompletes 1.302210 + Test2::Manual::Tooling::Plugin::ToolStarts 1.302210 + Test2::Manual::Tooling::Subtest 1.302210 + Test2::Manual::Tooling::TestBuilder 1.302210 + Test2::Manual::Tooling::Testing 1.302210 + Test2::Mock 1.302210 + Test2::Plugin 1.302210 + Test2::Plugin::BailOnFail 1.302210 + Test2::Plugin::DieOnFail 1.302210 + Test2::Plugin::ExitSummary 1.302210 + Test2::Plugin::SRand 1.302210 + Test2::Plugin::Times 1.302210 + Test2::Plugin::UTF8 1.302210 + Test2::Require 1.302210 + Test2::Require::AuthorTesting 1.302210 + Test2::Require::AutomatedTesting 1.302210 + Test2::Require::EnvVar 1.302210 + Test2::Require::ExtendedTesting 1.302210 + Test2::Require::Fork 1.302210 + Test2::Require::Module 1.302210 + Test2::Require::NonInteractiveTesting 1.302210 + Test2::Require::Perl 1.302210 + Test2::Require::RealFork 1.302210 + Test2::Require::ReleaseTesting 1.302210 + Test2::Require::Threads 1.302210 + Test2::Suite 1.302210 + Test2::Todo 1.302210 + Test2::Tools 1.302210 + Test2::Tools::AsyncSubtest 1.302210 + Test2::Tools::Basic 1.302210 + Test2::Tools::Class 1.302210 + Test2::Tools::ClassicCompare 1.302210 + Test2::Tools::Compare 1.302210 + Test2::Tools::Defer 1.302210 + Test2::Tools::Encoding 1.302210 + Test2::Tools::Event 1.302210 + Test2::Tools::Exception 1.302210 + Test2::Tools::Exports 1.302210 + Test2::Tools::GenTemp 1.302210 + Test2::Tools::Grab 1.302210 + Test2::Tools::Mock 1.302210 + Test2::Tools::Ref 1.302210 + Test2::Tools::Refcount 1.302210 + Test2::Tools::Spec 1.302210 + Test2::Tools::Subtest 1.302210 + Test2::Tools::Target 1.302210 + Test2::Tools::Tester 1.302210 + Test2::Tools::Tiny 1.302210 + Test2::Tools::Warnings 1.302210 + Test2::Util 1.302210 + Test2::Util::ExternalMeta 1.302210 + Test2::Util::Facets2Legacy 1.302210 + Test2::Util::Grabber 1.302210 + Test2::Util::Guard 1.302210 + Test2::Util::HashBase 1.302210 + Test2::Util::Importer 1.302210 + Test2::Util::Ref 1.302210 + Test2::Util::Sig 1.302210 + Test2::Util::Stash 1.302210 + Test2::Util::Sub 1.302210 + Test2::Util::Table 1.302210 + Test2::Util::Table::Cell 1.302210 + Test2::Util::Table::LineBreak 1.302210 + Test2::Util::Term 1.302210 + Test2::Util::Times 1.302210 + Test2::Util::Trace 1.302210 + Test2::V0 1.302210 + Test2::Workflow 1.302210 + Test2::Workflow::BlockBase 1.302210 + Test2::Workflow::Build 1.302210 + Test2::Workflow::Runner 1.302210 + Test2::Workflow::Task 1.302210 + Test2::Workflow::Task::Action 1.302210 + Test2::Workflow::Task::Group 1.302210 + Test::Builder 1.302210 + Test::Builder::Formatter 1.302210 + Test::Builder::Module 1.302210 + Test::Builder::Tester 1.302210 + Test::Builder::Tester::Color 1.302210 + Test::Builder::Tester::Tie 1.302210 + Test::Builder::TodoDiag 1.302210 + Test::More 1.302210 + Test::Simple 1.302210 + Test::Tester 1.302210 + Test::Tester::Capture 1.302210 + Test::Tester::CaptureRunner 1.302210 + Test::Tester::Delegate 1.302210 + Test::use::ok 1.302210 + ok 1.302210 requirements: + B 0 + Data::Dumper 0 + Exporter 0 ExtUtils::MakeMaker 0 File::Spec 0 File::Temp 0 Scalar::Util 1.13 Storable 0 + Term::Table 0.013 + Time::HiRes 0 + overload 0 perl 5.006002 utf8 0 - Test-SubCalls-1.09 - pathname: A/AD/ADAMK/Test-SubCalls-1.09.tar.gz - provides: - Test::SubCalls 1.09 - requirements: - ExtUtils::MakeMaker 6.42 - File::Spec 0.80 - Hook::LexWrap 0.20 - Test::Builder::Tester 1.02 - Test::More 0.42 - Test-TCP-2.19 - pathname: T/TO/TOKUHIROM/Test-TCP-2.19.tar.gz + Test-TCP-2.22 + pathname: M/MI/MIYAGAWA/Test-TCP-2.22.tar.gz provides: Net::EmptyPort undef - Test::TCP 2.19 + Test::TCP 2.22 Test::TCP::CheckPort undef requirements: ExtUtils::MakeMaker 6.64 @@ -8360,81 +7295,24 @@ DISTRIBUTIONS Test::SharedFork 0.29 Time::HiRes 0 perl 5.008001 - Test-Trap-v0.3.3 - pathname: E/EB/EBHANSSEN/Test-Trap-v0.3.3.tar.gz - provides: - Test::Trap v0.3.3 - Test::Trap::Builder v0.3.3 - Test::Trap::Builder::PerlIO v0.3.3 - Test::Trap::Builder::SystemSafe v0.3.3 - Test::Trap::Builder::TempFile v0.3.3 - requirements: - Carp 0 - Data::Dump 0 - Exporter 0 - File::Temp 0 - IO::Handle 0 - Module::Build 0 - Test::Builder 0 - Test::More 0 - Test::Tester 0.107 - base 0 - constant 0 - lib 0 - perl v5.6.2 - strict 0 - version 0 - warnings 0 - Test-Vars-0.014 - pathname: D/DR/DROLSKY/Test-Vars-0.014.tar.gz + Test-Vars-0.017 + pathname: J/JK/JKEENAN/Test-Vars-0.017.tar.gz provides: - Test::Vars 0.014 + Test::Vars 0.017 requirements: B 0 - ExtUtils::MakeMaker 6.59 + ExtUtils::MakeMaker 6.17 + ExtUtils::Manifest 0 + IO::Pipe 0 List::Util 1.33 - Module::Build::Tiny 0.035 - Test::More 0.88 + Storable 0 + Symbol 0 parent 0 perl 5.010000 - Test-WWW-Mechanize-1.48 - pathname: P/PE/PETDANCE/Test-WWW-Mechanize-1.48.tar.gz + Test-Warn-0.37 + pathname: B/BI/BIGJ/Test-Warn-0.37.tar.gz provides: - Test::WWW::Mechanize 1.48 - requirements: - Carp::Assert::More 0 - ExtUtils::MakeMaker 0 - HTML::TokeParser 0 - HTML::TreeBuilder 0 - HTTP::Server::Simple 0.42 - HTTP::Server::Simple::CGI 0 - LWP 6.02 - Test::Builder::Tester 1.09 - Test::LongString 0.15 - Test::More 0.96 - URI::file 0 - WWW::Mechanize 1.68 - parent 0 - perl 5.008 - Test-WWW-Mechanize-PSGI-0.37 - pathname: O/OA/OALDERS/Test-WWW-Mechanize-PSGI-0.37.tar.gz - provides: - Test::WWW::Mechanize::PSGI 0.37 - requirements: - Carp 0 - ExtUtils::MakeMaker 0 - HTTP::Message::PSGI 0 - Test::WWW::Mechanize 0 - Try::Tiny 0 - base 0 - perl 5.006 - strict 0 - warnings 0 - Test-Warn-0.32 - pathname: B/BI/BIGJ/Test-Warn-0.32.tar.gz - provides: - Test::Warn 0.32 - Test::Warn::Categorization 0.32 + Test::Warn 0.37 requirements: Carp 1.22 ExtUtils::MakeMaker 0 @@ -8442,29 +7320,16 @@ DISTRIBUTIONS Test::Builder 0.13 Test::Builder::Tester 1.02 perl 5.006 - Test-Warnings-0.026 - pathname: E/ET/ETHER/Test-Warnings-0.026.tar.gz - provides: - Test::Warnings 0.026 - requirements: - Carp 0 - Exporter 0 - ExtUtils::MakeMaker 0 - Test::Builder 0 - parent 0 - perl 5.006 - strict 0 - warnings 0 - Text-CSV_XS-1.34 - pathname: H/HM/HMBRAND/Text-CSV_XS-1.34.tgz + Text-CSV_XS-1.60 + pathname: H/HM/HMBRAND/Text-CSV_XS-1.60.tgz provides: - Text::CSV_XS 1.34 + Text::CSV_XS 1.60 requirements: Config 0 - DynaLoader 0 ExtUtils::MakeMaker 0 IO::Handle 0 Test::More 0 + XSLoader 0 Text-Diff-1.45 pathname: N/NE/NEILB/Text-Diff-1.45.tar.gz provides: @@ -8486,10 +7351,10 @@ DISTRIBUTIONS ExtUtils::MakeMaker 0 constant 0 perl 5.00503 - Text-SimpleTable-2.03 - pathname: M/MR/MRAMBERG/Text-SimpleTable-2.03.tar.gz + Text-SimpleTable-2.07 + pathname: M/MR/MRAMBERG/Text-SimpleTable-2.07.tar.gz provides: - Text::SimpleTable 2.03 + Text::SimpleTable 2.07 requirements: ExtUtils::MakeMaker 0 Test::More 0 @@ -8505,28 +7370,30 @@ DISTRIBUTIONS Text::SimpleTable 0 strict 0 warnings 0 - Text-Template-1.47 - pathname: M/MS/MSCHOUT/Text-Template-1.47.tar.gz + Text-Template-1.61 + pathname: M/MS/MSCHOUT/Text-Template-1.61.tar.gz provides: - Text::Template 1.47 - Text::Template::Preprocess 1.47 + Text::Template 1.61 + Text::Template::Preprocess 1.61 requirements: Carp 0 + Encode 0 Exporter 0 ExtUtils::MakeMaker 0 - perl 5.004 + base 0 + perl 5.008 strict 0 - vars 0 - Throwable-0.200013 - pathname: R/RJ/RJBS/Throwable-0.200013.tar.gz + warnings 0 + Throwable-1.001 + pathname: R/RJ/RJBS/Throwable-1.001.tar.gz provides: - StackTrace::Auto 0.200013 - Throwable 0.200013 - Throwable::Error 0.200013 + StackTrace::Auto 1.001 + Throwable 1.001 + Throwable::Error 1.001 requirements: Carp 0 Devel::StackTrace 1.32 - ExtUtils::MakeMaker 0 + ExtUtils::MakeMaker 6.78 Module::Runtime 0.002 Moo 1.000001 Moo::Role 0 @@ -8543,10 +7410,10 @@ DISTRIBUTIONS Test::More 0 Test::use::ok 0 Tie::RefHash 0 - Time-Duration-1.20 - pathname: N/NE/NEILB/Time-Duration-1.20.tar.gz + Time-Duration-1.21 + pathname: N/NE/NEILB/Time-Duration-1.21.tar.gz provides: - Time::Duration 1.20 + Time::Duration 1.21 requirements: Exporter 0 ExtUtils::MakeMaker 0 @@ -8554,19 +7421,30 @@ DISTRIBUTIONS perl 5.006 strict 0 warnings 0 - Time-Duration-Parse-0.13 - pathname: N/NE/NEILB/Time-Duration-Parse-0.13.tar.gz + Time-Duration-Parse-0.16 + pathname: N/NE/NEILB/Time-Duration-Parse-0.16.tar.gz provides: - Time::Duration::Parse 0.13 + Time::Duration::Parse 0.16 requirements: Carp 0 - Exporter::Lite 0 + Exporter 5.57 ExtUtils::MakeMaker 0 perl 5.006 strict 0 warnings 0 - TimeDate-2.30 - pathname: G/GB/GBARR/TimeDate-2.30.tar.gz + Time-Local-1.35 + pathname: D/DR/DROLSKY/Time-Local-1.35.tar.gz + provides: + Time::Local 1.35 + requirements: + Carp 0 + Exporter 0 + ExtUtils::MakeMaker 0 + constant 0 + parent 0 + strict 0 + TimeDate-2.33 + pathname: A/AT/ATOOMIC/TimeDate-2.33.tar.gz provides: Date::Format 2.24 Date::Format::Generic 2.24 @@ -8591,6 +7469,7 @@ DISTRIBUTIONS Date::Language::Icelandic 1.01 Date::Language::Italian 1.01 Date::Language::Norwegian 1.01 + Date::Language::Occitan 1.04 Date::Language::Oromo 0.99 Date::Language::Romanian 1.01 Date::Language::Russian 1.01 @@ -8604,42 +7483,43 @@ DISTRIBUTIONS Date::Language::TigrinyaEritrean 1.00 Date::Language::TigrinyaEthiopian 1.00 Date::Language::Turkish 1.0 - Date::Parse 2.30 + Date::Parse 2.33 Time::Zone 2.24 + TimeDate 1.21 requirements: ExtUtils::MakeMaker 0 - Tree-Simple-1.31 - pathname: R/RS/RSAVAGE/Tree-Simple-1.31.tgz + Tree-Simple-1.34 + pathname: R/RS/RSAVAGE/Tree-Simple-1.34.tgz provides: - Tree::Simple 1.31 - Tree::Simple::Visitor 1.31 + Tree::Simple 1.34 + Tree::Simple::Visitor 1.34 requirements: ExtUtils::MakeMaker 0 Scalar::Util 1.18 constant 0 strict 0 warnings 0 - Tree-Simple-VisitorFactory-0.15 - pathname: R/RS/RSAVAGE/Tree-Simple-VisitorFactory-0.15.tgz - provides: - Tree::Simple::Visitor::BreadthFirstTraversal 0.15 - Tree::Simple::Visitor::CreateDirectoryTree 0.15 - Tree::Simple::Visitor::FindByNodeValue 0.15 - Tree::Simple::Visitor::FindByPath 0.15 - Tree::Simple::Visitor::FindByUID 0.15 - Tree::Simple::Visitor::FromNestedArray 0.15 - Tree::Simple::Visitor::FromNestedHash 0.15 - Tree::Simple::Visitor::GetAllDescendents 0.15 - Tree::Simple::Visitor::LoadClassHierarchy 0.15 - Tree::Simple::Visitor::LoadDirectoryTree 0.15 - Tree::Simple::Visitor::PathToRoot 0.15 - Tree::Simple::Visitor::PostOrderTraversal 0.15 - Tree::Simple::Visitor::PreOrderTraversal 0.15 - Tree::Simple::Visitor::Sort 0.15 - Tree::Simple::Visitor::ToNestedArray 0.15 - Tree::Simple::Visitor::ToNestedHash 0.15 - Tree::Simple::Visitor::VariableDepthClone 0.15 - Tree::Simple::VisitorFactory 0.15 + Tree-Simple-VisitorFactory-0.16 + pathname: R/RS/RSAVAGE/Tree-Simple-VisitorFactory-0.16.tgz + provides: + Tree::Simple::Visitor::BreadthFirstTraversal 0.16 + Tree::Simple::Visitor::CreateDirectoryTree 0.16 + Tree::Simple::Visitor::FindByNodeValue 0.16 + Tree::Simple::Visitor::FindByPath 0.16 + Tree::Simple::Visitor::FindByUID 0.16 + Tree::Simple::Visitor::FromNestedArray 0.16 + Tree::Simple::Visitor::FromNestedHash 0.16 + Tree::Simple::Visitor::GetAllDescendents 0.16 + Tree::Simple::Visitor::LoadClassHierarchy 0.16 + Tree::Simple::Visitor::LoadDirectoryTree 0.16 + Tree::Simple::Visitor::PathToRoot 0.16 + Tree::Simple::Visitor::PostOrderTraversal 0.16 + Tree::Simple::Visitor::PreOrderTraversal 0.16 + Tree::Simple::Visitor::Sort 0.16 + Tree::Simple::Visitor::ToNestedArray 0.16 + Tree::Simple::Visitor::ToNestedHash 0.16 + Tree::Simple::Visitor::VariableDepthClone 0.16 + Tree::Simple::VisitorFactory 0.16 requirements: ExtUtils::MakeMaker 0 File::Spec 0.6 @@ -8649,10 +7529,10 @@ DISTRIBUTIONS base 0 strict 0 warnings 0 - Try-Tiny-0.28 - pathname: E/ET/ETHER/Try-Tiny-0.28.tar.gz + Try-Tiny-0.32 + pathname: E/ET/ETHER/Try-Tiny-0.32.tar.gz provides: - Try::Tiny 0.28 + Try::Tiny 0.32 requirements: Carp 0 Exporter 5.57 @@ -8661,91 +7541,145 @@ DISTRIBUTIONS perl 5.006 strict 0 warnings 0 - Twiggy-0.1025 - pathname: M/MI/MIYAGAWA/Twiggy-0.1025.tar.gz + Twitter-API-1.0006 + pathname: M/MM/MMIMS/Twitter-API-1.0006.tar.gz provides: - AnyEvent::Server::PSGI undef - Plack::Handler::Twiggy undef - Twiggy 0.1025 - Twiggy::Server undef - Twiggy::Server::SS undef - Twiggy::Writer undef + Twitter::API 1.0006 + Twitter::API::Context 1.0006 + Twitter::API::Error 1.0006 + Twitter::API::Role::RequestArgs 1.0006 + Twitter::API::Trait::ApiMethods 1.0006 + Twitter::API::Trait::AppAuth 1.0006 + Twitter::API::Trait::DecodeHtmlEntities 1.0006 + Twitter::API::Trait::Enchilada 1.0006 + Twitter::API::Trait::Migration 1.0006 + Twitter::API::Trait::NormalizeBooleans 1.0006 + Twitter::API::Trait::RateLimiting 1.0006 + Twitter::API::Trait::RetryOnError 1.0006 + Twitter::API::Util 1.0006 requirements: - AnyEvent 0 - ExtUtils::MakeMaker 0 - HTTP::Status 0 - Plack 0.99 + Carp 0 + Digest::SHA 0 + Encode 0 + HTML::Entities 0 + HTTP::Request::Common 0 + HTTP::Thin 0 + IO::Socket::SSL 0 + JSON::MaybeXS 0 + Module::Build::Tiny 0.034 + Module::Runtime 0 + Moo 0 + Moo::Role 0 + MooX::Aliases 0 + MooX::Traits 0 + Ref::Util 0 + Scalar::Util 0 + StackTrace::Auto 0 + Sub::Exporter::Progressive 0 + Throwable 0 + Time::HiRes 0 + Time::Local 0 Try::Tiny 0 - perl 5.008001 - Type-Tiny-1.002001 - pathname: T/TO/TOBYINK/Type-Tiny-1.002001.tar.gz - provides: - Devel::TypeTiny::Perl56Compat 1.002001 - Devel::TypeTiny::Perl58Compat 1.002001 - Error::TypeTiny 1.002001 - Error::TypeTiny::Assertion 1.002001 - Error::TypeTiny::Compilation 1.002001 - Error::TypeTiny::WrongNumberOfParameters 1.002001 - Eval::TypeTiny 1.002001 - Reply::Plugin::TypeTiny 1.002001 - Test::TypeTiny 1.002001 - Type::Coercion 1.002001 - Type::Coercion::FromMoose 1.002001 - Type::Coercion::Union 1.002001 - Type::Library 1.002001 - Type::Params 1.002001 - Type::Parser 1.002001 - Type::Registry 1.002001 - Type::Tiny 1.002001 - Type::Tiny::Class 1.002001 - Type::Tiny::Duck 1.002001 - Type::Tiny::Enum 1.002001 - Type::Tiny::Intersection 1.002001 - Type::Tiny::Role 1.002001 - Type::Tiny::Union 1.002001 - Type::Utils 1.002001 - Types::Common::Numeric 1.002001 - Types::Common::String 1.002001 - Types::Standard 1.002001 - Types::Standard::ArrayRef 1.002001 - Types::Standard::CycleTuple 1.002001 - Types::Standard::Dict 1.002001 - Types::Standard::HashRef 1.002001 - Types::Standard::Map 1.002001 - Types::Standard::ScalarRef 1.002001 - Types::Standard::Tuple 1.002001 - Types::TypeTiny 1.002001 - requirements: - Exporter::Tiny 0.026 + URI 0 + URL::Encode 0 + WWW::OAuth 0.006 + namespace::clean 0 + perl v5.14.1 + Type-Tiny-2.008001 + pathname: T/TO/TOBYINK/Type-Tiny-2.008001.tar.gz + provides: + Devel::TypeTiny::Perl58Compat 2.008001 + Error::TypeTiny 2.008001 + Error::TypeTiny::Assertion 2.008001 + Error::TypeTiny::Compilation 2.008001 + Error::TypeTiny::WrongNumberOfParameters 2.008001 + Eval::TypeTiny 2.008001 + Eval::TypeTiny::CodeAccumulator 2.008001 + Reply::Plugin::TypeTiny 2.008001 + Test::TypeTiny 2.008001 + Type::Coercion 2.008001 + Type::Coercion::FromMoose 2.008001 + Type::Coercion::Union 2.008001 + Type::Library 2.008001 + Type::Params 2.008001 + Type::Params::Alternatives 2.008001 + Type::Params::Parameter 2.008001 + Type::Params::Signature 2.008001 + Type::Parser 2.008001 + Type::Parser::AstBuilder 2.008001 + Type::Parser::Token 2.008001 + Type::Parser::TokenStream 2.008001 + Type::Registry 2.008001 + Type::Tie 2.008001 + Type::Tie::ARRAY 2.008001 + Type::Tie::BASE 2.008001 + Type::Tie::HASH 2.008001 + Type::Tie::SCALAR 2.008001 + Type::Tiny 2.008001 + Type::Tiny::Bitfield 2.008001 + Type::Tiny::Class 2.008001 + Type::Tiny::ConstrainedObject 2.008001 + Type::Tiny::Duck 2.008001 + Type::Tiny::Enum 2.008001 + Type::Tiny::Intersection 2.008001 + Type::Tiny::Role 2.008001 + Type::Tiny::Union 2.008001 + Type::Utils 2.008001 + Types::Common 2.008001 + Types::Common::Numeric 2.008001 + Types::Common::String 2.008001 + Types::Standard 2.008001 + Types::Standard::ArrayRef 2.008001 + Types::Standard::CycleTuple 2.008001 + Types::Standard::Dict 2.008001 + Types::Standard::HashRef 2.008001 + Types::Standard::Map 2.008001 + Types::Standard::ScalarRef 2.008001 + Types::Standard::StrMatch 2.008001 + Types::Standard::Tied 2.008001 + Types::Standard::Tuple 2.008001 + Types::TypeTiny 2.008001 + requirements: + Exporter::Tiny 1.006000 ExtUtils::MakeMaker 6.17 - perl 5.006001 - Types-Path-Tiny-0.005 - pathname: D/DA/DAGOLDEN/Types-Path-Tiny-0.005.tar.gz + perl 5.008001 + Types-Path-Tiny-0.006 + pathname: D/DA/DAGOLDEN/Types-Path-Tiny-0.006.tar.gz provides: - Types::Path::Tiny 0.005 + Types::Path::Tiny 0.006 requirements: - ExtUtils::MakeMaker 6.30 + ExtUtils::MakeMaker 6.17 Path::Tiny 0 Type::Library 0.008 Type::Utils 0 Types::Standard 0 Types::TypeTiny 0.004 + perl 5.008001 strict 0 warnings 0 - Types-Serialiser-1.0 - pathname: M/ML/MLEHMANN/Types-Serialiser-1.0.tar.gz + Types-Self-0.002 + pathname: T/TO/TOBYINK/Types-Self-0.002.tar.gz + provides: + Types::Self 0.002 + requirements: + ExtUtils::MakeMaker 6.17 + Role::Hooks 0 + Types::Standard 1.012 + perl 5.008001 + Types-Serialiser-1.01 + pathname: M/ML/MLEHMANN/Types-Serialiser-1.01.tar.gz provides: - JSON::PP::Boolean 1.0 - Types::Serialiser 1.0 - Types::Serialiser::BooleanBase 1.0 - Types::Serialiser::Error 1.0 + JSON::PP::Boolean 1.01 + Types::Serialiser 1.01 + Types::Serialiser::BooleanBase 1.01 + Types::Serialiser::Error 1.01 requirements: ExtUtils::MakeMaker 0 common::sense 0 - Types-URI-0.006 - pathname: T/TO/TOBYINK/Types-URI-0.006.tar.gz + Types-URI-0.007 + pathname: T/TO/TOBYINK/Types-URI-0.007.tar.gz provides: - Types::URI 0.006 + Types::URI 0.007 requirements: ExtUtils::MakeMaker 6.17 Type::Library 1.000000 @@ -8764,10 +7698,10 @@ DISTRIBUTIONS Type::Tiny 1.000000 UUID::Tiny 1.02 perl 5.008 - UNIVERSAL-require-0.18 - pathname: N/NE/NEILB/UNIVERSAL-require-0.18.tar.gz + UNIVERSAL-require-0.19 + pathname: N/NE/NEILB/UNIVERSAL-require-0.19.tar.gz provides: - UNIVERSAL::require 0.18 + UNIVERSAL::require 0.19 requirements: Carp 0 ExtUtils::MakeMaker 0 @@ -8775,52 +7709,62 @@ DISTRIBUTIONS perl 5.006 strict 0 warnings 0 - URI-1.72 - pathname: E/ET/ETHER/URI-1.72.tar.gz - provides: - URI 1.72 - URI::Escape 3.31 - URI::Heuristic 4.20 - URI::IRI 1.72 - URI::QueryParam 1.72 - URI::Split 1.72 - URI::URL 5.04 - URI::WithBase 2.20 - URI::data 1.72 - URI::file 4.21 - URI::file::Base 1.72 - URI::file::FAT 1.72 - URI::file::Mac 1.72 - URI::file::OS2 1.72 - URI::file::QNX 1.72 - URI::file::Unix 1.72 - URI::file::Win32 1.72 - URI::ftp 1.72 - URI::gopher 1.72 - URI::http 1.72 - URI::https 1.72 - URI::ldap 1.72 - URI::ldapi 1.72 - URI::ldaps 1.72 - URI::mailto 1.72 - URI::mms 1.72 - URI::news 1.72 - URI::nntp 1.72 - URI::pop 1.72 - URI::rlogin 1.72 - URI::rsync 1.72 - URI::rtsp 1.72 - URI::rtspu 1.72 - URI::sftp 1.72 - URI::sip 1.72 - URI::sips 1.72 - URI::snews 1.72 - URI::ssh 1.72 - URI::telnet 1.72 - URI::tn3270 1.72 - URI::urn 1.72 - URI::urn::isbn 1.72 - URI::urn::oid 1.72 + URI-5.31 + pathname: O/OA/OALDERS/URI-5.31.tar.gz + provides: + URI 5.31 + URI::Escape 5.31 + URI::Heuristic 5.31 + URI::IRI 5.31 + URI::QueryParam 5.31 + URI::Split 5.31 + URI::URL 5.31 + URI::WithBase 5.31 + URI::data 5.31 + URI::file 5.31 + URI::file::Base 5.31 + URI::file::FAT 5.31 + URI::file::Mac 5.31 + URI::file::OS2 5.31 + URI::file::QNX 5.31 + URI::file::Unix 5.31 + URI::file::Win32 5.31 + URI::ftp 5.31 + URI::ftpes 5.31 + URI::ftps 5.31 + URI::geo 5.31 + URI::gopher 5.31 + URI::http 5.31 + URI::https 5.31 + URI::icap 5.31 + URI::icaps 5.31 + URI::irc 5.31 + URI::ircs 5.31 + URI::ldap 5.31 + URI::ldapi 5.31 + URI::ldaps 5.31 + URI::mailto 5.31 + URI::mms 5.31 + URI::news 5.31 + URI::nntp 5.31 + URI::nntps 5.31 + URI::otpauth 5.31 + URI::pop 5.31 + URI::rlogin 5.31 + URI::rsync 5.31 + URI::rtsp 5.31 + URI::rtspu 5.31 + URI::scp 5.31 + URI::sftp 5.31 + URI::sip 5.31 + URI::sips 5.31 + URI::snews 5.31 + URI::ssh 5.31 + URI::telnet 5.31 + URI::tn3270 5.31 + URI::urn 5.31 + URI::urn::isbn 5.31 + URI::urn::oid 5.31 requirements: Carp 0 Cwd 0 @@ -8828,6 +7772,7 @@ DISTRIBUTIONS Encode 0 Exporter 5.57 ExtUtils::MakeMaker 0 + MIME::Base32 0 MIME::Base64 2 Net::Domain 0 Scalar::Util 0 @@ -8870,77 +7815,61 @@ DISTRIBUTIONS Test::More 0.88 URI 1.40 perl 5.008001 - URI-Query-0.16 - pathname: G/GA/GAVINC/URI-Query-0.16.tar.gz - provides: - URI::Query 0.16 - requirements: - Carp 0 - Clone 0 - ExtUtils::MakeMaker 0 - URI::Escape 0 - overload 0 - parent 0 - strict 0 - vars 0 - URI-db-0.18 - pathname: D/DW/DWHEELER/URI-db-0.18.tar.gz - provides: - URI::cassandra 0.18 - URI::couch 0.18 - URI::couchdb 0.18 - URI::cubrid 0.18 - URI::db 0.18 - URI::db2 0.18 - URI::derby 0.18 - URI::exasol 0.18 - URI::firebird 0.18 - URI::hive 0.18 - URI::impala 0.18 - URI::informix 0.18 - URI::ingres 0.18 - URI::interbase 0.18 - URI::ldapdb 0.18 - URI::maria 0.18 - URI::mariadb 0.18 - URI::max 0.18 - URI::maxdb 0.18 - URI::monet 0.18 - URI::monetdb 0.18 - URI::mongo 0.18 - URI::mongodb 0.18 - URI::mssql 0.18 - URI::mysql 0.18 - URI::oracle 0.18 - URI::pg 0.18 - URI::pgsql 0.18 - URI::pgxc 0.18 - URI::postgres 0.18 - URI::postgresql 0.18 - URI::postgresxc 0.18 - URI::redshift 0.18 - URI::sqlite 0.18 - URI::sqlite3 0.18 - URI::sqlserver 0.18 - URI::sybase 0.18 - URI::teradata 0.18 - URI::unify 0.18 - URI::vertica 0.18 + URI-db-0.23 + pathname: D/DW/DWHEELER/URI-db-0.23.tar.gz + provides: + URI::cassandra 0.23 + URI::clickhouse 0.20 + URI::cockroach 0.23 + URI::cockroachdb 0.23 + URI::couch 0.23 + URI::couchdb 0.23 + URI::cubrid 0.23 + URI::db 0.23 + URI::db2 0.23 + URI::derby 0.23 + URI::exasol 0.23 + URI::firebird 0.23 + URI::hive 0.23 + URI::impala 0.23 + URI::informix 0.23 + URI::ingres 0.23 + URI::interbase 0.23 + URI::ldapdb 0.23 + URI::maria 0.23 + URI::mariadb 0.23 + URI::max 0.23 + URI::maxdb 0.23 + URI::monet 0.23 + URI::monetdb 0.23 + URI::mongo 0.23 + URI::mongodb 0.23 + URI::mssql 0.23 + URI::mysql 0.23 + URI::oracle 0.23 + URI::pg 0.23 + URI::pgsql 0.23 + URI::pgxc 0.23 + URI::postgres 0.23 + URI::postgresql 0.23 + URI::postgresxc 0.23 + URI::redshift 0.23 + URI::snowflake 0.23 + URI::sqlite 0.23 + URI::sqlite3 0.23 + URI::sqlserver 0.23 + URI::sybase 0.23 + URI::teradata 0.23 + URI::unify 0.23 + URI::vertica 0.23 + URI::yugabyte 0.23 + URI::yugabytedb 0.23 requirements: Module::Build 0.30 Test::More 0.88 URI 1.40 URI::Nested 0.10 perl 5.008001 - URI-git-0.02 - pathname: M/MI/MIYAGAWA/URI-git-0.02.tar.gz - provides: - URI::git 0.02 - requirements: - ExtUtils::MakeMaker 6.42 - Filter::Util::Call 0 - Test::More 0 - URI 0 URI-ws-0.03 pathname: P/PL/PLICEASE/URI-ws-0.03.tar.gz provides: @@ -8949,6 +7878,18 @@ DISTRIBUTIONS requirements: ExtUtils::MakeMaker 6.30 URI 0 + URL-Encode-0.03 + pathname: C/CH/CHANSEN/URL-Encode-0.03.tar.gz + provides: + URL::Encode 0.03 + URL::Encode::PP 0.03 + requirements: + Carp 0 + Exporter 0 + ExtUtils::MakeMaker 6.59 + Test::More 0.88 + XSLoader 0 + perl 5.008001 UUID-Tiny-1.04 pathname: C/CA/CAUGUSTIN/UUID-Tiny-1.04.tar.gz provides: @@ -8962,22 +7903,22 @@ DISTRIBUTIONS POSIX 0 Test::More 0 Time::HiRes 0 - Unicode-LineBreak-2017.004 - pathname: N/NE/NEZUMI/Unicode-LineBreak-2017.004.tar.gz + Unicode-LineBreak-2019.001 + pathname: N/NE/NEZUMI/Unicode-LineBreak-2019.001.tar.gz provides: - Text::LineFold 2016.00702 + Text::LineFold 2018.012 Unicode::GCString 2013.10 - Unicode::LineBreak 2017.004 + Unicode::LineBreak 2019.001 requirements: Encode 1.98 ExtUtils::MakeMaker 6.26 MIME::Charset v1.6.2 Test::More 0.45 perl 5.008 - Variable-Magic-0.62 - pathname: V/VP/VPIT/Variable-Magic-0.62.tar.gz + Variable-Magic-0.64 + pathname: V/VP/VPIT/Variable-Magic-0.64.tar.gz provides: - Variable::Magic 0.62 + Variable::Magic 0.64 requirements: Carp 0 Config 0 @@ -8993,61 +7934,38 @@ DISTRIBUTIONS base 0 lib 0 perl 5.008 - WWW-Form-UrlEncoded-0.24 - pathname: K/KA/KAZEBURO/WWW-Form-UrlEncoded-0.24.tar.gz + WWW-Form-UrlEncoded-0.26 + pathname: K/KA/KAZEBURO/WWW-Form-UrlEncoded-0.26.tar.gz provides: - WWW::Form::UrlEncoded 0.24 + WWW::Form::UrlEncoded 0.26 WWW::Form::UrlEncoded::PP undef requirements: Exporter 0 - ExtUtils::CBuilder 0 Module::Build 0.4005 perl 5.008001 - WWW-Mechanize-1.86 - pathname: O/OA/OALDERS/WWW-Mechanize-1.86.tar.gz - provides: - WWW::Mechanize 1.86 - WWW::Mechanize::Image 1.86 - WWW::Mechanize::Link 1.86 - requirements: - Carp 0 - ExtUtils::MakeMaker 0 - Getopt::Long 0 - HTML::Form 1.00 - HTML::HeadParser 0 - HTML::TokeParser 0 - HTML::TreeBuilder 0 - HTTP::Cookies 0 - HTTP::Request 1.30 - HTTP::Request::Common 0 - LWP::UserAgent 5.827 - Pod::Usage 0 - Scalar::Util 0 - Tie::RefHash 0 - URI::URL 0 - URI::file 0 - base 0 - perl 5.006 - strict 0 - warnings 0 - WWW-Mechanize-Cached-1.51 - pathname: O/OA/OALDERS/WWW-Mechanize-Cached-1.51.tar.gz + WWW-OAuth-1.003 + pathname: D/DB/DBOOK/WWW-OAuth-1.003.tar.gz provides: - WWW::Mechanize::Cached 1.51 + WWW::OAuth 1.003 + WWW::OAuth::Request 1.003 + WWW::OAuth::Request::Basic 1.003 + WWW::OAuth::Request::HTTP_Request 1.003 + WWW::OAuth::Request::Mojo 1.003 + WWW::OAuth::Util 1.003 requirements: - Cache::FileCache 0 Carp 0 - Data::Dump 0 + Class::Tiny::Chained 0 + Crypt::SysRandom 0 + Digest::SHA 0 ExtUtils::MakeMaker 0 + List::Util 1.33 Module::Runtime 0 - Moo 1.004005 - MooX::Types::MooseLike::Base 0 - Storable 2.21 - WWW::Mechanize 0 - namespace::clean 0 - perl 5.006 - strict 0 - warnings 0 + Role::Tiny 2.000000 + Scalar::Util 0 + URI 1.28 + URI::Escape 3.26 + WWW::Form::UrlEncoded 0.23 + perl 5.008001 WWW-RobotRules-6.02 pathname: G/GA/GAAS/WWW-RobotRules-6.02.tar.gz provides: @@ -9060,28 +7978,11 @@ DISTRIBUTIONS Fcntl 0 URI 1.10 perl 5.008001 - Want-0.29 - pathname: R/RO/ROBIN/Want-0.29.tar.gz - provides: - Want 0.29 - requirements: - ExtUtils::MakeMaker 0 - XML-NamespaceSupport-1.12 - pathname: P/PE/PERIGRIN/XML-NamespaceSupport-1.12.tar.gz - provides: - XML::NamespaceSupport 1.12 - requirements: - ExtUtils::MakeMaker 6.17 - constant 0 - perl 5.006 - strict 0 - vars 0 - warnings 0 - XML-Parser-2.44 - pathname: T/TO/TODDR/XML-Parser-2.44.tar.gz + XML-Parser-2.47 + pathname: T/TO/TODDR/XML-Parser-2.47.tar.gz provides: - XML::Parser 2.44 - XML::Parser::Expat 2.44 + XML::Parser 2.47 + XML::Parser::Expat 2.47 XML::Parser::Style::Debug undef XML::Parser::Style::Objects undef XML::Parser::Style::Stream undef @@ -9090,56 +7991,40 @@ DISTRIBUTIONS requirements: ExtUtils::MakeMaker 0 LWP::UserAgent 0 - Test::More 0 perl 5.00405 - XML-SAX-0.99 - pathname: G/GR/GRANTM/XML-SAX-0.99.tar.gz - provides: - XML::SAX 0.99 - XML::SAX::DocumentLocator undef - XML::SAX::ParserFactory 1.01 - XML::SAX::PurePerl 0.99 - XML::SAX::PurePerl::DebugHandler undef - XML::SAX::PurePerl::Exception undef - XML::SAX::PurePerl::Productions undef - XML::SAX::PurePerl::Reader undef - XML::SAX::PurePerl::Reader::Stream undef - XML::SAX::PurePerl::Reader::String undef - XML::SAX::PurePerl::Reader::URI undef - requirements: - ExtUtils::MakeMaker 0 - File::Temp 0 - XML::NamespaceSupport 0.03 - XML::SAX::Base 1.05 - XML-SAX-Base-1.09 - pathname: G/GR/GRANTM/XML-SAX-Base-1.09.tar.gz - provides: - XML::SAX::Base 1.09 - XML::SAX::Base::NoHandler 1.09 - XML::SAX::Exception 1.09 - requirements: - ExtUtils::MakeMaker 0 - perl 5.008 - XML-SAX-Expat-0.51 - pathname: B/BJ/BJOERN/XML-SAX-Expat-0.51.tar.gz - provides: - XML::SAX::Expat 0.51 - requirements: - ExtUtils::MakeMaker 0 - XML::NamespaceSupport 0.03 - XML::Parser 2.27 - XML::SAX 0.03 - XML::SAX::Base 1.00 - XML-Simple-2.24 - pathname: G/GR/GRANTM/XML-Simple-2.24.tar.gz - provides: - XML::Simple 2.24 - requirements: - ExtUtils::MakeMaker 0 - XML::NamespaceSupport 1.04 - XML::SAX 0.15 - XML::SAX::Expat 0 - perl 5.008 + XML-XPath-1.48 + pathname: M/MA/MANWAR/XML-XPath-1.48.tar.gz + provides: + XML::XPath 1.48 + XML::XPath::Boolean 1.48 + XML::XPath::Builder 1.48 + XML::XPath::Expr 1.48 + XML::XPath::Function 1.48 + XML::XPath::Literal 1.48 + XML::XPath::LocationPath 1.48 + XML::XPath::Node 1.48 + XML::XPath::Node::Attribute 1.48 + XML::XPath::Node::AttributeImpl 1.48 + XML::XPath::Node::Comment 1.48 + XML::XPath::Node::Element 1.48 + XML::XPath::Node::Namespace 1.48 + XML::XPath::Node::PI 1.48 + XML::XPath::Node::Text 1.48 + XML::XPath::NodeSet 1.48 + XML::XPath::Number 1.48 + XML::XPath::Parser 1.48 + XML::XPath::PerlSAX 1.48 + XML::XPath::Root 1.48 + XML::XPath::Step 1.48 + XML::XPath::Variable 1.48 + XML::XPath::XMLParser 1.48 + requirements: + ExtUtils::MakeMaker 0 + Path::Tiny 0.076 + Scalar::Util 1.45 + Test::More 0 + XML::Parser 2.23 + perl 5.010001 XSLoader-0.24 pathname: S/SA/SAPER/XSLoader-0.24.tar.gz provides: @@ -9147,11 +8032,18 @@ DISTRIBUTIONS requirements: ExtUtils::MakeMaker 0 Test::More 0.47 - YAML-1.24 - pathname: T/TI/TINITA/YAML-1.24.tar.gz + XString-0.005 + pathname: A/AT/ATOOMIC/XString-0.005.tar.gz + provides: + XString 0.005 + requirements: + ExtUtils::MakeMaker 0 + perl 5.008 + YAML-1.31 + pathname: I/IN/INGY/YAML-1.31.tar.gz provides: - YAML 1.24 - YAML::Any 1.24 + YAML 1.31 + YAML::Any 1.31 YAML::Dumper undef YAML::Dumper::Base undef YAML::Error undef @@ -9175,51 +8067,102 @@ DISTRIBUTIONS requirements: ExtUtils::MakeMaker 0 perl 5.008001 - YAML-Syck-1.30 - pathname: T/TO/TODDR/YAML-Syck-1.30.tar.gz + YAML-LibYAML-v0.903.0 + pathname: T/TI/TINITA/YAML-LibYAML-v0.903.0.tar.gz provides: - JSON::Syck 1.30 - YAML::Dumper::Syck undef - YAML::Loader::Syck undef - YAML::Syck 1.30 + YAML::LibYAML v0.903.0 + YAML::XS v0.903.0 requirements: - ExtUtils::MakeMaker 6.59 - perl 5.006 - aliased-0.34 - pathname: E/ET/ETHER/aliased-0.34.tar.gz - provides: - aliased 0.34 + B::Deparse 0 + Exporter 0 + ExtUtils::MakeMaker 0 + Scalar::Util 0 + base 0 + constant 0 + perl 5.008001 + strict 0 + warnings 0 + YAML-PP-v0.39.0 + pathname: T/TI/TINITA/YAML-PP-v0.39.0.tar.gz + provides: + YAML::PP v0.39.0 + YAML::PP::Common v0.39.0 + YAML::PP::Constructor v0.39.0 + YAML::PP::Dumper v0.39.0 + YAML::PP::Emitter v0.39.0 + YAML::PP::Exception v0.39.0 + YAML::PP::Grammar v0.39.0 + YAML::PP::Highlight v0.39.0 + YAML::PP::Lexer v0.39.0 + YAML::PP::Loader v0.39.0 + YAML::PP::Parser v0.39.0 + YAML::PP::Perl v0.39.0 + YAML::PP::Preserve::Array v0.39.0 + YAML::PP::Preserve::Hash v0.39.0 + YAML::PP::Preserve::Scalar v0.39.0 + YAML::PP::Reader v0.39.0 + YAML::PP::Reader::File v0.39.0 + YAML::PP::Render v0.39.0 + YAML::PP::Representer v0.39.0 + YAML::PP::Schema v0.39.0 + YAML::PP::Schema::Binary v0.39.0 + YAML::PP::Schema::Catchall v0.39.0 + YAML::PP::Schema::Core v0.39.0 + YAML::PP::Schema::Failsafe v0.39.0 + YAML::PP::Schema::Include v0.39.0 + YAML::PP::Schema::JSON v0.39.0 + YAML::PP::Schema::Merge v0.39.0 + YAML::PP::Schema::Perl v0.39.0 + YAML::PP::Schema::Tie::IxHash v0.39.0 + YAML::PP::Schema::YAML1_1 v0.39.0 + YAML::PP::Type::MergeKey v0.39.0 + YAML::PP::Writer v0.39.0 + YAML::PP::Writer::File v0.39.0 requirements: + B 0 + B::Deparse 0 Carp 0 + Data::Dumper 0 + Encode 0 Exporter 0 - Module::Build::Tiny 0.039 - perl 5.006 + ExtUtils::MakeMaker 0 + File::Basename 0 + Getopt::Long 0 + MIME::Base64 0 + Module::Load 0 + Scalar::Util 1.07 + Tie::Array 0 + Tie::Hash 0 + base 0 + constant 0 + overload 0 + perl 5.008000 strict 0 warnings 0 - bareword-filehandles-0.005 - pathname: I/IL/ILMARI/bareword-filehandles-0.005.tar.gz + bareword-filehandles-0.007 + pathname: I/IL/ILMARI/bareword-filehandles-0.007.tar.gz provides: - bareword::filehandles 0.005 + bareword::filehandles 0.007 requirements: B::Hooks::OP::Check 0 ExtUtils::Depends 0 ExtUtils::MakeMaker 0 - Lexical::SealRequireHints 0 Test::More 0.88 XSLoader 0 + if 0 perl 5.008001 strict 0 warnings 0 - common-sense-3.74 - pathname: M/ML/MLEHMANN/common-sense-3.74.tar.gz + common-sense-3.75 + pathname: M/ML/MLEHMANN/common-sense-3.75.tar.gz provides: - common::sense 3.74 + common::sense 3.75 requirements: ExtUtils::MakeMaker 0 - indirect-0.38 - pathname: V/VP/VPIT/indirect-0.38.tar.gz + indirect-0.39 + pathname: V/VP/VPIT/indirect-0.39.tar.gz provides: - indirect 0.38 + indirect 0.39 requirements: Carp 0 Config 0 @@ -9234,28 +8177,27 @@ DISTRIBUTIONS XSLoader 0 lib 0 perl 5.008001 - libnet-3.11 - pathname: S/SH/SHAY/libnet-3.11.tar.gz + libnet-3.15 + pathname: S/SH/SHAY/libnet-3.15.tar.gz provides: Net undef - Net::Cmd 3.11 - Net::Config 3.11 - Net::Domain 3.11 - Net::FTP 3.11 - Net::FTP::A 3.11 - Net::FTP::E 3.11 - Net::FTP::I 3.11 - Net::FTP::L 3.11 - Net::FTP::_SSL_SingleSessionCache 3.11 - Net::FTP::dataconn 3.11 - Net::NNTP 3.11 - Net::NNTP::_SSL 3.11 - Net::Netrc 3.11 - Net::POP3 3.11 - Net::POP3::_SSL 3.11 - Net::SMTP 3.11 - Net::SMTP::_SSL 3.11 - Net::Time 3.11 + Net::Cmd 3.15 + Net::Config 3.15 + Net::Domain 3.15 + Net::FTP 3.15 + Net::FTP::A 3.15 + Net::FTP::E 3.15 + Net::FTP::I 3.15 + Net::FTP::L 3.15 + Net::FTP::dataconn 3.15 + Net::NNTP 3.15 + Net::NNTP::_SSL 3.15 + Net::Netrc 3.15 + Net::POP3 3.15 + Net::POP3::_SSL 3.15 + Net::SMTP 3.15 + Net::SMTP::_SSL 3.15 + Net::Time 3.15 requirements: Carp 0 Errno 0 @@ -9278,34 +8220,32 @@ DISTRIBUTIONS utf8 0 vars 0 warnings 0 - libwww-perl-6.29 - pathname: O/OA/OALDERS/libwww-perl-6.29.tar.gz - provides: - LWP 6.29 - LWP::Authen::Basic 6.29 - LWP::Authen::Digest 6.29 - LWP::Authen::Ntlm 6.29 - LWP::ConnCache 6.29 - LWP::Debug 6.29 - LWP::Debug::TraceHTTP 6.29 - LWP::DebugFile 6.29 - LWP::MemberMixin 6.29 - LWP::Protocol 6.29 - LWP::Protocol::MyFTP 6.29 - LWP::Protocol::cpan 6.29 - LWP::Protocol::data 6.29 - LWP::Protocol::file 6.29 - LWP::Protocol::ftp 6.29 - LWP::Protocol::gopher 6.29 - LWP::Protocol::http 6.29 - LWP::Protocol::loopback 6.29 - LWP::Protocol::mailto 6.29 - LWP::Protocol::nntp 6.29 - LWP::Protocol::nogo 6.29 - LWP::RobotUA 6.29 - LWP::Simple 6.29 - LWP::UserAgent 6.29 - libwww::perl undef + libwww-perl-6.78 + pathname: O/OA/OALDERS/libwww-perl-6.78.tar.gz + provides: + LWP 6.78 + LWP::Authen::Basic 6.78 + LWP::Authen::Digest 6.78 + LWP::Authen::Ntlm 6.78 + LWP::ConnCache 6.78 + LWP::Debug 6.78 + LWP::Debug::TraceHTTP 6.78 + LWP::DebugFile 6.78 + LWP::MemberMixin 6.78 + LWP::Protocol 6.78 + LWP::Protocol::cpan 6.78 + LWP::Protocol::data 6.78 + LWP::Protocol::file 6.78 + LWP::Protocol::ftp 6.78 + LWP::Protocol::gopher 6.78 + LWP::Protocol::http 6.78 + LWP::Protocol::loopback 6.78 + LWP::Protocol::mailto 6.78 + LWP::Protocol::nntp 6.78 + LWP::Protocol::nogo 6.78 + LWP::RobotUA 6.78 + LWP::Simple 6.78 + LWP::UserAgent 6.78 requirements: Digest::MD5 0 Encode 2.12 @@ -9313,56 +8253,57 @@ DISTRIBUTIONS ExtUtils::MakeMaker 0 File::Copy 0 File::Listing 6 + File::Temp 0 Getopt::Long 0 HTML::Entities 0 - HTML::HeadParser 0 + HTML::HeadParser 3.71 HTTP::Cookies 6 - HTTP::Daemon 6 HTTP::Date 6 HTTP::Negotiate 6 - HTTP::Request 6 - HTTP::Request::Common 6 - HTTP::Response 6 - HTTP::Status 6 + HTTP::Request 6.18 + HTTP::Request::Common 6.18 + HTTP::Response 6.18 + HTTP::Status 6.18 IO::Select 0 IO::Socket 0 LWP::MediaTypes 6 MIME::Base64 2.1 + Module::Load 0 Net::FTP 2.58 - Net::HTTP 6.07 + Net::HTTP 6.18 Scalar::Util 0 Try::Tiny 0 URI 1.10 URI::Escape 0 WWW::RobotRules 6 - base 0 + parent 0.217 perl 5.008001 strict 0 warnings 0 - multidimensional-0.013 - pathname: I/IL/ILMARI/multidimensional-0.013.tar.gz + multidimensional-0.014 + pathname: I/IL/ILMARI/multidimensional-0.014.tar.gz provides: - multidimensional 0.013 + multidimensional 0.014 requirements: B::Hooks::OP::Check 0.19 CPAN::Meta 2.112580 ExtUtils::Depends 0 ExtUtils::MakeMaker 0 - Lexical::SealRequireHints 0.005 Test::More 0.88 XSLoader 0 - perl 5.008 + if 0 + perl 5.008001 strict 0 warnings 0 - namespace-autoclean-0.28 - pathname: E/ET/ETHER/namespace-autoclean-0.28.tar.gz + namespace-autoclean-0.31 + pathname: E/ET/ETHER/namespace-autoclean-0.31.tar.gz provides: - namespace::autoclean 0.28 + namespace::autoclean 0.31 requirements: + B 0 B::Hooks::EndOfScope 0.12 ExtUtils::MakeMaker 0 List::Util 0 - Sub::Identify 0 namespace::clean 0.20 perl 5.006 strict 0 @@ -9376,23 +8317,37 @@ DISTRIBUTIONS ExtUtils::MakeMaker 0 Package::Stash 0.23 perl 5.008001 - strictures-2.000003 - pathname: H/HA/HAARG/strictures-2.000003.tar.gz + podlators-v6.0.2 + pathname: R/RR/RRA/podlators-v6.0.2.tar.gz + provides: + Pod undef + Pod::Man v6.0.2 + Pod::ParseLink v6.0.2 + Pod::Text v6.0.2 + Pod::Text::Color v6.0.2 + Pod::Text::Overstrike v6.0.2 + Pod::Text::Termcap v6.0.2 + requirements: + ExtUtils::MakeMaker 0 + Pod::Simple 3.26 + perl 5.012 + strictures-2.000006 + pathname: H/HA/HAARG/strictures-2.000006.tar.gz provides: - strictures 2.000003 + strictures 2.000006 strictures::extra undef requirements: bareword::filehandles 0 indirect 0 multidimensional 0 perl 5.006 - version-0.9918 - pathname: J/JP/JPEACOCK/version-0.9918.tar.gz + version-0.9933 + pathname: L/LE/LEONT/version-0.9933.tar.gz provides: - version 0.9918 - version::regex 0.9918 - version::vpp 0.9918 - version::vxs 0.9918 + version 0.9933 + version::regex 0.9933 + version::vpp 0.9933 + version::vxs 0.9933 requirements: ExtUtils::MakeMaker 0 perl 5.006002 diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..99066703d --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,64 @@ +services: + api-server: + build: + context: . + target: develop + volumes: + - './:/app/' + - '/app/local' + ports: + - '8001:8000' + environment: + # default is 120, shorten to work with compose label + COLUMNS: 96 + develop: + watch: + - path: ./cpanfile + action: rebuild + + api-test: + profiles: + - test + depends_on: + elasticsearch-test: + condition: service_healthy + build: + context: . + target: test + environment: + NET_ASYNC_HTTP_MAXCONNS: 1 + COLUMNS: 80 + ES: http://elasticsearch-test:9200 + HARNESS_ACTIVE: 1 + # Instantiate Catalyst models using metacpan_server_testing.conf + METACPAN_SERVER_CONFIG_LOCAL_SUFFIX: testing + MINICPAN: /CPAN + DEVEL_COVER_OPTIONS: +ignore,^t/|^test-data/|^etc/|^local/ + networks: + - elasticsearch + volumes: + - type: volume + source: elasticsearch-test + target: /usr/share/elasticsearch/data + + elasticsearch-test: + profiles: + - test + platform: linux/amd64 + image: elasticsearch:2.4 + environment: + - discovery.type=single-node + healthcheck: + timeout: 5s + start_period: 60s + test: ["CMD", "curl", "--fail", "http://localhost:9200/_cluster/health?wait_for_status=yellow&timeout=5s"] + ports: + - "9200" + networks: + - elasticsearch + +networks: + elasticsearch: + +volumes: + elasticsearch-test: diff --git a/docs/API-docs.md b/docs/API-docs.md index c74a7c203..10137aa6d 100644 --- a/docs/API-docs.md +++ b/docs/API-docs.md @@ -6,17 +6,17 @@ There is also [a repository of examples](https://github.com/metacpan/metacpan-ex _All of these URLs can be tested using the [MetaCPAN Explorer](https://explorer.metacpan.org)_ -To learn more about the ElasticSearch query DSL (Domain-Specific Language) check out Clinton Gormley's [Terms of Endearment - ES Query DSL Explained] (https://www.slideshare.net/clintongormley/terms-of-endearment-the-elasticsearch-query-dsl-explained) slides. +To learn more about the ElasticSearch query DSL (Domain-Specific Language) check out Clinton Gormley's [Terms of Endearment - ES Query DSL Explained](https://www.slideshare.net/clintongormley/terms-of-endearment-the-elasticsearch-query-dsl-explained) slides. -The query syntax is explained on ElasticSearch's [reference page](https://www.elasticsearch.org/guide/reference/query-dsl/). You can also check out this getting started tutorial about Elasticsearch [reference page](https://joelabrahamsson.com/elasticsearch-101/). +The query syntax is explained on ElasticSearch's [reference page](https://www.elastic.co/guide/en/elasticsearch/reference/2.4/query-dsl.html). You can also check out this getting started tutorial about Elasticsearch [reference page](http://joelabrahamsson.com/elasticsearch-101/). ## Being polite -Currently, the only rules around using the API are to "be polite". We have enforced an upper limit of a size of 5,000 on search requests. If you need to fetch more than 5,000 items, you should look at using the scrolling API. Search this page for "scroll" to get an example using [Search::Elasticsearch](https://metacpan.org/pod/Search::Elasticsearch) or see the [Elasticsearch scroll docs](https://www.elasticsearch.org/guide/reference/fastapi/search/scroll.html) if you are connecting in some other way. +Currently, the only rules around using the API are to "be polite". We have enforced an upper limit of a size of 5,000 on search requests. If you need to fetch more than 5,000 items, you should look at using the scrolling API. Search this page for "scroll" to get an example using [Search::Elasticsearch](https://metacpan.org/pod/Search::Elasticsearch) or see the [Elasticsearch scroll docs](https://www.elastic.co/guide/en/elasticsearch/reference/2.4/search-request-scroll.html) if you are connecting in some other way. You can certainly scroll if you are fetching less than 5,000 items. You might want to do this if you are expecting a large data set, but will still need to run many requests to get all of the required data. -Be aware that when you scroll, your docs will come back unsorted, as noted in the [ElasticSearch scan documentation](https://www.elasticsearch.org/guide/reference/fastapi/search/search-type.html). +Be aware that when you scroll, your docs will come back unsorted, as noted in the [ElasticSearch scan documentation](https://www.elastic.co/guide/en/elasticsearch/reference/2.4/search-request-search-type.html#scan). ## Identifying Yourself @@ -27,13 +27,12 @@ Part of being polite is letting us know who you are and how to reach you. This Available fields can be found by accessing the corresponding `_mapping` endpoint. -* [/author/_mapping](https://fastapi.metacpan.org/v1/author/_mapping) - [explore](https://explorer.metacpan.org/?url=/author/_mapping) -* [/distribution/_mapping](https://fastapi.metacpan.org/v1/distribution/_mapping) - [explore](https://explorer.metacpan.org/?url=/distribution/_mapping) -* [/favorite/_mapping](https://fastapi.metacpan.org/v1/favorite/_mapping) - [explore](https://explorer.metacpan.org/?url=/favorite/_mapping) -* [/file/_mapping](https://fastapi.metacpan.org/v1/file/_mapping) - [explore](https://explorer.metacpan.org/?url=/file/_mapping) -* [/module/_mapping](https://fastapi.metacpan.org/v1/module/_mapping) - [explore](https://explorer.metacpan.org/?url=/module/_mapping) -* [/rating/_mapping](https://fastapi.metacpan.org/v1/rating/_mapping) - [explore](https://explorer.metacpan.org/?url=/rating/_mapping) -* [/release/_mapping](https://fastapi.metacpan.org/v1/release/_mapping) - [explore](https://explorer.metacpan.org/?url=/release/_mapping) +* [`/author/_mapping`](https://fastapi.metacpan.org/v1/author/_mapping) - [explore](https://explorer.metacpan.org/?url=/author/_mapping) +* [`/distribution/_mapping`](https://fastapi.metacpan.org/v1/distribution/_mapping) - [explore](https://explorer.metacpan.org/?url=/distribution/_mapping) +* [`/favorite/_mapping`](https://fastapi.metacpan.org/v1/favorite/_mapping) - [explore](https://explorer.metacpan.org/?url=/favorite/_mapping) +* [`/file/_mapping`](https://fastapi.metacpan.org/v1/file/_mapping) - [explore](https://explorer.metacpan.org/?url=/file/_mapping) +* [`/module/_mapping`](https://fastapi.metacpan.org/v1/module/_mapping) - [explore](https://explorer.metacpan.org/?url=/module/_mapping) +* [`/release/_mapping`](https://fastapi.metacpan.org/v1/release/_mapping) - [explore](https://explorer.metacpan.org/?url=/release/_mapping) ## Field documentation @@ -44,42 +43,11 @@ Fields are documented in the API codebase: https://github.com/metacpan/metacpan- Performing a search without any constraints is an easy way to get sample data -* [/author/_search](https://fastapi.metacpan.org/v1/author/_search) -* [/distribution/_search](https://fastapi.metacpan.org/v1/distribution/_search) -* [/favorite/_search](https://fastapi.metacpan.org/v1/favorite/_search) -* [/file/_search](https://fastapi.metacpan.org/v1/file/_search) -* [/rating/_search](https://fastapi.metacpan.org/v1/rating/_search) -* [/release/_search](https://fastapi.metacpan.org/v1/release/_search) - -## Joins - -ElasticSearch itself doesn't support joining data across multiple types. The API server can, however, handle a `join` query parameter if the underlying type was set up accordingly. Browse https://github.com/metacpan/metacpan-api/blob/master/lib/MetaCPAN/Server/Controller/ to see all join conditions. Here are some examples. - -Joins on documents: - -* [/author/PERLER?join=favorite](https://fastapi.metacpan.org/v1/author/PERLER?join=favorite) -* [/author/PERLER?join=favorite&join=release](https://fastapi.metacpan.org/v1/author/PERLER?join=favorite&join=release) -* [/release/Moose?join=author](https://fastapi.metacpan.org/v1/release/Moose?join=author) -* [/module/Moose?join=release](https://fastapi.metacpan.org/v1/module/Moose?join=release) - -Joins on search results is work in progress. - -Restricting the joined results can be done by using the [boolean "should"](https://www.elasticsearch.org/guide/reference/query-dsl/bool-query.html) occurrence type: - -```sh -curl -XPOST https://fastapi.metacpan.org/v1/author/PERLER?join=release -d ' -{ - "query": { - "bool": { - "should": [{ - "term": { - "release.status": "latest" - } - }] - } - } -}' -``` +* [`/author/_search`](https://fastapi.metacpan.org/v1/author/_search) +* [`/distribution/_search`](https://fastapi.metacpan.org/v1/distribution/_search) +* [`/favorite/_search`](https://fastapi.metacpan.org/v1/favorite/_search) +* [`/file/_search`](https://fastapi.metacpan.org/v1/file/_search) +* [`/release/_search`](https://fastapi.metacpan.org/v1/release/_search) ## JSONP @@ -101,33 +69,33 @@ The `/download_url` endpoint exists specifically for the `cpanm` client. It tak Obviously anyone can use this endpoint, but we'll only consider changes to this endpoint after considering how `cpanm` might be affected. -* [https://fastapi.metacpan.org/v1/download_url/HTTP::Tiny](https://fastapi.metacpan.org/v1/download_url/HTTP::Tiny) -* [https://fastapi.metacpan.org/v1/download_url/Moose?version===0.01](https://fastapi.metacpan.org/v1/download_url/Moose?version===0.01) -* [https://fastapi.metacpan.org/v1/download_url/Moose?version=!=0.01](https://fastapi.metacpan.org/v1/download_url/Moose?version=!=0.01) -* [https://fastapi.metacpan.org/v1/download_url/Moose?version=<=0.02](https://fastapi.metacpan.org/v1/download_url/Moose?version=<=0.02) -* [https://fastapi.metacpan.org/v1/download_url/Try::Tiny?version=>0.21,<0.27,!=0.24](https://fastapi.metacpan.org/v1/download_url/Try::Tiny?version=>0.21,<0.27,!=0.24) -* [https://fastapi.metacpan.org/v1/download_url/Try::Tiny?version=>0.21,<0.27&dev=1](https://fastapi.metacpan.org/v1/download_url/Try::Tiny?version=>0.21,<0.27&dev=1) -* [https://fastapi.metacpan.org/v1/download_url/Try::Tiny?version=>0.21,<0.27,!=0.26&dev=1](https://fastapi.metacpan.org/v1/download_url/Try::Tiny?version=>0.21,<0.27,!=0.26&dev=1) +* [`https://fastapi.metacpan.org/v1/download_url/HTTP::Tiny`](https://fastapi.metacpan.org/v1/download_url/HTTP::Tiny) +* [`https://fastapi.metacpan.org/v1/download_url/Moose?version===0.01`](https://fastapi.metacpan.org/v1/download_url/Moose?version===0.01) +* [`https://fastapi.metacpan.org/v1/download_url/Moose?version=!=0.01`](https://fastapi.metacpan.org/v1/download_url/Moose?version=!=0.01) +* [`https://fastapi.metacpan.org/v1/download_url/Moose?version=<=0.02`](https://fastapi.metacpan.org/v1/download_url/Moose?version=<=0.02) +* [`https://fastapi.metacpan.org/v1/download_url/Try::Tiny?version=>0.21,<0.27,!=0.24`](https://fastapi.metacpan.org/v1/download_url/Try::Tiny?version=>0.21,<0.27,!=0.24) +* [`https://fastapi.metacpan.org/v1/download_url/Try::Tiny?version=>0.21,<0.27&dev=1`](https://fastapi.metacpan.org/v1/download_url/Try::Tiny?version=>0.21,<0.27&dev=1) +* [`https://fastapi.metacpan.org/v1/download_url/Try::Tiny?version=>0.21,<0.27,!=0.26&dev=1`](https://fastapi.metacpan.org/v1/download_url/Try::Tiny?version=>0.21,<0.27,!=0.26&dev=1) ### `/release/{distribution}` ### `/release/{author}/{release}` -The `/release` endpoint accepts either the name of a `distribution` (e.g. [/release/Moose](https://fastapi.metacpan.org/v1/release/Moose)), which returns the most recent release of the distribution. Or provide the full path which consists of its `author` and the name of the `release` (e.g. [/release/DOY/Moose-2.0001](https://fastapi.metacpan.org/v1/release/DOY/Moose-2.0001)). +The `/release` endpoint accepts either the name of a `distribution` (e.g. [`/release/Moose`](https://fastapi.metacpan.org/v1/release/Moose)), which returns the most recent release of the distribution. Or provide the full path which consists of its `author` and the name of the `release` (e.g. [`/release/DOY/Moose-2.0001`](https://fastapi.metacpan.org/v1/release/DOY/Moose-2.0001)). ### `/author/{author}` -`author` refers to the pauseid of the author. It must be uppercased (e.g. [/author/DOY](https://fastapi.metacpan.org/v1/author/DOY)). +`author` refers to the pauseid of the author. It must be uppercased (e.g. [`/author/DOY`](https://fastapi.metacpan.org/v1/author/DOY)). ### `/module/{module}` -Returns the corresponding `file` of the latest version of the `module`. Considering that Moose-2.0001 is the latest release, the result of [/module/Moose](https://fastapi.metacpan.org/v1/module/Moose) is the same as [/file/DOY/Moose-2.0001/lib/Moose.pm](https://fastapi.metacpan.org/v1/file/DOY/Moose-2.0001/lib/Moose.pm). +Returns the corresponding `file` of the latest version of the `module`. Considering that Moose-2.0001 is the latest release, the result of [`/module/Moose`](https://fastapi.metacpan.org/v1/module/Moose) is the same as [`/file/DOY/Moose-2.0001/lib/Moose.pm`](https://fastapi.metacpan.org/v1/file/DOY/Moose-2.0001/lib/Moose.pm). ### `/pod/{module}` ### `/pod/{author}/{release}/{path}` -Returns the POD of the given module. You can change the output format by either passing a `content-type` query parameter (e.g. [/pod/Moose?content-type=text/plain](https://fastapi.metacpan.org/v1/pod/Moose?content-type=text/plain) or by adding an `Accept` header to the HTTP request. Valid content types are: +Returns the POD of the given module. You can change the output format by either passing a `content-type` query parameter (e.g. [`/pod/Moose?content-type=text/plain`](https://fastapi.metacpan.org/v1/pod/Moose?content-type=text/plain) or by adding an `Accept` header to the HTTP request. Valid content types are: * text/html (default) * text/plain @@ -143,11 +111,11 @@ Returns the full source of the latest, authorized version of the given Names of latest releases by OALDERS: -https://fastapi.metacpan.org/v1/release/_search?q=author:OALDERS%20AND%20status:latest&fields=name,status&size=100 +[`https://fastapi.metacpan.org/v1/release/_search?q=author:OALDERS%20AND%20status:latest&fields=name,status&size=100`](https://fastapi.metacpan.org/v1/release/_search?q=author:OALDERS%20AND%20status:latest&fields=name,status&size=100) 5,000 CPAN Authors: -[https://fastapi.metacpan.org/v1/author/_search?q=*&size=5000](https://fastapi.metacpan.org/author/_search?q=*) +[`https://fastapi.metacpan.org/v1/author/_search?q=*&size=5000`](https://fastapi.metacpan.org/author/_search?q=*) All CPAN Authors Who Have Provided Twitter IDs: @@ -159,11 +127,11 @@ https://fastapi.metacpan.org/v1/author/_search?q=updated:*&sort=updated:desc First 100 distributions which SZABGAB has given a ++: - https://fastapi.metacpan.org/v1/favorite/_search?q=user:sWuxlxYeQBKoCQe1f-FQ_Q&size=100&fields=distribution +https://fastapi.metacpan.org/v1/favorite/_search?q=user:sWuxlxYeQBKoCQe1f-FQ_Q&size=100&fields=distribution The 100 most recent releases ( similar to https://metacpan.org/recent ) - https://fastapi.metacpan.org/v1/release/_search?q=status:latest&fields=name,status,date&sort=date:desc&size=100 +https://fastapi.metacpan.org/v1/release/_search?q=status:latest&fields=name,status,date&sort=date:desc&size=100 Number of ++'es that DOY's dists have received: @@ -206,22 +174,24 @@ dependency. ```sh curl -XPOST https://fastapi.metacpan.org/v1/release/_search -d '{ - "size": 5000, - "fields": [ "distribution" ], - "filter": { - "and": [ - { "term": { "dependency.module": "MooseX::NonMoose" } }, - { "term": {"maturity": "released"} }, - { "term": {"status": "latest"} } - ] - } + "size" : 5000, + "fields" : [ "distribution" ], + "query" : { + "bool" : { + "must" : [ + { "term" : { "dependency.module" : "MooseX::NonMoose" } }, + { "term" : { "maturity" : "released" } }, + { "term" : { "status" : "latest" } } + ] + } + } }' ``` -_Note it is also possible to use these queries in GET requests (useful for cross-domain JSONP requests) by appropriately encoding the JSON query into the `source` parameter of the URL. For example the query above [would become](https://fastapi.metacpan.org/v1/release/_search?source=%7B%22query%22%3A%7B%22match_all%22%3A%7B%7D%7D%2C%22size%22%3A5000%2C%22fields%22%3A%5B%22distribution%22%5D%2C%22filter%22%3A%7B%22and%22%3A%5B%7B%22term%22%3A%7B%22release.dependency.module%22%3A%22MooseX%3A%3ANonMoose%22%7D%7D%2C%7B%22term%22%3A%7B%22release.maturity%22%3A%22released%22%7D%7D%2C%7B%22term%22%3A%7B%22release.status%22%3A%22latest%22%7D%7D%5D%7D%7D):_ +_Note it is also possible to use these queries in GET requests (useful for cross-domain JSONP requests) by appropriately encoding the JSON query into the `source` parameter of the URL. For example the query above [would become](https://fastapi.metacpan.org/v1/release/_search?source=%7B%0A%20%20%20%20%22size%22%20%3A%205000%2C%0A%20%20%20%20%22fields%22%20%3A%20%5B%20%22distribution%22%20%5D%2C%0A%20%20%20%20%22query%22%20%3A%20%7B%0A%20%20%20%20%20%20%20%20%22bool%22%20%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22must%22%20%3A%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20%22term%22%20%3A%20%7B%20%22dependency.module%22%20%3A%20%22MooseX%3A%3ANonMoose%22%20%7D%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20%22term%22%20%3A%20%7B%20%22maturity%22%20%3A%20%22released%22%20%7D%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20%22term%22%20%3A%20%7B%20%22status%22%20%3A%20%22latest%22%20%7D%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%7D):_ ``` -curl 'https://fastapi.metacpan.org/v1/release/_search?source=%7B%22query%22%3A%7B%22match_all%22%3A%7B%7D%7D%2C%22size%22%3A5000%2C%22fields%22%3A%5B%22distribution%22%5D%2C%22filter%22%3A%7B%22and%22%3A%5B%7B%22term%22%3A%7B%22release.dependency.module%22%3A%22MooseX%3A%3ANonMoose%22%7D%7D%2C%7B%22term%22%3A%7B%22release.maturity%22%3A%22released%22%7D%7D%2C%7B%22term%22%3A%7B%22release.status%22%3A%22latest%22%7D%7D%5D%7D%7D' +curl 'https://fastapi.metacpan.org/v1/release/_search?source=%7B%0A%20%20%20%20%22size%22%20%3A%205000%2C%0A%20%20%20%20%22fields%22%20%3A%20%5B%20%22distribution%22%20%5D%2C%0A%20%20%20%20%22query%22%20%3A%20%7B%0A%20%20%20%20%20%20%20%20%22bool%22%20%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22must%22%20%3A%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20%22term%22%20%3A%20%7B%20%22dependency.module%22%20%3A%20%22MooseX%3A%3ANonMoose%22%20%7D%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20%22term%22%20%3A%20%7B%20%22maturity%22%20%3A%20%22released%22%20%7D%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20%22term%22%20%3A%20%7B%20%22status%22%20%3A%20%22latest%22%20%7D%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%7D' ``` ### [The size of the CPAN unpacked](https://github.com/metacpan/metacpan-examples/blob/master/scripts/file/5-size-of-cpan.pl) @@ -231,15 +201,15 @@ curl 'https://fastapi.metacpan.org/v1/release/_search?source=%7B%22query%22%3A%7%20%20```sh%20curl%20-XPOST%20https://fastapi.metacpan.org/v1/release/_search?size=100%20-d'{ - "query": { - "range" : { - "date" : { - "gte" : "2010-06-05T00:00:00", - "lte" : "2011-06-05T00:00:00" + "query" : { + "range" : { + "date" : { + "gte" : "2010-06-05T00:00:00", + "lte" : "2011-06-05T00:00:00" + } } - } - }, - "fields": ["license", "name", "distribution", "date", "version_numified"] + }, + "fields": [ "license", "name", "distribution", "date", "version_numified" ] }' ``` @@ -247,17 +217,17 @@ curl -XPOST https://fastapi.metacpan.org/v1/release/_search?size=100 -d '{ ```sh curl -XPOST https://fastapi.metacpan.org/v1/release/_search -d '{ - "query": { - "match_all": {} + "query" : { + "match_all" : {} }, - "aggs": { - "license": { - "terms": { - "field": "license" + "aggs" : { + "license" : { + "terms" : { + "field" : "license" } } }, - "size": 0 + "size" : 0 }' ``` @@ -265,15 +235,18 @@ curl -XPOST https://fastapi.metacpan.org/v1/release/_search -d '{ ```sh curl -XPOST https://fastapi.metacpan.org/v1/file/_search -d '{ - "query": { "filtered":{"query":{"match_all":{}},"filter":{"term":{"level":0}}} - }, - "aggs": { - "license": { - "terms": { - "size":100, - "field":"name" - } } }, - "size":0 + "query" : { + "term" : { "level" : 0 } + }, + "aggs" : { + "license" : { + "terms" : { + "size" : 100, + "field" : "name" + } + } + }, + "size" : 0 }' ``` @@ -281,14 +254,15 @@ curl -XPOST https://fastapi.metacpan.org/v1/file/_search -d '{ ```sh curl -XPOST https://fastapi.metacpan.org/v1/file/_search -d '{ - "query": { "filtered":{ - "query":{"match_all":{}}, - "filter":{"and":[ - {"term":{"module.name":"DBI::Profile"}}, - {"term":{"module.version":"2.014123"}} - ]} - }}, - "fields":["release"] + "query" : { + "bool" : { + "must" : [ + { "term" : { "module.name" : "DBI::Profile" } }, + { "term" : { "module.version" : "2.014123" } } + ] + } + }, + "fields" : [ "release" ] }' ``` @@ -309,14 +283,24 @@ Note that "size" should be the number of distributions you are looking for. ```sh lynx --dump --post_data https://fastapi.metacpan.org/v1/release/_search <new; -my $result = $author->index_perlmongers; -say dump( $result ); - -$author->es->refresh_index( index => 'cpan' ); diff --git a/es/account/mapping.json b/es/account/mapping.json new file mode 100644 index 000000000..1d89039a6 --- /dev/null +++ b/es/account/mapping.json @@ -0,0 +1,33 @@ +{ + "dynamic": false, + "properties": { + "access_token": { + "dynamic": true, + "properties": { + "client": { + "type": "keyword" + }, + "token": { + "type": "keyword" + } + } + }, + "code": { + "type": "keyword" + }, + "id": { + "type": "keyword" + }, + "identity": { + "dynamic": false, + "properties": { + "key": { + "type": "keyword" + }, + "name": { + "type": "keyword" + } + } + } + } +} diff --git a/es/account/settings.json b/es/account/settings.json new file mode 100644 index 000000000..bbb95c38b --- /dev/null +++ b/es/account/settings.json @@ -0,0 +1,5 @@ +{ + "number_of_replicas": 1, + "number_of_shards": 1, + "refresh_interval": "1s" +} diff --git a/es/author/mapping.json b/es/author/mapping.json new file mode 100644 index 000000000..d643dfe50 --- /dev/null +++ b/es/author/mapping.json @@ -0,0 +1,115 @@ +{ + "dynamic": false, + "properties": { + "asciiname": { + "fields": { + "analyzed": { + "analyzer": "standard", + "fielddata": false, + "store": true, + "type": "text" + } + }, + "type": "keyword" + }, + "blog": { + "dynamic": true, + "properties": { + "feed": { + "type": "keyword" + }, + "url": { + "type": "keyword" + } + } + }, + "city": { + "type": "keyword" + }, + "country": { + "type": "keyword" + }, + "donation": { + "dynamic": true, + "properties": { + "id": { + "type": "keyword" + }, + "name": { + "type": "keyword" + } + } + }, + "email": { + "type": "keyword" + }, + "gravatar_url": { + "type": "keyword" + }, + "is_pause_custodial_account": { + "type": "boolean" + }, + "location": { + "type": "geo_point" + }, + "name": { + "fields": { + "analyzed": { + "analyzer": "standard", + "fielddata": false, + "store": true, + "type": "text" + } + }, + "type": "keyword" + }, + "pauseid": { + "type": "keyword" + }, + "perlmongers": { + "dynamic": true, + "properties": { + "name": { + "type": "keyword" + }, + "url": { + "type": "keyword" + } + } + }, + "profile": { + "dynamic": false, + "include_in_root": true, + "properties": { + "id": { + "fields": { + "analyzed": { + "analyzer": "simple", + "fielddata": false, + "store": true, + "type": "text" + } + }, + "type": "keyword" + }, + "name": { + "type": "keyword" + } + }, + "type": "nested" + }, + "region": { + "type": "keyword" + }, + "updated": { + "format": "strict_date_optional_time||epoch_millis", + "type": "date" + }, + "user": { + "type": "keyword" + }, + "website": { + "type": "keyword" + } + } +} diff --git a/es/author/settings.json b/es/author/settings.json new file mode 100644 index 000000000..bbb95c38b --- /dev/null +++ b/es/author/settings.json @@ -0,0 +1,5 @@ +{ + "number_of_replicas": 1, + "number_of_shards": 1, + "refresh_interval": "1s" +} diff --git a/es/contributor/mapping.json b/es/contributor/mapping.json new file mode 100644 index 000000000..72017a284 --- /dev/null +++ b/es/contributor/mapping.json @@ -0,0 +1,23 @@ +{ + "dynamic": false, + "properties": { + "distribution": { + "type": "keyword" + }, + "email": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "pauseid": { + "type": "keyword" + }, + "release_author": { + "type": "keyword" + }, + "release_name": { + "type": "keyword" + } + } +} diff --git a/es/contributor/settings.json b/es/contributor/settings.json new file mode 100644 index 000000000..bbb95c38b --- /dev/null +++ b/es/contributor/settings.json @@ -0,0 +1,5 @@ +{ + "number_of_replicas": 1, + "number_of_shards": 1, + "refresh_interval": "1s" +} diff --git a/es/cover/mapping.json b/es/cover/mapping.json new file mode 100644 index 000000000..274adddc1 --- /dev/null +++ b/es/cover/mapping.json @@ -0,0 +1,34 @@ +{ + "dynamic": false, + "properties": { + "criteria": { + "dynamic": true, + "properties": { + "branch": { + "type": "float" + }, + "condition": { + "type": "float" + }, + "statement": { + "type": "float" + }, + "subroutine": { + "type": "float" + }, + "total": { + "type": "float" + } + } + }, + "distribution": { + "type": "keyword" + }, + "release": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } +} diff --git a/es/cover/settings.json b/es/cover/settings.json new file mode 100644 index 000000000..bbb95c38b --- /dev/null +++ b/es/cover/settings.json @@ -0,0 +1,5 @@ +{ + "number_of_replicas": 1, + "number_of_shards": 1, + "refresh_interval": "1s" +} diff --git a/es/cve/mapping.json b/es/cve/mapping.json new file mode 100644 index 000000000..8ec674c24 --- /dev/null +++ b/es/cve/mapping.json @@ -0,0 +1,36 @@ +{ + "dynamic": false, + "properties": { + "affected_versions": { + "type": "text" + }, + "cpansa_id": { + "type": "keyword" + }, + "cves": { + "type": "text" + }, + "description": { + "type": "text" + }, + "distribution": { + "type": "keyword" + }, + "references": { + "type": "text" + }, + "releases": { + "type": "keyword" + }, + "reported": { + "format": "strict_date_optional_time||epoch_millis", + "type": "date" + }, + "severity": { + "type": "text" + }, + "versions": { + "type": "keyword" + } + } +} diff --git a/es/cve/settings.json b/es/cve/settings.json new file mode 100644 index 000000000..bbb95c38b --- /dev/null +++ b/es/cve/settings.json @@ -0,0 +1,5 @@ +{ + "number_of_replicas": 1, + "number_of_shards": 1, + "refresh_interval": "1s" +} diff --git a/es/distribution/mapping.json b/es/distribution/mapping.json new file mode 100644 index 000000000..1e652f69b --- /dev/null +++ b/es/distribution/mapping.json @@ -0,0 +1,109 @@ +{ + "dynamic": false, + "properties": { + "bugs": { + "dynamic": true, + "properties": { + "github": { + "dynamic": true, + "properties": { + "active": { + "type": "integer" + }, + "closed": { + "type": "integer" + }, + "open": { + "type": "integer" + }, + "source": { + "type": "keyword" + } + } + }, + "rt": { + "dynamic": true, + "properties": { + "active": { + "type": "integer" + }, + "closed": { + "type": "integer" + }, + "new": { + "type": "integer" + }, + "open": { + "type": "integer" + }, + "patched": { + "type": "integer" + }, + "rejected": { + "type": "integer" + }, + "resolved": { + "type": "integer" + }, + "source": { + "type": "keyword" + }, + "stalled": { + "type": "integer" + } + } + } + } + }, + "external_package": { + "dynamic": true, + "properties": { + "cygwin": { + "type": "keyword" + }, + "debian": { + "type": "keyword" + }, + "fedora": { + "type": "keyword" + } + } + }, + "name": { + "type": "keyword" + }, + "repo": { + "dynamic": true, + "properties": { + "github": { + "dynamic": true, + "properties": { + "stars": { + "type": "integer" + }, + "watchers": { + "type": "integer" + } + } + } + } + }, + "river": { + "dynamic": true, + "properties": { + "bucket": { + "type": "integer" + }, + "bus_factor": { + "type": "integer" + }, + "immediate": { + "type": "integer" + }, + "total": { + "type": "integer" + } + } + } + } +} diff --git a/es/distribution/settings.json b/es/distribution/settings.json new file mode 100644 index 000000000..bbb95c38b --- /dev/null +++ b/es/distribution/settings.json @@ -0,0 +1,5 @@ +{ + "number_of_replicas": 1, + "number_of_shards": 1, + "refresh_interval": "1s" +} diff --git a/es/favorite/mapping.json b/es/favorite/mapping.json new file mode 100644 index 000000000..0aa0f6e88 --- /dev/null +++ b/es/favorite/mapping.json @@ -0,0 +1,24 @@ +{ + "dynamic": false, + "properties": { + "author": { + "type": "keyword" + }, + "date": { + "format": "strict_date_optional_time||epoch_millis", + "type": "date" + }, + "distribution": { + "type": "keyword" + }, + "id": { + "type": "keyword" + }, + "release": { + "type": "keyword" + }, + "user": { + "type": "keyword" + } + } +} diff --git a/es/favorite/settings.json b/es/favorite/settings.json new file mode 100644 index 000000000..bbb95c38b --- /dev/null +++ b/es/favorite/settings.json @@ -0,0 +1,5 @@ +{ + "number_of_replicas": 1, + "number_of_shards": 1, + "refresh_interval": "1s" +} diff --git a/es/file/mapping.json b/es/file/mapping.json new file mode 100644 index 000000000..12dc23970 --- /dev/null +++ b/es/file/mapping.json @@ -0,0 +1,242 @@ +{ + "dynamic": false, + "properties": { + "abstract": { + "fields": { + "analyzed": { + "analyzer": "standard", + "fielddata": false, + "store": true, + "type": "text" + } + }, + "type": "keyword" + }, + "author": { + "type": "keyword" + }, + "authorized": { + "type": "boolean" + }, + "binary": { + "type": "boolean" + }, + "date": { + "format": "strict_date_optional_time||epoch_millis", + "type": "date" + }, + "deprecated": { + "type": "boolean" + }, + "description": { + "type": "text" + }, + "dir": { + "type": "keyword" + }, + "directory": { + "type": "boolean" + }, + "dist_fav_count": { + "type": "integer" + }, + "distribution": { + "fields": { + "analyzed": { + "analyzer": "standard", + "fielddata": false, + "store": true, + "type": "text" + }, + "camelcase": { + "analyzer": "camelcase", + "store": true, + "type": "text" + }, + "lowercase": { + "analyzer": "lowercase", + "store": true, + "type": "text" + } + }, + "type": "keyword" + }, + "documentation": { + "fields": { + "analyzed": { + "analyzer": "standard", + "fielddata": false, + "store": true, + "type": "text" + }, + "camelcase": { + "analyzer": "camelcase", + "store": true, + "type": "text" + }, + "edge": { + "analyzer": "edge", + "store": true, + "type": "text" + }, + "edge_camelcase": { + "analyzer": "edge_camelcase", + "store": true, + "type": "text" + }, + "lowercase": { + "analyzer": "lowercase", + "store": true, + "type": "text" + } + }, + "type": "keyword" + }, + "documentation_length": { + "type": "integer" + }, + "download_url": { + "type": "keyword" + }, + "id": { + "type": "keyword" + }, + "indexed": { + "type": "boolean" + }, + "level": { + "type": "integer" + }, + "maturity": { + "type": "keyword" + }, + "mime": { + "type": "keyword" + }, + "module": { + "dynamic": false, + "include_in_root": true, + "properties": { + "associated_pod": { + "type": "text" + }, + "authorized": { + "type": "boolean" + }, + "indexed": { + "type": "boolean" + }, + "name": { + "fields": { + "analyzed": { + "analyzer": "standard", + "fielddata": false, + "store": true, + "type": "text" + }, + "camelcase": { + "analyzer": "camelcase", + "store": true, + "type": "text" + }, + "lowercase": { + "analyzer": "lowercase", + "store": true, + "type": "text" + } + }, + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "version_numified": { + "type": "float" + } + }, + "type": "nested" + }, + "name": { + "type": "keyword" + }, + "path": { + "type": "keyword" + }, + "pod": { + "analyzer": "standard", + "fields": { + "analyzed": { + "analyzer": "standard", + "type": "text" + } + }, + "type": "text" + }, + "pod_lines": { + "type": "keyword" + }, + "release": { + "fields": { + "analyzed": { + "analyzer": "standard", + "fielddata": false, + "store": true, + "type": "text" + }, + "camelcase": { + "analyzer": "camelcase", + "store": true, + "type": "text" + }, + "lowercase": { + "analyzer": "lowercase", + "store": true, + "type": "text" + } + }, + "type": "keyword" + }, + "sloc": { + "type": "integer" + }, + "slop": { + "type": "integer" + }, + "stat": { + "dynamic": true, + "properties": { + "gid": { + "type": "long" + }, + "mode": { + "type": "integer" + }, + "mtime": { + "type": "integer" + }, + "size": { + "type": "integer" + }, + "uid": { + "type": "long" + } + } + }, + "status": { + "type": "keyword" + }, + "suggest": { + "analyzer": "simple", + "max_input_length": 50, + "preserve_position_increments": true, + "preserve_separators": true, + "type": "completion" + }, + "version": { + "type": "keyword" + }, + "version_numified": { + "type": "float" + } + } +} diff --git a/es/file/settings.json b/es/file/settings.json new file mode 100644 index 000000000..1cdf6e2f0 --- /dev/null +++ b/es/file/settings.json @@ -0,0 +1,53 @@ +{ + "analysis": { + "analyzer": { + "camelcase": { + "filter": [ + "lowercase", + "unique" + ], + "tokenizer": "camelcase", + "type": "custom" + }, + "edge": { + "filter": [ + "lowercase", + "edge" + ], + "tokenizer": "standard", + "type": "custom" + }, + "edge_camelcase": { + "filter": [ + "lowercase", + "edge" + ], + "tokenizer": "camelcase", + "type": "custom" + }, + "fulltext": { + "type": "english" + }, + "lowercase": { + "filter": "lowercase", + "tokenizer": "keyword" + } + }, + "filter": { + "edge": { + "max_gram": "20", + "min_gram": "1", + "type": "edge_ngram" + } + }, + "tokenizer": { + "camelcase": { + "pattern": "([^\\p{L}\\d]+)|(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)|(?<=[\\p{L}&&[^\\p{Lu}]])(?=\\p{Lu})|(?<=\\p{Lu})(?=\\p{Lu}[\\p{L}&&[^\\p{Lu}]])", + "type": "pattern" + } + } + }, + "number_of_replicas": 1, + "number_of_shards": 1, + "refresh_interval": "1s" +} diff --git a/es/mirror/mapping.json b/es/mirror/mapping.json new file mode 100644 index 000000000..eaebd2742 --- /dev/null +++ b/es/mirror/mapping.json @@ -0,0 +1,118 @@ +{ + "dynamic": false, + "properties": { + "A_or_CNAME": { + "type": "keyword" + }, + "aka_name": { + "type": "keyword" + }, + "ccode": { + "type": "keyword" + }, + "city": { + "fields": { + "analyzed": { + "analyzer": "standard", + "fielddata": false, + "store": true, + "type": "text" + } + }, + "type": "keyword" + }, + "contact": { + "dynamic": false, + "properties": { + "contact_site": { + "type": "keyword" + }, + "contact_user": { + "type": "keyword" + } + } + }, + "continent": { + "fields": { + "analyzed": { + "analyzer": "standard", + "fielddata": false, + "store": true, + "type": "text" + } + }, + "type": "keyword" + }, + "country": { + "fields": { + "analyzed": { + "analyzer": "standard", + "fielddata": false, + "store": true, + "type": "text" + } + }, + "type": "keyword" + }, + "dnsrr": { + "type": "keyword" + }, + "freq": { + "type": "keyword" + }, + "ftp": { + "type": "keyword" + }, + "http": { + "type": "keyword" + }, + "inceptdate": { + "format": "strict_date_optional_time||epoch_millis", + "type": "date" + }, + "location": { + "type": "geo_point" + }, + "name": { + "type": "keyword" + }, + "note": { + "type": "keyword" + }, + "org": { + "fields": { + "analyzed": { + "analyzer": "standard", + "fielddata": false, + "store": true, + "type": "text" + } + }, + "type": "keyword" + }, + "region": { + "fields": { + "analyzed": { + "analyzer": "standard", + "fielddata": false, + "store": true, + "type": "text" + } + }, + "type": "keyword" + }, + "reitredate": { + "format": "strict_date_optional_time||epoch_millis", + "type": "date" + }, + "rsync": { + "type": "keyword" + }, + "src": { + "type": "keyword" + }, + "tz": { + "type": "keyword" + } + } +} diff --git a/es/mirror/settings.json b/es/mirror/settings.json new file mode 100644 index 000000000..bbb95c38b --- /dev/null +++ b/es/mirror/settings.json @@ -0,0 +1,5 @@ +{ + "number_of_replicas": 1, + "number_of_shards": 1, + "refresh_interval": "1s" +} diff --git a/es/package/mapping.json b/es/package/mapping.json new file mode 100644 index 000000000..0248dfe82 --- /dev/null +++ b/es/package/mapping.json @@ -0,0 +1,23 @@ +{ + "dynamic": false, + "properties": { + "author": { + "type": "keyword" + }, + "dist_version": { + "type": "keyword" + }, + "distribution": { + "type": "keyword" + }, + "file": { + "type": "keyword" + }, + "module_name": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } +} diff --git a/es/package/settings.json b/es/package/settings.json new file mode 100644 index 000000000..bbb95c38b --- /dev/null +++ b/es/package/settings.json @@ -0,0 +1,5 @@ +{ + "number_of_replicas": 1, + "number_of_shards": 1, + "refresh_interval": "1s" +} diff --git a/es/permission/mapping.json b/es/permission/mapping.json new file mode 100644 index 000000000..31c2e36b6 --- /dev/null +++ b/es/permission/mapping.json @@ -0,0 +1,14 @@ +{ + "dynamic": false, + "properties": { + "co_maintainers": { + "type": "keyword" + }, + "module_name": { + "type": "keyword" + }, + "owner": { + "type": "keyword" + } + } +} diff --git a/es/permission/settings.json b/es/permission/settings.json new file mode 100644 index 000000000..bbb95c38b --- /dev/null +++ b/es/permission/settings.json @@ -0,0 +1,5 @@ +{ + "number_of_replicas": 1, + "number_of_shards": 1, + "refresh_interval": "1s" +} diff --git a/es/release/mapping.json b/es/release/mapping.json new file mode 100644 index 000000000..4ab1b1a28 --- /dev/null +++ b/es/release/mapping.json @@ -0,0 +1,211 @@ +{ + "dynamic": false, + "properties": { + "abstract": { + "fields": { + "analyzed": { + "analyzer": "standard", + "fielddata": false, + "store": true, + "type": "text" + } + }, + "type": "keyword" + }, + "archive": { + "type": "keyword" + }, + "author": { + "type": "keyword" + }, + "authorized": { + "type": "boolean" + }, + "changes_file": { + "type": "keyword" + }, + "checksum_md5": { + "type": "keyword" + }, + "checksum_sha256": { + "type": "keyword" + }, + "date": { + "format": "strict_date_optional_time||epoch_millis", + "type": "date" + }, + "dependency": { + "dynamic": false, + "include_in_root": true, + "properties": { + "module": { + "type": "keyword" + }, + "phase": { + "type": "keyword" + }, + "relationship": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + }, + "type": "nested" + }, + "deprecated": { + "type": "boolean" + }, + "distribution": { + "fields": { + "analyzed": { + "analyzer": "standard", + "fielddata": false, + "store": true, + "type": "text" + }, + "camelcase": { + "analyzer": "camelcase", + "store": true, + "type": "text" + }, + "lowercase": { + "analyzer": "lowercase", + "store": true, + "type": "text" + } + }, + "type": "keyword" + }, + "download_url": { + "type": "keyword" + }, + "first": { + "type": "boolean" + }, + "id": { + "type": "keyword" + }, + "license": { + "type": "keyword" + }, + "main_module": { + "type": "keyword" + }, + "maturity": { + "type": "keyword" + }, + "name": { + "fields": { + "analyzed": { + "analyzer": "standard", + "fielddata": false, + "store": true, + "type": "text" + }, + "camelcase": { + "analyzer": "camelcase", + "store": true, + "type": "text" + }, + "lowercase": { + "analyzer": "lowercase", + "store": true, + "type": "text" + } + }, + "type": "keyword" + }, + "provides": { + "type": "keyword" + }, + "resources": { + "dynamic": true, + "include_in_root": true, + "properties": { + "bugtracker": { + "dynamic": true, + "include_in_root": true, + "properties": { + "mailto": { + "type": "keyword" + }, + "web": { + "type": "keyword" + } + }, + "type": "nested" + }, + "homepage": { + "type": "keyword" + }, + "license": { + "type": "keyword" + }, + "repository": { + "dynamic": true, + "include_in_root": true, + "properties": { + "type": { + "type": "keyword" + }, + "url": { + "type": "keyword" + }, + "web": { + "type": "keyword" + } + }, + "type": "nested" + } + }, + "type": "nested" + }, + "stat": { + "dynamic": true, + "properties": { + "gid": { + "type": "long" + }, + "mode": { + "type": "integer" + }, + "mtime": { + "type": "integer" + }, + "size": { + "type": "integer" + }, + "uid": { + "type": "long" + } + } + }, + "status": { + "type": "keyword" + }, + "tests": { + "dynamic": true, + "properties": { + "fail": { + "type": "integer" + }, + "na": { + "type": "integer" + }, + "pass": { + "type": "integer" + }, + "unknown": { + "type": "integer" + } + } + }, + "version": { + "type": "keyword" + }, + "version_numified": { + "type": "float" + } + } +} diff --git a/es/release/settings.json b/es/release/settings.json new file mode 100644 index 000000000..1cdf6e2f0 --- /dev/null +++ b/es/release/settings.json @@ -0,0 +1,53 @@ +{ + "analysis": { + "analyzer": { + "camelcase": { + "filter": [ + "lowercase", + "unique" + ], + "tokenizer": "camelcase", + "type": "custom" + }, + "edge": { + "filter": [ + "lowercase", + "edge" + ], + "tokenizer": "standard", + "type": "custom" + }, + "edge_camelcase": { + "filter": [ + "lowercase", + "edge" + ], + "tokenizer": "camelcase", + "type": "custom" + }, + "fulltext": { + "type": "english" + }, + "lowercase": { + "filter": "lowercase", + "tokenizer": "keyword" + } + }, + "filter": { + "edge": { + "max_gram": "20", + "min_gram": "1", + "type": "edge_ngram" + } + }, + "tokenizer": { + "camelcase": { + "pattern": "([^\\p{L}\\d]+)|(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)|(?<=[\\p{L}&&[^\\p{Lu}]])(?=\\p{Lu})|(?<=\\p{Lu})(?=\\p{Lu}[\\p{L}&&[^\\p{Lu}]])", + "type": "pattern" + } + } + }, + "number_of_replicas": 1, + "number_of_shards": 1, + "refresh_interval": "1s" +} diff --git a/es/session/mapping.json b/es/session/mapping.json new file mode 100644 index 000000000..d4f130c22 --- /dev/null +++ b/es/session/mapping.json @@ -0,0 +1,3 @@ +{ + "dynamic": false +} diff --git a/es/session/settings.json b/es/session/settings.json new file mode 100644 index 000000000..bbb95c38b --- /dev/null +++ b/es/session/settings.json @@ -0,0 +1,5 @@ +{ + "number_of_replicas": 1, + "number_of_shards": 1, + "refresh_interval": "1s" +} diff --git a/es/settings.json b/es/settings.json new file mode 100644 index 000000000..1cdf6e2f0 --- /dev/null +++ b/es/settings.json @@ -0,0 +1,53 @@ +{ + "analysis": { + "analyzer": { + "camelcase": { + "filter": [ + "lowercase", + "unique" + ], + "tokenizer": "camelcase", + "type": "custom" + }, + "edge": { + "filter": [ + "lowercase", + "edge" + ], + "tokenizer": "standard", + "type": "custom" + }, + "edge_camelcase": { + "filter": [ + "lowercase", + "edge" + ], + "tokenizer": "camelcase", + "type": "custom" + }, + "fulltext": { + "type": "english" + }, + "lowercase": { + "filter": "lowercase", + "tokenizer": "keyword" + } + }, + "filter": { + "edge": { + "max_gram": "20", + "min_gram": "1", + "type": "edge_ngram" + } + }, + "tokenizer": { + "camelcase": { + "pattern": "([^\\p{L}\\d]+)|(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)|(?<=[\\p{L}&&[^\\p{Lu}]])(?=\\p{Lu})|(?<=\\p{Lu})(?=\\p{Lu}[\\p{L}&&[^\\p{Lu}]])", + "type": "pattern" + } + } + }, + "number_of_replicas": 1, + "number_of_shards": 1, + "refresh_interval": "1s" +} diff --git a/etc/metacpan.pl b/etc/metacpan.pl deleted file mode 100644 index 67512ff91..000000000 --- a/etc/metacpan.pl +++ /dev/null @@ -1,23 +0,0 @@ -# do not edit this file -# create etc/metacpan_local.pl instead -use FindBin; - -{ - # ElasticSearch instance, can be either a single server - # or an arrayref of servers - es => ':9200', - # the port of the api server - port => '5000', - # log level - level => 'info', - # appender for Log4perl - # default layout is "%d %p{1} %c: %m{chomp}%n" - # can be overridden using the layout key - # defining logger in metacpan_local.pl will - # override and not append to this configuration - logger => [{ - class => 'Log::Log4perl::Appender::File', - filename => $FindBin::RealBin . '/../var/log/metacpan.log', - syswrite => 1, - }] -} \ No newline at end of file diff --git a/etc/metacpan_interactive.pl b/etc/metacpan_interactive.pl deleted file mode 100644 index 520df00b4..000000000 --- a/etc/metacpan_interactive.pl +++ /dev/null @@ -1,12 +0,0 @@ -use FindBin; -{ - level => 'info', - logger => [{ - class => 'Log::Log4perl::Appender::ScreenColoredLevels', - stdout => 0, - }, { - class => 'Log::Log4perl::Appender::File', - filename => $FindBin::RealBin . '/../var/log/metacpan.log', - syswrite => 1, - }] -} \ No newline at end of file diff --git a/etc/metacpan_testing.pl b/etc/metacpan_testing.pl deleted file mode 100644 index 7d7881ea5..000000000 --- a/etc/metacpan_testing.pl +++ /dev/null @@ -1,12 +0,0 @@ -{ - es => ($ENV{ES} || 'localhost:9900'), - port => '5900', - die_on_error => 1, - level => ($ENV{TEST_VERBOSE} ? 'info' : 'warn'), - cpan => 'var/t/tmp/fakecpan', - source_base => 'var/t/tmp/source', - logger => [{ - class => 'Log::Log4perl::Appender::Screen', - name => 'testing' - }] -} diff --git a/git/hooks/pre-commit b/git/hooks/pre-commit index 5854030e1..9256ae257 100755 --- a/git/hooks/pre-commit +++ b/git/hooks/pre-commit @@ -1,9 +1,15 @@ -#!/usr/bin/env perl +#!/bin/bash -use strict; -use warnings; -# Hack to use carton's local::lib. -use lib 'local/lib/perl5'; +declare -i status +status=0 -use Code::TidyAll::Git::Precommit; -Code::TidyAll::Git::Precommit->check( no_stash => 1 ); +PRECIOUS=$(which precious) +if [[ -z $PRECIOUS ]]; then + PRECIOUS=./bin/precious +fi + +if ! "$PRECIOUS" lint -s; then + status+=1 +fi + +exit $status diff --git a/improve-search-results/.gitignore b/improve-search-results/.gitignore deleted file mode 100644 index 3f12605e2..000000000 --- a/improve-search-results/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# carton/local::lib -/local/ diff --git a/improve-search-results/README.md b/improve-search-results/README.md deleted file mode 100644 index 142d17e2a..000000000 --- a/improve-search-results/README.md +++ /dev/null @@ -1,41 +0,0 @@ - -# Search result comparison system - -## Why - -We want to improve MetaCPAN's search results, getting them at least as good as search.cpan.org's but ideally -even better. - -## How - -Run multiple searches (via the API that the web UI now uses), with different weights (that are now arguments) and compare to each other (so one weighthing doesn't -then break another, or at least we can come to some -balance). - -### Installing - -You will need postgres installed with a database -that matches the current user and the current user needs -access (the MetaCPAN developer vm sets this up for you). - -```sh -cpanm Carton -carton install -``` - -### Running tests - -```sh - -carton exec /opt/perl-5.22.2/bin/perl ./app.pl eval 'app->perform_all_searches' -``` - -### Viewing results site -```sh -carton exec /opt/perl-5.22.2/bin/perl ./app.pl daemon -m production -l http://*:5000 -``` - - - - - diff --git a/improve-search-results/app.pl b/improve-search-results/app.pl deleted file mode 100755 index 83a62d0f8..000000000 --- a/improve-search-results/app.pl +++ /dev/null @@ -1,213 +0,0 @@ -use Mojolicious::Lite; - -use Mojo::Pg; -use List::MoreUtils 'first_index'; - -my $user = getpwuid($<); # for vagrant user on dev box - -# carton exec /opt/perl-5.22.2/bin/perl ./app.pl daemon -m production -l http://*:5000 - -helper pg => sub { state $pg = Mojo::Pg->new("postgresql:///${user}") }; - -app->pg->auto_migrate(1)->migrations->from_data; - -helper insert_search => sub { - my ($c, $search, $expect) = @_; - return !!$c->pg->db->query(<<' SQL', $search, $expect)->rows; - insert into searches (search, expect) values (?, ?) - SQL -}; - -helper insert_source => sub { - my ($c, $name, $query) = @_; - return !!$c->pg->db->query(<<' SQL', $name, $query)->rows; - insert into sources (name, query) values (?, ?, ?) - SQL -}; - -helper get_results => sub { - my $c = shift; - return $c->pg->db->query(<<' SQL')->expand->hash->{results}; - select json_object_agg(search, results) as results - from ( - select - searches.search, - json_object_agg(sources.name, results.rank) as results - from results - inner join searches on searches.id = results.search_id - inner join sources on sources.id = results.source_id - group by searches.search - ) x - SQL -}; - -helper perform_all_searches => sub { - my ($c) = @_; - my $queries = $c->pg->db->query(<<' SQL'); - select - searches.id as search_id, - sources.id as source_id, - searches.search, - searches.expect, - sources.name, - results.rank - from searches - cross join sources - left join results on searches.id = results.search_id - and sources.id = results.source_id - SQL - my $db = $c->pg->db; - my $sql = 'insert into results (search_id, source_id, rank) values (?, ?, ?)'; - $queries->hashes->each(sub{ - my $query = shift; - return if $query->{rank}; - my $rank = $c->perform_one_search(@{$query}{qw/search expect name query/}); - $db->query($sql, @{$query}{qw/search_id source_id/}, $rank); - }); -}; - -helper perform_one_search => sub { - my ($c, $search, $expect, $name, $query) = @_; - - my $rank = - $name eq 'SCO' ? _perform_sco($c, $search, $expect) : - $name eq 'MWEB' ? _perform_mweb($c, $search, $expect) : - _perform_mquery($c, $search, $expect, $query); - - return $rank // 100; -}; - -sub _perform_sco { - my ($c, $search, $expect) = @_; - my $url = Mojo::URL->new('http://search.cpan.org/search?mode=all&n=100'); - $url->query([query => $search]); - my $tx = $c->app->ua->get($url); - my $res = $tx->res->dom->find('.sr')->map('all_text'); - my $idx = first_index { $_ eq $expect } @{$res->to_array}; - return $idx < 0 ? undef : $idx + 1; -} - -sub _perform_mweb { - my ($c, $search, $expect) = @_; - my $url = Mojo::URL->new('https://metacpan.org/search?size=100'); - $url->query([q => $search]); - my $tx = $c->app->ua->get($url); - my $res = $tx->res->dom->find('.module-result big strong a')->map('all_text'); - my $idx = first_index { $_ eq $expect } @{$res->to_array}; - return $idx < 0 ? undef : $idx + 1; -} - -sub _perform_mquery {} - -get '/' => 'index'; - -get '/results' => sub { - my $c = shift; - $c->render(json => $c->get_results); -}; - -app->start; - -__DATA__ - -@@ index.html.ep - -<%== perform_all_searches %> - - - - - - MetaCPAN Search Comparison - - - - - - - - - - -@@ migrations - --- 1 up - -create table searches ( - id bigserial primary key, - search text not null unique, - expect text not null -); -insert into searches (search, expect) values -('tmpfile', 'File::Temp'), -('path', 'Path::Tiny'), -('dbix', 'DBIx::Class'), -('uri', 'URI'); - -create table sources ( - id bigserial primary key, - name text not null unique, - query text -); -insert into sources (name) values ('SCO'), ('MWEB'); - -create table results ( - id bigserial primary key, - search_id bigint references searches on delete cascade, - source_id bigint references sources on delete cascade, - rank integer -); - --- 1 down - -drop table if exists searches cascade; -drop table if exists sources cascade; -drop table if exists results cascade; \ No newline at end of file diff --git a/improve-search-results/cpanfile b/improve-search-results/cpanfile deleted file mode 100644 index a4f1508a4..000000000 --- a/improve-search-results/cpanfile +++ /dev/null @@ -1,6 +0,0 @@ -requires 'perl', '5.010'; - -requires 'Mojolicious', 7.23; -requires 'Mojolicious::Lite', 0; -requires 'Mojo::Pg', 2.35; - diff --git a/improve-search-results/cpanfile.snapshot b/improve-search-results/cpanfile.snapshot deleted file mode 100644 index 2d4bd0476..000000000 --- a/improve-search-results/cpanfile.snapshot +++ /dev/null @@ -1,241 +0,0 @@ -# carton snapshot format: version 1.0 -DISTRIBUTIONS - DBD-Pg-3.5.3 - pathname: T/TU/TURNSTEP/DBD-Pg-3.5.3.tar.gz - provides: - Bundle::DBD::Pg v3.5.3 - DBD::Pg v3.5.3 - requirements: - DBI 1.614 - ExtUtils::MakeMaker 6.11 - Test::More 0.88 - Time::HiRes 0 - version 0 - DBI-1.636 - pathname: T/TI/TIMB/DBI-1.636.tar.gz - provides: - Bundle::DBI 12.008696 - DBD::DBM 0.08 - DBD::DBM::Statement 0.08 - DBD::DBM::Table 0.08 - DBD::DBM::db 0.08 - DBD::DBM::dr 0.08 - DBD::DBM::st 0.08 - DBD::ExampleP 12.014311 - DBD::ExampleP::db 12.014311 - DBD::ExampleP::dr 12.014311 - DBD::ExampleP::st 12.014311 - DBD::File 0.44 - DBD::File::DataSource::File 0.44 - DBD::File::DataSource::Stream 0.44 - DBD::File::Statement 0.44 - DBD::File::Table 0.44 - DBD::File::TableSource::FileSystem 0.44 - DBD::File::db 0.44 - DBD::File::dr 0.44 - DBD::File::st 0.44 - DBD::Gofer 0.015327 - DBD::Gofer::Policy::Base 0.010088 - DBD::Gofer::Policy::classic 0.010088 - DBD::Gofer::Policy::pedantic 0.010088 - DBD::Gofer::Policy::rush 0.010088 - DBD::Gofer::Transport::Base 0.014121 - DBD::Gofer::Transport::corostream undef - DBD::Gofer::Transport::null 0.010088 - DBD::Gofer::Transport::pipeone 0.010088 - DBD::Gofer::Transport::stream 0.014599 - DBD::Gofer::db 0.015327 - DBD::Gofer::dr 0.015327 - DBD::Gofer::st 0.015327 - DBD::NullP 12.014715 - DBD::NullP::db 12.014715 - DBD::NullP::dr 12.014715 - DBD::NullP::st 12.014715 - DBD::Proxy 0.2004 - DBD::Proxy::RPC::PlClient 0.2004 - DBD::Proxy::db 0.2004 - DBD::Proxy::dr 0.2004 - DBD::Proxy::st 0.2004 - DBD::Sponge 12.010003 - DBD::Sponge::db 12.010003 - DBD::Sponge::dr 12.010003 - DBD::Sponge::st 12.010003 - DBDI 12.015129 - DBI 1.636 - DBI::Const::GetInfo::ANSI 2.008697 - DBI::Const::GetInfo::ODBC 2.011374 - DBI::Const::GetInfoReturn 2.008697 - DBI::Const::GetInfoType 2.008697 - DBI::DBD 12.015129 - DBI::DBD::Metadata 2.014214 - DBI::DBD::SqlEngine 0.06 - DBI::DBD::SqlEngine::DataSource 0.06 - DBI::DBD::SqlEngine::Statement 0.06 - DBI::DBD::SqlEngine::Table 0.06 - DBI::DBD::SqlEngine::TableSource 0.06 - DBI::DBD::SqlEngine::TieMeta 0.06 - DBI::DBD::SqlEngine::TieTables 0.06 - DBI::DBD::SqlEngine::db 0.06 - DBI::DBD::SqlEngine::dr 0.06 - DBI::DBD::SqlEngine::st 0.06 - DBI::Gofer::Execute 0.014283 - DBI::Gofer::Request 0.012537 - DBI::Gofer::Response 0.011566 - DBI::Gofer::Serializer::Base 0.009950 - DBI::Gofer::Serializer::DataDumper 0.009950 - DBI::Gofer::Serializer::Storable 0.015586 - DBI::Gofer::Transport::Base 0.012537 - DBI::Gofer::Transport::pipeone 0.012537 - DBI::Gofer::Transport::stream 0.012537 - DBI::Profile 2.015065 - DBI::ProfileData 2.010008 - DBI::ProfileDumper 2.015325 - DBI::ProfileDumper::Apache 2.014121 - DBI::ProfileSubs 0.009396 - DBI::ProxyServer 0.3005 - DBI::ProxyServer::db 0.3005 - DBI::ProxyServer::dr 0.3005 - DBI::ProxyServer::st 0.3005 - DBI::SQL::Nano 1.015544 - DBI::SQL::Nano::Statement_ 1.015544 - DBI::SQL::Nano::Table_ 1.015544 - DBI::Util::CacheMemory 0.010315 - DBI::Util::_accessor 0.009479 - DBI::common 1.636 - requirements: - ExtUtils::MakeMaker 6.48 - Test::Simple 0.90 - perl 5.008 - Mojo-Pg-2.35 - pathname: S/SR/SRI/Mojo-Pg-2.35.tar.gz - provides: - Mojo::Pg 2.35 - Mojo::Pg::Database undef - Mojo::Pg::Migrations undef - Mojo::Pg::PubSub undef - Mojo::Pg::Results undef - Mojo::Pg::Transaction undef - requirements: - DBD::Pg 3.005001 - ExtUtils::MakeMaker 0 - Mojolicious 7.15 - perl 5.010001 - Mojolicious-7.23 - pathname: S/SR/SRI/Mojolicious-7.23.tar.gz - provides: - Mojo undef - Mojo::Asset undef - Mojo::Asset::File undef - Mojo::Asset::Memory undef - Mojo::Base undef - Mojo::ByteStream undef - Mojo::Cache undef - Mojo::Collection undef - Mojo::Content undef - Mojo::Content::MultiPart undef - Mojo::Content::Single undef - Mojo::Cookie undef - Mojo::Cookie::Request undef - Mojo::Cookie::Response undef - Mojo::DOM undef - Mojo::DOM::CSS undef - Mojo::DOM::HTML undef - Mojo::Date undef - Mojo::EventEmitter undef - Mojo::Exception undef - Mojo::File undef - Mojo::Headers undef - Mojo::HelloWorld undef - Mojo::Home undef - Mojo::IOLoop undef - Mojo::IOLoop::Client undef - Mojo::IOLoop::Delay undef - Mojo::IOLoop::Server undef - Mojo::IOLoop::Stream undef - Mojo::IOLoop::Subprocess undef - Mojo::IOLoop::TLS undef - Mojo::JSON undef - Mojo::JSON::Pointer undef - Mojo::Loader undef - Mojo::Log undef - Mojo::Message undef - Mojo::Message::Request undef - Mojo::Message::Response undef - Mojo::Parameters undef - Mojo::Path undef - Mojo::Reactor undef - Mojo::Reactor::EV undef - Mojo::Reactor::Poll undef - Mojo::Server undef - Mojo::Server::CGI undef - Mojo::Server::Daemon undef - Mojo::Server::Hypnotoad undef - Mojo::Server::Morbo undef - Mojo::Server::PSGI undef - Mojo::Server::PSGI::_IO undef - Mojo::Server::Prefork undef - Mojo::Template undef - Mojo::Transaction undef - Mojo::Transaction::HTTP undef - Mojo::Transaction::WebSocket undef - Mojo::URL undef - Mojo::Upload undef - Mojo::UserAgent undef - Mojo::UserAgent::CookieJar undef - Mojo::UserAgent::Proxy undef - Mojo::UserAgent::Server undef - Mojo::UserAgent::Transactor undef - Mojo::Util undef - Mojo::WebSocket undef - Mojolicious 7.23 - Mojolicious::Command undef - Mojolicious::Command::cgi undef - Mojolicious::Command::cpanify undef - Mojolicious::Command::daemon undef - Mojolicious::Command::eval undef - Mojolicious::Command::generate undef - Mojolicious::Command::generate::app undef - Mojolicious::Command::generate::lite_app undef - Mojolicious::Command::generate::makefile undef - Mojolicious::Command::generate::plugin undef - Mojolicious::Command::get undef - Mojolicious::Command::inflate undef - Mojolicious::Command::prefork undef - Mojolicious::Command::psgi undef - Mojolicious::Command::routes undef - Mojolicious::Command::test undef - Mojolicious::Command::version undef - Mojolicious::Commands undef - Mojolicious::Controller undef - Mojolicious::Lite undef - Mojolicious::Plugin undef - Mojolicious::Plugin::Config undef - Mojolicious::Plugin::Config::Sandbox undef - Mojolicious::Plugin::DefaultHelpers undef - Mojolicious::Plugin::EPLRenderer undef - Mojolicious::Plugin::EPRenderer undef - Mojolicious::Plugin::HeaderCondition undef - Mojolicious::Plugin::JSONConfig undef - Mojolicious::Plugin::Mount undef - Mojolicious::Plugin::PODRenderer undef - Mojolicious::Plugin::TagHelpers undef - Mojolicious::Plugins undef - Mojolicious::Renderer undef - Mojolicious::Routes undef - Mojolicious::Routes::Match undef - Mojolicious::Routes::Pattern undef - Mojolicious::Routes::Route undef - Mojolicious::Sessions undef - Mojolicious::Static undef - Mojolicious::Types undef - Mojolicious::Validator undef - Mojolicious::Validator::Validation undef - Test::Mojo undef - ojo undef - requirements: - ExtUtils::MakeMaker 0 - IO::Socket::IP 0.37 - JSON::PP 2.27103 - Pod::Simple 3.09 - Time::Local 1.2 - perl 5.010001 diff --git a/lib/Catalyst/Action/Deserialize/MetaCPANSanitizedJSON.pm b/lib/Catalyst/Action/Deserialize/MetaCPANSanitizedJSON.pm index 1e9c10454..e46d7b8e2 100644 --- a/lib/Catalyst/Action/Deserialize/MetaCPANSanitizedJSON.pm +++ b/lib/Catalyst/Action/Deserialize/MetaCPANSanitizedJSON.pm @@ -1,10 +1,10 @@ package Catalyst::Action::Deserialize::MetaCPANSanitizedJSON; use Moose; -use namespace::autoclean; -use Try::Tiny; use Cpanel::JSON::XS (); use MetaCPAN::Server::QuerySanitizer (); +use namespace::autoclean; +use Try::Tiny qw( catch try ); extends 'Catalyst::Action::Deserialize::JSON'; @@ -39,7 +39,7 @@ around execute => sub { if ( my $source = delete $params->{source} ) { # NOTE: merge $controller->{json_options} if we ever use it - my $json = JSON->new->utf8; + my $json = Cpanel::JSON::XS->new->utf8; # if it decodes if ( try { $source = $json->decode($source); } ) { diff --git a/lib/Catalyst/Authentication/Store/Proxy.pm b/lib/Catalyst/Authentication/Store/Proxy.pm index a97673f75..d941a60df 100644 --- a/lib/Catalyst/Authentication/Store/Proxy.pm +++ b/lib/Catalyst/Authentication/Store/Proxy.pm @@ -2,8 +2,8 @@ package Catalyst::Authentication::Store::Proxy; # ABSTRACT: Delegates authentication logic to the user object use Moose; -use Catalyst::Utils; -use MetaCPAN::Types qw( HashRef Str ); +use Catalyst::Utils (); +use MetaCPAN::Types::TypeTiny qw( ClassName HashRef Str ); has user_class => ( is => 'ro', @@ -14,7 +14,7 @@ has user_class => ( ); has handles => ( is => 'ro', isa => HashRef ); has config => ( is => 'ro', isa => HashRef ); -has app => ( is => 'ro', isa => 'ClassName' ); +has app => ( is => 'ro', isa => ClassName ); has realm => ( is => 'ro' ); sub BUILDARGS { @@ -51,7 +51,7 @@ sub new_object { sub from_session { my ( $self, $c, $frozenuser ) = @_; - my $user = $self->new_object( $self->config, $c ); + my $user = $self->new_object( $self->config, $c ); my $delegate = $self->handles->{from_session}; return $user->$delegate( $c, $frozenuser ); } @@ -64,7 +64,7 @@ sub for_session { sub find_user { my ( $self, $authinfo, $c ) = @_; - my $user = $self->new_object( $self->config, $c ); + my $user = $self->new_object( $self->config, $c ); my $delegate = $self->handles->{find_user}; return $user->$delegate( $authinfo, $c ); diff --git a/lib/Catalyst/Plugin/Session/Store/ElasticSearch.pm b/lib/Catalyst/Plugin/Session/Store/ElasticSearch.pm index 0ccc266d0..68159b5cb 100644 --- a/lib/Catalyst/Plugin/Session/Store/ElasticSearch.pm +++ b/lib/Catalyst/Plugin/Session/Store/ElasticSearch.pm @@ -4,36 +4,26 @@ package Catalyst::Plugin::Session::Store::ElasticSearch; use Moose; extends 'Catalyst::Plugin::Session::Store'; -use List::MoreUtils qw(); -use MooseX::Types::ElasticSearch qw(:all); +use MetaCPAN::Types::TypeTiny qw( ES ); + +use MetaCPAN::ESConfig qw( es_doc_path ); +use MetaCPAN::Server::Config (); +use MetaCPAN::Util qw( true false ); has _session_es => ( - required => 1, - is => 'ro', - coerce => 1, - isa => ES, - default => sub { shift->_session_plugin_config->{servers} || ':9200' } -); -has _session_es_index => ( - required => 1, - is => 'ro', - default => sub { shift->_session_plugin_config->{index} || 'user' } -); -has _session_es_type => ( - required => 1, - is => 'ro', - default => sub { shift->_session_plugin_config->{type} || 'session' } + is => 'ro', + lazy => 1, + coerce => 1, + isa => ES, + default => + sub { MetaCPAN::Server::Config::config()->{elasticsearch_servers} }, ); sub get_session_data { my ( $self, $key ) = @_; if ( my ($sid) = $key =~ /^\w+:(.*)/ ) { my $data = eval { - $self->_session_es->get( - index => $self->_session_es_index, - type => $self->_session_es_type, - id => $sid, - ); + $self->_session_es->get( es_doc_path('session'), id => $sid, ); } || return undef; if ( $key =~ /^expires:/ ) { return $data->{_source}->{_expires}; @@ -49,11 +39,10 @@ sub store_session_data { if ( my ($sid) = $key =~ /^session:(.*)/ ) { $session->{_expires} = $self->session_expires; $self->_session_es->index( - index => $self->_session_es_index, - type => $self->_session_es_type, + es_doc_path('session'), id => $sid, body => $session, - refresh => 1, + refresh => true, ); } } @@ -63,10 +52,9 @@ sub delete_session_data { if ( my ($sid) = $key =~ /^session:(.*)/ ) { eval { $self->_session_es->delete( - index => $self->_session_es_index, - type => $self->_session_es_type, + es_doc_path('session'), id => $sid, - refresh => 1, + refresh => true, ); }; } @@ -90,8 +78,6 @@ sub delete_expired_sessions { } MyApp->config( 'Plugin::Session' => { servers => ':9200', - index => 'user', - type => 'session', } ); =head1 DESCRIPTION diff --git a/lib/ElasticSearchX/Model/Document/Role.pm b/lib/ElasticSearchX/Model/Document/Role.pm new file mode 100644 index 000000000..6d2b58be2 --- /dev/null +++ b/lib/ElasticSearchX/Model/Document/Role.pm @@ -0,0 +1,24 @@ +package ElasticSearchX::Model::Document::Role; +use strict; +use warnings; + +use MetaCPAN::Model::Hacks; + +no warnings 'redefine'; + +my $_put = \&_put; +*_put = sub { + my ($self) = @_; + my $es = $self->index->model->es; + + my %return = &$_put; + + if ( $es->api_version le '6_0' ) { + return %return; + } + + delete $return{type}; + return %return; +}; + +1; diff --git a/lib/ElasticSearchX/Model/Document/Set.pm b/lib/ElasticSearchX/Model/Document/Set.pm new file mode 100644 index 000000000..7adc669ca --- /dev/null +++ b/lib/ElasticSearchX/Model/Document/Set.pm @@ -0,0 +1,63 @@ +package ElasticSearchX::Model::Document::Set; +use strict; +use warnings; + +use MetaCPAN::Model::Hacks; + +no warnings 'redefine'; + +our %query_override; +my $_build_query = \&_build_query; +*_build_query = sub { + my $query = $_build_query->(@_); + %$query = ( %$query, %query_override ); + return $query; +}; + +our %qs_override; +my $_build_qs = \&_build_qs; +*_build_qs = sub { + my $qs = $_build_qs->(@_); + %$qs = ( %$qs, %qs_override ); + return $qs; +}; + +# ESXM normally tries to use search_type => scan, which is deprecated or +# removed in newer Elasticsearch versions. Sorting on _doc gives the same +# optimization. +my $delete = \&delete; +*delete = sub { + local %qs_override = ( search_type => 'query_then_fetch' ); + local %query_override = ( sort => '_doc' ); + return $delete->(@_); +}; + +my $get = \&get; +*get = sub { + my ( $self, $args, $qs ) = @_; + if ( $self->es->api_version eq '2_0' ) { + goto &$get; + } + my %qs = %{ $qs || {} }; + if ( my $fields = $self->fields ) { + $qs{_source} = $fields; + local $self->{fields}; + return $get->( $self, $args, \%qs ); + } + goto &$get; +}; + +# ESXM will try to inflate based on the index/type stored in the result. We +# are using aliases, and ESXM doesn't know about the actual index that the +# docs are stored in. Instead, allow it to use the configured index/type for +# this doc set. +my $inflate_result = \&inflate_result; +*inflate_result = sub { + my ( $self, $res ) = @_; + my $new_res = {%$res}; + delete $new_res->{_index}; + delete $new_res->{_type}; + $self->$inflate_result($new_res); +}; + +1; diff --git a/lib/MetaCPAN/API.pm b/lib/MetaCPAN/API.pm new file mode 100644 index 000000000..86b29ab84 --- /dev/null +++ b/lib/MetaCPAN/API.pm @@ -0,0 +1,172 @@ +package MetaCPAN::API; + +=head1 DESCRIPTION + +This is the API Minion server. + + # Display information on jobs in queue + ./bin/run bin/api.pl minion job -s + +=cut + +use Mojo::Base 'Mojolicious'; + +use File::Temp (); +use List::Util qw( any ); +use MetaCPAN::Script::Runner (); +use Try::Tiny qw( catch try ); +use MetaCPAN::Server::Config (); + +sub startup { + my $self = shift; + + unless ( $self->config->{config_override} ) { + $self->config( MetaCPAN::Server::Config::config() ); + } + + die 'need secret' unless $self->config->{secret}; + + $self->secrets( [ $self->config->{secret} ] ); + + $self->static->paths( [ $self->home->child('root') ] ); + + $self->plugin( Minion => $self->_build_db_params ); + + $self->minion->add_task( + index_release => $self->_gen_index_task_sub('release') ); + + $self->minion->add_task( + index_latest => $self->_gen_index_task_sub('latest') ); + + $self->minion->add_task( + index_favorite => $self->_gen_index_task_sub('favorite') ); + + $self->_set_up_routes; +} + +sub _gen_index_task_sub { + my ( $self, $type ) = @_; + + return sub { + my ( $job, @args ) = @_; + + my @warnings; + local $SIG{__WARN__} = sub { + push @warnings, $_[0]; + warn $_[0]; + }; + + # @args could be ( '--latest', '/path/to/release' ); + unshift @args, $type; + + # Runner expects to have been called via CLI + local @ARGV = @args; + try { + MetaCPAN::Script::Runner->run(@args); + $job->finish( @warnings ? { warnings => \@warnings } : () ); + } + catch { + warn $_; + $job->fail( { + message => $_, + @warnings ? ( warnings => \@warnings ) : (), + } ); + }; + } +} + +sub _set_up_routes { + my $self = shift; + + my $r = $self->routes; + + my $admin = $r->under( + '/admin' => sub { + my $c = shift; + my $username = $c->session('github_username'); + if ( $self->_is_admin($username) ) { + return 1; + } + + # Direct non-admins away from the app + elsif ($username) { + $c->redirect_to('https://metacpan.org/'); + return 0; + } + + # This is possibly a logged out admin + $c->redirect_to('/auth/github/authenticate'); + return 0; + } + ); + + $self->_set_up_oauth_routes; + $self->plugin( 'Minion::Admin' => { route => $admin->any('/minion') } ); +} + +sub _is_admin { + my $self = shift; + my $username = $ENV{HARNESS_ACTIVE} ? $ENV{FORCE_ADMIN_AUTH} : shift; + return 0 unless $username; + + my @admins = ( + 'haarg', 'jberger', 'mickeyn', 'oalders', + 'ranguard', 'reyjrar', 'ssoriche', + $ENV{HARNESS_ACTIVE} ? 'tester' : (), + ); + + return any { $username eq $_ } @admins; +} + +sub _build_db_params { + my $self = shift; + + my $db_params; + if ( $ENV{HARNESS_ACTIVE} ) { + my $file = File::Temp->new( UNLINK => 1, SUFFIX => '.db' ); + return { SQLite => 'sqlite:' . $file }; + } + + die "Unable to determine dsn from configuration" + unless $self->config->{minion_dsn}; + + if ( $self->config->{minion_dsn} =~ /^postgresql:/ ) { + return { Pg => $self->config->{minion_dsn} }; + } + + if ( $self->config->{minion_dsn} =~ /^sqlite:/ ) { + return { SQLite => $self->config->{minion_dsn} }; + } + + die "Unsupported Database in dsn: " . $self->config->{minion_dsn}; +} + +sub _set_up_oauth_routes { + my $self = shift; + + my $oauth = $self->config->{oauth}; + + # We could do better DRY here, but it might be more complicated than it's + # worth + + $self->plugin( + 'Web::Auth', + module => 'Github', + key => $oauth->{github}->{key}, + secret => $oauth->{github}->{secret}, + user_info => 1, + on_finished => sub { + my ( $c, $access_token, $account_info ) = @_; + my $username = $account_info->{login}; + $c->session( is_logged_in => 1 ); + $c->session( github_username => $username ); + if ( $self->_is_admin($username) ) { + $c->redirect_to('/admin'); + return; + } + $c->redirect_to( $self->config->{front_end_url} ); + }, + ); +} + +1; diff --git a/lib/MetaCPAN/API/Controller/Admin.pm b/lib/MetaCPAN/API/Controller/Admin.pm new file mode 100644 index 000000000..a7095cf89 --- /dev/null +++ b/lib/MetaCPAN/API/Controller/Admin.pm @@ -0,0 +1,15 @@ +package MetaCPAN::API::Controller::Admin; + +use Mojo::Base 'Mojolicious::Controller'; + +sub identity_search_form { } + +sub search_identities { + my $self = shift; + my $data = $self->model->user->lookup( $self->param('name'), + $self->param('key') ); + $self->stash( user_data => $data ); + $self->render('admin/search_identities'); +} + +1; diff --git a/lib/MetaCPAN/API/Model/Role/ES.pm b/lib/MetaCPAN/API/Model/Role/ES.pm new file mode 100644 index 000000000..080b0e079 --- /dev/null +++ b/lib/MetaCPAN/API/Model/Role/ES.pm @@ -0,0 +1,16 @@ +package MetaCPAN::API::Model::Role::ES; + +use Moose::Role; + +use MetaCPAN::Types::TypeTiny qw( Object ); + +has es => ( + is => 'ro', + isa => Object, + handles => { _run_query => 'search', }, + required => 1, +); + +no Moose::Role; +1; + diff --git a/lib/MetaCPAN/API/Model/User.pm b/lib/MetaCPAN/API/Model/User.pm new file mode 100644 index 000000000..5414be5c0 --- /dev/null +++ b/lib/MetaCPAN/API/Model/User.pm @@ -0,0 +1,32 @@ +package MetaCPAN::API::Model::User; + +use MetaCPAN::ESConfig qw( es_doc_path ); +use MetaCPAN::Moose; + +with 'MetaCPAN::API::Model::Role::ES'; + +sub lookup { + my ( $self, $name, $key ) = @_; + + my $query = { + bool => { + must => [ + { term => { 'identity.name' => $name } }, + { term => { 'identity.key' => $key } }, + ] + } + }; + + my $res = $self->_run_query( + es_doc_path('account'), + body => { query => $query }, + search_type => 'dfs_query_then_fetch', + ); + + return $res->{hits}{hits}[0]{_source}; +} + +__PACKAGE__->meta->make_immutable; + +1; + diff --git a/lib/MetaCPAN/API/Plugin/Model.pm b/lib/MetaCPAN/API/Plugin/Model.pm new file mode 100644 index 000000000..f33dd4b8e --- /dev/null +++ b/lib/MetaCPAN/API/Plugin/Model.pm @@ -0,0 +1,49 @@ +package MetaCPAN::API::Plugin::Model; + +use Mojo::Base 'Mojolicious::Plugin'; + +use Carp (); + +# Models from the catalyst app +use MetaCPAN::Query::Search (); + +# New models +use MetaCPAN::API::Model::Cover (); +use MetaCPAN::API::Model::Download (); +use MetaCPAN::API::Model::User (); + +has app => sub { Carp::croak 'app is required' }, weak => 1; + +has download => sub { + my $self = shift; + return MetaCPAN::API::Model::Download->new( es => $self->app->es ); +}; + +has search => sub { + my $self = shift; + return MetaCPAN::Query::Search->new( es => $self->app->es, ); +}; + +has user => sub { + my $self = shift; + return MetaCPAN::API::Model::User->new( es => $self->app->es ); +}; + +has cover => sub { + my $self = shift; + return MetaCPAN::API::Model::Cover->new( es => $self->app->es ); +}; + +sub register { + my ( $plugin, $app, $conf ) = @_; + $plugin->app($app); + + # cached models + $app->helper( 'model.download' => sub { $plugin->download } ); + $app->helper( 'model.search' => sub { $plugin->search } ); + $app->helper( 'model.user' => sub { $plugin->user } ); + $app->helper( 'model.cover' => sub { $plugin->cover } ); +} + +1; + diff --git a/lib/MetaCPAN/Document/Author.pm b/lib/MetaCPAN/Document/Author.pm index 7a3e5db84..48296bb18 100644 --- a/lib/MetaCPAN/Document/Author.pm +++ b/lib/MetaCPAN/Document/Author.pm @@ -3,14 +3,23 @@ package MetaCPAN::Document::Author; use MetaCPAN::Moose; # load order important for next 2 modules -use ElasticSearchX::Model::Document::Types qw(:all); +use ElasticSearchX::Model::Document::Types qw( Location ); use ElasticSearchX::Model::Document; # load order not important -use Gravatar::URL (); -use MetaCPAN::Types qw(:all); -use MooseX::Types::Structured qw(Dict Tuple Optional); -use MetaCPAN::Util; +use Gravatar::URL (); +use MetaCPAN::Types qw( ESBool Profile ); +use MetaCPAN::Types::TypeTiny qw( + ArrayRef + ArrayRefPromote + Blog + Dict + HashRef + NonEmptySimpleStr + PerlMongers + Str +); +use MetaCPAN::Util qw(true false); has name => ( is => 'ro', @@ -28,7 +37,7 @@ has asciiname => ( ); has [qw(website email)] => - ( is => 'ro', required => 1, isa => ArrayRef, coerce => 1 ); + ( is => 'ro', required => 1, isa => ArrayRefPromote, coerce => 1 ); has pauseid => ( is => 'ro', @@ -95,8 +104,9 @@ has updated => ( has is_pause_custodial_account => ( is => 'ro', - isa => Bool, - default => 0, + isa => ESBool, + coerce => 1, + default => sub {false}, ); sub _build_gravatar_url { @@ -106,8 +116,8 @@ sub _build_gravatar_url { # because we want to show the author's CPAN identity. # Using another e-mail than the CPAN one removes flexibility for # the author and ultimately could be a privacy leak. - # The author can manage this identity both on his gravatar account - # (by assigning an image to his author@cpan.org) + # The author can manage this identity both on their gravatar account + # (by assigning an image to their author@cpan.org) # and now by changing this URL from metacpa.org return Gravatar::URL::gravatar_url( email => $self->pauseid . '@cpan.org', diff --git a/lib/MetaCPAN/Document/Author/Profile.pm b/lib/MetaCPAN/Document/Author/Profile.pm index 1ce0b37a7..497828b07 100644 --- a/lib/MetaCPAN/Document/Author/Profile.pm +++ b/lib/MetaCPAN/Document/Author/Profile.pm @@ -8,8 +8,8 @@ use ElasticSearchX::Model::Document; with 'ElasticSearchX::Model::Document::EmbeddedRole'; +use MetaCPAN::Types::TypeTiny qw( Str ); use MetaCPAN::Util; -use MetaCPAN::Types qw( Str ); has name => ( is => 'ro', diff --git a/lib/MetaCPAN/Document/Author/Set.pm b/lib/MetaCPAN/Document/Author/Set.pm deleted file mode 100644 index 2120ecd2b..000000000 --- a/lib/MetaCPAN/Document/Author/Set.pm +++ /dev/null @@ -1,26 +0,0 @@ -package MetaCPAN::Document::Author::Set; - -use Moose; - -use MetaCPAN::Query::Author; - -extends 'ElasticSearchX::Model::Document::Set'; - -has query_author => ( - is => 'ro', - isa => 'MetaCPAN::Query::Author', - lazy => 1, - builder => '_build_query_author', - handles => [qw< by_ids by_user search prefix_search >], -); - -sub _build_query_author { - my $self = shift; - return MetaCPAN::Query::Author->new( - es => $self->es, - index_name => $self->index->name, - ); -} - -__PACKAGE__->meta->make_immutable; -1; diff --git a/lib/MetaCPAN/Document/CVE.pm b/lib/MetaCPAN/Document/CVE.pm new file mode 100644 index 000000000..155b1b57a --- /dev/null +++ b/lib/MetaCPAN/Document/CVE.pm @@ -0,0 +1,63 @@ +package MetaCPAN::Document::CVE; + +use MetaCPAN::Moose; + +use ElasticSearchX::Model::Document; +use MetaCPAN::Types::TypeTiny qw( ArrayRef Str ); + +has distribution => ( + is => 'ro', + isa => Str, + required => 1, +); + +has cpansa_id => ( + is => 'ro', + isa => Str, + required => 1, +); + +has description => ( + is => 'ro', + isa => Str, + required => 1, +); + +has severity => ( + is => 'ro', + isa => Str, + required => 1, +); + +has reported => ( + is => 'ro', + isa => Str, + required => 1, +); + +has affected_versions => ( + is => 'ro', + isa => ArrayRef, + required => 1, +); + +has cves => ( + is => 'ro', + isa => ArrayRef, + required => 1, +); + +has references => ( + is => 'ro', + isa => ArrayRef, + required => 1, +); + +has versions => ( + is => 'ro', + isa => ArrayRef, + required => 1, +); + +__PACKAGE__->meta->make_immutable; +1; diff --git a/lib/MetaCPAN/Document/Contributor.pm b/lib/MetaCPAN/Document/Contributor.pm index ea83f975e..dec572834 100644 --- a/lib/MetaCPAN/Document/Contributor.pm +++ b/lib/MetaCPAN/Document/Contributor.pm @@ -3,7 +3,7 @@ package MetaCPAN::Document::Contributor; use MetaCPAN::Moose; use ElasticSearchX::Model::Document; -use MetaCPAN::Types qw( Str ); +use MetaCPAN::Types::TypeTiny qw( ArrayRef Str ); has distribution => ( is => 'ro', @@ -24,9 +24,18 @@ has release_name => ( ); has pauseid => ( - is => 'ro', - isa => Str, - required => 1, + is => 'ro', + isa => Str, +); + +has name => ( + is => 'ro', + isa => Str, +); + +has email => ( + is => 'ro', + isa => ArrayRef [Str], ); __PACKAGE__->meta->make_immutable; diff --git a/lib/MetaCPAN/Document/Contributor/Set.pm b/lib/MetaCPAN/Document/Contributor/Set.pm deleted file mode 100644 index 18e19deb5..000000000 --- a/lib/MetaCPAN/Document/Contributor/Set.pm +++ /dev/null @@ -1,26 +0,0 @@ -package MetaCPAN::Document::Contributor::Set; - -use Moose; - -use MetaCPAN::Query::Contributor; - -extends 'ElasticSearchX::Model::Document::Set'; - -has query_contributor => ( - is => 'ro', - isa => 'MetaCPAN::Query::Contributor', - lazy => 1, - builder => '_build_query_contributor', - handles => [qw< find_author_contributions find_release_contributors >], -); - -sub _build_query_contributor { - my $self = shift; - return MetaCPAN::Query::Contributor->new( - es => $self->es, - index_name => 'contributor', - ); -} - -__PACKAGE__->meta->make_immutable; -1; diff --git a/lib/MetaCPAN/Document/Cover.pm b/lib/MetaCPAN/Document/Cover.pm index 30d91bdfe..1ab9a5991 100644 --- a/lib/MetaCPAN/Document/Cover.pm +++ b/lib/MetaCPAN/Document/Cover.pm @@ -3,7 +3,7 @@ package MetaCPAN::Document::Cover; use MetaCPAN::Moose; use ElasticSearchX::Model::Document; -use MetaCPAN::Types qw( HashRef Str ); +use MetaCPAN::Types::TypeTiny qw( HashRef Str ); has distribution => ( is => 'ro', diff --git a/lib/MetaCPAN/Document/Cover/Set.pm b/lib/MetaCPAN/Document/Cover/Set.pm deleted file mode 100644 index 05e6278a8..000000000 --- a/lib/MetaCPAN/Document/Cover/Set.pm +++ /dev/null @@ -1,26 +0,0 @@ -package MetaCPAN::Document::Cover::Set; - -use Moose; - -use MetaCPAN::Query::Cover (); - -extends 'ElasticSearchX::Model::Document::Set'; - -has query_cover => ( - is => 'ro', - isa => 'MetaCPAN::Query::Cover', - lazy => 1, - builder => '_build_query_cover', - handles => [qw< find_release_coverage >], -); - -sub _build_query_cover { - my $self = shift; - return MetaCPAN::Query::Cover->new( - es => $self->es, - index_name => 'cover', - ); -} - -__PACKAGE__->meta->make_immutable; -1; diff --git a/lib/MetaCPAN/Document/Dependency.pm b/lib/MetaCPAN/Document/Dependency.pm index 123953d28..e54f85fd9 100644 --- a/lib/MetaCPAN/Document/Dependency.pm +++ b/lib/MetaCPAN/Document/Dependency.pm @@ -9,7 +9,6 @@ use ElasticSearchX::Model::Document; with 'ElasticSearchX::Model::Document::EmbeddedRole'; use MetaCPAN::Util; -use MetaCPAN::Types qw( Str ); has [qw(phase relationship module version)] => ( is => 'ro', required => 1 ); diff --git a/lib/MetaCPAN/Document/Distribution.pm b/lib/MetaCPAN/Document/Distribution.pm index 25bde766d..64c178664 100644 --- a/lib/MetaCPAN/Document/Distribution.pm +++ b/lib/MetaCPAN/Document/Distribution.pm @@ -7,7 +7,8 @@ use namespace::autoclean; use Moose; use ElasticSearchX::Model::Document; -use MetaCPAN::Types qw( ArrayRef BugSummary RiverSummary); +use MetaCPAN::Types::TypeTiny qw( BugSummary RiverSummary ); +use MetaCPAN::Util qw(true false); has name => ( is => 'ro', @@ -27,12 +28,20 @@ has river => ( isa => RiverSummary, dynamic => 1, writer => '_set_river', + default => sub { + +{ + bucket => 0, + bus_factor => 1, + immediate => 0, + total => 0, + }; + }, ); sub releases { my $self = shift; - return $self->index->type("release") - ->filter( { term => { "distribution" => $self->name } } ); + return $self->index->model->doc("release") + ->query( { term => { "distribution" => $self->name } } ); } sub set_first_release { @@ -41,11 +50,11 @@ sub set_first_release { my @releases = $self->releases->sort( ["date"] )->all; my $first = shift @releases; - $first->_set_first(1); + $first->_set_first(true); $first->put; for my $rel (@releases) { - $rel->_set_first(0); + $rel->_set_first(false); $rel->put; } diff --git a/lib/MetaCPAN/Document/Distribution/Set.pm b/lib/MetaCPAN/Document/Distribution/Set.pm deleted file mode 100644 index cf275c749..000000000 --- a/lib/MetaCPAN/Document/Distribution/Set.pm +++ /dev/null @@ -1,26 +0,0 @@ -package MetaCPAN::Document::Distribution::Set; - -use Moose; - -use MetaCPAN::Query::Distribution; - -extends 'ElasticSearchX::Model::Document::Set'; - -has query_distribution => ( - is => 'ro', - isa => 'MetaCPAN::Query::Distribution', - lazy => 1, - builder => '_build_query_distribution', - handles => [qw< get_river_data_by_dist get_river_data_by_dists >], -); - -sub _build_query_distribution { - my $self = shift; - return MetaCPAN::Query::Distribution->new( - es => $self->es, - index_name => 'cpan', - ); -} - -__PACKAGE__->meta->make_immutable; -1; diff --git a/lib/MetaCPAN/Document/Favorite.pm b/lib/MetaCPAN/Document/Favorite.pm index 001bc9f3c..eaf7cbcf1 100644 --- a/lib/MetaCPAN/Document/Favorite.pm +++ b/lib/MetaCPAN/Document/Favorite.pm @@ -6,8 +6,7 @@ use warnings; use Moose; use ElasticSearchX::Model::Document; -use DateTime; -use MetaCPAN::Types qw(:all); +use DateTime (); use MetaCPAN::Util; has id => ( diff --git a/lib/MetaCPAN/Document/Favorite/Set.pm b/lib/MetaCPAN/Document/Favorite/Set.pm deleted file mode 100644 index 6e3112021..000000000 --- a/lib/MetaCPAN/Document/Favorite/Set.pm +++ /dev/null @@ -1,32 +0,0 @@ -package MetaCPAN::Document::Favorite::Set; - -use Moose; - -use MetaCPAN::Query::Favorite; - -extends 'ElasticSearchX::Model::Document::Set'; - -has query_favorite => ( - is => 'ro', - isa => 'MetaCPAN::Query::Favorite', - lazy => 1, - builder => '_build_query_favorite', - handles => [ - qw< agg_by_distributions - by_user - leaderboard - recent - users_by_distribution > - ], -); - -sub _build_query_favorite { - my $self = shift; - return MetaCPAN::Query::Favorite->new( - es => $self->es, - index_name => $self->index->name, - ); -} - -__PACKAGE__->meta->make_immutable; -1; diff --git a/lib/MetaCPAN/Document/File.pm b/lib/MetaCPAN/Document/File.pm index 475d6bb51..c9fd79c8a 100644 --- a/lib/MetaCPAN/Document/File.pm +++ b/lib/MetaCPAN/Document/File.pm @@ -7,15 +7,14 @@ use utf8; use Moose; use ElasticSearchX::Model::Document; -use Encode; -use List::AllUtils qw( any ); -use MetaCPAN::Document::Module; -use MetaCPAN::Types qw(:all); -use MetaCPAN::Util qw(numify_version); -use Plack::MIME; -use Pod::Text; -use Try::Tiny qw( catch try ); -use URI::Escape (); +use List::Util qw( any ); +use MetaCPAN::Document::Module (); +use MetaCPAN::Types qw( ESBool Module ); +use MetaCPAN::Types::TypeTiny qw( ArrayRef Int Maybe Num ScalarRef Stat Str ); +use MetaCPAN::Util qw(numify_version true false); +use Plack::MIME (); +use Pod::Text (); +use Try::Tiny qw( catch try ); Plack::MIME->add_type( '.t' => 'text/x-script.perl' ); Plack::MIME->add_type( '.pod' => 'text/x-pod' ); @@ -42,8 +41,8 @@ it is also set if the entire release is marked deprecated (see L ( is => 'ro', - isa => Bool, - default => 0, + isa => ESBool, + default => sub {false}, writer => '_set_deprecated', ); @@ -67,7 +66,7 @@ my $RE_SECTION = qr/^\s*(\S+)((\h+-+\h+(.+))|(\r?\n\h*\r?\n\h*(.+)))?/ms; sub _build_section { my $self = shift; - my $text = ${ $self->content }; + my $text = ${ $self->content }; my $section = MetaCPAN::Util::extract_section( $text, 'NAME' ); # if it's a POD file without a name section, let's try to generate @@ -252,9 +251,9 @@ File is binary or not. has binary => ( is => 'ro', - isa => Bool, + isa => ESBool, required => 1, - default => 0, + default => sub {false}, ); =head2 authorized @@ -266,8 +265,8 @@ See L. has authorized => ( required => 1, is => 'ro', - isa => Bool, - default => 1, + isa => ESBool, + default => sub {true}, writer => '_set_authorized', ); @@ -293,8 +292,8 @@ Return true if this object represents a directory. has directory => ( is => 'ro', required => 1, - isa => Bool, - default => 0, + isa => ESBool, + default => sub {false}, ); =head2 documentation @@ -370,6 +369,18 @@ sub _build_documentation { return undef; } +has documentation_length => ( + is => 'ro', + isa => Maybe [Int], + lazy => 1, + builder => '_build_documentation_length', +); + +sub _build_documentation_length { + my ($self) = @_; + return length( $self->documentation ); +} + =head2 suggest Autocomplete info for documentation. @@ -395,9 +406,8 @@ sub _build_suggest { $weight = 0 if $weight < 0; return +{ - input => [$doc], - payload => { doc_name => $doc }, - weight => $weight, + input => [$doc], + weight => $weight, }; } @@ -413,13 +423,13 @@ not. See L for a more verbose explanation. has indexed => ( required => 1, is => 'ro', - isa => Bool, + isa => ESBool, lazy => 1, default => sub { my ($self) = @_; - return 0 if $self->is_in_other_files; - return 0 if !$self->metadata->should_index_file( $self->path ); - return 1; + return false if $self->is_in_other_files; + return false if !$self->metadata->should_index_file( $self->path ); + return true; }, writer => '_set_indexed', ); @@ -440,7 +450,7 @@ has level => ( ); sub _build_level { - my $self = shift; + my $self = shift; my @level = split( /\//, $self->path ); return @level - 1; } @@ -568,7 +578,7 @@ sub _build_sloc { return 0 unless ( $self->is_perl_file ); my @content = split( "\n", ${ $self->content } ); - my $pods = 0; + my $pods = 0; # Use pod_lines data to remove pod content from string. map { @@ -877,7 +887,7 @@ sub set_indexed { if ( exists $meta->provides->{ $mod->name } and $self->path eq $meta->provides->{ $mod->name }{file} ) { - $mod->_set_indexed(1); + $mod->_set_indexed(true); return; } } @@ -885,16 +895,16 @@ sub set_indexed { # files listed under 'other files' are not shown in a search if ( $self->is_in_other_files() ) { foreach my $mod ( @{ $self->module } ) { - $mod->_set_indexed(0); + $mod->_set_indexed(false); } - $self->_set_indexed(0); + $self->_set_indexed(false); return; } # files under no_index directories should not be indexed foreach my $dir ( @{ $meta->no_index->{directory} } ) { if ( $self->path eq $dir or $self->path =~ /^$dir\// ) { - $self->_set_indexed(0); + $self->_set_indexed(false); return; } } @@ -903,25 +913,29 @@ sub set_indexed { if ( $mod->name !~ /^[A-Za-z]/ or !$meta->should_index_package( $mod->name ) ) { - $mod->_set_indexed(0); + $mod->_set_indexed(false); next; } - $mod->_set_indexed( - $mod->hide_from_pause( ${ $self->content }, $self->name ) - ? 0 - : 1 - ); + $mod->_set_indexed(true); } - $self->_set_indexed( + if ( my $doc_name = $self->documentation ) { - # .pm file with no package declaration but pod should be indexed - !@{ $self->module } || + # normalize the documentation name for comparison the same way module + # names are normalized + my $normalized_doc_name = $doc_name =~ s{'}{::}gr; + $self->_set_indexed( + ( + # .pm file with no package declaration but pod should be indexed + !@{ $self->module } || # don't index if the documentation doesn't match any of its modules - !!grep { $self->documentation eq $_->name } @{ $self->module } - ) if ( $self->documentation ); + grep { $normalized_doc_name eq $_->name } + @{ $self->module } + ) ? true : false + ); + } } =head2 set_authorized @@ -951,19 +965,27 @@ as unauthorized as well. sub set_authorized { my ( $self, $perms ) = @_; - # only authorized perl distributions make it into the CPAN - return () if ( $self->distribution eq 'perl' ); - foreach my $module ( @{ $self->module } ) { - $module->_set_authorized(0) - if ( $perms->{ $module->name } && !grep { $_ eq $self->author } - @{ $perms->{ $module->name } } ); + if ( $self->distribution eq 'perl' ) { + my $allowed = grep $_ eq $self->author, @{ $perms->{perl} }; + foreach my $module ( @{ $self->module } ) { + $module->_set_authorized( $allowed ? true : false ); + } + $self->_set_authorized( $allowed ? true : false ); + } + else { + foreach my $module ( @{ $self->module } ) { + $module->_set_authorized(false) + if ( $perms->{ $module->name } + && !grep { $_ eq $self->author } + @{ $perms->{ $module->name } } ); + } + $self->_set_authorized(false) + if ( $self->authorized + && $self->documentation + && $perms->{ $self->documentation } + && !grep { $_ eq $self->author } + @{ $perms->{ $self->documentation } } ); } - $self->_set_authorized(0) - if ( $self->authorized - && $self->documentation - && $perms->{ $self->documentation } - && !grep { $_ eq $self->author } - @{ $perms->{ $self->documentation } } ); return grep { !$_->authorized && $_->indexed } @{ $self->module }; } diff --git a/lib/MetaCPAN/Document/File/Set.pm b/lib/MetaCPAN/Document/File/Set.pm deleted file mode 100644 index 5f5ef3062..000000000 --- a/lib/MetaCPAN/Document/File/Set.pm +++ /dev/null @@ -1,671 +0,0 @@ -package MetaCPAN::Document::File::Set; - -use Moose; - -use MetaCPAN::Util qw( single_valued_arrayref_to_scalar ); -use Ref::Util qw( is_hashref ); -use List::Util qw( max ); - -use MetaCPAN::Query::File; -use MetaCPAN::Query::Favorite; - -extends 'ElasticSearchX::Model::Document::Set'; - -has query_file => ( - is => 'ro', - isa => 'MetaCPAN::Query::File', - lazy => 1, - builder => '_build_query_file', - handles => [qw< dir interesting_files >], -); - -sub _build_query_file { - my $self = shift; - return MetaCPAN::Query::File->new( - es => $self->es, - index_name => $self->index->name, - ); -} - -has query_favorite => ( - is => 'ro', - isa => 'MetaCPAN::Query::Favorite', - lazy => 1, - builder => '_build_query_favorite', - handles => [qw< agg_by_distributions >], -); - -sub _build_query_favorite { - my $self = shift; - return MetaCPAN::Query::Favorite->new( - es => $self->es, - index_name => $self->index->name, - ); -} - -my @ROGUE_DISTRIBUTIONS = qw( - Bundle-Everything - kurila - perl-5.005_02+apache1.3.3+modperl - perlbench - perl_debug - pod2texi - spodcxx -); - -sub find { - my ( $self, $module ) = @_; - my @candidates = $self->index->type('file')->query( - { - bool => { - must => [ - { term => { indexed => 1, } }, - { term => { authorized => 1 } }, - { term => { status => 'latest' } }, - { - or => [ - { - nested => { - path => "module", - filter => { - and => [ - { - term => { - "module.name" => $module - } - }, - { - term => { - "module.authorized" => 1 - } - }, - ] - } - } - }, - { term => { documentation => $module } }, - ] - }, - ], - should => [ - { term => { documentation => $module } }, - { - nested => { - path => 'module', - filter => { - and => [ - { term => { 'module.name' => $module } }, - { - exists => { - field => 'module.associated_pod' - } - }, - ] - } - } - }, - ] - } - } - )->sort( - [ - '_score', - { 'version_numified' => { order => 'desc' } }, - { 'date' => { order => 'desc' } }, - { 'mime' => { order => 'asc' } }, - { 'stat.mtime' => { order => 'desc' } } - ] - )->search_type('dfs_query_then_fetch')->size(100)->all; - - my ($file) = grep { - grep { $_->indexed && $_->authorized && $_->name eq $module } - @{ $_->module || [] } - } grep { !$_->documentation || $_->documentation eq $module } - @candidates; - - $file ||= shift @candidates; - return $file ? $self->get( $file->id ) : undef; -} - -sub find_pod { - my ( $self, $name ) = @_; - my $file = $self->find($name); - return $file unless ($file); - my ($module) - = grep { $_->indexed && $_->authorized && $_->name eq $name } - @{ $file->module || [] }; - if ( $module && ( my $pod = $module->associated_pod ) ) { - my ( $author, $release, @path ) = split( /\//, $pod ); - return $self->get( - { - author => $author, - release => $release, - path => join( '/', @path ), - } - ); - } - else { - return $file; - } -} - -sub documented_modules { - my ( $self, $release ) = @_; - return $self->filter( - { - and => [ - { term => { release => $release->{name} } }, - { term => { author => $release->{author} } }, - { - or => [ - { - and => [ - { - exists => { - field => 'module.name', - } - }, - { - term => { - 'module.indexed' => 1 - } - }, - ] - }, - { - and => [ - { - exists => { - field => 'pod.analyzed', - } - }, - { term => { indexed => 1 } }, - ] - }, - ] - }, - ], - } - )->size(999) - ->source( [qw(name module path documentation distribution)] )->all; -} - -=head2 find_download_url - - -cpanm Foo -=> status: latest, maturity: released - -cpanm --dev Foo -=> status: -backpan, sort_by: version_numified,date - -cpanm Foo~1.0 -=> status: latest, maturity: released, module.version_numified: gte: 1.0 - -cpanm --dev Foo~1.0 --> status: -backpan, module.version_numified: gte: 1.0, sort_by: version_numified,date - -cpanm Foo~<2 -=> maturity: released, module.version_numified: lt: 2, sort_by: status,version_numified,date - -cpanm --dev Foo~<2 -=> status: -backpan, module.version_numified: lt: 2, sort_by: status,version_numified,date - - $file->find_download_url(http://github.com/'Foo',%20%7B%20version%20=%3E%20$version,%20dev%20=%3E%200|1%20%7D); - -Sorting: - - if it's stable: - prefer latest > cpan > backpan - then sort by version desc - then sort by date descending (rev chron) - - if it's dev: - sort by version desc - sort by date descending (reverse chronologically) - - -=cut - -sub find_download_url { - my ( $self, $module, $args ) = @_; - $args ||= {}; - - my $dev = $args->{dev}; - my $version = $args->{version}; - my $explicit_version = $version && $version =~ /==/; - - # exclude backpan if dev, and - # require released modules if neither dev nor explicit version - my @filters - = $dev ? { not => { term => { status => 'backpan' } } } - : !$explicit_version ? { term => { maturity => 'released' } } - : (); - - my $version_filters = $self->_version_filters($version); - - # filters to be applied to the nested modules - my $module_f = { - nested => { - path => 'module', - inner_hits => { _source => 'version' }, - filter => { - bool => { - must => [ - { term => { 'module.authorized' => 1 } }, - { term => { 'module.indexed' => 1 } }, - { term => { 'module.name' => $module } }, - ( - exists $version_filters->{must} - ? @{ $version_filters->{must} } - : () - ) - ], - ( - exists $version_filters->{must_not} - ? ( must_not => [ $version_filters->{must_not} ] ) - : () - ) - } - } - } - }; - - my $filter - = @filters - ? { bool => { must => [ @filters, $module_f ] } } - : $module_f; - - # sort by score, then version desc, then date desc - my @sort = ( - '_score', - { - 'module.version_numified' => { - mode => 'max', - order => 'desc', - nested_path => 'module', - nested_filter => $module_f->{nested}{filter} - } - }, - { date => { order => 'desc' } } - ); - - my $query; - - if ($dev) { - $query = { filtered => { filter => $filter } }; - } - else { - # if not dev, then prefer latest > cpan > backpan - $query = { - function_score => { - filter => $filter, - score_mode => 'first', - boost_mode => 'replace', - functions => [ - { - filter => { term => { status => 'latest' } }, - weight => 3 - }, - { - filter => { term => { status => 'cpan' } }, - weight => 2 - }, - { filter => { match_all => {} }, weight => 1 }, - ] - } - }; - } - - my $res - = $self->size(1)->query($query) - ->source( [ 'download_url', 'date', 'status' ] ) - ->search_type('dfs_query_then_fetch')->sort( \@sort )->raw->all; - return unless $res->{hits}{total}; - - my $hit = $res->{hits}{hits}[0]; - - return +{ - %{ $hit->{_source} }, - %{ $hit->{inner_hits}{module}{hits}{hits}[0]{_source} }, - }; -} - -sub _version_filters { - my ( $self, $version ) = @_; - - return () unless $version; - - if ( $version =~ s/^==\s*// ) { - return +{ - must => [ - { - term => { - 'module.version_numified' => $self->_numify($version) - } - } - ] - }; - } - elsif ( $version =~ /^[<>!]=?\s*/ ) { - my %ops = qw(< lt <= lte > gt >= gte); - my ( %filters, %range, @exclusion ); - my @requirements = split /,\s*/, $version; - for my $r (@requirements) { - if ( $r =~ s/^([<>]=?)\s*// ) { - $range{ $ops{$1} } = $self->_numify($r); - } - elsif ( $r =~ s/\!=\s*// ) { - push @exclusion, $self->_numify($r); - } - } - - if ( keys %range ) { - $filters{must} - = [ { range => { 'module.version_numified' => \%range } } ]; - } - - if (@exclusion) { - $filters{must_not} = []; - push @{ $filters{must_not} }, map { - +{ - term => { - 'module.version_numified' => $self->_numify($_) - } - } - } @exclusion; - } - - return \%filters; - } - elsif ( $version !~ /\s/ ) { - return +{ - must => [ - { - range => { - 'module.version_numified' => - { 'gte' => $self->_numify($version) } - }, - } - ] - }; - } -} - -sub _numify { - my ( $self, $ver ) = @_; - $ver =~ s/_//g; - version->new($ver)->numify; -} - -=head2 history - -Find the history of a given module/documentation. - -=cut - -sub history { - my ( $self, $type, $module, @path ) = @_; - my $search - = $type eq "module" - ? $self->query( - { - nested => { - path => 'module', - query => { - constant_score => { - filter => { - bool => { - must => [ - { term => { "module.authorized" => 1 } }, - { term => { "module.indexed" => 1 } }, - { term => { "module.name" => $module } }, - ] - } - } - } - } - } - } - ) - : $type eq "file" ? $self->query( - { - bool => { - must => [ - { term => { path => join( "/", @path ) } }, - { term => { distribution => $module } }, - ] - } - } - ) - - # XXX: to fix: no filtering on 'release' so this query - # will produce modules matching duplications. -- Mickey - : $type eq "documentation" ? $self->query( - { - bool => { - must => [ - { match_phrase => { documentation => $module } }, - { term => { indexed => 1 } }, - { term => { authorized => 1 } }, - ] - } - } - ) - - # clearly, one doesn't know what they want in this case - : $self->query( - bool => { - must => [ - { term => { indexed => 1 } }, - { term => { authorized => 1 } }, - ] - } - ); - return $search->sort( [ { date => 'desc' } ] ); -} - -sub autocomplete { - my ( $self, @terms ) = @_; - my $query = join( q{ }, @terms ); - return $self unless $query; - - my $data = $self->search_type('dfs_query_then_fetch')->query( - { - filtered => { - query => { - multi_match => { - query => $query, - type => 'most_fields', - fields => [ 'documentation', 'documentation.*' ], - analyzer => 'camelcase', - minimum_should_match => '80%' - }, - }, - filter => { - bool => { - must => [ - { exists => { field => 'documentation' } }, - { term => { status => 'latest' } }, - { term => { indexed => 1 } }, - { term => { authorized => 1 } } - ], - must_not => [ - { - terms => - { distribution => \@ROGUE_DISTRIBUTIONS } - }, - ], - } - } - } - } - )->sort( [ '_score', 'documentation' ] ); - - $data = $data->fields( [qw(documentation release author distribution)] ) - unless $self->fields; - - $data = $data->source(0)->raw->all; - - single_valued_arrayref_to_scalar( $_->{fields} ) - for @{ $data->{hits}{hits} }; - - return $data; -} - -sub autocomplete_suggester { - my ( $self, $query ) = @_; - return $self unless $query; - - my $search_size = 100; - - my $suggestions - = $self->search_type('dfs_query_then_fetch')->es->suggest( - { - index => $self->index->name, - body => { - documentation => { - text => $query, - completion => { - field => "suggest", - size => $search_size, - } - } - }, - } - ); - - my %docs; - - for my $suggest ( @{ $suggestions->{documentation}[0]{options} } ) { - $docs{ $suggest->{text} } = max grep {defined} - ( $docs{ $suggest->{text} }, $suggest->{score} ); - } - - my @fields = (qw(documentation distribution author release deprecated)); - my $data = $self->es->search( - { - index => $self->index->name, - type => 'file', - body => { - query => { - bool => { - must => [ - { term => { indexed => 1 } }, - { term => { authorized => 1 } }, - { term => { status => 'latest' } }, - { - terms => { 'documentation' => [ keys %docs ] } - }, - ], - must_not => [ - { - terms => - { distribution => \@ROGUE_DISTRIBUTIONS } - }, - ], - } - }, - }, - fields => \@fields, - size => $search_size, - } - ); - - my %valid = map { - my $got = $_->{fields}; - my %record; - @record{@fields} = map { $got->{$_}[0] } @fields; - $record{name} = delete $record{documentation}; # rename - ( $_->{fields}{documentation}[0] => \%record ); - } @{ $data->{hits}{hits} }; - - # normalize 'deprecated' field values to boolean (1/0) values (because ES) - for my $v ( values %valid ) { - $v->{deprecated} = 1 if $v->{deprecated} eq 'true'; - $v->{deprecated} = 0 if $v->{deprecated} eq 'false'; - } - - # remove any exact match, it will be added later - my $exact = delete $valid{$query}; - - my $favorites - = $self->agg_by_distributions( - [ map { $_->{distribution} } values %valid ] )->{favorites}; - - no warnings 'uninitialized'; - my @sorted = map { $valid{$_} } - sort { - $valid{$a}->{deprecated} <=> $valid{$b}->{deprecated} - || $favorites->{ $valid{$b}->{distribution} } - <=> $favorites->{ $valid{$a}->{distribution} } - || $docs{$b} <=> $docs{$a} - || length($a) <=> length($b) - || $a cmp $b - } - keys %valid; - - return +{ suggestions => [ grep {defined} ( $exact, @sorted ) ] }; -} - -sub find_changes_files { - my ( $self, $author, $release ) = @_; - - # find the most likely file - # TODO: should we do this when the release is indexed - # and store the result as { 'changes_file' => $name } - - my @candidates = qw( - CHANGES Changes ChangeLog Changelog CHANGELOG NEWS - ); - - # use $c->model b/c we can't let any filters apply here - my $file = $self->raw->filter( - { - and => [ - { term => { release => $release } }, - { term => { author => $author } }, - { - or => [ - - # if it's a perl release, get perldelta - { - and => [ - { term => { distribution => 'perl' } }, - { - term => { - 'name' => 'perldelta.pod' - } - }, - ] - }, - - # otherwise look for one of these candidates in the root - { - and => [ - { term => { level => 0 } }, - { term => { directory => 0 } }, - { - or => [ - map { { term => { 'name' => $_ } } } - @candidates - ] - } - ] - } - ], - } - ] - } - )->size(1) - - # HACK: Sort by level/desc to put pod/perldeta.pod first (if found) - # otherwise sort root files by name and select the first. - ->sort( [ { level => 'desc' }, { name => 'asc' } ] )->first; - - return unless is_hashref($file); - return $file->{_source}; -} - -__PACKAGE__->meta->make_immutable; -1; diff --git a/lib/MetaCPAN/Document/Mirror.pm b/lib/MetaCPAN/Document/Mirror.pm index 48c956b68..7b3b04e94 100644 --- a/lib/MetaCPAN/Document/Mirror.pm +++ b/lib/MetaCPAN/Document/Mirror.pm @@ -4,11 +4,10 @@ use strict; use warnings; use Moose; -use ElasticSearchX::Model::Document::Types qw( Location ); +use MooseX::Types::ElasticSearch qw( Location ); use ElasticSearchX::Model::Document; -use MetaCPAN::Types qw( ArrayRef Dict Str ); -use MooseX::Types::Structured qw(Dict ); # not sure why I have to do this +use MetaCPAN::Types::TypeTiny qw( Dict Str ); has name => ( is => 'ro', diff --git a/lib/MetaCPAN/Document/Mirror/Set.pm b/lib/MetaCPAN/Document/Mirror/Set.pm deleted file mode 100644 index b07889e58..000000000 --- a/lib/MetaCPAN/Document/Mirror/Set.pm +++ /dev/null @@ -1,26 +0,0 @@ -package MetaCPAN::Document::Mirror::Set; - -use Moose; - -use MetaCPAN::Query::Mirror; - -extends 'ElasticSearchX::Model::Document::Set'; - -has query_mirror => ( - is => 'ro', - isa => 'MetaCPAN::Query::Mirror', - lazy => 1, - builder => '_build_query_mirror', - handles => [qw< search >], -); - -sub _build_query_mirror { - my $self = shift; - return MetaCPAN::Query::Mirror->new( - es => $self->es, - index_name => $self->index->name, - ); -} - -__PACKAGE__->meta->make_immutable; -1; diff --git a/lib/MetaCPAN/Document/Module.pm b/lib/MetaCPAN/Document/Module.pm index 2b93e70a6..a3901bae1 100644 --- a/lib/MetaCPAN/Document/Module.pm +++ b/lib/MetaCPAN/Document/Module.pm @@ -8,8 +8,9 @@ use ElasticSearchX::Model::Document; with 'ElasticSearchX::Model::Document::EmbeddedRole'; -use MetaCPAN::Types qw( Bool Maybe Num Str ); -use MetaCPAN::Util; +use MetaCPAN::Types qw( ESBool ); +use MetaCPAN::Types::TypeTiny qw( Maybe Num Str ); +use MetaCPAN::Util qw(true false); =head1 SYNOPSIS @@ -73,16 +74,16 @@ has version => ( is => 'ro' ); has indexed => ( is => 'ro', required => 1, - isa => Bool, - default => 1, + isa => ESBool, + default => sub {true}, writer => '_set_indexed', ); has authorized => ( is => 'ro', required => 1, - isa => Bool, - default => 1, + isa => ESBool, + default => sub {true}, writer => '_set_authorized', ); @@ -110,30 +111,6 @@ sub _build_version_numified { my $bom = qr/(?:\x00\x00\xfe\xff|\xff\xfe\x00\x00|\xfe\xff|\xff\xfe|\xef\xbb\xbf)/; -sub hide_from_pause { - my ( $self, $content, $file_name ) = @_; - return 0 if defined($file_name) && $file_name =~ m{\.pm\.PL\z}; - my $pkg = $self->name; - -# This regexp is *almost* the same as $PKG_REGEXP in Module::Metadata. -# [b] We need to allow/ignore a possible BOM since we read in binary mode. -# Module::Metadata, for example, checks for a BOM and then sets the encoding. -# [s] We change `\s` to `\h` because we want to verify that it's on one line. -# [p] We replace $PKG_NAME_REGEXP with the specific package we're looking for. -# [v] Simplify the optional whitespace/version group ($V_NUM_REGEXP). - return $content =~ / # match a package declaration - ^ # start of line - (?:\A$bom)? # possible BOM at the start of the file [b] - [\h\{;]* # intro chars on a line [s] - package # the word 'package' - \h+ # whitespace [s] - (\Q$pkg\E) # a package name [p] - (\h+ v?[0-9._]+)? # optional version number (preceded by whitespace) [v] - \h* # optional whitesapce [s] - [;\{] # semicolon line terminator or block start - /mx ? 0 : 1; -} - =head2 set_associated_pod Expects an instance C<$file> of L as first parameter diff --git a/lib/MetaCPAN/Document/Package.pm b/lib/MetaCPAN/Document/Package.pm index 0d5e46629..e5ee7bf9f 100644 --- a/lib/MetaCPAN/Document/Package.pm +++ b/lib/MetaCPAN/Document/Package.pm @@ -3,7 +3,7 @@ package MetaCPAN::Document::Package; use MetaCPAN::Moose; use ElasticSearchX::Model::Document; -use MetaCPAN::Types qw( Str ); +use MetaCPAN::Types::TypeTiny qw( Str ); has module_name => ( is => 'ro', diff --git a/lib/MetaCPAN/Document/Package/Set.pm b/lib/MetaCPAN/Document/Package/Set.pm deleted file mode 100644 index 3a9aec12c..000000000 --- a/lib/MetaCPAN/Document/Package/Set.pm +++ /dev/null @@ -1,26 +0,0 @@ -package MetaCPAN::Document::Package::Set; - -use Moose; - -use MetaCPAN::Query::Package; - -extends 'ElasticSearchX::Model::Document::Set'; - -has query_package => ( - is => 'ro', - isa => 'MetaCPAN::Query::Package', - lazy => 1, - builder => '_build_query_package', - handles => [qw< get_modules >], -); - -sub _build_query_package { - my $self = shift; - return MetaCPAN::Query::Package->new( - es => $self->es, - index_name => $self->index->name, - ); -} - -__PACKAGE__->meta->make_immutable; -1; diff --git a/lib/MetaCPAN/Document/Permission.pm b/lib/MetaCPAN/Document/Permission.pm index c3e1ebe6b..b72524dfd 100644 --- a/lib/MetaCPAN/Document/Permission.pm +++ b/lib/MetaCPAN/Document/Permission.pm @@ -3,7 +3,7 @@ package MetaCPAN::Document::Permission; use MetaCPAN::Moose; use ElasticSearchX::Model::Document; -use MetaCPAN::Types qw( ArrayRef Str ); +use MetaCPAN::Types::TypeTiny qw( ArrayRef Str ); has module_name => ( is => 'ro', diff --git a/lib/MetaCPAN/Document/Permission/Set.pm b/lib/MetaCPAN/Document/Permission/Set.pm deleted file mode 100644 index ac51db2d4..000000000 --- a/lib/MetaCPAN/Document/Permission/Set.pm +++ /dev/null @@ -1,26 +0,0 @@ -package MetaCPAN::Document::Permission::Set; - -use Moose; - -use MetaCPAN::Query::Permission; - -extends 'ElasticSearchX::Model::Document::Set'; - -has query_permission => ( - is => 'ro', - isa => 'MetaCPAN::Query::Permission', - lazy => 1, - builder => '_build_query_permission', - handles => [qw< by_author by_modules >], -); - -sub _build_query_permission { - my $self = shift; - return MetaCPAN::Query::Permission->new( - es => $self->es, - index_name => $self->index->name, - ); -} - -__PACKAGE__->meta->make_immutable; -1; diff --git a/lib/MetaCPAN/Document/Rating.pm b/lib/MetaCPAN/Document/Rating.pm deleted file mode 100644 index 14b7c88a5..000000000 --- a/lib/MetaCPAN/Document/Rating.pm +++ /dev/null @@ -1,55 +0,0 @@ -package MetaCPAN::Document::Rating; - -use strict; -use warnings; - -use Moose; -use ElasticSearchX::Model::Document::Types qw(:all); -use ElasticSearchX::Model::Document; - -use MetaCPAN::Types qw( ArrayRef Bool Num Str ); -use MooseX::Types::Structured qw( Dict ); - -has details => ( - is => 'ro', - isa => Dict [ documentation => Str ], -); - -has rating => ( - required => 1, - is => 'ro', - isa => Num, - builder => '_build_rating', -); - -has [qw(distribution release author user)] => ( - required => 1, - is => 'ro', - isa => Str, -); - -has date => ( - required => 1, - is => 'ro', - isa => 'DateTime', - default => sub { DateTime->now }, -); - -has helpful => ( - required => 1, - is => 'ro', - isa => ArrayRef [ Dict [ user => Str, value => Bool ] ], - default => sub { [] }, -); - -sub _build_rating { - my $self = shift; - die "Provide details to calculate a rating"; - my %details = %{ $self->details }; - my $rating = 0; - $rating += $_ for ( values %details ); - return $rating / scalar keys %details; -} - -__PACKAGE__->meta->make_immutable; -1; diff --git a/lib/MetaCPAN/Document/Rating/Set.pm b/lib/MetaCPAN/Document/Rating/Set.pm deleted file mode 100644 index 9bb30d73c..000000000 --- a/lib/MetaCPAN/Document/Rating/Set.pm +++ /dev/null @@ -1,26 +0,0 @@ -package MetaCPAN::Document::Rating::Set; - -use Moose; - -use MetaCPAN::Query::Rating; - -extends 'ElasticSearchX::Model::Document::Set'; - -has query_rating => ( - is => 'ro', - isa => 'MetaCPAN::Query::Rating', - lazy => 1, - builder => '_build_query_rating', - handles => [qw< by_distributions >], -); - -sub _build_query_rating { - my $self = shift; - return MetaCPAN::Query::Rating->new( - es => $self->es, - index_name => $self->index->name, - ); -} - -__PACKAGE__->meta->make_immutable; -1; diff --git a/lib/MetaCPAN/Document/Release.pm b/lib/MetaCPAN/Document/Release.pm index d6cffce81..ad92baf61 100644 --- a/lib/MetaCPAN/Document/Release.pm +++ b/lib/MetaCPAN/Document/Release.pm @@ -1,15 +1,19 @@ package MetaCPAN::Document::Release; -use strict; -use warnings; - use Moose; -use DateTime qw(); -use Ref::Util qw(); -use ElasticSearchX::Model::Document; -use MetaCPAN::Types qw(:all); -use MetaCPAN::Util qw( numify_version ); +use ElasticSearchX::Model::Document; +use MetaCPAN::Types qw( Dependency ESBool ); +use MetaCPAN::Types::TypeTiny qw( + ArrayRef + HashRefCPANMeta + Num + Resources + Stat + Str + Tests +); +use MetaCPAN::Util qw( numify_version true false ); =head1 PROPERTIES @@ -146,6 +150,11 @@ has download_url => ( builder => '_build_download_url', ); +has [qw(checksum_md5 checksum_sha256)] => ( + is => 'ro', + isa => Str, +); + has [qw(distribution name)] => ( is => 'ro', required => 1, @@ -218,23 +227,23 @@ has tests => ( has authorized => ( is => 'ro', required => 1, - isa => Bool, - default => 1, + isa => ESBool, + default => sub {true}, writer => '_set_authorized', ); has first => ( is => 'ro', required => 1, - isa => Bool, - default => 0, + isa => ESBool, + default => sub {false}, writer => '_set_first', ); has metadata => ( coerce => 1, is => 'ro', - isa => HashRef, + isa => HashRefCPANMeta, dynamic => 1, source_only => 1, ); @@ -253,8 +262,8 @@ has changes_file => ( has deprecated => ( is => 'ro', - isa => Bool, - default => sub {0}, + isa => ESBool, + default => sub {false}, writer => '_set_deprecated', ); @@ -268,26 +277,23 @@ sub _build_download_url { sub set_first { my $self = shift; - my $is_first = $self->index->type('release')->filter( - { - and => [ + my $is_first = $self->index->model->doc('release')->query( { + bool => { + must => [ { term => { distribution => $self->distribution } }, { range => { - version_numified => - { 'lt' => $self->version_numified } + version_numified => { lt => $self->version_numified } } }, - - # REINDEX: after a full reindex, the above line is to replaced with: - # { term => { first => 1 } }, - # currently, the "first" property is not computed on all releases - # since this feature has not been around when last reindexed - ] - } - )->count - ? 0 - : 1; + ], + }, + + # REINDEX: after a full reindex, the above line is to replaced with: + # { term => { first => 1 } }, + # currently, the "first" property is not computed on all releases + # since this feature has not been around when last reindexed + } )->count ? false : true; $self->_set_first($is_first); } diff --git a/lib/MetaCPAN/Document/Release/Set.pm b/lib/MetaCPAN/Document/Release/Set.pm deleted file mode 100644 index dbdc58ffd..000000000 --- a/lib/MetaCPAN/Document/Release/Set.pm +++ /dev/null @@ -1,101 +0,0 @@ -package MetaCPAN::Document::Release::Set; - -use Moose; - -use MetaCPAN::Util qw( single_valued_arrayref_to_scalar ); - -use MetaCPAN::Query::Release; - -extends 'ElasticSearchX::Model::Document::Set'; - -has query_release => ( - is => 'ro', - isa => 'MetaCPAN::Query::Release', - lazy => 1, - builder => '_build_query_release', - handles => [ - qw< - activity - all_by_author - author_status - by_author - by_author_and_name - get_contributors - get_files - latest_by_author - latest_by_distribution - modules - recent - requires - reverse_dependencies - top_uploaders - versions - > - ], -); - -sub _build_query_release { - my $self = shift; - return MetaCPAN::Query::Release->new( - es => $self->es, - index_name => $self->index->name, - ); -} - -sub find { - my ( $self, $name ) = @_; - my $file = $self->filter( - { - and => [ - { term => { distribution => $name } }, - { term => { status => 'latest' } } - ] - } - )->sort( [ { date => 'desc' } ] )->raw->first; - return unless $file; - - my $data = $file->{_source} - || single_valued_arrayref_to_scalar( $file->{fields} ); - return $data; -} - -sub predecessor { - my ( $self, $name ) = @_; - return $self->filter( - { - and => [ - { term => { distribution => $name } }, - { not => { filter => { term => { status => 'latest' } } } }, - ] - } - )->sort( [ { date => 'desc' } ] )->first; -} - -sub find_github_based { - shift->filter( - { - and => [ - { term => { status => 'latest' } }, - { - or => [ - { - prefix => { - "resources.bugtracker.web" => - 'http://github.com/' - } - }, - { - prefix => { - "resources.bugtracker.web" => - 'https://github.com/' - } - }, - ] - } - ] - } - ); -} - -__PACKAGE__->meta->make_immutable; -1; diff --git a/lib/MetaCPAN/ESConfig.pm b/lib/MetaCPAN/ESConfig.pm new file mode 100644 index 000000000..e84f1d928 --- /dev/null +++ b/lib/MetaCPAN/ESConfig.pm @@ -0,0 +1,261 @@ +use v5.20; +use warnings; +use experimental qw( signatures postderef ); + +package MetaCPAN::ESConfig; + +use Carp qw( croak ); +use Const::Fast qw( const ); +use Cpanel::JSON::XS (); +use Exporter qw( import ); +use Hash::Merge::Simple qw( merge ); +use MetaCPAN::Server::Config (); +use MetaCPAN::Types::TypeTiny qw( Defined HashRef ); +use MetaCPAN::Util qw( root_dir true false ); +use Module::Runtime qw( $module_name_rx require_module ); + +const my %config => merge( + { + documents => { + author => { + index => 'author', + type => 'author', + mapping => 'es/author/mapping.json', + settings => 'es/author/settings.json', + model => 'MetaCPAN::Document::Author', + }, + cve => { + index => 'cve', + type => 'cve', + mapping => 'es/cve/mapping.json', + settings => 'es/cve/settings.json', + model => 'MetaCPAN::Document::CVE', + }, + contributor => { + index => 'contributor', + type => 'contributor', + mapping => 'es/contributor/mapping.json', + settings => 'es/contributor/settings.json', + model => 'MetaCPAN::Document::Contributor', + }, + cover => { + index => 'cover', + type => 'cover', + mapping => 'es/cover/mapping.json', + settings => 'es/cover/settings.json', + model => 'MetaCPAN::Document::Cover', + }, + distribution => { + index => 'distribution', + type => 'distribution', + mapping => 'es/distribution/mapping.json', + settings => 'es/distribution/settings.json', + model => 'MetaCPAN::Document::Distribution', + }, + favorite => { + index => 'favorite', + type => 'favorite', + mapping => 'es/favorite/mapping.json', + settings => 'es/favorite/settings.json', + model => 'MetaCPAN::Document::Favorite', + }, + file => { + index => 'file', + type => 'file', + mapping => 'es/file/mapping.json', + settings => 'es/file/settings.json', + model => 'MetaCPAN::Document::File', + }, + mirror => { + index => 'mirror', + type => 'mirror', + mapping => 'es/mirror/mapping.json', + settings => 'es/mirror/settings.json', + model => 'MetaCPAN::Document::Mirror', + }, + package => { + index => 'package', + type => 'package', + mapping => 'es/package/mapping.json', + settings => 'es/package/settings.json', + model => 'MetaCPAN::Document::Package', + }, + permission => { + index => 'permission', + type => 'permission', + mapping => 'es/permission/mapping.json', + settings => 'es/permission/settings.json', + model => 'MetaCPAN::Document::Permission', + }, + release => { + index => 'release', + type => 'release', + mapping => 'es/release/mapping.json', + settings => 'es/release/settings.json', + model => 'MetaCPAN::Document::Release', + }, + + account => { + index => 'account', + type => 'account', + mapping => 'es/account/mapping.json', + settings => 'es/account/settings.json', + model => 'MetaCPAN::Model::User::Account', + }, + session => { + index => 'session', + type => 'session', + mapping => 'es/session/mapping.json', + settings => 'es/session/settings.json', + model => 'MetaCPAN::Model::User::Session', + }, + }, + }, + MetaCPAN::Server::Config::config()->{elasticsearch} || {}, +)->%*; + +{ + use Moo; +} + +has all_indexes => ( + is => 'lazy', + default => sub ($self) { + my %seen; + [ + sort + grep !$seen{$_}++, + map $_->{index}, + values $self->documents->%* + ]; + }, +); + +my $DefinedHash = ( HashRef [Defined] )->plus_coercions( + HashRef, + => sub ($hash) { + return { + map { + my $value = $hash->{$_}; + defined $value ? ( $_ => $value ) : (); + } keys %$hash + }; + }, +); + +has documents => ( + is => 'ro', + isa => HashRef [$DefinedHash], + coerce => 1, + required => 1, +); + +sub _load_es_data ( $location, $def_sub ) { + my $data; + + if ( ref $location ) { + $data = $location; + } + elsif ( $location + =~ /\A($module_name_rx)(?:::([0-9a-zA-Z_]+)\(\)|->($module_name_rx))?\z/ + ) + { + my ( $module, $sub, $method ) = ( $1, $2, $3 ); + require_module $module; + if ($method) { + $data = $module->$method; + } + else { + $sub ||= $def_sub; + no strict 'refs'; + my $code = \&{"${module}::${sub}"}; + die "can't find $location" + if !defined &$code; + $data = $code->(); + } + } + else { + my $abs_path = File::Spec->rel2abs( $location, root_dir() ); + open my $fh, '<', $abs_path + or die "can't open mapping file $abs_path: $!"; + $data = do { local $/; <$fh> }; + } + + return $data + if ref $data; + + return Cpanel::JSON::XS::decode_json($data); +} + +sub _walk : prototype(&$); + +sub _walk : prototype(&$) { + my ( $cb, $data ) = @_; + if ( ref $data eq 'HASH' ) { + $cb->($data); + _walk( \&$cb, $data->{$_} ) for keys %$data; + } + elsif ( ref $data eq 'ARRAY' ) { + $cb->($data); + _walk( \&$cb, $_ ) for @$data; + } +} + +sub mapping ( $self, $doc, $version ) { + my $doc_data = $self->documents->{$doc} + or croak "unknown document $doc"; + my $data = _load_es_data( $doc_data->{mapping}, 'mapping' ); + if ( $version && $version eq '2_0' ) { + _walk( + sub { + my ($d) = @_; + if ( my $type = $d->{type} ) { + if ( $type eq 'keyword' ) { + $d->{type} = 'string'; + $d->{index} = 'not_analyzed'; + $d->{ignore_above} = 2048; + } + elsif ( $type eq 'text' ) { + $d->{type} = 'string'; + if ( exists $d->{fielddata} && !$d->{fielddata} ) { + $d->{fielddata} = { format => false }; + } + } + } + + }, + $data + ); + } + return $data; +} + +sub index_settings ( $self, $doc, $version = undef ) { + my $documents = $self->documents; + my $doc_data = exists $documents->{$doc} && $documents->{$doc} + or return {}; + my $settings = exists $doc_data->{settings} && $doc_data->{settings} + or return {}; + my $data = _load_es_data( $settings, 'settings' ); + return $data; +} + +sub doc_path ( $self, $doc ) { + my $doc_data = $self->documents->{$doc} + or croak "unknown document $doc"; + return ( + ( $doc_data->{index} ? ( index => $doc_data->{index} ) : () ), + ( $doc_data->{type} ? ( type => $doc_data->{type} ) : () ), + ); +} + +our @EXPORT_OK = qw( + es_config + es_doc_path +); + +my $single = __PACKAGE__->new(%config); +sub es_config : prototype() {$single} +sub es_doc_path ($doc) { $single->doc_path($doc) } + +1; diff --git a/lib/MetaCPAN/Model.pm b/lib/MetaCPAN/Model.pm index 782045640..e98d5ac6e 100644 --- a/lib/MetaCPAN/Model.pm +++ b/lib/MetaCPAN/Model.pm @@ -4,51 +4,33 @@ package MetaCPAN::Model; use Moose; use ElasticSearchX::Model; - -analyzer lowercase => ( - tokenizer => 'keyword', - filter => 'lowercase', -); - -analyzer fulltext => ( type => 'english' ); - -tokenizer camelcase => ( - type => 'pattern', - pattern => - "([^\\p{L}\\d]+)|(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)|(?<=[\\p{L}&&[^\\p{Lu}]])(?=\\p{Lu})|(?<=\\p{Lu})(?=\\p{Lu}[\\p{L}&&[^\\p{Lu}]])" -); - -filter edge => ( - type => 'edge_ngram', - min_gram => 1, - max_gram => 20 -); - -analyzer camelcase => ( - type => 'custom', - tokenizer => 'camelcase', - filter => [ 'lowercase', 'unique' ] -); - -analyzer edge_camelcase => ( - type => 'custom', - tokenizer => 'camelcase', - filter => [ 'lowercase', 'edge' ] -); - -analyzer edge => ( - type => 'custom', - tokenizer => 'standard', - filter => [ 'lowercase', 'edge' ] -); - -index cpan => ( - namespace => 'MetaCPAN::Document', - alias_for => ( $ENV{'ES_SCRIPT_INDEX'} || 'cpan_v1_01' ), - shards => 3 -); - -index user => ( namespace => 'MetaCPAN::Model::User' ); +use MetaCPAN::ESConfig qw(es_config); +use Module::Runtime qw( require_module use_package_optimistically ); + +my %indexes; +my $docs = es_config->documents; +for my $name ( sort keys %$docs ) { + my $doc = $docs->{$name}; + my $model = $doc->{model} + or next; + require_module($model); + use_package_optimistically( $model . '::Set' ); + my $index = $doc->{index} + or die "no index for $name documents!"; + + $indexes{$index}{types}{$name} = $model->meta; +} + +for my $index ( sort keys %indexes ) { + index $index => %{ $indexes{$index} }; +} + +sub doc { + my ( $self, $doc ) = @_; + my $doc_config = es_config->documents->{$doc}; + return $self->index( $doc_config->{index} ) + ->type( $doc_config->{type} // $doc_config->{index} ); +} __PACKAGE__->meta->make_immutable; 1; diff --git a/lib/MetaCPAN/Model/Archive.pm b/lib/MetaCPAN/Model/Archive.pm index fa8d62ad9..3ad4eebae 100644 --- a/lib/MetaCPAN/Model/Archive.pm +++ b/lib/MetaCPAN/Model/Archive.pm @@ -3,12 +3,12 @@ package MetaCPAN::Model::Archive; use v5.10; use Moose; use MooseX::StrictConstructor; -use MetaCPAN::Types qw(AbsFile AbsDir ArrayRef Bool); +use MetaCPAN::Types::TypeTiny qw( AbsPath ArrayRef Bool InstanceOf Str ); -use Archive::Any; -use Carp; -use File::Temp (); -use Path::Class (); +use Archive::Any (); +use Carp qw( croak ); +use Digest::file qw( digest_file_hex ); +use Path::Tiny qw( path ); =head1 NAME @@ -38,27 +38,25 @@ The Archive will clean up its extraction directory upon destruction. I -The file to be extracted. It will be returned as a Path::Class +The file to be extracted. It will be returned as a Path::Tiny object. =cut has file => ( is => 'ro', - isa => AbsFile, + isa => AbsPath, coerce => 1, required => 1, ); has _extractor => ( is => 'ro', - isa => 'Archive::Any', - handles => [ - qw( - is_impolite - is_naughty - ) - ], + isa => InstanceOf ['Archive::Any'], + handles => [ qw( + is_impolite + is_naughty + ) ], init_arg => undef, lazy => 1, default => sub { @@ -68,31 +66,52 @@ has _extractor => ( }, ); +# MD5 digest for the archive file +has file_digest_md5 => ( + is => 'ro', + isa => Str, + lazy => 1, + default => sub { + my $self = shift; + digest_file_hex( $self->file, 'MD5' ); + }, +); + +# SHA256 digest for the archive file +has file_digest_sha256 => ( + is => 'ro', + isa => Str, + lazy => 1, + default => sub { + my $self = shift; + digest_file_hex( $self->file, 'SHA-256' ); + }, +); + # Holding the File::Temp::Dir object here is necessary to keep it -# alive until the object is destroyed. Path::Class::Dir will not hold -# onto the ojbect. +# alive until the object is destroyed. has _tempdir => ( is => 'ro', - isa => 'File::Temp::Dir', + isa => AbsPath, init_arg => undef, lazy => 1, default => sub { my $scratch_disk = '/mnt/scratch_disk'; return -d $scratch_disk - ? File::Temp->newdir('/mnt/scratch_disk/tempXXXXX') - : File::Temp->newdir; + ? Path::Tiny->tempdir('/mnt/scratch_disk/tempXXXXX') + : Path::Tiny->tempdir; }, ); has extract_dir => ( is => 'ro', - isa => AbsDir, + isa => AbsPath, lazy => 1, coerce => 1, default => sub { my $self = shift; - return Path::Class::Dir->new( $self->_tempdir ); + return path( $self->_tempdir ); }, ); @@ -131,7 +150,7 @@ has files => ( my $extract_dir = $archive->extract; Extract the archive into a temp directory. The directory will be a -L. +L object. Only the first call to extract will perform the extraction. After that it will just return the extraction directory. If you want to diff --git a/lib/MetaCPAN/Model/ESWrapper.pm b/lib/MetaCPAN/Model/ESWrapper.pm new file mode 100644 index 000000000..cd990c897 --- /dev/null +++ b/lib/MetaCPAN/Model/ESWrapper.pm @@ -0,0 +1,61 @@ +package MetaCPAN::Model::ESWrapper; +use strict; +use warnings; + +use MetaCPAN::Types::TypeTiny qw( ES ); + +sub new { + my ( $class, $es ) = @_; + if ( $es->api_version le '6_0' ) { + return $es; + } + return bless { es => ES->assert_coerce($es) }, $class; +} + +sub DESTROY { } + +sub AUTOLOAD { + my $sub = our $AUTOLOAD =~ s/.*:://r; + my $self = shift; + $self->{es}->$sub(@_); +} + +sub _args { + my $self = shift; + if ( @_ == 1 ) { + return ( $self, %{ $_[0] } ); + } + return ( $self, @_ ); +} + +sub count { + my ( $self, %args ) = &_args; + delete $args{type}; + $self->{es}->count(%args); +} + +sub get { + my ( $self, %args ) = &_args; + delete $args{type}; + $self->{es}->get(%args); +} + +sub delete { + my ( $self, %args ) = &_args; + delete $args{type}; + $self->{es}->delete(%args); +} + +sub search { + my ( $self, %args ) = &_args; + delete $args{type}; + $self->{es}->search(%args); +} + +sub scroll_helper { + my ( $self, %args ) = &_args; + delete $args{type}; + $self->{es}->scroll_helper(%args); +} + +1; diff --git a/lib/MetaCPAN/Model/Email/PAUSE.pm b/lib/MetaCPAN/Model/Email/PAUSE.pm new file mode 100644 index 000000000..b022dcf0d --- /dev/null +++ b/lib/MetaCPAN/Model/Email/PAUSE.pm @@ -0,0 +1,90 @@ +package MetaCPAN::Model::Email::PAUSE; + +use MetaCPAN::Moose; + +use Email::Sender::Simple qw( sendmail ); +use Email::Sender::Transport::SMTP (); +use Email::Simple (); +use Encode (); +use MetaCPAN::Types::TypeTiny qw( Object Uri ); +use Try::Tiny qw( catch try ); + +with('MetaCPAN::Role::HasConfig'); + +has _author => ( + is => 'ro', + isa => Object, + init_arg => 'author', + required => 1, +); + +has _url => ( + is => 'ro', + isa => Uri, + init_arg => 'url', + required => 1, +); + +sub send { + my $self = shift; + + my $email = Email::Simple->create( + header => [ + 'Content-Type' => 'text/plain; charset=utf-8', + To => $self->_author->{email}->[0], + From => 'notifications@metacpan.org', + Subject => 'Connect MetaCPAN with your PAUSE account', + 'MIME-Version' => '1.0', + ], + body => $self->_email_body, + ); + + my $config = $self->config->{smtp}; + my $transport = Email::Sender::Transport::SMTP->new( { + debug => 1, + host => $config->{host}, + port => $config->{port}, + sasl_username => $config->{username}, + sasl_password => $config->{password}, + ssl => 1, + } ); + + my $success = 0; + try { + $success = sendmail( $email, { transport => $transport } ); + } + catch { + warn 'Could not send message: ' . $_; + }; + + return $success; +} + +sub _email_body { + my $self = shift; + my $name = $self->_author->name; + my $uri = $self->_url; + + my $body = < ( is => 'ro', - isa => 'MetaCPAN::Model::Archive', + isa => InstanceOf ['MetaCPAN::Model::Archive'], lazy => 1, builder => '_build_archive', ); @@ -37,7 +36,7 @@ has dependencies => ( has distinfo => ( is => 'ro', - isa => 'CPAN::DistnameInfo', + isa => InstanceOf ['CPAN::DistnameInfo'], handles => { maturity => 'maturity', author => 'cpanid', @@ -54,14 +53,14 @@ has distinfo => ( has document => ( is => 'ro', - isa => 'MetaCPAN::Document::Release', + isa => InstanceOf ['MetaCPAN::Document::Release'], lazy => 1, builder => '_build_document', ); has file => ( is => 'ro', - isa => AbsFile, + isa => AbsPath, required => 1, coerce => 1, ); @@ -76,7 +75,7 @@ has files => ( has date => ( is => 'ro', - isa => 'DateTime', + isa => InstanceOf ['DateTime'], lazy => 1, default => sub { my $self = shift; @@ -84,11 +83,11 @@ has date => ( }, ); -has index => ( is => 'ro' ); +has model => ( is => 'ro' ); has metadata => ( is => 'ro', - isa => 'CPAN::Meta', + isa => InstanceOf ['CPAN::Meta'], lazy => 1, builder => '_build_metadata', ); @@ -122,6 +121,7 @@ has status => ( isa => Str, ); +has es => ( is => 'ro' ); has bulk => ( is => 'ro' ); =head2 run @@ -186,19 +186,21 @@ sub _build_dependencies { sub _build_document { my $self = shift; - my $st = $self->file->stat; + my $st = $self->file->stat; my $stat = { map { $_ => $st->$_ } qw(mode size mtime) }; my $meta = $self->metadata; my $dependencies = $self->dependencies; my $document = DlogS_trace {"adding release $_"} +{ - abstract => MetaCPAN::Util::strip_pod( $meta->abstract ), - archive => $self->filename, - author => $self->author, - date => $self->date . q{}, - dependency => $dependencies, - distribution => $self->distribution, + abstract => MetaCPAN::Util::strip_pod( $meta->abstract ), + archive => $self->filename, + author => $self->author, + checksum_md5 => $self->archive->file_digest_md5, + checksum_sha256 => $self->archive->file_digest_sha256, + date => $self->date . q{}, + dependency => $dependencies, + distribution => $self->distribution, # CPAN::Meta->license *must* be called in list context # (and *may* return multiple strings). @@ -219,13 +221,20 @@ sub _build_document { || $document->{abstract} eq 'null' ); $document - = $self->index->type('release')->put( $document, { refresh => 1 } ); + = $self->model->doc('release')->put( $document, { refresh => true } ); + + # create distribution if doesn't exist + $self->es->update( + es_doc_path('distribution'), + id => $self->distribution, + body => { + doc => { + name => $self->distribution, + }, + doc_as_upsert => true, + }, + ); - # create will die if the document already exists - eval { - $self->index->type('distribution') - ->put( { name => $self->distribution }, { create => 1 } ); - }; return $document; } @@ -324,15 +333,12 @@ sub _build_files { my @files; log_debug { 'Indexing ', scalar @{ $self->archive->files }, ' files' }; - my $file_set = $self->index->type('file'); + my $file_set = $self->model->doc('file'); my $extract_dir = $self->extract; File::Find::find( sub { - my $child - = -d $File::Find::name - ? Path::Class::Dir->new($File::Find::name) - : Path::Class::File->new($File::Find::name); + my $child = path($File::Find::name); return if $self->_is_broken_file($File::Find::name); my $relative = $child->relative($extract_dir); my $stat = do { @@ -350,14 +356,15 @@ sub _build_files { my $file = $file_set->new_document( Dlog_trace {"adding file $_"} +{ author => $self->author, - binary => -B $child, + binary => -B $child ? true : false, content => $child->is_dir ? \"" : \( scalar $child->slurp ), date => $self->date, - directory => $child->is_dir, + directory => $child->is_dir ? true : false, distribution => $self->distribution, - indexed => $self->metadata->should_index_file($fpath) ? 1 - : 0, + indexed => $self->metadata->should_index_file($fpath) + ? true + : false, local_path => $child, maturity => $self->maturity, metadata => $self->metadata, @@ -402,14 +409,12 @@ sub _build_metadata { my $extract_dir = $self->extract; - return $self->_load_meta_file || CPAN::Meta->new( - { - license => 'unknown', - name => $self->distribution, - no_index => { directory => [@always_no_index_dirs] }, - version => $self->version || 0, - } - ); + return $self->_load_meta_file || CPAN::Meta->new( { + license => 'unknown', + name => $self->distribution, + no_index => { directory => [@always_no_index_dirs] }, + version => $self->version || 0, + } ); } sub _load_meta_file { @@ -429,32 +434,24 @@ sub _load_meta_file { } return unless (@files); - # YAML YAML::Tiny YAML::XS don't offer better results - my @backends = qw(CPAN::Meta::YAML YAML::Syck); - my $error; - while ( my $mod = shift @backends ) { - $ENV{PERL_YAML_BACKEND} = $mod; - my $last; - for my $file (@files) { - try { - $last = CPAN::Meta->load_file($file); - } - catch { - $error = $_; - log_warn {"META file ($file) could not be loaded: $error"}; - }; - if ($last) { - last; - } + my $last; + for my $file (@files) { + try { + $last = CPAN::Meta->load_file($file); } + catch { + log_warn {"META file ($file) could not be loaded: $_"}; + }; if ($last) { - push( @{ $last->{no_index}->{directory} }, - @always_no_index_dirs ); - return $last; + last; } } + if ($last) { + push( @{ $last->{no_index}->{directory} }, @always_no_index_dirs ); + return $last; + } - log_warn {'No META files could be loaded'} unless @backends; + log_warn {'No META files could be loaded'}; } sub extract { @@ -484,22 +481,21 @@ sub _modules_from_meta { my $provides = $self->metadata->provides; my $files = $self->files; + my %files = map +( $_->path => $_ ), @$files; foreach my $module ( sort keys %$provides ) { my $data = $provides->{$module}; my $path = File::Spec->canonpath( $data->{file} ); - # Obey no_index and take the shortest path if multiple files match. - my ($file) = sort { length( $a->path ) <=> length( $b->path ) } - grep { $_->indexed && $_->path =~ /\Q$path\E$/ } @$files; + my $file = $files{$path} + or next; - next unless $file; - $file->add_module( - { - name => $module, - version => $data->{version}, - indexed => 1, - } - ); + next unless $file->indexed; + + $file->add_module( { + name => $module, + version => $data->{version}, + indexed => true, + } ); push( @modules, $file ); } @@ -523,14 +519,12 @@ sub _modules_from_files { next if !$info; foreach my $module_name ( keys %{$info} ) { - $file->add_module( - { - name => $module_name, - defined $info->{$module_name}->{version} - ? ( version => $info->{$module_name}->{version} ) - : (), - } - ); + $file->add_module( { + name => $module_name, + defined $info->{$module_name}->{version} + ? ( version => $info->{$module_name}->{version} ) + : (), + } ); } push @modules, $file; } @@ -550,26 +544,30 @@ sub _modules_from_files { # Ignore packages that people cannot claim. # https://github.com/andk/pause/blob/master/lib/PAUSE/pmfile.pm#L236 - for my $pkg ( grep { $_ ne 'main' && $_ ne 'DB' } - $info->packages_inside ) - { + # + # Parse::PMFile and PAUSE translate apostrophes to double colons, + # but Module::Metadata does not. + my @packages + = map s{'}{::}gr, + grep { $_ ne 'main' && $_ ne 'DB' } + $info->packages_inside; + + for my $pkg (@packages) { my $version = $info->version($pkg); - $file->add_module( - { - name => $pkg, - defined $version + $file->add_module( { + name => $pkg, + defined $version # Stringify if it's a version object, otherwise fall back to stupid stringification # Changes in Module::Metadata were causing inconsistencies in the return value, # we are just trying to survive. - ? ( - version => ref $version eq 'version' - ? $version->stringify - : ( $version . q{} ) - ) - : () - } - ); + ? ( + version => ref $version eq 'version' + ? $version->stringify + : ( $version . q{} ) + ) + : () + } ); } push( @modules, $file ); alarm(0); diff --git a/lib/MetaCPAN/Model/Search.pm b/lib/MetaCPAN/Model/Search.pm deleted file mode 100644 index bc357e31e..000000000 --- a/lib/MetaCPAN/Model/Search.pm +++ /dev/null @@ -1,397 +0,0 @@ -package MetaCPAN::Model::Search; - -use MetaCPAN::Moose; - -use Const::Fast qw( const ); -use Log::Contextual qw( :log :dlog ); -use MooseX::StrictConstructor; -use Cpanel::JSON::XS (); - -use Hash::Merge qw( merge ); -use List::Util qw( min uniq ); -use MetaCPAN::Types qw( Object Str ); -use MetaCPAN::Util qw( single_valued_arrayref_to_scalar ); - -has es => ( - is => 'ro', - isa => Object, - handles => { _run_query => 'search', }, - required => 1, -); - -has index => ( - is => 'ro', - isa => Str, - required => 1, -); - -const my $RESULTS_PER_RUN => 200; -const my @ROGUE_DISTRIBUTIONS => - qw(kurila perl_debug perl_mlb perl-5.005_02+apache1.3.3+modperl pod2texi perlbench spodcxx Bundle-Everything); - -sub _not_rogue { - my @rogue_dists - = map { { term => { 'distribution' => $_ } } } @ROGUE_DISTRIBUTIONS; - return { not => { filter => { or => \@rogue_dists } } }; -} - -sub search_simple { - my ( $self, $search_term ) = @_; - my $es_query = $self->build_query($search_term); - my $es_results = $self->run_query( file => $es_query ); - return $es_results; -} - -sub search_for_first_result { - my ( $self, $search_term ) = @_; - my $es_query = $self->build_query($search_term); - my $es_results = $self->run_query( file => $es_query ); - return unless $es_results->{hits}{total}; - - my $data = $es_results->{hits}{hits}[0]; - single_valued_arrayref_to_scalar( $data->{fields} ); - return $data->{fields}; -} - -=head2 search_web - - search_web( $search_term, $from, $page_size, $collapsed ); - -- search_term: - - can be unqualified string e.g. 'paging' - - can be author e.g: 'author:LLAP' - - can be module e.g.: 'module:Data::Pageset' - - can be distribution e.g.: 'dist:Data-Pageset' - -- from: where in result set to start, int - -- page_size: number of results per page, int - -- collapsed: whether to merge results by dist or not - -=cut - -sub search_web { - my ( $self, $search_term, $from, $page_size, $collapsed, - $max_collapsed_hits ) - = @_; - $page_size //= 20; - $from //= 0; - - # munge the search_term - # these would be nicer if we had variable-length lookbehinds... - # Allow q = 'author:LLAP' or 'module:Data::Page' or 'dist:' - # We are mapping to correct ES fields here - wonder if ANYONE - # uses these?!?!?! - $search_term # - =~ s{(^|\s)author:([a-zA-Z]+)(?=\s|$)}{$1author:\U$2\E}g; - $search_term - =~ s/(^|\s)dist(ribution)?:([\w-]+)(?=\s|$)/$1distribution:$3/g; - $search_term - =~ s/(^|\s)module:(\w[\w:]*)(?=\s|$)/$1module.name.analyzed:$2/g; - - my $results - = $collapsed // $search_term !~ /(distribution|module\.name\S*):/ - ? $self->_search_collapsed( $search_term, $from, $page_size, - $max_collapsed_hits ) - : $self->_search_expanded( $search_term, $from, $page_size ); - - return $results; -} - -sub _search_expanded { - my ( $self, $search_term, $from, $page_size ) = @_; - - # Used for distribution and module searches, the limit is included in - # the query and ES does the right thing (because we are not collapsing - # results by distribution). - my $es_query = $self->build_query( - $search_term, - { - size => $page_size, - from => $from - } - ); - - my $es_results = $self->run_query( file => $es_query ); - - # Extract results from es - my $results = $self->_extract_results($es_results); - - $results = [ - map { - { - hits => [$_], - distribution => $_->{distribution}, - total => 1, - } - } @$results - ]; - - my $return = { - results => $results, - total => $es_results->{hits}->{total}, - took => $es_results->{took}, - collapsed => Cpanel::JSON::XS::false(), - }; - return $return; -} - -sub _search_collapsed { - my ( $self, $search_term, $from, $page_size, $max_collapsed_hits ) = @_; - - $max_collapsed_hits ||= 5; - - my $total_size = $from + $page_size; - - my $es_query_opts = { - size => 0, - fields => [ - qw( - ) - ], - }; - - my $es_query = $self->build_query( $search_term, $es_query_opts ); - my $fields = delete $es_query->{fields}; - my $source = delete $es_query->{_source}; - - $es_query->{aggregations} = { - by_dist => { - terms => { - size => $total_size, - field => 'distribution', - order => { - max_score => 'desc', - }, - }, - aggregations => { - top_files => { - top_hits => { - fields => $fields, - _source => $source, - size => $max_collapsed_hits, - }, - }, - max_score => { - max => { - lang => "expression", - script => "_score", - }, - }, - }, - }, - total_dists => { - cardinality => { - field => 'distribution', - }, - }, - }; - - my $es_results = $self->run_query( file => $es_query ); - - my $output = { - results => [], - total => $es_results->{aggregations}{total_dists}{value}, - took => $es_results->{took}, - collapsed => Cpanel::JSON::XS::true(), - }; - - my $last = min( $total_size - 1, - $#{ $es_results->{aggregations}{by_dist}{buckets} } ); - my @dists = @{ $es_results->{aggregations}{by_dist}{buckets} } - [ $from .. $last ]; - - @{ $output->{results} } = map { - +{ - hits => $self->_extract_results( $_->{top_files} ), - distribution => $_->{key}, - total => $_->{doc_count}, - }; - } @dists; - - return $output; -} - -sub build_query { - my ( $self, $search_term, $params ) = @_; - $params //= {}; - ( my $clean = $search_term ) =~ s/::/ /g; - - my $negative - = { term => { 'mime' => { value => 'text/x-script.perl' } } }; - - my $positive = { - bool => { - should => [ - - # exact matches result in a huge boost - { - term => { - 'documentation' => { - value => $search_term, - boost => 20, - } - } - }, - { - term => { - 'module.name' => { - value => $search_term, - boost => 20, - } - } - }, - - # take the maximum score from the module name and the abstract/pod - { - dis_max => { - queries => [ - { - query_string => { - fields => [ - qw(documentation.analyzed^2 module.name.analyzed^2 distribution.analyzed), - qw(documentation.camelcase module.name.camelcase distribution.camelcase) - ], - query => $clean, - boost => 3, - default_operator => 'AND', - allow_leading_wildcard => 0, - use_dis_max => 1, - - } - }, - { - query_string => { - fields => - [qw(abstract.analyzed pod.analyzed)], - query => $clean, - default_operator => 'AND', - allow_leading_wildcard => 0, - use_dis_max => 1, - - } - } - ] - } - } - - ] - } - }; - - my $search = merge( - $params, - { - query => { - filtered => { - query => { - function_score => { - - # prefer shorter module names - script_score => { - script => { - lang => 'groovy', - file => 'prefer_shorter_module_names_400', - }, - }, - query => { - boosting => { - negative_boost => 0.5, - negative => $negative, - positive => $positive - } - } - } - }, - filter => { - and => [ - $self->_not_rogue, - { term => { status => 'latest' } }, - { term => { 'authorized' => 1 } }, - { term => { 'indexed' => 1 } }, - { - or => [ - { - and => [ - { - exists => { - field => 'module.name' - } - }, - { - term => - { 'module.indexed' => 1 } - } - ] - }, - { - exists => { field => 'documentation' } - }, - ] - } - ] - } - } - }, - _source => [ - "module", - ], - fields => [ - qw( - abstract.analyzed - author - authorized - date - description - dist_fav_count - distribution - documentation - id - indexed - path - pod_lines - release - status - ) - ], - } - ); - - # Ensure our requested fields are unique so that Elasticsearch doesn't - # return us the same value multiple times in an unexpected arrayref. - $search->{fields} = [ uniq @{ $search->{fields} || [] } ]; - - return $search; -} - -sub run_query { - my ( $self, $type, $es_query ) = @_; - return $self->_run_query( - index => $self->index, - type => $type, - body => $es_query, - search_type => 'dfs_query_then_fetch', - ); -} - -sub _extract_results { - my ( $self, $es_results ) = @_; - - return [ - map { - my $res = $_; - single_valued_arrayref_to_scalar( $res->{fields} ); - +{ - abstract => delete $res->{fields}->{'abstract.analyzed'}, - favorites => delete $res->{fields}->{dist_fav_count}, - %{ $res->{fields} }, - %{ $res->{_source} }, - score => $res->{_score}, - } - } @{ $es_results->{hits}{hits} } - ]; -} - -1; - diff --git a/lib/MetaCPAN/Model/User/Account.pm b/lib/MetaCPAN/Model/User/Account.pm index d130f5074..bfb37ce31 100644 --- a/lib/MetaCPAN/Model/User/Account.pm +++ b/lib/MetaCPAN/Model/User/Account.pm @@ -6,10 +6,9 @@ use warnings; use Moose; use ElasticSearchX::Model::Document; -use MetaCPAN::Model::User::Identity; -use MetaCPAN::Types qw(:all); -use MooseX::Types::Structured qw(Dict); -use MetaCPAN::Util; +use MetaCPAN::Types qw( Identity ); +use MetaCPAN::Types::TypeTiny qw( ArrayRef Dict Str ); +use MetaCPAN::Util qw(true false); =head1 PROPERTIES @@ -70,55 +69,20 @@ has access_token => ( handles => { add_access_token => 'push' }, ); -=head2 passed_captcha - -L when the user passed the captcha. - -=cut - -has passed_captcha => ( - is => 'ro', - isa => 'DateTime', - writer => '_set_passed_captcha', -); - -=head2 looks_human - -Certain features are disabled unless a user C. This attribute -is true if the user is connected to a PAUSE account or he L. - -=cut - -has looks_human => ( - required => 1, - is => 'ro', - isa => Bool, - lazy => 1, - builder => '_build_looks_human', - clearer => 'clear_looks_human', -); - -sub _build_looks_human { - my $self = shift; - return $self->has_identity('pause') || ( $self->passed_captcha ? 1 : 0 ); -} - =head1 METHODS =head2 add_identity Adds an identity to L. If the identity is a PAUSE account, -the user ID is added to the corresponding L document -and L is updated. +the user ID is added to the corresponding L document. =cut after add_identity => sub { my ( $self, $identity ) = @_; if ( $identity->{name} eq 'pause' ) { - $self->clear_looks_human; - my $profile = $self->index->model->index('cpan')->type('author') - ->get( $identity->{key} ); + my $profile + = $self->index->model->doc('author')->get( $identity->{key} ); # Not every user is an author if ($profile) { @@ -148,13 +112,12 @@ sub get_identities { sub remove_identity { my ( $self, $identity ) = @_; - my $ids = $self->identities; + my $ids = $self->identity; my ($id) = grep { $_->{name} eq $identity } @$ids; @$ids = grep { $_->{name} ne $identity } @$ids; if ( $identity eq 'pause' ) { - my $profile = $self->index->model->index('cpan')->type('author') - ->get( $id->{key} ); + my $profile = $self->index->model->doc('author')->get( $id->{key} ); if ( $profile && $profile->user eq $self->id ) { $profile->_clear_user; diff --git a/lib/MetaCPAN/Model/User/Account/Set.pm b/lib/MetaCPAN/Model/User/Account/Set.pm index 83fedfb5f..6891aacf1 100644 --- a/lib/MetaCPAN/Model/User/Account/Set.pm +++ b/lib/MetaCPAN/Model/User/Account/Set.pm @@ -15,14 +15,14 @@ Find an account based on its identity. sub find { my ( $self, $p ) = @_; - return $self->filter( - { - and => [ + return $self->query( { + bool => { + must => [ { term => { 'identity.name' => $p->{name} } }, - { term => { 'identity.key' => $p->{key} } } - ] + { term => { 'identity.key' => $p->{key} } }, + ], } - )->first; + } )->first; } =head2 find_code @@ -35,7 +35,7 @@ Find account by C<$code>. See L. sub find_code { my ( $self, $token ) = @_; - return $self->filter( { term => { 'code' => $token } } )->first; + return $self->query( { term => { code => $token } } )->first; } =head2 find_token @@ -48,7 +48,7 @@ Find account by C<$access_token>. See L. sub find_token { my ( $self, $token ) = @_; - return $self->filter( { term => { 'access_token.token' => $token } } ) + return $self->query( { term => { 'access_token.token' => $token } } ) ->first; } diff --git a/lib/MetaCPAN/Model/User/Identity.pm b/lib/MetaCPAN/Model/User/Identity.pm index 8ed4598bb..6236b31a2 100644 --- a/lib/MetaCPAN/Model/User/Identity.pm +++ b/lib/MetaCPAN/Model/User/Identity.pm @@ -5,7 +5,7 @@ use warnings; use Moose; use ElasticSearchX::Model::Document; -use MetaCPAN::Types qw( HashRef ); +use MetaCPAN::Types::TypeTiny qw( HashRef ); has name => ( is => 'ro', diff --git a/lib/MetaCPAN/Pod/Renderer.pm b/lib/MetaCPAN/Pod/Renderer.pm index bb2903925..6cb0591dd 100644 --- a/lib/MetaCPAN/Pod/Renderer.pm +++ b/lib/MetaCPAN/Pod/Renderer.pm @@ -2,12 +2,11 @@ package MetaCPAN::Pod::Renderer; use MetaCPAN::Moose; -use MetaCPAN::Pod::XHTML; -use MetaCPAN::Types qw( Uri ); -use Pod::Markdown; -use Pod::POM; -use Pod::POM::View::Pod; -use Pod::Text; +use MetaCPAN::Pod::HTML; +use MetaCPAN::Types::TypeTiny qw( Uri ); +use Pod::Markdown (); +use Pod::Simple::JustPod (); +use Pod::Text (); has perldoc_url_prefix => ( is => 'ro', @@ -34,7 +33,7 @@ sub markdown_renderer { sub pod_renderer { my $self = shift; - return Pod::POM->new; + return Pod::Simple::JustPod->new; } sub text_renderer { @@ -45,12 +44,11 @@ sub text_renderer { sub html_renderer { my $self = shift; - my $parser = MetaCPAN::Pod::XHTML->new; + my $parser = MetaCPAN::Pod::HTML->new; $parser->html_footer(''); $parser->html_header(''); $parser->index(1); - $parser->anchor_items(1); $parser->no_errata_section( $self->no_errata_section ); $parser->perldoc_url_prefix( $self->perldoc_url_prefix ); $parser->link_mappings( $self->link_mappings ); @@ -83,9 +81,7 @@ sub to_pod { my $self = shift; my $source = shift; - my $renderer = $self->pod_renderer; - my $pom = $renderer->parse_text($source); - return Pod::POM::View::Pod->print($pom); + return $self->_generic_render( $self->pod_renderer, $source ); } sub _generic_render { diff --git a/lib/MetaCPAN/Query.pm b/lib/MetaCPAN/Query.pm new file mode 100644 index 000000000..d9160f077 --- /dev/null +++ b/lib/MetaCPAN/Query.pm @@ -0,0 +1,52 @@ +package MetaCPAN::Query; +use Moose; + +use Module::Runtime qw( require_module ); +use Module::Pluggable::Object (); +use MetaCPAN::Types::TypeTiny qw( ES ); + +has es => ( + is => 'ro', + required => 1, + isa => ES, + coerce => 1, +); + +my @plugins = Module::Pluggable::Object->new( + search_path => [__PACKAGE__], + max_depth => 3, + require => 0, +)->plugins; + +for my $class (@plugins) { + require_module($class); + my $name = $class->can('name') && $class->name + or next; + + my $in = "_in_$name"; + my $gen = "_gen_$name"; + + has $in => ( + is => 'ro', + init_arg => $name, + weak_ref => 1, + ); + + has $gen => ( + is => 'ro', + init_arg => undef, + lazy => 1, + default => sub { + my $self = shift; + $class->new( + es => $self->es, + query => $self, + ); + }, + ); + + no strict 'refs'; + *$name = sub { $_[0]->$in // $_[0]->$gen }; +} + +1; diff --git a/lib/MetaCPAN/Query/Author.pm b/lib/MetaCPAN/Query/Author.pm index 609cd8d8a..f3323e913 100644 --- a/lib/MetaCPAN/Query/Author.pm +++ b/lib/MetaCPAN/Query/Author.pm @@ -2,8 +2,9 @@ package MetaCPAN::Query::Author; use MetaCPAN::Moose; -use MetaCPAN::Util qw( single_valued_arrayref_to_scalar ); -use Ref::Util qw( is_arrayref ); +use MetaCPAN::ESConfig qw( es_doc_path ); +use MetaCPAN::Util qw( MAX_RESULT_WINDOW hit_total ); +use Ref::Util qw( is_arrayref ); with 'MetaCPAN::Query::Role::Common'; @@ -13,27 +14,19 @@ sub by_ids { map {uc} @{$ids}; my $body = { - query => { - constant_score => { - filter => { ids => { values => $ids } } - } - }, - size => scalar @{$ids}, + query => { ids => { values => $ids } }, + size => scalar @{$ids}, }; - my $authors = $self->es->search( - index => $self->index_name, - type => 'author', - body => $body, - ); - return {} unless $authors->{hits}{total}; + my $authors = $self->es->search( es_doc_path('author'), body => $body, ); - my @authors = map { - single_valued_arrayref_to_scalar( $_->{_source} ); - $_->{_source} - } @{ $authors->{hits}{hits} }; + my @authors = map $_->{_source}, @{ $authors->{hits}{hits} }; - return { authors => \@authors }; + return { + authors => \@authors, + took => $authors->{took}, + total => hit_total($authors), + }; } sub by_user { @@ -41,26 +34,36 @@ sub by_user { $users = [$users] unless is_arrayref($users); my $authors = $self->es->search( - index => $self->index_name, - type => 'author', - body => { + es_doc_path('author'), + body => { query => { terms => { user => $users } }, size => 500, } ); - return {} unless $authors->{hits}{total}; - my @authors = map { - single_valued_arrayref_to_scalar( $_->{_source} ); - $_->{_source} - } @{ $authors->{hits}{hits} }; + my @authors = map $_->{_source}, @{ $authors->{hits}{hits} }; - return { authors => \@authors }; + return { + authors => \@authors, + took => $authors->{took}, + total => hit_total($authors), + }; } sub search { my ( $self, $query, $from ) = @_; + $from //= 0; + my $size = 10; + + if ( $from * $size >= MAX_RESULT_WINDOW ) { + return +{ + authors => [], + took => 0, + total => 0, + }; + } + my $body = { query => { bool => { @@ -68,40 +71,33 @@ sub search { { match => { 'name.analyzed' => - { query => $query, operator => 'and' } + { query => $query, operator => 'AND' } } }, { match => { 'asciiname.analyzed' => - { query => $query, operator => 'and' } + { query => $query, operator => 'AND' } } }, { match => { 'pauseid' => uc($query) } }, { match => { 'profile.id' => lc($query) } }, - ] + ], } }, - size => 10, + size => $size, from => $from || 0, }; - my $ret = $self->es->search( - index => $self->index_name, - type => 'author', - body => $body, - ); - return {} unless $ret->{hits}{total}; + my $ret = $self->es->search( es_doc_path('author'), body => $body, ); - my @authors = map { - single_valued_arrayref_to_scalar( $_->{_source} ); - +{ %{ $_->{_source} }, id => $_->{_id} } - } @{ $ret->{hits}{hits} }; + my @authors = map { +{ %{ $_->{_source} }, id => $_->{_id} } } + @{ $ret->{hits}{hits} }; return +{ authors => \@authors, took => $ret->{took}, - total => $ret->{hits}{total}, + total => hit_total($ret), }; } @@ -120,21 +116,15 @@ sub prefix_search { from => $from, }; - my $ret = $self->es->search( - index => $self->index_name, - type => 'author', - body => $body, - ); + my $ret = $self->es->search( es_doc_path('author'), body => $body, ); - my @authors = map { - single_valued_arrayref_to_scalar( $_->{_source} ); - +{ %{ $_->{_source} }, id => $_->{_id} } - } @{ $ret->{hits}{hits} }; + my @authors = map { +{ %{ $_->{_source} }, id => $_->{_id} } } + @{ $ret->{hits}{hits} }; return +{ authors => \@authors, took => $ret->{took}, - total => $ret->{hits}{total}, + total => hit_total($ret), }; } diff --git a/lib/MetaCPAN/Query/CVE.pm b/lib/MetaCPAN/Query/CVE.pm new file mode 100644 index 000000000..20a58d328 --- /dev/null +++ b/lib/MetaCPAN/Query/CVE.pm @@ -0,0 +1,63 @@ +package MetaCPAN::Query::CVE; + +use MetaCPAN::Moose; + +use MetaCPAN::ESConfig qw( es_doc_path ); + +with 'MetaCPAN::Query::Role::Common'; + +sub find_cves_by_cpansa { + my ( $self, $cpansa_id ) = @_; + + my $query = +{ term => { cpansa_id => $cpansa_id } }; + + my $res = $self->es->search( + es_doc_path('cve'), + body => { + query => $query, + size => 999, + } + ); + + return +{ cve => [ map { $_->{_source} } @{ $res->{hits}{hits} } ] }; +} + +sub find_cves_by_release { + my ( $self, $author, $release ) = @_; + + my $query = +{ match => { releases => "$author/$release" } }; + + my $res = $self->es->search( + es_doc_path('cve'), + body => { + query => $query, + size => 999, + } + ); + + return +{ cve => [ map { $_->{_source} } @{ $res->{hits}{hits} } ] }; +} + +sub find_cves_by_dist { + my ( $self, $dist, $version ) = @_; + + my $query = +{ + match => { + dist => $dist, + ( defined $version ? ( versions => $version ) : () ), + } + }; + + my $res = $self->es->search( + es_doc_path('cve'), + body => { + query => $query, + size => 999, + } + ); + + return +{ cve => [ map { $_->{_source} } @{ $res->{hits}{hits} } ] }; +} + +__PACKAGE__->meta->make_immutable; +1; diff --git a/lib/MetaCPAN/Query/Contributor.pm b/lib/MetaCPAN/Query/Contributor.pm index 2b4ba8eb3..d0b1859b9 100644 --- a/lib/MetaCPAN/Query/Contributor.pm +++ b/lib/MetaCPAN/Query/Contributor.pm @@ -2,6 +2,9 @@ package MetaCPAN::Query::Contributor; use MetaCPAN::Moose; +use MetaCPAN::ESConfig qw( es_doc_path ); +use MetaCPAN::Util qw(hit_total); + with 'MetaCPAN::Query::Role::Common'; sub find_release_contributors { @@ -10,25 +13,30 @@ sub find_release_contributors { my $query = +{ bool => { must => [ - { term => { release_author => $author } }, - { term => { release_name => $name } }, + { term => { release_author => $author } }, + { term => { release_name => $name } }, + { exists => { field => 'pauseid' } }, ] } }; my $res = $self->es->search( - index => $self->index_name, - type => 'contributor', - body => { - query => $query, - size => 999, + es_doc_path('contributor'), + body => { + query => $query, + size => 999, + _source => [ qw( + distribution + pauseid + release_author + release_name + ) ], } ); - $res->{hits}{total} or return {}; + hit_total($res) or return {}; return +{ - contributors => [ map { $_->{_source} } @{ $res->{hits}{hits} } ] - }; + contributors => [ map { $_->{_source} } @{ $res->{hits}{hits} } ] }; } sub find_author_contributions { @@ -37,18 +45,22 @@ sub find_author_contributions { my $query = +{ term => { pauseid => $pauseid } }; my $res = $self->es->search( - index => $self->index_name, - type => 'contributor', - body => { - query => $query, - size => 999, + es_doc_path('contributor'), + body => { + query => $query, + size => 999, + _source => [ qw( + distribution + pauseid + release_author + release_name + ) ], } ); - $res->{hits}{total} or return {}; + hit_total($res) or return {}; return +{ - contributors => [ map { $_->{_source} } @{ $res->{hits}{hits} } ] - }; + contributors => [ map { $_->{_source} } @{ $res->{hits}{hits} } ] }; } __PACKAGE__->meta->make_immutable; diff --git a/lib/MetaCPAN/Query/Cover.pm b/lib/MetaCPAN/Query/Cover.pm index 4a7b9a6d2..d524ea5c9 100644 --- a/lib/MetaCPAN/Query/Cover.pm +++ b/lib/MetaCPAN/Query/Cover.pm @@ -2,6 +2,9 @@ package MetaCPAN::Query::Cover; use MetaCPAN::Moose; +use MetaCPAN::ESConfig qw( es_doc_path ); +use MetaCPAN::Util qw(hit_total); + with 'MetaCPAN::Query::Role::Common'; sub find_release_coverage { @@ -10,16 +13,18 @@ sub find_release_coverage { my $query = +{ term => { release => $release } }; my $res = $self->es->search( - index => $self->index_name, - type => 'cover', - body => { + es_doc_path('cover'), + body => { query => $query, size => 999, } ); - $res->{hits}{total} or return {}; + hit_total($res) or return {}; - return $res->{hits}{hits}[0]{_source}; + return +{ + %{ $res->{hits}{hits}[0]{_source} }, + url => "http://cpancover.com/latest/$release/index.html", + }; } __PACKAGE__->meta->make_immutable; diff --git a/lib/MetaCPAN/Query/Distribution.pm b/lib/MetaCPAN/Query/Distribution.pm index 241bb1f6e..71140d573 100644 --- a/lib/MetaCPAN/Query/Distribution.pm +++ b/lib/MetaCPAN/Query/Distribution.pm @@ -2,8 +2,25 @@ package MetaCPAN::Query::Distribution; use MetaCPAN::Moose; +use MetaCPAN::ESConfig qw( es_doc_path ); +use MetaCPAN::Util qw(hit_total); + with 'MetaCPAN::Query::Role::Common'; +sub rogue_list { + return qw( + Acme-DependOnEverything + Bundle-Everything + kurila + perl-5.005_02+apache1.3.3+modperl + perlbench + perl_debug + perl_mlb + pod2texi + spodcxx + ); +} + sub get_river_data_by_dist { my ( $self, $dist ) = @_; @@ -14,14 +31,13 @@ sub get_river_data_by_dist { }; my $res = $self->es->search( - index => $self->index_name, - type => 'distribution', - body => { + es_doc_path('distribution'), + body => { query => $query, size => 999, } ); - $res->{hits}{total} or return {}; + hit_total($res) or return {}; return +{ river => +{ $dist => $res->{hits}{hits}[0]{_source}{river} } }; } @@ -36,14 +52,13 @@ sub get_river_data_by_dists { }; my $res = $self->es->search( - index => $self->index_name, - type => 'distribution', - body => { + es_doc_path('distribution'), + body => { query => $query, size => 999, } ); - $res->{hits}{total} or return {}; + hit_total($res) or return {}; return +{ river => +{ diff --git a/lib/MetaCPAN/Query/Favorite.pm b/lib/MetaCPAN/Query/Favorite.pm index 4630a83fa..67d521657 100644 --- a/lib/MetaCPAN/Query/Favorite.pm +++ b/lib/MetaCPAN/Query/Favorite.pm @@ -2,18 +2,24 @@ package MetaCPAN::Query::Favorite; use MetaCPAN::Moose; -use MetaCPAN::Util qw( single_valued_arrayref_to_scalar ); +use MetaCPAN::ESConfig qw( es_doc_path ); +use MetaCPAN::Util qw( MAX_RESULT_WINDOW hit_total ); with 'MetaCPAN::Query::Role::Common'; sub agg_by_distributions { my ( $self, $distributions, $user ) = @_; - return unless $distributions; + return { + favorites => {}, + myfavorites => {}, + took => 0, + } + unless $distributions; my $body = { size => 0, query => { - terms => { 'distribution' => $distributions } + terms => { distribution => $distributions } }, aggregations => { favorites => { @@ -25,9 +31,9 @@ sub agg_by_distributions { $user ? ( myfavorites => { - filter => { term => { 'user' => $user } }, + filter => { term => { user => $user } }, aggregations => { - enteries => { + entries => { terms => { field => 'distribution' } } } @@ -37,11 +43,7 @@ sub agg_by_distributions { } }; - my $ret = $self->es->search( - index => $self->index_name, - type => 'favorite', - body => $body, - ); + my $ret = $self->es->search( es_doc_path('favorite'), body => $body, ); my %favorites = map { $_->{key} => $_->{doc_count} } @{ $ret->{aggregations}{favorites}{buckets} }; @@ -64,28 +66,24 @@ sub by_user { $size ||= 250; my $favs = $self->es->search( - index => $self->index_name, - type => 'favorite', - body => { - query => { term => { user => $user } }, - fields => [qw( author date distribution )], - sort => ['distribution'], - size => $size, + es_doc_path('favorite'), + body => { + query => { term => { user => $user } }, + _source => [qw( author date distribution )], + sort => ['distribution'], + size => $size, } ); - return {} unless $favs->{hits}{total}; + return {} unless hit_total($favs); my $took = $favs->{took}; - my @favs = map { $_->{fields} } @{ $favs->{hits}{hits} }; - - single_valued_arrayref_to_scalar( \@favs ); + my @favs = map { $_->{_source} } @{ $favs->{hits}{hits} }; # filter out backpan only distributions my $no_backpan = $self->es->search( - index => $self->index_name, - type => 'release', - body => { + es_doc_path('release'), + body => { query => { bool => { must => [ @@ -99,14 +97,14 @@ sub by_user { ] } }, - fields => ['distribution'], - size => scalar(@favs), + _source => ['distribution'], + size => scalar(@favs), } ); $took += $no_backpan->{took}; - if ( $no_backpan->{hits}{total} ) { - my %has_no_backpan = map { $_->{fields}{distribution}[0] => 1 } + if ( hit_total($no_backpan) ) { + my %has_no_backpan = map { $_->{_source}{distribution} => 1 } @{ $no_backpan->{hits}{hits} }; @favs = grep { exists $has_no_backpan{ $_->{distribution} } } @favs; @@ -122,24 +120,26 @@ sub leaderboard { size => 0, query => { match_all => {} }, aggregations => { - leaderboard => - { terms => { field => 'distribution', size => 600 }, }, + leaderboard => { + terms => { + field => 'distribution', + size => 100, + }, + }, + totals => { + cardinality => { + field => 'distribution', + }, + }, }, }; - my $ret = $self->es->search( - index => $self->index_name, - type => 'favorite', - body => $body, - ); - - my @leaders - = @{ $ret->{aggregations}{leaderboard}{buckets} }[ 0 .. 99 ]; + my $ret = $self->es->search( es_doc_path('favorite'), body => $body, ); return { - leaderboard => \@leaders, + leaderboard => $ret->{aggregations}{leaderboard}{buckets}, + total => $ret->{aggregations}{totals}{value}, took => $ret->{took}, - total => $ret->{total} }; } @@ -148,24 +148,30 @@ sub recent { $page //= 1; $size //= 100; + if ( $page * $size >= MAX_RESULT_WINDOW ) { + return +{ + favorites => [], + took => 0, + total => 0, + }; + } + my $favs = $self->es->search( - index => $self->index_name, - type => 'favorite', - body => { + es_doc_path('favorite'), + body => { size => $size, from => ( $page - 1 ) * $size, query => { match_all => {} }, sort => [ { 'date' => { order => 'desc' } } ] } ); - return {} unless $favs->{hits}{total}; my @favs = map { $_->{_source} } @{ $favs->{hits}{hits} }; return +{ favorites => \@favs, took => $favs->{took}, - total => $favs->{total} + total => hit_total($favs), }; } @@ -173,20 +179,17 @@ sub users_by_distribution { my ( $self, $distribution ) = @_; my $favs = $self->es->search( - index => $self->index_name, - type => 'favorite', - body => { + es_doc_path('favorite'), + body => { query => { term => { distribution => $distribution } }, _source => ['user'], size => 1000, } ); - return {} unless $favs->{hits}{total}; + return {} unless hit_total($favs); my @plusser_users = map { $_->{_source}{user} } @{ $favs->{hits}{hits} }; - single_valued_arrayref_to_scalar( \@plusser_users ); - return { users => \@plusser_users }; } diff --git a/lib/MetaCPAN/Query/File.pm b/lib/MetaCPAN/Query/File.pm index 62b4039ee..15696c491 100644 --- a/lib/MetaCPAN/Query/File.pm +++ b/lib/MetaCPAN/Query/File.pm @@ -2,7 +2,9 @@ package MetaCPAN::Query::File; use MetaCPAN::Moose; -use MetaCPAN::Util qw( single_valued_arrayref_to_scalar ); +use List::Util qw( max ); +use MetaCPAN::ESConfig qw( es_doc_path ); +use MetaCPAN::Util qw( hit_total true false ); with 'MetaCPAN::Query::Role::Common'; @@ -24,29 +26,258 @@ sub dir { ] }, }, - size => 999, - fields => [ + size => 999, + _source => [ qw(name stat.mtime path stat.size directory slop documentation mime) ], }; - my $data = $self->es->search( - { - index => $self->index_name, - type => 'file', - body => $body, - } - ); - return unless $data->{hits}{total}; + my $data = $self->es->search( { + es_doc_path('file'), body => $body, + } ); - my $dir = [ map { $_->{fields} } @{ $data->{hits}{hits} } ]; - single_valued_arrayref_to_scalar($dir); + my $dir = [ map { $_->{_source} } @{ $data->{hits}{hits} } ]; return { dir => $dir }; } +sub _doc_files { + my @files = @_; + my %s; + return + map +( "$_", "$_.pod", "$_.md", "$_.markdown", "$_.mdown", + "$_.mkdn", ), + grep !$s{$_}++, + map +( $_, uc $_ ), + @_; +} + +my %special_files = ( + changelog => [ + _doc_files( qw( + Changelog + ChangeLog + Changes + News + ) ), + ], + contributing => [ + _doc_files( qw( + Contributing + Hacking + Development + ) ), + ], + license => [ qw( + LICENCE + LICENSE + Copyright + COPYRIGHT + Copying + COPYING + Artistic + ARTISTIC + ) ], + install => [ + _doc_files( qw( + Install + ) ), + ], + dist => [ qw( + Build.PL + MANIFEST + META.json + META.yml + Makefile.PL + alienfile + cpanfile + prereqs.json + prereqs.yml + dist.ini + minil.toml + ) ], + security => [ + _doc_files( qw( + Security + security + ) ), + qw( + security.txt + ), + ], + other => [ + _doc_files( qw( + Authors + Credits + FAQ + README + THANKS + ToDo + Todo + ) ), + ], +); +my %perl_files = ( + changelog => [ qw( + perldelta.pod + ) ], + license => [ qw( + perlartistic.pod + perlgpl.pod + ) ], + contributing => [ qw( + perlhack.pod + ) ], +); + +my @shared_path_prefix_examples = qw( + example + examples + Example + Examples + sample + samples + demo + demos +); + +my %path_files = ( + example => [ + qw( + eg + ex + ), + @shared_path_prefix_examples, + ], +); + +my %prefix_files = ( example => [ @shared_path_prefix_examples, ], ); + +my %file_to_type; +my %type_to_regex; +my %query_parts; + +my %sort_order; + +for my $type ( keys %special_files ) { + my @files = @{ $special_files{$type} || [] }; + my @perl_files = @{ $perl_files{$type} || [] }; + + $sort_order{ $files[$_] } = $_ for 0 .. $#files; + + my @root_file = grep !/\.pod$/, @files; + my @non_root_file = grep /\.pod$/, @files; + + my @parts; + if (@root_file) { + push @parts, + { + bool => { + must => [ + { term => { level => 0 } }, + { terms => { name => \@root_file } }, + ], + ( + @perl_files + ? ( must_not => + [ { term => { distribution => 'perl' } } ] ) + : () + ), + } + }; + } + if (@non_root_file) { + push @parts, + { + bool => { + must => [ { terms => { name => \@non_root_file } } ], + ( + @perl_files + ? ( must_not => + [ { term => { distribution => 'perl' } } ] ) + : () + ), + } + }; + } + if (@perl_files) { + push @parts, + { + bool => { + must => [ + { term => { distribution => 'perl' } }, + { terms => { name => \@perl_files } }, + ], + } + }; + } + + $file_to_type{$_} = $type for @files, @perl_files; + push @{ $query_parts{$type} }, @parts; +} + +for my $type ( keys %prefix_files ) { + my @prefixes = @{ $prefix_files{$type} }; + + my @parts = map +{ prefix => { 'name' => $_ } }, @prefixes; + + push @{ $query_parts{$type} }, @parts; + + my ($regex) = map qr{(?:\A|/)(?:$_)[^/]*\z}, join '|', @prefixes; + + if ( $type_to_regex{$type} ) { + $type_to_regex{$type} = qr{$type_to_regex{$type}|$regex}; + } + else { + $type_to_regex{$type} = $regex; + } +} + +for my $type ( keys %path_files ) { + my @prefixes = @{ $path_files{$type} }; + + my @parts = map +{ prefix => { 'path' => "$_/" } }, @prefixes; + + push @{ $query_parts{$type} }, @parts; + + my ($regex) = map qr{\A(?:$_)/}, join '|', @prefixes; + + if ( $type_to_regex{$type} ) { + $type_to_regex{$type} = qr{$type_to_regex{$type}|$regex}; + } + else { + $type_to_regex{$type} = $regex; + } +} + sub interesting_files { - my ( $self, $author, $release ) = @_; + my ( $self, $author, $release, $categories, $options ) = @_; + + $categories = [ sort keys %query_parts ] + if !$categories || !@$categories; + + my $return = { + files => [], + total => 0, + took => 0, + }; + + my @clauses = map @{ $query_parts{$_} // [] }, @$categories; + + return $return + unless @clauses; + + $options->{_source} //= [ qw( + author + distribution + documentation + name + path + pod_lines + release + status + ) ]; + $options->{size} //= 250; my $body = { query => { @@ -54,168 +285,473 @@ sub interesting_files { must => [ { term => { release => $release } }, { term => { author => $author } }, - { term => { directory => \0 } }, - { not => { prefix => { 'path' => 'corpus/' } } }, - { not => { prefix => { 'path' => 'fatlib/' } } }, - { not => { prefix => { 'path' => 'inc/' } } }, - { not => { prefix => { 'path' => 'local/' } } }, - { not => { prefix => { 'path' => 'perl5/' } } }, - { not => { prefix => { 'path' => 'share/' } } }, - { not => { prefix => { 'path' => 't/' } } }, - { not => { prefix => { 'path' => 'xt/' } } }, - { - bool => { - should => [ - { - bool => { - must => [ - { term => { level => 0 } }, - { - terms => { - name => [ - qw( - alienfile - AUTHORS - Build.PL - CHANGELOG - CHANGELOG.md - ChangeLog - ChangeLog.md - Changelog - Changelog.md - CHANGES - CHANGES.md - Changes - Changes.md - CONTRIBUTING - CONTRIBUTING.md - Contributing - COPYING - Copying - COPYRIGHT - cpanfile - CREDITS - DEVELOPMENT - DEVELOPMENT.md - Development - Development.md - dist.ini - FAQ - FAQ.md - HACKING - HACKING.md - Hacking - Hacking.md - INSTALL - INSTALL.md - LICENCE - LICENSE - MANIFEST - Makefile.PL - META.json - META.yml - minil.toml - NEWS - NEWS.md - README - README.markdown - README.md - README.mdown - README.mkdn - THANKS - TODO - TODO.md - ToDo - ToDo.md - Todo - Todo.md - ) - ] - } - } - ] - } - }, - { - bool => { - must => [ - { - terms => { - name => [ - qw( - CONTRIBUTING.pm - CONTRIBUTING.pod - Contributing.pm - Contributing.pod - ChangeLog.pm - ChangeLog.pod - Changelog.pm - Changelog.pod - CHANGES.pm - CHANGES.pod - Changes.pm - Changes.pod - HACKING.pm - HACKING.pod - Hacking.pm - Hacking.pod - TODO.pm - TODO.pod - ToDo.pm - ToDo.pod - Todo.pm - Todo.pod - ) - ] - } - } - ] - } - }, - map { - { prefix => { 'name' => $_ } }, - { prefix => { 'path' => $_ } }, - - # With "prefix" we don't need the plural "s". - } qw( - ex eg - example Example - sample - ) - ] - } - } - ] + { term => { directory => false } }, + { bool => { should => \@clauses } }, + ], + must_not => [ + { prefix => { 'path' => 'corpus/' } }, + { prefix => { 'path' => 'fatlib/' } }, + { prefix => { 'path' => 'inc/' } }, + { prefix => { 'path' => 'local/' } }, + { prefix => { 'path' => 'perl5/' } }, + { prefix => { 'path' => 'share/' } }, + { prefix => { 'path' => 't/' } }, + { prefix => { 'path' => 'xt/' } }, + ], + }, + }, + %$options, + }; + + my $data = $self->es->search( { + es_doc_path('file'), body => $body, + } ); + + $return->{took} = $data->{took}; + $return->{total} = hit_total($data); + + return $return + unless $return->{total}; + + my $files = [ map $_->{_source}, @{ $data->{hits}{hits} } ]; + + for my $file (@$files) { + my $category = $file_to_type{ $file->{name} }; + if ( !$category ) { + for my $type ( keys %type_to_regex ) { + if ( $file->{path} =~ $type_to_regex{$type} ) { + $category = $type; + last; + } + } + } + $category ||= 'unknown'; + + $file->{category} = $category; + } + + $return->{files} = $files; + + return $return; +} + +sub files_by_category { + my ( $self, $author, $release, $categories, $options ) = @_; + my $return = $self->interesting_files( $author, $release, $categories, + $options ); + my $files = delete $return->{files}; + + $return->{categories} = { map +( $_ => [] ), @$categories }; + + for my $file (@$files) { + my $category = $file->{category}; + push @{ $return->{categories}{$category} }, $file; + } + + for my $category (@$categories) { + my $files = $return->{categories}{$category}; + @$files = map $_->[0], + sort { $a->[1] <=> $b->[1] || $a->[2] cmp $b->[2] } + map [ $_, $sort_order{ $_->{name} } || 9999, $_->{path} ], + @$files; + } + return $return; +} + +sub find_changes_files { + my ( $self, $author, $release ) = @_; + my $result = $self->files_by_category( $author, $release, ['changelog'], + { _source => true } ); + my ($file) = @{ $result->{categories}{changelog} || [] }; + return $file; +} + +sub _autocomplete { + my ( $self, $query ) = @_; + + my $search_size = 100; + + my $sugg_res = $self->es->search( + es_doc_path('file'), + body => { + suggest => { + documentation => { + text => $query, + completion => { + field => "suggest", + size => $search_size, + }, + }, } }, + ); + + my %docs; + for my $suggest ( @{ $sugg_res->{suggest}{documentation}[0]{options} } ) { + $docs{ $suggest->{text} } = max grep {defined} + ( $docs{ $suggest->{text} }, $suggest->{score} ); + } + + my $res = $self->es->search( + es_doc_path('file'), + body => { + query => { + bool => { + must => [ + { term => { indexed => true } }, + { term => { authorized => true } }, + { term => { status => 'latest' } }, + { terms => { documentation => [ keys %docs ] } }, + ], + must_not => [ + { + terms => { + distribution => [ + $self->query->distribution->rogue_list + ] + }, + }, + ], + } + }, + _source => [ qw( + author + date + deprecated + distribution + documentation + release + ) ], + size => $search_size, + }, + ); + + my $hits = $res->{hits}{hits}; + + my $fav_res + = $self->query->favorite->agg_by_distributions( + [ map $_->{_source}{distribution}, @$hits ] ); + + my $favs = $fav_res->{favorites}; + + my %valid = map { + my $source = $_->{_source}; + ( + $source->{documentation} => { + %$source, favorites => $favs->{ $source->{distribution} }, + } + ); + } @{ $res->{hits}{hits} }; + + # remove any exact match, it will be added later + my $exact = delete $valid{$query}; + + no warnings 'uninitialized'; + my @sorted = map { $valid{$_} } + sort { + my $a_data = $valid{$a}; + my $b_data = $valid{$b}; + $a_data->{deprecated} <=> $b_data->{deprecated} + || $b_data->{favorites} <=> $a_data->{favorites} + || $docs{$b} <=> $docs{$a} + || length($a) <=> length($b) + || $a cmp $b + } + keys %valid; + + return { + took => $sugg_res->{took} + $res->{took} + $fav_res->{took}, + suggestions => [ ( $exact ? $exact : () ), @sorted ], + }; +} + +sub autocomplete { + my ( $self, @terms ) = @_; + my $data = $self->_autocomplete( join ' ', @terms ); - # NOTE: We could inject author/release/distribution into each result - # in the controller if asking ES for less data would be better. - fields => [ - qw( - name documentation path pod_lines - author release distribution status - ) + return { + took => $data->{took}, + hits => { + hits => [ + map { + my $source = $_; + +{ + fields => { + map +( $_ => $source->{$_} ), qw( + documentation + release + author + distribution + ), + }, + }; + } @{ $data->{suggestions} } + ], + }, + }; +} + +sub autocomplete_suggester { + my ( $self, @terms ) = @_; + my $data = $self->_autocomplete( join ' ', @terms ); + + return { + took => $data->{took}, + suggestions => [ + map +{ + author => $_->{author}, + date => $_->{date}, + deprecated => $_->{deprecated}, + distribution => $_->{distribution}, + name => $_->{documentation}, + release => $_->{release}, + }, + @{ $data->{suggestions} } ], - size => 250, }; +} - my $data = $self->es->search( - { - index => $self->index_name, - type => 'file', - body => $body, - } +sub documented_modules { + my ( $self, $author, $release ) = @_; + my $query = { + bool => { + must => [ + { term => { author => $author } }, + { term => { release => $release } }, + { exists => { field => "documentation" } }, + { + bool => { + should => [ + { + bool => { + must => [ + { + exists => + { field => 'module.name' } + }, + { + term => + { 'module.indexed' => true } + }, + ], + } + }, + { + bool => { + must => [ + { + exists => + { field => 'pod.analyzed' } + }, + { term => { indexed => true } }, + ], + } + }, + ], + } + }, + ], + }, + }; + my $res = $self->es->search( + es_doc_path('file'), + body => { + query => $query, + size => 999, + _source => [qw(name module path documentation distribution)], + }, ); - return unless $data->{hits}{total}; - my $files = [ map { $_->{fields} } @{ $data->{hits}{hits} } ]; - single_valued_arrayref_to_scalar($files); + return { + took => $res->{took}, + files => [ map $_->{_source}, @{ $res->{hits}{hits} } ], + }; +} + +sub find_module { + my ( $self, $module, $fields ) = @_; + + my $query = { + bool => { + must => [ + { term => { indexed => true } }, + { term => { authorized => true } }, + { term => { status => 'latest' } }, + { + bool => { + should => [ + { term => { documentation => $module } }, + { + nested => { + path => "module", + query => { + bool => { + must => [ + { + term => { "module.name" => + $module } + }, + { + bool => { should => + [ + { term => + { "module.authorized" + => true + } }, + { exists => + { field => + 'module.associated_pod' + } }, + ], + } + }, + ], + }, + }, + } + }, + ] + } + }, + ], + }, + }; + + my $res = $self->es->search( + es_doc_path('file'), + search_type => 'dfs_query_then_fetch', + body => { + query => $query, + sort => [ + '_score', + { 'version_numified' => { order => 'desc' } }, + { 'date' => { order => 'desc' } }, + { 'mime' => { order => 'asc' } }, + { 'stat.mtime' => { order => 'desc' } } + ], + _source => [ + qw( documentation module.indexed module.authoried module.name ) + ], + size => 100, + }, + ); + + my @candidates = @{ $res->{hits}{hits} }; + + my ($file) = grep { + grep { $_->{indexed} && $_->{authorized} && $_->{name} eq $module } + @{ $_->{module} || [] } + } grep { !$_->{documentation} || $_->{documentation} eq $module } + @candidates; + + $file ||= shift @candidates; + return undef + if !$file; + return $self->es->get_source( + es_doc_path('file'), + id => $file->{_id}, + ( $fields ? ( _source => $fields ) : () ), + ); +} + +sub find_pod { + my ( $self, $name ) = @_; + my $file = $self->find_module($name); + return $file + unless $file; + my ($module) + = grep { $_->{indexed} && $_->{authorized} && $_->{name} eq $name } + @{ $file->{module} || [] }; + if ( $module && ( my $pod = $module->{associated_pod} ) ) { + my ( $author, $release, @path ) = split( /\//, $pod ); + my $query = { + bool => { + must => [ + { term => { author => $author } }, + { term => { release => $release } }, + { term => { path => join( '/', @path ) } }, + ], + }, + }; + my $pod_file = $self->es->search( + es_doc_path('file'), + body => { + query => $query, + }, + ); + return $pod_file->{hits}{hits}[0]->{_source}; + } + else { + return $file; + } +} + +sub history { + my ( $self, $type, $name, $path, $opts ) = @_; + + $opts ||= {}; + if ( ref $path ) { + $path = join '/', @$path; + } + + my $source = $opts->{fields}; + + my $query + = $type eq "module" + ? { + nested => { + path => 'module', + query => { + constant_score => { + filter => { + bool => { + must => [ + { term => { "module.authorized" => true } }, + { term => { "module.indexed" => true } }, + { term => { "module.name" => $name } }, + ] + } + } + } + } + } + } + : $type eq "file" ? { + bool => { + must => [ + { term => { path => $path } }, + { term => { distribution => $name } }, + ] + } + } + + # XXX: to fix: no filtering on 'release' so this query + # will produce modules matching duplications. -- Mickey + : $type eq "documentation" ? { + bool => { + must => [ + { match_phrase => { documentation => $name } }, + { term => { indexed => true } }, + { term => { authorized => true } }, + ] + } + } + : return undef; + + my $res = $self->es->search( + es_doc_path('file'), + body => { + query => $query, + size => 500, + sort => [ { date => 'desc' } ], + ( $source ? ( _source => $source ) : () ), + }, + ); return { - files => $files, - total => $data->{hits}{total}, - took => $data->{took} + took => $res->{took}, + total => hit_total($res), + files => [ map $_->{_source}, @{ $res->{hits}{hits} } ], }; } diff --git a/lib/MetaCPAN/Query/Mirror.pm b/lib/MetaCPAN/Query/Mirror.pm index ce3d4588a..c16ee36e0 100644 --- a/lib/MetaCPAN/Query/Mirror.pm +++ b/lib/MetaCPAN/Query/Mirror.pm @@ -1,6 +1,9 @@ package MetaCPAN::Query::Mirror; use MetaCPAN::Moose; +use MetaCPAN::Util qw( hit_total ); + +use MetaCPAN::ESConfig qw( es_doc_path ); with 'MetaCPAN::Query::Role::Common'; @@ -11,17 +14,10 @@ sub search { if ($q) { my @protocols = grep /^ (?: http | ftp | rsync ) $/x, split /\s+/, $q; - my $query = { + $query = { bool => { - must_not => { - bool => { - should => [ - map +{ filter => { missing => { field => $_ } } }, - @protocols - ] - } - } - } + must => [ map +{ exists => { field => $_ } }, @protocols ] + }, }; } @@ -45,15 +41,13 @@ sub search { } my $ret = $self->es->search( - index => $self->index_name, - type => 'mirror', - body => { + es_doc_path('mirror'), + body => { size => 999, query => $query, @sort, }, ); - return unless $ret->{hits}{total}; my $data = [ map +{ @@ -65,7 +59,7 @@ sub search { return { mirrors => $data, - total => $ret->{hits}{total}, + total => hit_total($ret), took => $ret->{took} }; } diff --git a/lib/MetaCPAN/Query/Package.pm b/lib/MetaCPAN/Query/Package.pm index c218e1b57..00027f683 100644 --- a/lib/MetaCPAN/Query/Package.pm +++ b/lib/MetaCPAN/Query/Package.pm @@ -2,33 +2,31 @@ package MetaCPAN::Query::Package; use MetaCPAN::Moose; +use MetaCPAN::ESConfig qw( es_doc_path ); + with 'MetaCPAN::Query::Role::Common'; sub get_modules { my ( $self, $dist, $ver ) = @_; my $query = +{ - query => { - bool => { - must => [ - { term => { distribution => $dist } }, - { term => { dist_version => $ver } }, - ], - } + bool => { + must => [ + { term => { distribution => $dist } }, + { term => { dist_version => $ver } }, + ], } }; my $res = $self->es->search( - index => $self->index_name, - type => 'package', - body => { + es_doc_path('package'), + body => { query => $query, size => 999, _source => [qw< module_name >], } ); - return unless $res->{hits}{total}; return +{ modules => [ map { $_->{_source}{module_name} } @{ $res->{hits}{hits} } ] }; } diff --git a/lib/MetaCPAN/Query/Permission.pm b/lib/MetaCPAN/Query/Permission.pm index af5ebba08..311a68aab 100644 --- a/lib/MetaCPAN/Query/Permission.pm +++ b/lib/MetaCPAN/Query/Permission.pm @@ -2,7 +2,8 @@ package MetaCPAN::Query::Permission; use MetaCPAN::Moose; -use Ref::Util qw( is_arrayref ); +use MetaCPAN::ESConfig qw( es_doc_path ); +use Ref::Util qw( is_arrayref ); with 'MetaCPAN::Query::Role::Common'; @@ -21,12 +22,7 @@ sub by_author { size => 5_000, }; - my $ret = $self->es->search( - index => $self->index_name, - type => 'permission', - body => $body, - ); - return unless $ret->{hits}{total}; + my $ret = $self->es->search( es_doc_path('permission'), body => $body, ); my $data = [ sort { $a->{module_name} cmp $b->{module_name} } @@ -42,7 +38,8 @@ sub by_modules { my @modules = map +{ term => { module_name => $_ } }, grep defined, @{$modules}; - return unless @modules; + return { permissions => [] } + unless @modules; my $body = { query => { @@ -51,12 +48,7 @@ sub by_modules { size => 1_000, }; - my $ret = $self->es->search( - index => $self->index_name, - type => 'permission', - body => $body, - ); - return unless $ret->{hits}{total}; + my $ret = $self->es->search( es_doc_path('permission'), body => $body, ); my $data = [ sort { $a->{module_name} cmp $b->{module_name} } diff --git a/lib/MetaCPAN/Query/Rating.pm b/lib/MetaCPAN/Query/Rating.pm deleted file mode 100644 index b803c09f4..000000000 --- a/lib/MetaCPAN/Query/Rating.pm +++ /dev/null @@ -1,47 +0,0 @@ -package MetaCPAN::Query::Rating; - -use MetaCPAN::Moose; - -with 'MetaCPAN::Query::Role::Common'; - -sub by_distributions { - my ( $self, $distributions ) = @_; - - my $body = { - size => 0, - query => { terms => { distribution => $distributions } }, - aggregations => { - ratings => { - terms => { - field => 'distribution' - }, - aggregations => { - ratings_dist => { - stats => { - field => 'rating' - } - } - } - } - } - }; - - my $ret = $self->es->search( - index => $self->index_name, - type => 'rating', - body => $body, - ); - return unless $ret->{hits}{total}; - - my %distributions = map { $_->{key} => $_->{ratings_dist} } - @{ $ret->{aggregations}{ratings}{buckets} }; - - return { - distributions => \%distributions, - total => $ret->{hits}{total}, - took => $ret->{took} - }; -} - -__PACKAGE__->meta->make_immutable; -1; diff --git a/lib/MetaCPAN/Query/Release.pm b/lib/MetaCPAN/Query/Release.pm index 268e71094..b45011e25 100644 --- a/lib/MetaCPAN/Query/Release.pm +++ b/lib/MetaCPAN/Query/Release.pm @@ -1,8 +1,11 @@ package MetaCPAN::Query::Release; +use v5.20; use MetaCPAN::Moose; -use MetaCPAN::Util qw( single_valued_arrayref_to_scalar ); +use MetaCPAN::ESConfig qw( es_doc_path ); +use MetaCPAN::Util + qw( MAX_RESULT_WINDOW hit_total single_valued_arrayref_to_scalar true false ); with 'MetaCPAN::Query::Role::Common'; @@ -19,15 +22,18 @@ sub author_status { my ( $id_2, $id_1 ) = $id =~ /^((\w)\w)/; $status->{links} = { - cpan_directory => "http://cpan.org/authors/id/$id_1/$id_2/$id", + cpan_directory => + "https://www.cpan.org/authors/id/$id_1/$id_2/$id", backpan_directory => "https://cpan.metacpan.org/authors/id/$id_1/$id_2/$id", - cpants => "http://cpants.cpanauthors.org/author/$id", + cpants => "https://cpants.cpanauthors.org/author/$id", cpantesters_reports => - "http://cpantesters.org/author/$id_1/$id.html", - cpantesters_matrix => "http://matrix.cpantesters.org/?author=$id", + "https://www.cpantesters.org/author/$id_1/$id.html", + cpantesters_matrix => + "https://matrix.cpantesters.org/?author=$id", metacpan_explorer => "https://explorer.metacpan.org/?url=/author/$id", + repology => "https://repology.org/maintainer/$id%40cpan", }; } @@ -36,21 +42,18 @@ sub author_status { sub aggregate_status_by_author { my ( $self, $pauseid ) = @_; - my $agg = $self->es->search( - { - index => $self->index_name, - type => 'release', - body => { - query => { - term => { author => $pauseid } - }, - aggregations => { - count => { terms => { field => 'status' } } - }, - size => 0, - } + my $agg = $self->es->search( { + es_doc_path('release'), + body => { + query => { + term => { author => $pauseid } + }, + aggregations => { + count => { terms => { field => 'status' } } + }, + size => 0, } - ); + } ); my %ret = ( cpan => 0, latest => 0, backpan => 0 ); if ($agg) { $ret{ $_->{'key'} } = $_->{'doc_count'} @@ -63,164 +66,25 @@ sub aggregate_status_by_author { sub get_contributors { my ( $self, $author_name, $release_name ) = @_; - my $query = +{ - query => { - bool => { - must => [ - { term => { name => $release_name } }, - { term => { author => $author_name } }, - ], - }, - } - }; - my $res = $self->es->search( - index => $self->index_name, - type => 'release', - body => { - query => $query, + es_doc_path('contributor'), + body => { + query => { + bool => { + must => [ + { term => { release_name => $release_name } }, + { term => { release_author => $author_name } }, + ], + }, + }, size => 999, - _source => [qw< metadata.author metadata.x_contributors >], + _source => [qw< email name pauseid >], } ); - my $release = $res->{hits}{hits}[0]{_source}; - my $contribs = $release->{metadata}{x_contributors} || []; - my $authors = $release->{metadata}{author} || []; - - for ( \( $contribs, $authors ) ) { - - # If a sole contributor is a string upgrade it to an array... - $$_ = [$$_] - if !ref $$_; - - # but if it's any other kind of value don't die trying to parse it. - $$_ = [] - unless Ref::Util::is_arrayref($$_); - } - $authors = [ grep { $_ ne 'unknown' } @$authors ]; - - # this check is against a failure in tests (because fake author) - return - unless $self->es->exists( - index => $self->index_name, - type => 'author', - id => $author_name, - ); - - my $author = $self->es->get( - index => $self->index_name, - type => 'author', - id => $author_name, - ); - - my $author_email = $author->{_source}{email}; - my $author_gravatar_url = $author->{_source}{gravatar_url}; - - my $author_info = { - email => [ - lc "$author_name\@cpan.org", - ( - Ref::Util::is_arrayref($author_email) ? @{$author_email} - : $author_email - ), - ], - name => $author_name, - ( - $author_gravatar_url ? ( gravatar_url => $author_gravatar_url ) - : () - ), - }; - my %seen = map { $_ => $author_info } - ( @{ $author_info->{email} }, $author_info->{name}, ); - - my @contribs = map { - my $name = $_; - my $email; - if ( $name =~ s/\s*<([^<>]+@[^<>]+)>// ) { - $email = $1; - } - my $info; - my $dupe; - if ( $email and $info = $seen{$email} ) { - $dupe = 1; - } - elsif ( $info = $seen{$name} ) { - $dupe = 1; - } - else { - $info = { - name => $name, - email => [], - }; - } - $seen{$name} ||= $info; - if ($email) { - push @{ $info->{email} }, $email - unless grep { $_ eq $email } @{ $info->{email} }; - $seen{$email} ||= $info; - } - $dupe ? () : $info; - } ( @$authors, @$contribs ); - - for my $contrib (@contribs) { - - # heuristic to autofill pause accounts - if ( !$contrib->{pauseid} ) { - my ($pauseid) - = map { /^(.*)\@cpan\.org$/ ? $1 : () } - @{ $contrib->{email} }; - $contrib->{pauseid} = uc $pauseid - if $pauseid; - - } - - # check if contributor's email points to a registered author - if ( !$contrib->{pauseid} ) { - for my $email ( @{ $contrib->{email} } ) { - my $check_author = $self->es->search( - index => $self->index_name, - type => 'author', - body => { - query => { term => { email => $email } }, - size => 10, - } - ); - - if ( $check_author->{hits}{total} ) { - $contrib->{pauseid} - = uc $check_author->{hits}{hits}[0]{_source}{pauseid}; - } - } - } - } - - my $contrib_query = +{ - query => { - terms => { - pauseid => - [ map { $_->{pauseid} ? $_->{pauseid} : () } @contribs ] - } - } - }; + my @contribs = map $_->{_source}, @{ $res->{hits}{hits} }; - my $contrib_authors = $self->es->search( - index => $self->index_name, - type => 'author', - body => { - query => $contrib_query, - size => 999, - _source => [qw< pauseid gravatar_url >], - } - ); - - my %id2url = map { $_->{_source}{pauseid} => $_->{_source}{gravatar_url} } - @{ $contrib_authors->{hits}{hits} }; - for my $contrib (@contribs) { - next unless $contrib->{pauseid}; - $contrib->{gravatar_url} = $id2url{ $contrib->{pauseid} } - if exists $id2url{ $contrib->{pauseid} }; - } + @contribs = sort { fc $a->{name} cmp fc $b->{name} } @contribs; return { contributors => \@contribs }; } @@ -240,9 +104,8 @@ sub get_files { }; my $ret = $self->es->search( - index => $self->index_name, - type => 'file', - body => { + es_doc_path('file'), + body => { query => $query, size => 999, _source => [qw< name path >], @@ -254,6 +117,24 @@ sub get_files { return { files => [ map { $_->{_source} } @{ $ret->{hits}{hits} } ] }; } +sub get_checksums { + my ( $self, $release ) = @_; + + my $query = { term => { name => $release } }; + + my $ret = $self->es->search( + es_doc_path('release'), + body => { + query => $query, + size => 1, + _source => [qw< checksum_md5 checksum_sha256 >], + } + ); + + return {} unless @{ $ret->{hits}{hits} }; + return $ret->{hits}{hits}[0]{_source}; +} + sub _activity_filters { my ( $self, $params, $start ) = @_; my ( $author, $distribution, $module, $new_dists ) @@ -274,7 +155,7 @@ sub _activity_filters { if ( $new_dists and $new_dists eq 'n' ) { push @filters, ( - +{ term => { first => 1 } }, + +{ term => { first => true } }, +{ terms => { status => [qw( cpan latest )] } }, ); } @@ -307,11 +188,7 @@ sub activity { size => 0, }; - my $ret = $self->es->search( - index => $self->index_name, - type => 'release', - body => $body, - ); + my $ret = $self->es->search( es_doc_path('release'), body => $body, ); my $data = { map { $_->{key} => $_->{doc_count} } @{ $ret->{aggregations}{histo}{entries}{buckets} } }; @@ -340,26 +217,73 @@ sub by_author_and_name { } }; - my $ret = $self->es->search( - index => $self->index_name, - type => 'release', - body => $body, - ); - return unless $ret->{hits}{total}; + my $ret = $self->es->search( es_doc_path('release'), body => $body, ); my $data = $ret->{hits}{hits}[0]{_source}; - single_valued_arrayref_to_scalar($data); return { took => $ret->{took}, release => $data, - total => $ret->{hits}{total} + total => hit_total($ret), + }; +} + +sub by_author_and_names { + my ( $self, $releases ) = @_; + + # $releases: ArrayRef[ Dict[ author => Str, name => Str ] ] + + my $body = { + size => ( 0 + @$releases ), + query => { + bool => { + should => [ + map { + +{ + bool => { + must => [ + { + term => { + author => uc( $_->{author} ) + } + }, + { term => { 'name' => $_->{name} } }, + ] + } + } + } @$releases + ] + } + } + }; + + my $ret = $self->es->search( es_doc_path('release'), body => $body, ); + + my @releases; + for my $hit ( @{ $ret->{hits}{hits} } ) { + my $src = $hit->{_source}; + push @releases, $src; + } + + return { + took => $ret->{took}, + total => hit_total($ret), + releases => \@releases, }; } sub by_author { - my ( $self, $pauseid, $size ) = @_; + my ( $self, $pauseid, $page, $size ) = @_; $size //= 1000; + $page //= 1; + + if ( $page * $size >= MAX_RESULT_WINDOW ) { + return { + releases => [], + took => 0, + total => 0, + }; + } my $body = { query => { @@ -376,21 +300,16 @@ sub by_author { qw( abstract author authorized date distribution license metadata.version resources.repository status tests ) ], size => $size, + from => ( $page - 1 ) * $size, }; - my $ret = $self->es->search( - index => $self->index_name, - type => 'release', - body => $body, - ); - return unless $ret->{hits}{total}; + my $ret = $self->es->search( es_doc_path('release'), body => $body, ); my $data = [ map { $_->{_source} } @{ $ret->{hits}{hits} } ]; - single_valued_arrayref_to_scalar($data); return { releases => $data, - total => $ret->{hits}{total}, + total => hit_total($ret), took => $ret->{took} }; } @@ -415,20 +334,14 @@ sub latest_by_distribution { size => 1 }; - my $ret = $self->es->search( - index => $self->index_name, - type => 'release', - body => $body, - ); - return unless $ret->{hits}{total}; + my $ret = $self->es->search( es_doc_path('release'), body => $body, ); my $data = $ret->{hits}{hits}[0]{_source}; - single_valued_arrayref_to_scalar($data); return { release => $data, took => $ret->{took}, - total => $ret->{hits}{total} + total => hit_total($ret), }; } @@ -446,79 +359,124 @@ sub latest_by_author { }, sort => [ 'distribution', { 'version_numified' => { reverse => 1 } } ], - fields => [qw(author distribution name status abstract date)], - size => 1000, + _source => [ + qw(author distribution name status abstract date download_url version authorized maturity) + ], + size => 1000, }; - my $ret = $self->es->search( - index => $self->index_name, - type => 'release', - body => $body, - ); - return unless $ret->{hits}{total}; + my $ret = $self->es->search( es_doc_path('release'), body => $body, ); - my $data = [ map { $_->{fields} } @{ $ret->{hits}{hits} } ]; - single_valued_arrayref_to_scalar($data); + my $data = [ map { $_->{_source} } @{ $ret->{hits}{hits} } ]; return { took => $ret->{took}, releases => $data }; } sub all_by_author { - my ( $self, $author, $size, $page ) = @_; + my ( $self, $author, $page, $size ) = @_; $size //= 100; $page //= 1; + if ( $page * $size >= MAX_RESULT_WINDOW ) { + return { + releases => [], + took => 0, + total => 0, + }; + } + my $body = { - query => { term => { author => uc($author) } }, - sort => [ { date => 'desc' } ], - fields => [ + query => { term => { author => uc($author) } }, + sort => [ { date => 'desc' } ], + _source => [ qw(author distribution name status abstract date download_url version authorized maturity) ], size => $size, from => ( $page - 1 ) * $size, }; - my $ret = $self->es->search( - index => $self->index_name, - type => 'release', - body => $body, - ); - return unless $ret->{hits}{total}; + my $ret = $self->es->search( es_doc_path('release'), body => $body, ); - my $data = [ map { $_->{fields} } @{ $ret->{hits}{hits} } ]; - single_valued_arrayref_to_scalar($data); + my $data = [ map { $_->{_source} } @{ $ret->{hits}{hits} } ]; return { took => $ret->{took}, releases => $data, - total => $ret->{hits}{total} + total => hit_total($ret), }; } sub versions { - my ( $self, $dist ) = @_; + my ( $self, $dist, $versions ) = @_; + + my $size = 1000; + + my $query; + + # 'versions' param was sent + if ( @{$versions} ) { + my $filter_versions; + + # we only want 'latest' version + if ( @{$versions} == 1 and $versions->[0] eq 'latest' ) { + $filter_versions = { term => { status => 'latest' } }; + } + else { + if ( grep $_ eq 'latest', @{$versions} ) { + + # we want a combination of 'latest' and specific versions + @{$versions} = grep $_ ne 'latest', @{$versions}; + $filter_versions = { + bool => { + should => [ + { terms => { version => $versions } }, + { term => { status => 'latest' } }, + ], + } + }; + } + else { + # we only want specific versions + $filter_versions = { terms => { version => $versions } }; + } + } + + $query = { + bool => { + must => [ + { term => { distribution => $dist } }, + $filter_versions + ] + } + }; + } + else { + $query = { term => { distribution => $dist } }; + } my $body = { - query => { term => { distribution => $dist } }, - size => 250, - sort => [ { date => 'desc' } ], - fields => [ - qw( name date author version status maturity authorized download_url) - ], + query => $query, + size => $size, + sort => [ { date => 'desc' } ], + _source => [ qw( + name + date + author + version + status + maturity + authorized + download_url + main_module + ) ], }; - my $ret = $self->es->search( - index => $self->index_name, - type => 'release', - body => $body, - ); - return unless $ret->{hits}{total}; + my $ret = $self->es->search( es_doc_path('release'), body => $body, ); - my $data = [ map { $_->{fields} } @{ $ret->{hits}{hits} } ]; - single_valued_arrayref_to_scalar($data); + my $data = [ map { $_->{_source} } @{ $ret->{hits}{hits} } ]; return { releases => $data, - total => $ret->{hits}{total}, + total => hit_total($ret), took => $ret->{took} }; } @@ -553,11 +511,7 @@ sub top_uploaders { size => 0, }; - my $ret = $self->es->search( - index => $self->index_name, - type => 'release', - body => $body, - ); + my $ret = $self->es->search( es_doc_path('release'), body => $body, ); my $counts = { map { $_->{key} => $_->{doc_count} } @{ $ret->{aggregations}{author}{entries}{buckets} } }; @@ -570,47 +524,8 @@ sub top_uploaders { sub requires { my ( $self, $module, $page, $page_size, $sort ) = @_; - $page //= 1; - $page_size //= 20; - - $sort = _fix_sort_value($sort); - - my $query = { - query => { - filtered => { - query => { 'match_all' => {} }, - filter => { - and => [ - { term => { 'status' => 'latest' } }, - { term => { 'authorized' => 1 } }, - { - term => { - 'dependency.module' => $module - } - } - ] - } - } - } - }; - - my $ret = $self->es->search( - index => $self->index_name, - type => 'release', - body => { - query => $query, - from => $page * $page_size - $page_size, - size => $page_size, - sort => [$sort], - } - ); - return {} unless $ret->{hits}{total}; - - return +{ - data => [ map { $_->{_source} } @{ $ret->{hits}{hits} } ], - total => $ret->{hits}{total}, - took => $ret->{took} - }; + return $self->_get_depended_releases( [$module], $page, $page_size, + $sort ); } sub reverse_dependencies { @@ -631,60 +546,57 @@ sub _get_latest_release { my ( $self, $distribution ) = @_; my $release = $self->es->search( - index => $self->index_name, - type => 'release', - body => { + es_doc_path('release'), + body => { query => { bool => { must => [ { term => { distribution => $distribution } }, { term => { status => 'latest' } }, - { term => { authorized => 1 } }, + { term => { authorized => true } }, ] }, }, - fields => [qw< name author >], + _source => [qw< name author >], }, ); - return unless $release->{hits}{total}; - my ($release_info) = map { $_->{fields} } @{ $release->{hits}{hits} }; - single_valued_arrayref_to_scalar($release_info); + my ($release_info) = map { $_->{_source} } @{ $release->{hits}{hits} }; - return +{ + return $release_info->{name} && $release_info->{author} + ? +{ name => $release_info->{name}, author => $release_info->{author}, - }; + } + : undef; } sub _get_provided_modules { my ( $self, $release ) = @_; my $provided_modules = $self->es->search( - index => $self->index_name, - type => 'file', - body => { + es_doc_path('file'), + body => { query => { bool => { must => [ { term => { 'release' => $release->{name} } }, { term => { 'author' => $release->{author} } }, - { term => { 'module.authorized' => 1 } }, - { term => { 'module.indexed' => 1 } }, + { term => { 'module.authorized' => true } }, + { term => { 'module.indexed' => true } }, ] } }, size => 999, } ); - return unless $provided_modules->{hits}{total}; - return [ - map { $_->{name} } - grep { $_->{indexed} && $_->{authorized} } - map { @{ $_->{_source}{module} } } - @{ $provided_modules->{hits}{hits} } - ]; + my @modules = map { $_->{name} } + grep { $_->{indexed} && $_->{authorized} } + map { @{ $_->{_source}{module} } } + @{ $provided_modules->{hits}{hits} }; + + return @modules ? \@modules : undef; } sub _fix_sort_value { @@ -703,60 +615,90 @@ sub _get_depended_releases { $page //= 1; $page_size //= 50; + if ( $page * $page_size >= MAX_RESULT_WINDOW ) { + return +{ + data => [], + took => 0, + total => 0, + }; + } + $sort = _fix_sort_value($sort); - # because 'terms' doesn't work properly - my $filter_modules = { - bool => { - should => [ - map +{ term => { 'dependency.module' => $_ } }, - @{$modules} - ] - } + my $dependency_filter = { + nested => { + path => 'dependency', + query => { + bool => { + must => [ + { + term => + { 'dependency.relationship' => 'requires' } + }, + { + terms => { + 'dependency.phase' => [ qw( + configure + build + runtime + test + ) ] + } + }, + { terms => { 'dependency.module' => $modules } }, + ], + }, + }, + }, }; my $depended = $self->es->search( - index => $self->index_name, - type => 'release', - body => { + es_doc_path('release'), + body => { query => { bool => { must => [ - $filter_modules, + $dependency_filter, { term => { status => 'latest' } }, - { term => { authorized => 1 } }, - ] - } + { term => { authorized => true } }, + ], + }, }, size => $page_size, - from => $page * $page_size - $page_size, + from => ( $page - 1 ) * $page_size, sort => $sort, } ); - return unless $depended->{hits}{total}; return +{ data => [ map { $_->{_source} } @{ $depended->{hits}{hits} } ], - total => $depended->{hits}{total}, + total => hit_total($depended), took => $depended->{took}, }; } sub recent { - my ( $self, $page, $page_size, $type ) = @_; - my $query; + my ( $self, $type, $page, $page_size ) = @_; + $page //= 1; + $page_size //= 10000; + $type //= ''; + + if ( $page * $page_size >= MAX_RESULT_WINDOW ) { + return +{ + releases => [], + took => 0, + total => 0, + }; + } + my $query; if ( $type eq 'n' ) { $query = { - constant_score => { - filter => { - bool => { - must => [ - { term => { first => 1 } }, - { terms => { status => [qw< cpan latest >] } }, - ] - } - } + bool => { + must => [ + { term => { first => true } }, + { terms => { status => [qw< cpan latest >] } }, + ] } }; } @@ -764,36 +706,25 @@ sub recent { $query = { match_all => {} }; } else { - $query = { - constant_score => { - filter => { - terms => { status => [qw< cpan latest >] } - } - } - }; + $query = { terms => { status => [qw< cpan latest >] } }; } my $body = { - size => $page_size, - from => ( $page - 1 ) * $page_size, - query => $query, - fields => [qw(name author status abstract date distribution)], - sort => [ { 'date' => { order => 'desc' } } ] + size => $page_size, + from => ( $page - 1 ) * $page_size, + query => $query, + _source => + [qw(name author status abstract date distribution maturity)], + sort => [ { 'date' => { order => 'desc' } } ] }; - my $ret = $self->es->search( - index => $self->index_name, - type => 'release', - body => $body, - ); - return unless $ret->{hits}{total}; + my $ret = $self->es->search( es_doc_path('release'), body => $body, ); - my $data = [ map { $_->{fields} } @{ $ret->{hits}{hits} } ]; - single_valued_arrayref_to_scalar($data); + my $data = [ map { $_->{_source} } @{ $ret->{hits}{hits} } ]; return { releases => $data, - total => $ret->{hits}{total}, + total => hit_total($ret), took => $ret->{took} }; } @@ -807,7 +738,7 @@ sub modules { must => [ { term => { release => $release } }, { term => { author => $author } }, - { term => { directory => 0 } }, + { term => { directory => false } }, { bool => { should => [ @@ -820,8 +751,9 @@ sub modules { } }, { - term => - { 'module.indexed' => 1 } + term => { + 'module.indexed' => true + } } ] } @@ -840,7 +772,7 @@ sub modules { } }, { - term => { 'indexed' => 1 } + term => { 'indexed' => true } }, ] } @@ -856,42 +788,355 @@ sub modules { # Sort by documentation name; if there isn't one, sort by path. sort => [ 'documentation', 'path' ], - _source => [ "module", "abstract" ], - - fields => [ - qw( - author - authorized - distribution - documentation - indexed - path - pod_lines - release - status - ) - ], + _source => [ qw( + module + abstract + author + authorized + distribution + documentation + indexed + path + pod_lines + release + status + ) ], }; - my $ret = $self->es->search( - index => $self->index_name, - type => 'file', - body => $body, - ); - return unless $ret->{hits}{total}; + my $ret = $self->es->search( es_doc_path('file'), body => $body, ); - my @files = map +{ - %{ ( single_valued_arrayref_to_scalar( $_->{fields} ) )[0] }, - %{ $_->{_source} } - }, - @{ $ret->{hits}{hits} }; + my @files = map $_->{_source}, @{ $ret->{hits}{hits} }; return { files => \@files, - total => $ret->{hits}{total}, + total => hit_total($ret), took => $ret->{took} }; } +=head2 find_download_url + +cpanm Foo +=> status: latest, maturity: released + +cpanm --dev Foo +=> status: -backpan, sort_by: version_numified,date + +cpanm Foo~1.0 +=> status: latest, maturity: released, module.version_numified: gte: 1.0 + +cpanm --dev Foo~1.0 +-> status: -backpan, module.version_numified: gte: 1.0, sort_by: version_numified,date + +cpanm Foo~<2 +=> maturity: released, module.version_numified: lt: 2, sort_by: status,version_numified,date + +cpanm --dev Foo~<2 +=> status: -backpan, module.version_numified: lt: 2, sort_by: status,version_numified,date + + $release->find_download_url(http://github.com/'module',%20'Foo',%20%7B%20version%20=%3E%20$version,%20dev%20=%3E%200|1%20%7D); + +Sorting: + + if it's stable: + prefer latest > cpan > backpan + then sort by version desc + then sort by date descending (rev chron) + + if it's dev: + sort by version desc + sort by date descending (reverse chronologically) + + +=cut + +sub find_download_url { + my ( $self, $type, $name, $args ) = @_; + $args ||= {}; + + my $dev = $args->{dev}; + my $version = $args->{version}; + my $explicit_version = $version && $version =~ /==/; + + my @filters; + + die 'type must be module or dist' + unless $type eq 'module' || $type eq 'dist'; + my $module_filter = $type eq 'module'; + + if ( !$explicit_version ) { + push @filters, + { bool => { must_not => [ { term => { status => 'backpan' } } ] } + }; + if ( !$dev ) { + push @filters, { term => { maturity => 'released' } }; + } + } + + my $prefix = $module_filter ? 'module.' : ''; + + my $version_filters + = $self->_version_filters( $version, $prefix . 'version_numified' ); + + my $entity_filter = { + bool => { + must => [ + { term => { $prefix . 'authorized' => true } }, + ( + $module_filter + ? ( + { term => { $prefix . 'indexed' => true } }, + { term => { $prefix . 'name' => $name } } + ) + : { term => { 'distribution' => $name } }, + ), + ( + exists $version_filters->{must} + ? @{ $version_filters->{must} } + : () + ) + ], + ( + exists $version_filters->{must_not} + ? ( must_not => [ @{ $version_filters->{must_not} } ] ) + : () + ) + } + }; + + # filters to be applied to the nested modules + if ($module_filter) { + push @filters, + { + nested => { + path => 'module', + query => $entity_filter, + } + }; + } + else { + push @filters, $entity_filter; + } + + my $filter + = @filters + ? { bool => { must => \@filters } } + : $filters[0]; + + my $version_sort + = $module_filter + ? { + 'module.version_numified' => { + mode => 'max', + order => 'desc', + ( + $self->es->api_version ge '6_0' + ? ( + nested => { + path => 'module', + filter => $entity_filter, + }, + ) + : ( + nested_path => 'module', + nested_filter => $entity_filter, + ) + ), + } + } + : { version_numified => { order => 'desc' } }; + + # sort by score, then version desc, then date desc + my @sort = ( '_score', $version_sort, { date => { order => 'desc' } } ); + + my $query; + + if ($dev) { + $query = $filter; + } + else { + # if not dev, then prefer latest > cpan > backpan + $query = { + function_score => { + query => $filter, + score_mode => 'first', + boost_mode => 'replace', + functions => [ + { + filter => { term => { status => 'latest' } }, + weight => 3 + }, + { + filter => { term => { status => 'cpan' } }, + weight => 2 + }, + { filter => { match_all => {} }, weight => 1 }, + ] + } + }; + } + + my $body = { + query => $query, + size => 1, + sort => \@sort, + _source => [ qw( + checksum_md5 + checksum_sha256 + date + distribution + download_url + release + status + version + name + ) ], + }; + + my $res = $self->es->search( + es_doc_path( $module_filter ? 'file' : 'release' ), + body => $body, + search_type => 'dfs_query_then_fetch', + ); + + return unless hit_total($res); + + my @checksums; + + my $hit = $res->{hits}{hits}[0]; + my $source = $hit->{_source}; + my $release = $source->{release}; + + if ($release) { + my $checksums = $self->get_checksums($release); + @checksums = ( + ( + $checksums->{checksum_md5} + ? ( checksum_md5 => $checksums->{checksum_md5} ) + : () + ), + ( + $checksums->{checksum_sha256} + ? ( checksum_sha256 => $checksums->{checksum_sha256} ) + : () + ), + ); + } + + my $source_name = delete $source->{name}; + if ( !$module_filter ) { + $source->{release} = $source_name; + } + + my $module + = $hit->{inner_hits}{module} + ? $hit->{inner_hits}{module}{hits}{hits}[0]{_source} + : {}; + + return +{ %$source, %$module, @checksums, }; +} + +sub _version_filters { + my ( $self, $version, $field ) = @_; + + return () unless $version; + + if ( $version =~ s/^==\s*// ) { + return +{ + must => [ { + term => { + $field => $self->_numify($version) + } + } ] + }; + } + elsif ( $version =~ /^[<>!]=?\s*/ ) { + my %ops = qw(< lt <= lte > gt >= gte); + my ( %filters, %range, @exclusion ); + my @requirements = split /,\s*/, $version; + for my $r (@requirements) { + if ( $r =~ s/^([<>]=?)\s*// ) { + $range{ $ops{$1} } = $self->_numify($r); + } + elsif ( $r =~ s/\!=\s*// ) { + push @exclusion, $self->_numify($r); + } + } + + if ( keys %range ) { + $filters{must} + = [ { range => { $field => \%range } } ]; + } + + if (@exclusion) { + $filters{must_not} = []; + push @{ $filters{must_not} }, + map { +{ term => { $field => $self->_numify($_) } } } + @exclusion; + } + + return \%filters; + } + elsif ( $version !~ /\s/ ) { + return +{ + must => [ { + range => { + $field => { 'gte' => $self->_numify($version) } + }, + } ] + }; + } +} + +sub _numify { + my ( $self, $ver ) = @_; + $ver =~ s/_//g; + version->new($ver)->numify; +} + +sub predecessor { + my ( $self, $name ) = @_; + + my $res = $self->es->search( + es_doc_path('release'), + body => { + query => { + bool => { + must => [ { term => { distribution => $name } }, ], + must_not => [ { term => { status => 'latest' } }, ], + }, + }, + sort => [ { date => 'desc' } ], + size => 1, + }, + ); + my ($release) = $res->{hits}{hits}[0]; + return unless $release; + return $release->{_source}; +} + +sub find { + my ( $self, $name ) = @_; + + my $res = $self->es->search( + es_doc_path('release'), + body => { + query => { + bool => { + must => [ + { term => { distribution => $name } }, + { term => { status => 'latest' } }, + ], + }, + }, + sort => [ { date => 'desc' } ], + size => 1, + }, + ); + my ($file) = $res->{hits}{hits}[0]; + return undef unless $file; + return $file->{_source}; +} + __PACKAGE__->meta->make_immutable; 1; diff --git a/lib/MetaCPAN/Query/Role/Common.pm b/lib/MetaCPAN/Query/Role/Common.pm index cb2c29e28..bc86b311b 100644 --- a/lib/MetaCPAN/Query/Role/Common.pm +++ b/lib/MetaCPAN/Query/Role/Common.pm @@ -1,10 +1,46 @@ package MetaCPAN::Query::Role::Common; - use Moose::Role; -use MetaCPAN::Types qw( Str ); -has es => ( is => 'ro', ); +use MetaCPAN::Types::TypeTiny qw( ES ); + +has es => ( + is => 'ro', + required => 1, + isa => ES, + coerce => 1, +); + +sub name { + my $self = shift; + my $class = ref $self || $self; + + $class =~ /^MetaCPAN::Query::([^:]+)$/ + or return undef; + return lc $1; +} + +has _in_query => ( + is => 'ro', + init_arg => 'query', + weak_ref => 1, +); + +has _gen_query => ( + is => 'ro', + lazy => 1, + init_arg => undef, + default => sub { + my $self = shift; + my $name = $self->name; + + require MetaCPAN::Query; + MetaCPAN::Query->new( + es => $self->es, + ( $name ? ( $name => $self ) : () ), + ); + }, +); -has index_name => ( is => 'ro', ); +sub query { $_[0]->_in_query // $_[0]->_gen_query } 1; diff --git a/lib/MetaCPAN/Query/Search.pm b/lib/MetaCPAN/Query/Search.pm new file mode 100644 index 000000000..d5cf21897 --- /dev/null +++ b/lib/MetaCPAN/Query/Search.pm @@ -0,0 +1,397 @@ +package MetaCPAN::Query::Search; + +use MetaCPAN::Moose; + +use Const::Fast qw( const ); +use Hash::Merge qw( merge ); +use List::Util qw( min uniq ); +use Log::Contextual qw( :log :dlog ); +use MetaCPAN::ESConfig qw( es_doc_path ); +use MetaCPAN::Util qw( MAX_RESULT_WINDOW hit_total true false ); +use MooseX::StrictConstructor; + +with 'MetaCPAN::Query::Role::Common'; + +const my $RESULTS_PER_RUN => 200; +const my @ROGUE_DISTRIBUTIONS => qw( + Acme-DependOnEverything + Bundle-Everything + kurila + perl-5.005_02+apache1.3.3+modperl + perlbench + perl_debug + perl_mlb + pod2texi + spodcxx +); + +sub search_for_first_result { + my ( $self, $search_term ) = @_; + my $es_query = $self->build_query($search_term); + my $es_results = $self->run_query( file => $es_query ); + + my $data = $es_results->{hits}{hits}[0]; + return $data->{_source}; +} + +=head2 search_web + + search_web( $search_term, $from, $page_size, $collapsed ); + +- search_term: + - can be unqualified string e.g. 'paging' + - can be author e.g: 'author:LLAP' + - can be module e.g.: 'module:Data::Pageset' + - can be distribution e.g.: 'dist:Data-Pageset' + +- from: where in result set to start, int + +- page_size: number of results per page, int + +- collapsed: whether to merge results by dist or not + +=cut + +sub search_web { + my ( $self, $search_term, $page, $page_size, $collapsed, + $max_collapsed_hits ) + = @_; + $page_size //= 20; + $page //= 1; + + if ( $page * $page_size >= MAX_RESULT_WINDOW ) { + return { + results => [], + total => 0, + tool => 0, + colapsed => $collapsed ? true : false, + }; + } + + $search_term =~ s{([+=>_search_collapsed( $search_term, $page, $page_size, + $max_collapsed_hits ) + : $self->_search_expanded( $search_term, $page, $page_size ); + + return $results; +} + +sub _search_expanded { + my ( $self, $search_term, $page, $page_size ) = @_; + + # Used for distribution and module searches, the limit is included in + # the query and ES does the right thing (because we are not collapsing + # results by distribution). + my $es_query = $self->build_query( + $search_term, + { + size => $page_size, + from => ( $page - 1 ) * $page_size, + } + ); + + my $es_results = $self->run_query( file => $es_query ); + + # Extract results from es + my $results = $self->_extract_results($es_results); + + $results = [ + map { { + hits => [$_], + distribution => $_->{distribution}, + total => 1, + } } @$results + ]; + + my $return = { + results => $results, + total => hit_total($es_results), + took => $es_results->{took}, + collapsed => false, + }; + return $return; +} + +sub _search_collapsed { + my ( $self, $search_term, $page, $page_size, $max_collapsed_hits ) = @_; + + $max_collapsed_hits ||= 5; + + my $from = ( $page - 1 ) * $page_size; + my $total_size = $page * $page_size; + + my $es_query_opts = { + size => 0, + _source => [ qw( + ) ], + }; + + my $es_query = $self->build_query( $search_term, $es_query_opts ); + my $source = delete $es_query->{_source}; + + my $script_key = $self->es->api_version ge '5_0' ? 'source' : 'inline'; + + $es_query->{aggregations} = { + by_dist => { + terms => { + size => $total_size, + field => 'distribution', + order => { + max_score => 'desc', + }, + }, + aggregations => { + top_files => { + top_hits => { + _source => $source, + size => $max_collapsed_hits, + }, + }, + max_score => { + max => { + script => { + lang => "expression", + $script_key => "_score", + }, + }, + }, + }, + }, + total_dists => { + cardinality => { + field => 'distribution', + }, + }, + }; + + my $es_results = $self->run_query( file => $es_query ); + + my $output = { + results => [], + total => $es_results->{aggregations}{total_dists}{value}, + took => $es_results->{took}, + collapsed => true, + }; + + my $last = min( $total_size - 1, + $#{ $es_results->{aggregations}{by_dist}{buckets} } ); + my @dists = @{ $es_results->{aggregations}{by_dist}{buckets} } + [ $from .. $last ]; + + @{ $output->{results} } = map { + +{ + hits => $self->_extract_results( $_->{top_files} ), + distribution => $_->{key}, + total => $_->{doc_count}, + }; + } @dists; + + return $output; +} + +sub build_query { + my ( $self, $search_term, $params ) = @_; + $params //= {}; + ( my $clean = $search_term ) =~ s/::/ /g; + + my $query = { + bool => { + filter => [ + { term => { status => 'latest' } }, + { term => { authorized => true } }, + { term => { indexed => true } }, + { + bool => { + should => [ + { + bool => { + must => [ + { + exists => + { field => 'module.name' } + }, + { + term => + { 'module.indexed' => true } + } + ], + } + }, + { exists => { field => 'documentation' } }, + ], + } + }, + ], + must_not => [ { + terms => { + distribution => [ $self->query->distribution->rogue_list ] + } + } ], + must => [ + { + bool => { + should => [ + + # exact matches result in a huge boost + { + term => { + 'documentation' => { + value => $search_term, + boost => 20, + } + } + }, + { + term => { + 'module.name' => { + value => $search_term, + boost => 20, + } + } + }, + + # take the maximum score from the module name and the abstract/pod + { + dis_max => { + queries => [ + { + query_string => { + fields => [ + qw(documentation.analyzed^2 module.name.analyzed^2 distribution.analyzed), + qw(documentation.camelcase module.name.camelcase distribution.camelcase) + ], + query => $clean, + boost => 3, + default_operator => 'AND', + allow_leading_wildcard => + false, + + } + }, + { + query_string => { + fields => [ + qw(abstract.analyzed pod.analyzed) + ], + query => $clean, + default_operator => 'AND', + allow_leading_wildcard => + false, + }, + }, + ], + } + }, + ], + } + }, + ], + }, + }; + + my $script_key = $self->es->api_version ge '5_0' ? 'source' : 'inline'; + + $query = { + function_score => { + script_score => { + + # prefer shorter module names + script => { + lang => 'expression', + $script_key => + "_score - (doc['documentation_length'].value == 0 ? 26 : doc['documentation_length'].value)/400", + }, + }, + query => { + boosting => { + negative_boost => 0.5, + positive => $query, + negative => { + bool => { + should => [ + { + term => { 'mime' => 'text/x-script.perl' } + }, + { term => { 'deprecated' => true } }, + ], + }, + }, + }, + }, + }, + }; + + my $search = merge( + $params, + { + query => $query, + _source => [ qw( + module + abstract + author + authorized + date + description + dist_fav_count + distribution + documentation + id + indexed + path + pod_lines + release + status + ) ], + } + ); + + # Ensure our requested fields are unique so that Elasticsearch doesn't + # return us the same value multiple times in an unexpected arrayref. + $search->{_source} = [ uniq @{ $search->{_source} || [] } ]; + + return $search; +} + +sub run_query { + my ( $self, $doc, $es_query ) = @_; + return $self->es->search( + es_doc_path($doc), + body => $es_query, + search_type => 'dfs_query_then_fetch', + ); +} + +sub _extract_results { + my ( $self, $es_results ) = @_; + + return [ + map { + my $res = $_; + +{ + favorites => delete $res->{_source}->{dist_fav_count}, + %{ $res->{_source} }, + score => $res->{_score}, + } + } @{ $es_results->{hits}{hits} } + ]; +} + +1; + diff --git a/lib/MetaCPAN/Queue.pm b/lib/MetaCPAN/Queue.pm deleted file mode 100644 index c19f6e538..000000000 --- a/lib/MetaCPAN/Queue.pm +++ /dev/null @@ -1,80 +0,0 @@ -package MetaCPAN::Queue; - -=head1 DESCRIPTION - -This is not a web app. It's purely here to manage the API's release indexing -queue. - - # On vagrant VM - ./bin/run morbo bin/queue.pl - - # Display information on jobs in queue - ./bin/run bin/queue.pl minion job - -To run the minion admin web interface, run the following on one of the servers: - - # Run the daemon on a local port (tunnel to display on your browser) - ./bin/run bin/queue.pl daemon - -=cut - -use Mojo::Base 'Mojolicious'; - -use MetaCPAN::Queue::Helper (); -use MetaCPAN::Script::Runner (); -use Try::Tiny qw( catch try ); - -sub startup { - my $self = shift; - - # for Mojo cookies, which we won't be needing - $self->secrets( ['veni vidi vici'] ); - - my $helper = MetaCPAN::Queue::Helper->new; - $self->plugin( Minion => $helper->backend ); - $self->plugin( 'Minion::Admin' => { route => $self->routes->any('/') } ); - - $self->minion->add_task( - index_release => $self->_gen_index_task_sub('release') ); - - $self->minion->add_task( - index_latest => $self->_gen_index_task_sub('latest') ); - - $self->minion->add_task( - index_favorite => $self->_gen_index_task_sub('favorite') ); -} - -sub _gen_index_task_sub { - my ( $self, $type ) = @_; - - return sub { - my ( $job, @args ) = @_; - - my @warnings; - local $SIG{__WARN__} = sub { - push @warnings, $_[0]; - warn $_[0]; - }; - - # @args could be ( '--latest', '/path/to/release' ); - unshift @args, $type; - - # Runner expects to have been called via CLI - local @ARGV = @args; - try { - MetaCPAN::Script::Runner->run(@args); - $job->finish( @warnings ? { warnings => \@warnings } : () ); - } - catch { - warn $_; - $job->fail( - { - message => $_, - @warnings ? ( warnings => \@warnings ) : (), - } - ); - }; - } -} - -1; diff --git a/lib/MetaCPAN/Queue/Helper.pm b/lib/MetaCPAN/Queue/Helper.pm deleted file mode 100644 index 975356d8c..000000000 --- a/lib/MetaCPAN/Queue/Helper.pm +++ /dev/null @@ -1,35 +0,0 @@ -package MetaCPAN::Queue::Helper; - -use Moose; - -use File::Temp (); -use MetaCPAN::Types qw( HashRef ); -use Module::Load qw( load ); - -has backend => ( - is => 'ro', - isa => HashRef, - lazy => 1, - builder => '_build_backend', -); - -with 'MetaCPAN::Role::HasConfig'; - -# We could also use an in-memory SQLite db, but this gives us the option of not -# unlinking in order to debug the contents of the db, if we need to. - -sub _build_backend { - my $self = shift; - - if ( $ENV{HARNESS_ACTIVE} ) { - load(Minion::Backend::SQLite); - my $file = File::Temp->new( UNLINK => 1, SUFFIX => '.db' ); - return { SQLite => 'sqlite:' . $file }; - } - - load(Minion::Backend::Pg); - return { Pg => $self->config->{minion_dsn} }; -} - -__PACKAGE__->meta->make_immutable; -1; diff --git a/lib/MetaCPAN/Role/HasConfig.pm b/lib/MetaCPAN/Role/HasConfig.pm index f0c506f1c..ad1bae0d2 100644 --- a/lib/MetaCPAN/Role/HasConfig.pm +++ b/lib/MetaCPAN/Role/HasConfig.pm @@ -2,11 +2,10 @@ package MetaCPAN::Role::HasConfig; use Moose::Role; -use FindBin; -use Config::ZOMG (); -use MetaCPAN::Types qw(HashRef); +use MetaCPAN::Server::Config (); +use MetaCPAN::Types::TypeTiny qw( HashRef ); -# Done like this so can be required by a roles +# Done like this so can be required by a role sub config { return $_[0]->_config; } @@ -20,10 +19,7 @@ has _config => ( sub _build_config { my $self = shift; - return Config::ZOMG->new( - name => 'metacpan_server', - path => "$FindBin::RealBin/..", - )->load; + return MetaCPAN::Server::Config::config(); } 1; diff --git a/lib/MetaCPAN/Role/HasRogueDistributions.pm b/lib/MetaCPAN/Role/HasRogueDistributions.pm index ba8614d56..14a02facc 100644 --- a/lib/MetaCPAN/Role/HasRogueDistributions.pm +++ b/lib/MetaCPAN/Role/HasRogueDistributions.pm @@ -2,24 +2,22 @@ package MetaCPAN::Role::HasRogueDistributions; use Moose::Role; -use MetaCPAN::Types qw( ArrayRef ); +use MetaCPAN::Types::TypeTiny qw( ArrayRef ); has rogue_distributions => ( is => 'ro', isa => ArrayRef, default => sub { - [ - qw( - Bundle-Everything - kurila - perl-5.005_02+apache1.3.3+modperl - perlbench - perl_debug - perl_mlb - pod2texi - spodcxx - ) - ]; + [ qw( + Bundle-Everything + kurila + perl-5.005_02+apache1.3.3+modperl + perlbench + perl_debug + perl_mlb + pod2texi + spodcxx + ) ]; }, ); diff --git a/lib/MetaCPAN/Role/Logger.pm b/lib/MetaCPAN/Role/Logger.pm index f9b1bdaa0..95d80d662 100644 --- a/lib/MetaCPAN/Role/Logger.pm +++ b/lib/MetaCPAN/Role/Logger.pm @@ -2,10 +2,12 @@ package MetaCPAN::Role::Logger; use v5.10; use Moose::Role; -use MetaCPAN::Types qw(:all); + use Log::Contextual qw( set_logger ); use Log::Log4perl ':easy'; -use Path::Class (); +use MetaCPAN::Types::TypeTiny qw( Logger Str ); +use MooseX::Getopt (); ## no perlimports +use Path::Tiny qw( path ); has level => ( is => 'ro', @@ -45,8 +47,7 @@ sub set_logger_once { return; } -# XXX NOT A MOOSE BUILDER -# XXX This doesn't belong here. +# Not actually a Moose builder, so we should probably rename it. sub _build_logger { my ($config) = @_; my $log = Log::Log4perl->get_logger( $ARGV[0] @@ -58,7 +59,7 @@ sub _build_logger { if ( $c->{class} =~ /Appender::File$/ && $c->{filename} ) { # Create the log file's parent directory if necessary. - Path::Class::File->new( $c->{filename} )->parent->mkpath; + path( $c->{filename} )->parent->mkpath; } my $app = Log::Log4perl::Appender->new( $c->{class}, %$c ); diff --git a/lib/MetaCPAN/Role/Script.pm b/lib/MetaCPAN/Role/Script.pm index b8fc36c56..3ed00e450 100644 --- a/lib/MetaCPAN/Role/Script.pm +++ b/lib/MetaCPAN/Role/Script.pm @@ -2,32 +2,42 @@ package MetaCPAN::Role::Script; use Moose::Role; -use ElasticSearchX::Model::Document::Types qw(:all); -use FindBin; -use Git::Helpers qw( checkout_root ); -use Log::Contextual qw( :log :dlog ); -use MetaCPAN::Model; -use MetaCPAN::Types qw(:all); -use MetaCPAN::Queue (); -use Term::ANSIColor qw( colored ); -use IO::Interactive qw( is_interactive ); -use IO::Prompt; - -use Carp (); +use Carp (); +use IO::Prompt::Tiny qw( prompt ); +use Log::Contextual qw( :log :dlog ); +use MetaCPAN::Model (); +use MetaCPAN::Types::TypeTiny qw( AbsPath Bool ES HashRef Int Path Str ); +use MetaCPAN::Util qw( root_dir ); +use Mojo::Server (); +use Term::ANSIColor qw( colored ); +use MetaCPAN::Model::ESWrapper (); + +use MooseX::Getopt::OptionTypeMap (); +for my $type ( Path, AbsPath, ES ) { + MooseX::Getopt::OptionTypeMap->add_option_type_to_map( $type, '=s' ); +} with( 'MetaCPAN::Role::HasConfig', 'MetaCPAN::Role::Fastly', 'MetaCPAN::Role::Logger' ); has cpan => ( - is => 'ro', - isa => Dir, - lazy => 1, - builder => '_build_cpan', - coerce => 1, + is => 'ro', + isa => Path, + lazy => 1, + builder => '_build_cpan', + coerce => 1, documentation => 'Location of a local CPAN mirror, looks for $ENV{MINICPAN} and ~/CPAN', ); +has cpan_file_map => ( + is => 'ro', + isa => HashRef, + lazy => 1, + builder => '_build_cpan_file_map', + traits => ['NoGetopt'], +); + has die_on_error => ( is => 'ro', isa => Bool, @@ -35,6 +45,13 @@ has die_on_error => ( documentation => 'Die on errors instead of simply logging', ); +has exit_code => ( + isa => Int, + is => 'rw', + default => 0, + documentation => 'Exit Code to be returned on termination', +); + has ua => ( is => 'ro', lazy => 1, @@ -51,39 +68,34 @@ has es => ( is => 'ro', isa => ES, required => 1, + init_arg => 'elasticsearch_servers', coerce => 1, documentation => 'Elasticsearch http connection string', ); has model => ( - is => 'ro', - lazy => 1, - builder => '_build_model', - traits => ['NoGetopt'], -); - -has index => ( - reader => '_index', - is => 'ro', - isa => Str, - default => 'cpan', - documentation => - 'Index to use, defaults to "cpan" (when used: also export ES_SCRIPT_INDEX)', + is => 'ro', + init_arg => undef, + lazy => 1, + builder => '_build_model', + traits => ['NoGetopt'], ); has port => ( isa => Int, is => 'ro', - required => 1, + required => 0, + lazy => 1, + default => sub {5000}, documentation => 'Port for the proxy, defaults to 5000', ); has home => ( is => 'ro', - isa => Dir, + isa => Path, lazy => 1, coerce => 1, - default => sub { checkout_root() }, + default => sub { root_dir() }, ); has _minion => ( @@ -91,7 +103,7 @@ has _minion => ( isa => 'Minion', lazy => 1, handles => { _add_to_queue => 'enqueue', stats => 'stats', }, - default => sub { MetaCPAN::Queue->new->minion }, + default => sub { Mojo::Server->new->build_app('MetaCPAN::API')->minion }, ); has queue => ( @@ -101,40 +113,33 @@ has queue => ( documentation => 'add indexing jobs to the minion queue', ); -sub BUILDARGS { - my ( $self, @args ) = @_; - my %args = @args == 1 ? %{ $args[0] } : @args; - - if ( exists $args{'index'} ) { - die - "when setting --index, please export ES_SCRIPT_INDEX to the same value\n" - unless $ENV{'ES_SCRIPT_INDEX'} - and $args{'index'} eq $ENV{'ES_SCRIPT_INDEX'}; - } - - return \%args; -} - sub handle_error { - my ( $self, $error ) = @_; + my ( $self, $error, $die_always ) = @_; + + # Die if configured (for the test suite). + $die_always = $self->die_on_error unless defined $die_always; # Always log. log_fatal {$error}; - # Die if configured (for the test suite). - Carp::croak $error if $self->die_on_error; + $! = $self->exit_code if ( $self->exit_code != 0 ); + + Carp::croak $error if $die_always; } -sub index { - my $self = shift; - return $self->model->index( $self->_index ); +sub print_error { + my ( $self, $error ) = @_; + + log_error {$error}; } sub _build_model { my $self = shift; # es provided by ElasticSearchX::Model::Role - return MetaCPAN::Model->new( es => $self->es ); + + my $es = MetaCPAN::Model::ESWrapper->new( $self->es ); + return MetaCPAN::Model->new( es => $es ); } sub _build_ua { @@ -167,42 +172,129 @@ sub _build_cpan { } -sub remote { - shift->es->nodes->info->[0]; +sub _build_cpan_file_map { + my $self = shift; + my $ls = $self->cpan->child(qw(indices find-ls.gz)); + unless ( -e $ls ) { + die "File $ls does not exist"; + } + log_info {"Reading $ls"}; + my $cpan = {}; + open my $fh, "<:gzip", $ls; + while (<$fh>) { + my $path = ( split(/\s+/) )[-1]; + next unless ( $path =~ /^authors\/id\/\w+\/\w+\/(\w+)\/(.*)$/ ); + $cpan->{$1}{$2} = 1; + } + close $fh; + return $cpan; } sub run { } before run => sub { my $self = shift; - $self->set_logger_once; - - #Dlog_debug {"Connected to $_"} $self->remote; }; sub are_you_sure { my ( $self, $msg ) = @_; + my $iconfirmed = 0; - if (is_interactive) { - print colored( ['bold red'], "*** Warning ***: $msg" ), "\n"; - my $answer = prompt - 'Are you sure you want to do this (type "YES" to confirm) ? '; + if ( -t *STDOUT ) { + my $answer + = prompt colored( ['bold red'], "*** Warning ***: $msg" ) . "\n" + . 'Are you sure you want to do this (type "YES" to confirm) ? '; if ( $answer ne 'YES' ) { - print "bye.\n"; - exit 0; + log_error {"Confirmation incorrect: '$answer'"}; + print "Operation will be interruped!\n"; + + #Set System Error: 125 - ECANCELED - Operation canceled + $self->exit_code(125); + $self->handle_error( 'Operation canceled on User Request', 1 ); + } + else { + log_info {'Operation confirmed.'}; + print "alright then...\n"; + $iconfirmed = 1; } - print "alright then...\n"; } + else { + log_info {"*** Warning ***: $msg"}; + $iconfirmed = 1; + } + + return $iconfirmed; } +before perform_purges => sub { + my ($self) = @_; + if ( $self->has_surrogate_keys_to_purge ) { + log_info { + "CDN Purge: " . join ', ', $self->surrogate_keys_to_purge; + }; + } +}; + 1; __END__ =pod +=head1 NAME + +MetaCPAN::Role::Script - Base Role which is used by many command line applications + =head1 SYNOPSIS Roles which should be available to all modules. +=head1 OPTIONS + +This Role makes the command line application accept the following options + +=over 4 + +=item Option C<--await 15> + +This option will set the I. +After C seconds the Application will fail with an Exception and the Exit Code [112] +(C<112 - EHOSTDOWN - Host is down>) will be returned + + bin/metacpan --await 15 + +B If the I service does not become available +within C seconds it exits the Script with Exit Code C< 112 >. + +See L> + +=back + +=head1 METHODS + +This Role provides the following methods + +=over 4 + +=item C + +Requests the user to confirm the operation with "I< YES >" + +B When the operator input does not match "I< YES >" it will exit the Script +with Exit Code [125] (C<125 - ECANCELED - Operation canceled>). + +=item C + +Logs the string C with the log function as fatal error. +If C is not equel C< 0 > sets its value in C< $! >. +If the option C<--die_on_error> is enabled it throws an Exception with C. +If the parameter C is set it overrides the option C<--die_on_error>. + +=item C + +Logs the string C with the log function and displays it in red. +But it does not end the application. + +=back + =cut diff --git a/lib/MetaCPAN/Script/Author.pm b/lib/MetaCPAN/Script/Author.pm index 756fba4d8..00e59e372 100644 --- a/lib/MetaCPAN/Script/Author.pm +++ b/lib/MetaCPAN/Script/Author.pm @@ -6,15 +6,17 @@ use warnings; use Moose; with 'MooseX::Getopt', 'MetaCPAN::Role::Script'; -use DateTime::Format::ISO8601 (); -use Email::Valid (); -use Encode (); -use File::stat (); -use Cpanel::JSON::XS qw( decode_json ); -use Log::Contextual qw( :log ); -use MetaCPAN::Document::Author; -use URI (); -use XML::Simple qw(XMLin); +use Cpanel::JSON::XS qw( decode_json ); +use DateTime (); +use Email::Valid (); +use Encode (); +use Log::Contextual qw( :log :dlog ); +use MetaCPAN::Document::Author (); +use MetaCPAN::ESConfig qw( es_doc_path ); +use MetaCPAN::Types::TypeTiny qw( Str ); +use MetaCPAN::Util qw(diff_struct true false); +use URI (); +use XML::XPath (); =head1 SYNOPSIS @@ -29,166 +31,292 @@ has author_fh => ( default => sub { shift->cpan . '/authors/00whois.xml' }, ); +has pauseid => ( + is => 'ro', + isa => Str, +); + sub run { my $self = shift; - # check we are using a dedicated index, prompts if not - # my $index = $self->index->name; - # $self->are_you_sure( - # "Author script is run against a non-author specific index: $index !!!" - # ) unless $index =~ /author/; - $self->index_authors; - $self->index->refresh; + $self->es->indices->refresh; +} + +my @author_config_fields = qw( + name + asciiname + profile + blog + perlmongers + donation + email + website + city + region + country + location + extra +); + +my @cpan_fields = qw( + pauseid + name + email + website + asciiname + is_pause_custodial_account +); + +my @compare_fields = do { + my %seen; + sort grep !$seen{$_}++, @cpan_fields, @author_config_fields; +}; + +has whois_data => ( + is => 'ro', + traits => ['NoGetopt'], + lazy => 1, + builder => '_build_whois_data', +); + +sub _build_whois_data { + my $self = shift; + + my $whois_data = {}; + + my $xp = XML::XPath->new( filename => $self->author_fh ); + + for my $author ( $xp->find('/cpan-whois/cpanid')->get_nodelist ) { + my $data = { + map +( $_->getLocalName, $_->string_value ), + grep $_->isa('XML::XPath::Node::Element'), + $author->getChildNodes + }; + + my $pauseid = $data->{id}; + my $existing = $whois_data->{$pauseid}; + if ( !$existing + || $existing->{type} eq 'author' && $data->{type} eq 'list' ) + { + $whois_data->{$pauseid} = $data; + } + } + + return $whois_data; } sub index_authors { my $self = shift; - my $type = $self->index->type('author'); - my $authors = XMLin( $self->author_fh )->{cpanid}; - my $count = keys %$authors; - log_debug {"Counting author"}; - log_info {"Indexing $count authors"}; - - log_debug {"Getting last update dates"}; - my $dates - = $type->raw->filter( { exists => { field => 'updated' } } ) - ->size(10000)->all; - $dates = { - map { - $_->{pauseid} => - DateTime::Format::ISO8601->parse_datetime( $_->{updated} ) - } map { $_->{_source} } @{ $dates->{hits}->{hits} } - }; + my $authors = $self->whois_data; + + if ( $self->pauseid ) { + log_info {"Indexing 1 author"}; + $authors = { $self->pauseid => $authors->{ $self->pauseid } }; + } + else { + my $count = keys %$authors; + log_debug {"Counting author"}; + log_info {"Indexing $count authors"}; + } + + my @author_ids_to_purge; my $bulk = $self->es->bulk_helper( - index => $self->index->name, - type => 'author', + es_doc_path('author'), max_count => 250, timeout => '25m', ); - my @author_ids_to_purge; + my $scroll = $self->es->scroll_helper( + es_doc_path('author'), + size => 500, + body => { + query => { + $self->pauseid + ? ( + term => { + pauseid => $self->pauseid, + }, + ) + : ( match_all => {} ), + }, + _source => [@compare_fields], + sort => '_doc', + }, + ); - while ( my ( $pauseid, $data ) = each %$authors ) { - my ( $name, $email, $homepage, $asciiname ) - = ( @$data{qw(fullname email homepage asciiname)} ); - $name = undef if ( ref $name ); - $asciiname = q{} unless defined $asciiname; - $email = lc($pauseid) . '@cpan.org' - unless ( $email && Email::Valid->address($email) ); - log_debug { - Encode::encode_utf8( - sprintf( "Indexing %s: %s <%s>", $pauseid, $name, $email ) ); - }; - my $conf = $self->author_config( $pauseid, $dates ) || next; - my $put = { - pauseid => $pauseid, - name => $name, - asciiname => ref $asciiname ? undef : $asciiname, - email => $email, - website => $homepage, - map { $_ => $conf->{$_} } - grep { defined $conf->{$_} } keys %$conf - }; - $put->{website} = [ $put->{website} ] - unless ( ref $put->{website} eq 'ARRAY' ); - $put->{website} = [ + # update authors + while ( my $doc = $scroll->next ) { + my $pauseid = $doc->{_id}; + my $whois_data = delete $authors->{$pauseid} || next; + $self->update_author( $bulk, $pauseid, $whois_data, $doc->{_source} ); + } + + # new authors + for my $pauseid ( keys %$authors ) { + my $whois_data = delete $authors->{$pauseid} || next; + $self->update_author( $bulk, $pauseid, $whois_data ); + } + + $bulk->flush; + $self->es->indices->refresh; + + $self->perform_purges; + + log_info {"done"}; +} + +sub author_data_from_cpan { + my $self = shift; + my ( $pauseid, $whois_data ) = @_; + + my $author_config = $self->author_config($pauseid) || {}; + + my $data = { + pauseid => $pauseid, + name => $whois_data->{fullname}, + email => $whois_data->{email}, + website => $whois_data->{homepage}, + asciiname => $whois_data->{asciiname}, + %$author_config, + is_pause_custodial_account => ( + ( $whois_data->{fullname} // '' ) + =~ /\(PAUSE Custodial Account\)/ ? true : false + ), + }; + + undef $data->{name} + if ref $data->{name}; - # normalize www.homepage.com to http://www.homepage.com - map { $_->scheme ? $_->as_string : 'http://' . $_->as_string } - map { URI->new($_)->canonical } - grep {$_} @{ $put->{website} } - ]; + if ( !length $data->{name} ) { + $data->{name} = $pauseid; + } - $put->{is_pause_custodial_account} = 1 - if $name and $name =~ /\(PAUSE Custodial Account\)/; + $data->{asciiname} = q{} + if !defined $data->{asciiname}; - # Now check the format we have is actually correct - my @errors = MetaCPAN::Document::Author->validate($put); - next if scalar @errors; + $data->{email} = lc($pauseid) . '@cpan.org' + unless $data->{email} && Email::Valid->address( $data->{email} ); - my $author = $type->new_document($put); - $author->gravatar_url; # build gravatar_url + $data->{website} = [ - # Do not import lat / lon's in the wrong order, or just invalid - if ( my $loc = $author->{location} ) { + # normalize www.homepage.com to http://www.homepage.com + map +( $_->scheme ? '' : 'http://' ) . $_->as_string, + map URI->new($_)->canonical, + grep $_, + map +( ref eq 'ARRAY' ? @$_ : $_ ), + $data->{website} + ]; + # Do not import lat / lon's in the wrong order, or just invalid + if ( my $loc = $data->{location} ) { + if ( ref $loc ne 'ARRAY' || @$loc != 2 ) { + delete $data->{location}; + } + else { my $lat = $loc->[1]; my $lon = $loc->[0]; - if ( $lat > 90 or $lat < -90 ) { + if ( !defined $lat or $lat > 90 or $lat < -90 ) { # Invalid latitude - delete $author->{location}; + delete $data->{location}; } - elsif ( $lon > 180 or $lon < -180 ) { + elsif ( !defined $lon or $lon > 180 or $lon < -180 ) { # Invalid longitude - delete $author->{location}; + delete $data->{location}; } } + } + + return $data; +} - push @author_ids_to_purge, $put->{pauseid}; +sub update_author { + my $self = shift; + my ( $bulk, $pauseid, $whois_data, $current_data ) = @_; + + my $data = $self->author_data_from_cpan( $pauseid, $whois_data ); - # Only try put if this is a valid format - $bulk->update( - { - id => $pauseid, - doc => $put, - doc_as_upsert => 1, + log_debug { + Encode::encode_utf8( sprintf( + "Indexing %s: %s <%s>", + $pauseid, $data->{name}, $data->{email} + ) ); + }; + + # Now check the format we have is actually correct + if ( my @errors = MetaCPAN::Document::Author->validate($data) ) { + Dlog_error { + "Invalid data for $pauseid: $_" + } + \@errors; + return; + } + + if ( my $diff = diff_struct( $current_data, $data, 1 ) ) { + + # log a sampling of differences + if ( $self->has_surrogate_keys_to_purge % 10 == 9 ) { + Dlog_debug { + "Found difference in $pauseid: $_" } - ); + $diff; + } + } + else { + return; } - $bulk->flush; - $self->index->refresh; - $self->purge_author_key(@author_ids_to_purge); - $self->perform_purges; + $data->{updated} = DateTime->now( time_zone => 'UTC' )->iso8601; - log_info {"done"}; + $bulk->update( { + id => $pauseid, + doc => $data, + doc_as_upsert => true, + } ); + + $self->purge_author_key($pauseid); } sub author_config { - my ( $self, $pauseid, $dates ) = @_; - - my $fallback = $dates->{$pauseid} ? undef : {}; + my ( $self, $pauseid ) = @_; - my $dir = $self->cpan->subdir( 'authors', + my $dir = $self->cpan->child( 'authors', MetaCPAN::Util::author_dir($pauseid) ); - my @files; - opendir( my $dh, $dir ) || return $fallback; + return undef + unless $dir->is_dir; + + my $author_cpan_files = $self->cpan_file_map->{$pauseid} + or return undef; # Get the most recent version - my ($file) - = sort { $dir->file($b)->stat->mtime <=> $dir->file($a)->stat->mtime } - grep {m/author-.*?\.json/} readdir($dh); - return $fallback unless ($file); - $file = $dir->file($file); - return $fallback if !-e $file; + my ($file) = map $_->[0], sort { $b->[1] <=> $a->[1] } + map [ $_ => $_->stat->mtime ], + grep $author_cpan_files->{ $_->basename }, + $dir->children(qr/\Aauthor-.*\.json\z/); - my $mtime = DateTime->from_epoch( epoch => $file->stat->mtime ); - - if ( $dates->{$pauseid} && $dates->{$pauseid} > $mtime ) { - log_debug {"Skipping $pauseid (newer version in index)"}; - return undef; - } + return undef + unless $file; my $author; eval { - $author = decode_json( $file->slurp ); + $author = decode_json( $file->slurp_raw ); 1; } or do { log_warn {"$file is broken: $@"}; - return $fallback; + return undef; + }; + + return { + map { + my $value = $author->{$_}; + defined $value ? ( $_ => $value ) : () + } @author_config_fields }; - $author - = { map { $_ => $author->{$_} } - qw(name asciiname profile blog perlmongers donation email website city region country location extra) - }; - $author->{updated} = $mtime->iso8601; - return $author; } __PACKAGE__->meta->make_immutable; diff --git a/lib/MetaCPAN/Script/Backpan.pm b/lib/MetaCPAN/Script/Backpan.pm index a013214c4..935ed4a36 100644 --- a/lib/MetaCPAN/Script/Backpan.pm +++ b/lib/MetaCPAN/Script/Backpan.pm @@ -5,9 +5,9 @@ use warnings; use Moose; -use Log::Contextual qw( :log :dlog ); -use BackPAN::Index; -use MetaCPAN::Types qw( Bool HashRef Str ); +use Log::Contextual qw( :log :dlog ); +use MetaCPAN::ESConfig qw( es_doc_path ); +use MetaCPAN::Types::TypeTiny qw( Bool HashRef Str ); with 'MetaCPAN::Role::Script', 'MooseX::Getopt::Dashes'; @@ -31,13 +31,6 @@ has files_only => ( documentation => 'only update the "file" index', ); -has _cpan_files_list => ( - is => 'ro', - isa => HashRef, - lazy => 1, - builder => '_build_cpan_files_list', -); - has _release_status => ( is => 'ro', isa => HashRef, @@ -50,25 +43,6 @@ has _bulk => ( default => sub { +{} }, ); -sub _build_cpan_files_list { - my $self = shift; - my $ls = $self->cpan->file(qw(indices find-ls.gz)); - unless ( -e $ls ) { - log_error {"File $ls does not exist"}; - exit; - } - log_info {"Reading $ls"}; - my $cpan = {}; - open my $fh, "<:gzip", $ls; - while (<$fh>) { - my $path = ( split(/\s+/) )[-1]; - next unless ( $path =~ /^authors\/id\/\w+\/\w+\/(\w+)\/(.*)$/ ); - $cpan->{$1}{$2} = 1; - } - close $fh; - return $cpan; -} - sub run { my $self = shift; @@ -89,25 +63,26 @@ sub build_release_status_map { log_info {"find_releases"}; my $scroll = $self->es->scroll_helper( - size => 500, scroll => '5m', - index => $self->index->name, - type => 'release', - fields => [ 'author', 'archive', 'name' ], - body => $self->_get_release_query, + es_doc_path('release'), + body => { + %{ $self->_get_release_query }, + size => 500, + _source => [ 'author', 'archive', 'name' ], + }, ); while ( my $release = $scroll->next ) { - my $author = $release->{fields}{author}[0]; - my $archive = $release->{fields}{archive}[0]; - my $name = $release->{fields}{name}[0]; + my $author = $release->{_source}{author}; + my $archive = $release->{_source}{archive}; + my $name = $release->{_source}{name}; next unless $name; # bypass some broken releases $self->_release_status->{$author}{$name} = [ ( $self->undo - or exists $self->_cpan_files_list->{$author}{$archive} - ) + or exists $self->cpan_file_map->{$author}{$archive} + ) ? 'cpan' : 'backpan', $release->{_id} @@ -121,7 +96,8 @@ sub _get_release_query { unless ( $self->undo ) { return +{ query => { - not => { term => { status => 'backpan' } } + bool => + { must_not => [ { term => { status => 'backpan' } } ] } } }; } @@ -150,8 +126,7 @@ sub update_releases { log_info {"update_releases"}; $self->_bulk->{release} ||= $self->es->bulk_helper( - index => $self->index->name, - type => 'release', + es_doc_path('release'), max_count => 250, timeout => '5m', ); @@ -160,14 +135,12 @@ sub update_releases { # value = [ status, _id ] for ( values %{ $self->_release_status->{$author} } ) { - $self->_bulk->{release}->update( - { - id => $_->[1], - doc => { - status => $_->[0], - } + $self->_bulk->{release}->update( { + id => $_->[1], + doc => { + status => $_->[0], } - ); + } ); } } } @@ -191,12 +164,9 @@ sub update_files_author { log_info { "update_files: " . $author }; my $scroll = $self->es->scroll_helper( - size => 500, scroll => '5m', - index => $self->index->name, - type => 'file', - fields => ['release'], - body => { + es_doc_path('file'), + body => { query => { bool => { must => [ @@ -204,28 +174,27 @@ sub update_files_author { { terms => { release => $author_releases } } ] } - } + }, + size => 500, + _source => ['release'], }, ); $self->_bulk->{file} ||= $self->es->bulk_helper( - index => $self->index->name, - type => 'file', + es_doc_path('file'), max_count => 250, timeout => '5m', ); my $bulk = $self->_bulk->{file}; while ( my $file = $scroll->next ) { - my $release = $file->{fields}{release}[0]; - $bulk->update( - { - id => $file->{_id}, - doc => { - status => $self->_release_status->{$author}{$release}[0] - } + my $release = $file->{_source}{release}; + $bulk->update( { + id => $file->{_id}, + doc => { + status => $self->_release_status->{$author}{$release}[0] } - ); + } ); } } diff --git a/lib/MetaCPAN/Script/Backup.pm b/lib/MetaCPAN/Script/Backup.pm index 446c6da0c..2ced44ea0 100644 --- a/lib/MetaCPAN/Script/Backup.pm +++ b/lib/MetaCPAN/Script/Backup.pm @@ -4,25 +4,36 @@ use strict; use warnings; use feature qw( state ); -use Data::Printer; -use DateTime; -use IO::Zlib (); -use Cpanel::JSON::XS; -use Log::Contextual qw( :log :dlog ); -use MetaCPAN::Types qw( Bool Int Str File ); +use Cpanel::JSON::XS qw( decode_json encode_json ); +use DateTime (); +use IO::Zlib (); +use Log::Contextual qw( :log :dlog ); +use MetaCPAN::Types::TypeTiny qw( Bool CommaSepOption Int Path Str ); +use MetaCPAN::Util qw( true false ); +use MetaCPAN::ESConfig qw( es_config ); use Moose; -use Try::Tiny; +use Try::Tiny qw( catch try ); with 'MetaCPAN::Role::Script', 'MooseX::Getopt::Dashes'; has batch_size => ( - is => 'ro', - isa => Int, - default => 100, + is => 'ro', + isa => Int, + default => 100, documentation => 'Number of documents to restore in one batch, defaults to 100', ); +has index => ( + reader => '_index', + is => 'ro', + isa => CommaSepOption, + coerce => 1, + default => sub { es_config->all_indexes }, + documentation => 'ES indexes to backup, defaults to "' + . join( ', ', @{ es_config->all_indexes } ) . '"', +); + has type => ( is => 'ro', isa => Str, @@ -50,7 +61,7 @@ has dry_run => ( has restore => ( is => 'ro', - isa => File, + isa => Path, coerce => 1, documentation => 'Restore a backup', ); @@ -62,32 +73,38 @@ sub run { return $self->run_restore if $self->restore; my $es = $self->es; - $self->index->refresh; - - my $filename = join( '-', - DateTime->now->strftime('%F'), - grep {defined} $self->index->name, - $self->type ); - - my $file = $self->home->subdir(qw(var backup))->file("$filename.json.gz"); - $file->dir->mkpath unless ( -e $file->dir ); - my $fh = IO::Zlib->new( "$file", 'wb4' ); - - my $scroll = $es->scroll_helper( - index => $self->index->name, - $self->type ? ( type => $self->type ) : (), - size => $self->size, - search_type => 'scan', - fields => [qw(_parent _source)], - scroll => '1m', - ); - log_info { 'Backing up ', $scroll->total, ' documents' }; + for my $index ( @{ $self->_index } ) { + + $self->es->indices->refresh( index => $index ); + + my $filename = join( '-', + DateTime->now->strftime('%F'), + grep {defined} $index, + $self->type ); - while ( my $result = $scroll->next ) { - print $fh encode_json($result), $/; + my $file = $self->home->child( qw(var backup), "$filename.json.gz" ); + $file->parent->mkpath unless ( -e $file->parent ); + my $fh = IO::Zlib->new( "$file", 'wb4' ); + + my $scroll = $es->scroll_helper( + index => $index, + $self->type ? ( type => $self->type ) : (), + scroll => '1m', + body => { + _source => true, + size => $self->size, + sort => '_doc', + }, + ); + + log_info { 'Backing up ', $scroll->total, ' documents' }; + + while ( my $result = $scroll->next ) { + print $fh encode_json($result), $/; + } + close $fh; } - close $fh; log_info {'done'}; } @@ -95,7 +112,7 @@ sub run_restore { my $self = shift; return log_fatal { $self->restore, q{ doesn't exist} } - unless ( -e $self->restore ); + unless ( -e $self->restore ); log_info { 'Restoring from ', $self->restore }; my @bulk; @@ -112,7 +129,7 @@ sub run_restore { try { $raw = decode_json($line) } catch { - log_warn {"cannot decode JSON: $line --- $_"}; + log_warn {"cannot decode JSON: $line --- $&"}; }; # Create our bulk_helper if we need, @@ -129,7 +146,7 @@ sub run_restore { # Fetch relevant bulk helper my $bulk = $bulk_store{$bulk_key}; - my $parent = $raw->{fields}->{_parent}; + my $parent = $raw->{_parent}; if ( $raw->{_type} eq 'author' ) { @@ -159,23 +176,19 @@ sub run_restore { ); if ($exists) { - $bulk->update( - { - id => $raw->{_id}, - doc => $raw->{_source}, - doc_as_upsert => 1, - } - ); + $bulk->update( { + id => $raw->{_id}, + doc => $raw->{_source}, + doc_as_upsert => true, + } ); } else { - $bulk->create( - { - id => $raw->{_id}, - $parent ? ( parent => $parent ) : (), - source => $raw->{_source}, - } - ); + $bulk->create( { + id => $raw->{_id}, + $parent ? ( parent => $parent ) : (), + source => $raw->{_source}, + } ); } } @@ -191,8 +204,8 @@ sub run_purge { my $self = shift; my $now = DateTime->now; - $self->home->subdir(qw(var backup))->recurse( - callback => sub { + $self->home->child(qw(var backup))->visit( + sub { my $file = shift; return if ( $file->is_dir ); @@ -206,12 +219,13 @@ sub run_purge { if ( $mtime->clone->truncate( to => 'week' ) != $mtime->clone->truncate( to => 'day' ) ) { - log_info {"Removing old backup $file"}; + log_info {"Removing old backup $file"}; return log_info {'Not (dry run)'} if ( $self->dry_run ); $file->remove; } - } + }, + { recurse => 1 } ); } diff --git a/lib/MetaCPAN/Script/CPANTesters.pm b/lib/MetaCPAN/Script/CPANTesters.pm index f49120dc5..ebf630ae8 100644 --- a/lib/MetaCPAN/Script/CPANTesters.pm +++ b/lib/MetaCPAN/Script/CPANTesters.pm @@ -1,17 +1,16 @@ package MetaCPAN::Script::CPANTesters; -use strict; -use warnings; - -use DBI (); -use File::Spec::Functions qw(catfile); -use File::Temp qw(tempdir); -use File::stat qw(stat); -use IO::Uncompress::Bunzip2 qw(bunzip2); -use Log::Contextual qw( :log :dlog ); -use MetaCPAN::Types qw( Bool File Uri ); use Moose; +use DBI (); +use ElasticSearchX::Model::Document::Types qw( ESBulk ); +use File::stat qw( stat ); +use IO::Uncompress::Bunzip2 qw( bunzip2 ); +use Log::Contextual qw( :log :dlog ); +use MetaCPAN::ESConfig qw( es_doc_path ); +use MetaCPAN::Types::TypeTiny qw( Bool Path Uri ); +use MetaCPAN::Util qw( true false ); + with 'MetaCPAN::Role::Script', 'MooseX::Getopt::Dashes'; has db => ( @@ -31,9 +30,9 @@ has force_refresh => ( # XXX move path to config has mirror_file => ( is => 'ro', - isa => File, + isa => Path, default => sub { - shift->home->file( 'var', ( $ENV{HARNESS_ACTIVE} ? 't' : () ), + shift->home->child( 'var', ( $ENV{HARNESS_ACTIVE} ? 't' : () ), 'tmp', 'cpantesters.db' ); }, coerce => 1, @@ -46,13 +45,10 @@ has skip_download => ( has _bulk => ( is => 'ro', - isa => 'Search::Elasticsearch::Bulk', + isa => ESBulk, lazy => 1, default => sub { - $_[0]->es->bulk_helper( - index => $_[0]->index->name, - type => 'release' - ); + $_[0]->es->bulk_helper( es_doc_path('release') ); }, ); @@ -60,14 +56,14 @@ has _bulk => ( sub _build_db { my $self = shift; return $ENV{HARNESS_ACTIVE} - ? $self->home->file('t/var/cpantesters-release-fake.db.bz2') + ? $self->home->child('t/var/cpantesters-release-fake.db.bz2') : 'http://devel.cpantesters.org/release/release.db.bz2'; } sub run { my $self = shift; $self->index_reports; - $self->index->refresh; + $self->es->indices->refresh; } sub index_reports { @@ -88,10 +84,11 @@ sub index_reports { bunzip2 "$db.bz2" => "$db", AutoClose => 1 if -e "$db.bz2"; my $scroll = $es->scroll_helper( - index => $self->index->name, - search_type => 'scan', - size => '500', - type => 'release', + es_doc_path('release'), + size => '500', + body => { + sort => '_doc', + }, ); my %releases; @@ -104,8 +101,8 @@ sub index_reports { $version =~ s{\Av}{} if $version; $releases{ - join( '-', grep {defined} $data->{distribution}, $version ) - } = $data; + join( '-', grep {defined} $data->{distribution}, $version ) } + = $data; } log_info { 'Opening database file at ' . $db }; @@ -130,7 +127,7 @@ sub index_reports { $version =~ s{\+}{}g; $version =~ s{\A-}{}; - my $release = join( '-', $row_from_db->{dist}, $version ); + my $release = join( '-', $row_from_db->{dist}, $version ); my $release_doc = $releases{$release}; # there's a cpantesters dist we haven't indexed @@ -156,13 +153,11 @@ sub index_reports { next unless ($insert_ok); my %tests = map { $_ => $row_from_db->{$_} } qw(fail pass na unknown); - $self->_bulk->update( - { - doc => { tests => \%tests }, - doc_as_upsert => 1, - id => $release_doc->{id}, - } - ); + $self->_bulk->update( { + doc => { tests => \%tests }, + doc_as_upsert => true, + id => $release_doc->{id}, + } ); } $self->_bulk->flush; log_info {'done'}; diff --git a/lib/MetaCPAN/Script/CPANTestersAPI.pm b/lib/MetaCPAN/Script/CPANTestersAPI.pm index a2ee0b094..0c9e6ca50 100644 --- a/lib/MetaCPAN/Script/CPANTestersAPI.pm +++ b/lib/MetaCPAN/Script/CPANTestersAPI.pm @@ -3,9 +3,12 @@ package MetaCPAN::Script::CPANTestersAPI; use strict; use warnings; -use Log::Contextual qw( :log :dlog ); -use Cpanel::JSON::XS qw( decode_json ); -use MetaCPAN::Types qw( Uri ); +use Cpanel::JSON::XS qw( decode_json ); +use ElasticSearchX::Model::Document::Types qw( ESBulk ); +use Log::Contextual qw( :log :dlog ); +use MetaCPAN::ESConfig qw( es_doc_path ); +use MetaCPAN::Types::TypeTiny qw( Uri ); +use MetaCPAN::Util qw( true false ); use Moose; with 'MetaCPAN::Role::Script', 'MooseX::Getopt::Dashes'; @@ -22,18 +25,17 @@ sub _build_url { my ($self) = @_; $ENV{HARNESS_ACTIVE} ? 'file:' - . $self->home->file('t/var/cpantesters-release-api-fake.json') + . $self->home->child('t/var/cpantesters-release-api-fake.json') : 'http://api-3.cpantesters.org/v3/release'; } has _bulk => ( is => 'ro', - isa => 'Search::Elasticsearch::Bulk', + isa => ESBulk, lazy => 1, default => sub { $_[0]->es->bulk_helper( - index => $_[0]->index->name, - type => 'release', + es_doc_path('release'), max_count => 250, timeout => '30m', ); @@ -43,7 +45,7 @@ has _bulk => ( sub run { my $self = shift; $self->index_reports; - $self->index->refresh; + $self->es->indices->refresh; } sub index_reports { @@ -61,10 +63,11 @@ sub index_reports { my $data = decode_json $json; my $scroll = $es->scroll_helper( - index => $self->index->name, - search_type => 'scan', - size => '500', - type => 'release', + es_doc_path('release'), + size => '500', + body => { + sort => '_doc', + }, ); # Create a cache of all releases (dist + version combos) @@ -78,8 +81,8 @@ sub index_reports { $version =~ s{\Av}{} if $version; $releases{ - join( '-', grep {defined} $data->{distribution}, $version ) - } = $data; + join( '-', grep {defined} $data->{distribution}, $version ) } + = $data; } for my $row (@$data) { @@ -95,7 +98,7 @@ sub index_reports { $version =~ s{\+}{}g; $version =~ s{\A-}{}; - my $release = join( '-', $row->{dist}, $version ); + my $release = join( '-', $row->{dist}, $version ); my $release_doc = $releases{$release}; # there's a cpantesters dist we haven't indexed @@ -122,13 +125,11 @@ sub index_reports { next unless $insert_ok; my %tests = map { $_ => $row->{$_} } qw(fail pass na unknown); - $self->_bulk->update( - { - doc => { tests => \%tests }, - doc_as_upsert => 1, - id => $release_doc->{id}, - } - ); + $self->_bulk->update( { + doc => { tests => \%tests }, + doc_as_upsert => true, + id => $release_doc->{id}, + } ); } $self->_bulk->flush; diff --git a/lib/MetaCPAN/Script/CVE.pm b/lib/MetaCPAN/Script/CVE.pm new file mode 100644 index 000000000..2c22c58f0 --- /dev/null +++ b/lib/MetaCPAN/Script/CVE.pm @@ -0,0 +1,261 @@ +package MetaCPAN::Script::CVE; + +use Moose; +use namespace::autoclean; + +use Cpanel::JSON::XS qw( decode_json ); +use Log::Contextual qw( :log :dlog ); +use MetaCPAN::ESConfig qw( es_doc_path ); +use MetaCPAN::Types::TypeTiny qw( Bool Str Uri ); +use MetaCPAN::Util qw( hit_total numify_version true false ); +use Path::Tiny qw( path ); +use Ref::Util qw( is_arrayref ); + +with 'MetaCPAN::Role::Script', 'MooseX::Getopt'; + +has cve_url => ( + is => 'ro', + isa => Uri, + coerce => 1, + default => 'https://cpan-security.github.io/cpansa-feed/cpansa.json', +); + +has cve_dev_url => ( + is => 'ro', + isa => Uri, + coerce => 1, + default => 'https://cpan-security.github.io/cpansa-feed/cpansa_dev.json', +); + +has test => ( + is => 'ro', + isa => Bool, + default => 0, + documentation => 'Test mode (pulls smaller development data set)', +); + +has json_file => ( + is => 'ro', + isa => Str, + default => 0, + documentation => + 'Path to JSON file to be read instead of URL (for testing)', +); + +my %range_ops = qw(< lt <= lte > gt >= gte); + +my %valid_keys = map { $_ => 1 } qw< + affected_versions + cpansa_id + cves + description + distribution + references + releases + reported + severity + versions +>; + +sub run { + my $self = shift; + my $data = $self->retrieve_cve_data; + $self->index_cve_data($data); + return 1; +} + +sub index_cve_data { + my ( $self, $data ) = @_; + + my $bulk = $self->es->bulk_helper( es_doc_path('cve') ); + + log_info {'Updating the cve index'}; + + for my $dist ( sort keys %{$data} ) { + for my $cpansa ( @{ $data->{$dist} } ) { + if ( !$cpansa->{cpansa_id} ) { + log_warn { sprintf( "Dist '%s' missing cpansa_id", $dist ) }; + next; + } + + my @matches; + + if ( !is_arrayref( $cpansa->{affected_versions} ) ) { + log_debug { + sprintf( "Dist '%s' has non-array affected_versions %s", + $dist, $cpansa->{affected_versions} ) + }; + + # Temp - remove after fixed upstream + # (affected_versions will always be an array) + $cpansa->{affected_versions} + = [ $cpansa->{affected_versions} ]; + + # next; + } + + my @filters; + my @afv_filters; + + for my $afv ( @{ $cpansa->{affected_versions} } ) { + + # Temp - remove after fixed upstream + # (affected_versions will always be an array) + next unless $afv; + + my @rules = map {s/\(.*?\)//gr} split /,/, $afv; + + my @rule_filters; + + for my $rule (@rules) { + my ( $op, $num ) = $rule =~ /^([=<>]*)(.*)$/; + $num = numify_version($num); + + if ( !$op ) { + log_debug { + sprintf( + "Dist '%s' - affected_versions has no operator", + $dist ) + }; + + # Temp - remove after fixed upstream + # (affected_versions will always have an operator) + $op ||= '='; + } + + if ( exists $range_ops{$op} ) { + push @rule_filters, + +{ + range => { + version_numified => + { $range_ops{$op} => $num } + } + }; + } + else { + push @rule_filters, + +{ term => { version_numified => $num } }; + } + } + + # multiple rules (csv) in affected_version line -> AND + if ( @rule_filters == 1 ) { + push @afv_filters, @rule_filters; + } + elsif ( @rule_filters > 1 ) { + push @afv_filters, { bool => { must => \@rule_filters } }; + } + } + + # multiple elements in affected_version -> OR + if ( @afv_filters == 1 ) { + push @filters, @afv_filters; + } + elsif ( @afv_filters > 1 ) { + push @filters, { bool => { should => \@afv_filters } }; + } + + if (@filters) { + my $query = {}; + + my $releases = $self->es->search( + es_doc_path('release'), + body => { + query => { + bool => { + must => [ + { term => { distribution => $dist } }, + @filters, + ] + } + }, + _source => [ "version", "name", "author", ], + size => 2000, + }, + ); + + if ( hit_total($releases) ) { + ## no critic (ControlStructures::ProhibitMutatingListFunctions) + @matches = map { $_->[0] } + sort { $a->[1] <=> $b->[1] } + map { + [ + $_->{_source}, + numify_version( $_->{_source}{version} ) + ]; + } @{ $releases->{hits}{hits} }; + } + else { + log_debug { + sprintf( "Dist '%s' doesn't have matches.", $dist ) + }; + next; + } + } + + my $doc_data = { + distribution => $dist, + cpansa_id => $cpansa->{cpansa_id}, + affected_versions => $cpansa->{affected_versions}, + cves => $cpansa->{cves}, + description => $cpansa->{description}, + references => $cpansa->{references}, + reported => $cpansa->{reported}, + severity => $cpansa->{severity}, + versions => [ map { $_->{version} } @matches ], + releases => [ map {"$_->{author}/$_->{name}"} @matches ], + }; + + for my $k ( keys %{$doc_data} ) { + delete $doc_data->{$k} unless exists $valid_keys{$k}; + } + + $bulk->update( { + id => $cpansa->{cpansa_id}, + doc => $doc_data, + doc_as_upsert => true, + } ); + } + } + + $bulk->flush; +} + +sub retrieve_cve_data { + my $self = shift; + + return decode_json( path( $self->json_file )->slurp ) if $self->json_file; + + my $url = $self->test ? $self->cve_dev_url : $self->cve_url; + + log_info { 'Fetching data from ', $url }; + my $resp = $self->ua->get($url); + + $self->handle_error( $resp->status_line ) unless $resp->is_success; + + # clean up headers if .json.gz is served as gzip type + # rather than json encoded with gzip + if ( $resp->header('Content-Type') eq 'application/x-gzip' ) { + $resp->header( 'Content-Type' => 'application/json' ); + $resp->header( 'Content-Encoding' => 'gzip' ); + } + + return decode_json( $resp->decoded_content ); +} + +__PACKAGE__->meta->make_immutable; + +1; + +=pod + +=head1 SYNOPSIS + + # bin/metacpan cve [--test] [json_file] + +=head1 DESCRIPTION + +Retrieves the CPAN CVE data from its source and +updates our ES information. + +=cut diff --git a/lib/MetaCPAN/Script/Check.pm b/lib/MetaCPAN/Script/Check.pm index f17991f19..81b115ca0 100644 --- a/lib/MetaCPAN/Script/Check.pm +++ b/lib/MetaCPAN/Script/Check.pm @@ -3,10 +3,12 @@ package MetaCPAN::Script::Check; use strict; use warnings; -use File::Spec::Functions qw(catfile); -use Log::Contextual qw( :log ); +use File::Spec::Functions qw( catfile ); +use Log::Contextual qw( :log ); use Moose; -use MetaCPAN::Types qw( Bool Int Str ); +use MetaCPAN::ESConfig qw( es_doc_path ); +use MetaCPAN::Types::TypeTiny qw( Bool Int Str ); +use MetaCPAN::Util qw( true false ); with 'MetaCPAN::Role::Script', 'MooseX::Getopt'; @@ -25,9 +27,9 @@ has module => ( ); has max_errors => ( - is => 'ro', - isa => Int, - default => 0, + is => 'ro', + isa => Int, + default => 0, documentation => 'the maximum number of errors to encounter before stopping', ); @@ -84,19 +86,27 @@ sub check_modules { # look up this module in ElasticSearch and see what we have on it my $results = $es->search( - index => $self->index->name, - type => 'file', - size => 100, # shouldn't get more than this - fields => [ - qw(name release author distribution version authorized indexed maturity date) - ], - query => { match_all => {} }, - filter => { - and => [ - { term => { 'module.name' => $pkg } }, - { term => { 'authorized' => 'true' } }, - { term => { 'maturity' => 'released' } }, - ], + es_doc_path('file'), + query => { + bool => { + must => [ + { term => { 'module.name' => $pkg } }, + { term => { 'authorized' => true } }, + { term => { 'maturity' => 'released' } }, + ], + }, + size => 100, # shouldn't get more than this + _source => [ qw( + name + release + author + distribution + version + authorized + indexed + maturity + date + ) ], }, ); my @files = @{ $results->{hits}->{hits} }; @@ -104,21 +114,22 @@ sub check_modules { # now find the first latest releases for these files foreach my $file (@files) { my $release_results = $es->search( - index => $self->index->name, - type => 'release', - size => 1, - fields => - [qw(name status authorized version id date)], - query => { match_all => {} }, - filter => { - and => [ - { - term => { - 'name' => $file->{fields}->{release} - } - }, - { term => { 'status' => 'latest' } }, - ], + es_doc_path('release'), + query => { + bool => { + must => [ + { + term => { + name => + $file->{_source}->{release} + } + }, + { term => { status => 'latest' } }, + ], + }, + size => 1, + _source => + [qw(name status authorized version id date)], }, ); @@ -133,21 +144,22 @@ sub check_modules { if ( !@releases ) { foreach my $file (@files) { my $release_results = $es->search( - index => $self->index->name, - type => 'release', - size => 1, - fields => - [qw(name status authorized version id date)], - query => { match_all => {} }, - filter => { - and => [ - { - term => { - 'name' => - $file->{fields}->{release} - } - } - ] + es_doc_path('release'), + query => { + bool => { + must => [ + { + term => { + name => $file->{_source} + ->{release} + } + }, + ], + }, + size => 1, + _source => [ + qw(name status authorized version id date) + ], }, ); @@ -159,10 +171,10 @@ sub check_modules { # if we found the releases tell them about it if (@releases) { if ( @releases == 1 - && $releases[0]->{fields}->{status} eq 'latest' ) + && $releases[0]->{_source}->{status} eq 'latest' ) { log_info { - "Found latest release $releases[0]->{fields}->{name} for $pkg"; + "Found latest release $releases[0]->{_source}->{name} for $pkg"; } unless $self->errors_only; } @@ -170,16 +182,16 @@ sub check_modules { log_error {"Could not find latest release for $pkg"}; foreach my $rel (@releases) { log_warn { - " Found release $rel->{fields}->{name}"; + " Found release $rel->{_source}->{name}"; }; log_warn { - " STATUS : $rel->{fields}->{status}"; + " STATUS : $rel->{_source}->{status}"; }; log_warn { - " AUTORIZED : $rel->{fields}->{authorized}"; + " AUTORIZED : $rel->{_source}->{authorized}"; }; log_warn { - " DATE : $rel->{fields}->{date}"; + " DATE : $rel->{_source}->{date}"; }; } $self->_set_error_count( $self->error_count + 1 ); @@ -190,17 +202,17 @@ sub check_modules { "Module $pkg doesn't have any releases in ElasticSearch!"; }; foreach my $file (@files) { - log_warn {" Found file $file->{fields}->{name}"}; + log_warn {" Found file $file->{_source}->{name}"}; log_warn { - " RELEASE : $file->{fields}->{release}"; + " RELEASE : $file->{_source}->{release}"; }; log_warn { - " AUTHOR : $file->{fields}->{author}"; + " AUTHOR : $file->{_source}->{author}"; }; log_warn { - " AUTHORIZED : $file->{fields}->{authorized}"; + " AUTHORIZED : $file->{_source}->{authorized}"; }; - log_warn {" DATE : $file->{fields}->{date}"}; + log_warn {" DATE : $file->{_source}->{date}"}; } $self->_set_error_count( $self->error_count + 1 ); } diff --git a/lib/MetaCPAN/Script/Checksum.pm b/lib/MetaCPAN/Script/Checksum.pm new file mode 100644 index 000000000..57d1b68af --- /dev/null +++ b/lib/MetaCPAN/Script/Checksum.pm @@ -0,0 +1,137 @@ +package MetaCPAN::Script::Checksum; + +use Moose; + +use Log::Contextual qw( :log ); +use MetaCPAN::ESConfig qw( es_doc_path ); +use MetaCPAN::Types::TypeTiny qw( Bool Int ); +use MetaCPAN::Util qw( true false ); + +use Digest::file qw( digest_file_hex ); + +with 'MooseX::Getopt', 'MetaCPAN::Role::Script'; + +=head1 SYNOPSIS + +Fill checksums for releases + +=cut + +has limit => ( + is => 'ro', + isa => Int, + default => 1000, +); + +has dry_run => ( + is => 'ro', + isa => Bool, + default => 1, +); + +sub run { + my $self = shift; + + my $bulk; + if ( !$self->dry_run ) { + $bulk = $self->es->bulk_helper( es_doc_path('release') ); + } + else { + log_warn {"--- DRY-RUN ---"}; + } + + log_info {"Searching for releases missing checksums"}; + + my $scroll = $self->es->scroll_helper( + es_doc_path('release'), + scroll => '10m', + body => { + query => { + bool => { + must_not => [ + { + exists => { + field => "checksum_md5" + } + }, + ], + }, + }, + _source => [qw( name download_url )], + }, + ); + + log_warn { "Found " . $scroll->total . " releases" }; + log_warn { "Limit is " . $self->limit }; + + my $count = 0; + + while ( my $p = $scroll->next ) { + if ( $self->limit >= 0 and $count++ >= $self->limit ) { + log_info {"Max number of changes reached."}; + last; + } + + log_info { "Adding checksums for " . $p->{_source}{name} }; + + if ( my $download_url = $p->{_source}{download_url} ) { + my $file + = $self->cpan . "/authors" . $download_url =~ s/^.*authors//r; + my $checksum_md5 = digest_file_hex( $file, 'MD5' ); + my $checksum_sha256 = digest_file_hex( $file, 'SHA-256' ); + + if ( $self->dry_run ) { + log_info { "--- MD5: " . $checksum_md5 } + log_info { "--- SHA256: " . $checksum_sha256 } + } + else { + $bulk->update( { + id => $p->{_id}, + doc => { + checksum_md5 => $checksum_md5, + checksum_sha256 => $checksum_sha256 + }, + doc_as_upsert => true, + } ); + } + } + else { + log_info { + $p->{_source}{name} . " is missing a download_url" + }; + } + } + + if ( !$self->dry_run ) { + $bulk->flush; + } + + log_info {'Finished adding checksums'}; +} + +__PACKAGE__->meta->make_immutable; +1; + +=pod + +=head1 SYNOPSIS + + # bin/metacpan checksum --[no-]dry_run --limit X + +=head1 DESCRIPTION + +Backfill checksums for releases + +=head2 dry_run + +Don't update - just show what would have been updated (default) + +=head2 no-dry_run + +Update records + +=head2 limit + +Max number of records to update. default=1000, for unlimited set to -1 + +=cut diff --git a/lib/MetaCPAN/Script/Contributor.pm b/lib/MetaCPAN/Script/Contributor.pm index 3eab4e61f..230216060 100644 --- a/lib/MetaCPAN/Script/Contributor.pm +++ b/lib/MetaCPAN/Script/Contributor.pm @@ -6,9 +6,8 @@ use warnings; use Moose; use Log::Contextual qw( :log ); -use Ref::Util qw( is_arrayref ); -use MetaCPAN::Types qw( Bool HashRef Int Str ); +use MetaCPAN::Types::TypeTiny qw( Bool HashRef Int Str ); with 'MetaCPAN::Role::Script', 'MooseX::Getopt', 'MetaCPAN::Script::Role::Contributor'; @@ -21,15 +20,15 @@ has all => ( ); has distribution => ( - is => 'ro', - isa => Str, + is => 'ro', + isa => Str, documentation => 'update contributors for all releases matching distribution name', ); has release => ( - is => 'ro', - isa => Str, + is => 'ro', + isa => Str, documentation => 'update contributors for a single release (format: author/release_name)', ); @@ -79,31 +78,7 @@ sub run { ? { range => { date => { gte => sprintf( 'now-%dd', $self->age ) } } } : return; - my $timeout = $self->all ? '720m' : '5m'; - - my $scroll = $self->es->scroll_helper( - size => 500, - scroll => $timeout, - index => $self->index->name, - type => 'release', - body => { query => $query }, - fields => [qw( author distribution name )], - ); - - my @data; - - while ( my $r = $scroll->next ) { - my $contrib_data = $self->get_cpan_author_contributors( - $r->{fields}{author}[0], - $r->{fields}{name}[0], - $r->{fields}{distribution}[0], - ); - next unless is_arrayref($contrib_data); - log_debug { 'adding release ' . $r->{fields}{name}[0] }; - push @data => @{$contrib_data}; - } - - $self->update_release_contirbutors( \@data, $timeout ); + $self->update_contributors($query); } __PACKAGE__->meta->make_immutable; diff --git a/lib/MetaCPAN/Script/Cover.pm b/lib/MetaCPAN/Script/Cover.pm index 6b51441ac..e14f51d0c 100644 --- a/lib/MetaCPAN/Script/Cover.pm +++ b/lib/MetaCPAN/Script/Cover.pm @@ -3,9 +3,12 @@ package MetaCPAN::Script::Cover; use Moose; use namespace::autoclean; -use Cpanel::JSON::XS qw( decode_json ); -use Log::Contextual qw( :log :dlog ); -use MetaCPAN::Types qw( Bool Uri); +use Cpanel::JSON::XS qw( decode_json ); +use Log::Contextual qw( :log :dlog ); +use MetaCPAN::ESConfig qw( es_doc_path ); +use MetaCPAN::Types::TypeTiny qw( Bool Str Uri ); +use Path::Tiny qw( path ); +use MetaCPAN::Util qw( hit_total true false ); with 'MetaCPAN::Role::Script', 'MooseX::Getopt'; @@ -30,6 +33,14 @@ has test => ( documentation => 'Test mode (pulls smaller development data set)', ); +has json_file => ( + is => 'ro', + isa => Str, + default => 0, + documentation => + 'Path to JSON file to be read instead of URL (for testing)', +); + my %valid_keys = map { $_ => 1 } qw< branch condition statement subroutine total >; @@ -43,10 +54,7 @@ sub run { sub index_cover_data { my ( $self, $data ) = @_; - my $bulk = $self->es->bulk_helper( - index => 'cover', - type => 'cover', - ); + my $bulk = $self->es->bulk_helper( es_doc_path('cover') ); log_info {'Updating the cover index'}; @@ -54,14 +62,13 @@ sub index_cover_data { for my $version ( keys %{ $data->{$dist} } ) { my $release = $dist . '-' . $version; my $rel_check = $self->es->search( - index => 'cpan', - type => 'release', - size => 0, - body => { + es_doc_path('release'), + size => 0, + body => { query => { term => { name => $release } }, }, ); - if ( $rel_check->{hits}{total} ) { + if ( hit_total($rel_check) ) { log_info { "Adding release info for '" . $release . "'" }; } else { @@ -75,18 +82,16 @@ sub index_cover_data { delete $doc_data{$k} unless exists $valid_keys{$k}; } - $bulk->update( - { - id => $release, - doc => { - distribution => $dist, - version => $version, - release => $release, - criteria => \%doc_data, - }, - doc_as_upsert => 1, - } - ); + $bulk->update( { + id => $release, + doc => { + distribution => $dist, + version => $version, + release => $release, + criteria => \%doc_data, + }, + doc_as_upsert => true, + } ); } } @@ -96,6 +101,8 @@ sub index_cover_data { sub retrieve_cover_data { my $self = shift; + return decode_json( path( $self->json_file )->slurp ) if $self->json_file; + my $url = $self->test ? $self->cover_dev_url : $self->cover_url; log_info { 'Fetching data from ', $url }; @@ -129,4 +136,3 @@ Retrieves the CPAN cover data from its source and updates our ES information. =cut - diff --git a/lib/MetaCPAN/Script/External.pm b/lib/MetaCPAN/Script/External.pm index 85011b512..76d50ee59 100644 --- a/lib/MetaCPAN/Script/External.pm +++ b/lib/MetaCPAN/Script/External.pm @@ -5,14 +5,18 @@ use namespace::autoclean; use Email::Sender::Simple (); use Email::Simple (); -use Log::Contextual qw( :log ); +use Log::Contextual qw( :log ); +use MetaCPAN::ESConfig qw( es_doc_path ); -use MetaCPAN::Types qw( Str ); +use MetaCPAN::Types::TypeTiny qw( Str ); +use MetaCPAN::Util qw( true false ); -with 'MetaCPAN::Role::Script', 'MooseX::Getopt', +with( + 'MetaCPAN::Role::Script', 'MetaCPAN::Script::Role::External::Cygwin', 'MetaCPAN::Script::Role::External::Debian', - 'MetaCPAN::Script::Role::External::Fedora'; + 'MooseX::Getopt', +); has external_source => ( is => 'ro', @@ -32,7 +36,6 @@ sub run { $ret = $self->run_cygwin if $self->external_source eq 'cygwin'; $ret = $self->run_debian if $self->external_source eq 'debian'; - $ret = $self->run_fedora if $self->external_source eq 'fedora'; my $email_body = $ret->{errors_email_body}; if ($email_body) { @@ -62,8 +65,7 @@ sub update { my $external_source = $self->external_source; my $scroll = $self->es->scroll_helper( - index => $self->index->name, - type => 'distribution', + es_doc_path('distribution'), scroll => '10m', body => { query => { @@ -88,38 +90,31 @@ sub update { } } - my $bulk = $self->es->bulk_helper( - index => $self->index->name, - type => 'distribution', - ); + my $bulk = $self->es->bulk_helper( es_doc_path('distribution'), ); for my $d ( keys %{$dist} ) { log_debug {"[$external_source] adding $d"}; - $bulk->update( - { - id => $d, - doc => +{ - 'external_package' => { - $external_source => $dist->{$d} - } - }, - doc_as_upsert => 1, - } - ); + $bulk->update( { + id => $d, + doc => +{ + 'external_package' => { + $external_source => $dist->{$d} + } + }, + doc_as_upsert => true, + } ); } for my $d (@to_remove) { log_debug {"[$external_source] removing $d"}; - $bulk->update( - { - id => $d, - doc => +{ - 'external_package' => { - $external_source => undef - } + $bulk->update( { + id => $d, + doc => +{ + 'external_package' => { + $external_source => undef } } - ); + } ); } $bulk->flush; diff --git a/lib/MetaCPAN/Script/Favorite.pm b/lib/MetaCPAN/Script/Favorite.pm index 846fd18af..958203e85 100644 --- a/lib/MetaCPAN/Script/Favorite.pm +++ b/lib/MetaCPAN/Script/Favorite.pm @@ -4,7 +4,9 @@ use Moose; use Log::Contextual qw( :log ); -use MetaCPAN::Types qw( Bool Int Str ); +use MetaCPAN::ESConfig qw( es_doc_path ); +use MetaCPAN::Types::TypeTiny qw( Bool Int Str ); +use MetaCPAN::Util qw( true false ); with 'MooseX::Getopt', 'MetaCPAN::Role::Script'; @@ -22,16 +24,16 @@ has queue => ( ); has check_missing => ( - is => 'ro', - isa => Bool, - default => 0, + is => 'ro', + isa => Bool, + default => 0, documentation => 'Report distributions that are missing from "file" or queue jobs if "--queue" specified', ); has age => ( - is => 'ro', - isa => Int, + is => 'ro', + isa => Int, documentation => 'Update distributions that were voted on in the last X minutes', ); @@ -49,8 +51,8 @@ has distribution => ( ); has count => ( - is => 'ro', - isa => Int, + is => 'ro', + isa => Int, documentation => 'Update this count to a given distribution (will only work with "--distribution"', ); @@ -69,13 +71,13 @@ sub run { } $self->index_favorites; - $self->index->refresh; + $self->es->indices->refresh; } sub index_favorites { my $self = shift; - my $body; + my $query = { match_all => {} }; my $age_filter; if ( $self->age ) { $age_filter = { @@ -86,41 +88,31 @@ sub index_favorites { } if ( $self->distribution ) { - $body = { - query => { - term => { distribution => $self->distribution } - } - }; + $query = { term => { distribution => $self->distribution } }; } elsif ( $self->age ) { my $favs = $self->es->scroll_helper( - index => $self->index->name, - type => 'favorite', - search_type => 'scan', - scroll => '5m', - fields => [qw< distribution >], - size => 500, - body => { - query => $age_filter, - ( $self->limit ? ( size => $self->limit ) : () ) + es_doc_path('favorite'), + scroll => '5m', + body => { + query => $age_filter, + _source => [qw< distribution >], + size => $self->limit || 500, + sort => '_doc', } ); my %recent_dists; while ( my $fav = $favs->next ) { - my $dist = $fav->{fields}{distribution}[0]; + my $dist = $fav->{_source}{distribution}; $recent_dists{$dist}++ if $dist; } my @keys = keys %recent_dists; if (@keys) { - $body = { - query => { - terms => { distribution => \@keys } - } - }; + $query = { terms => { distribution => \@keys } }; } } @@ -133,17 +125,18 @@ sub index_favorites { } else { my $favs = $self->es->scroll_helper( - index => $self->index->name, - type => 'favorite', - search_type => 'scan', - scroll => '30s', - fields => [qw< distribution >], - size => 500, - ( $body ? ( body => $body ) : () ), + es_doc_path('favorite'), + scroll => '30s', + body => { + query => $query, + _source => [qw< distribution >], + size => 500, + sort => '_doc', + }, ); while ( my $fav = $favs->next ) { - my $dist = $fav->{fields}{distribution}[0]; + my $dist = $fav->{_source}{distribution}; $dist_fav_count{$dist}++ if $dist; } @@ -160,13 +153,9 @@ sub index_favorites { } my $files = $self->es->scroll_helper( - index => $self->index->name, - type => 'file', - search_type => 'scan', - scroll => '15m', - fields => [qw< id distribution >], - size => 500, - body => { + es_doc_path('file'), + scroll => '15m', + body => { query => { bool => { must_not => [ @@ -174,12 +163,15 @@ sub index_favorites { ], @age_filter, } - } + }, + _source => [qw< distribution >], + size => 500, + sort => '_doc', }, ); while ( my $file = $files->next ) { - my $dist = $file->{fields}{distribution}[0]; + my $dist = $file->{_source}{distribution}; next unless $dist; next if exists $missing{$dist} or exists $dist_fav_count{$dist}; @@ -188,8 +180,9 @@ sub index_favorites { my @count_flag; if ( $self->count or $dist_fav_count{$dist} ) { - @count_flag = ( '--count', - $self->count || $dist_fav_count{$dist} ); + @count_flag = ( + '--count', $self->count || $dist_fav_count{$dist} + ); } $self->_add_to_queue( index_favorite => @@ -228,36 +221,32 @@ sub index_favorites { } else { my $bulk = $self->es->bulk_helper( - index => $self->index->name, - type => 'file', + es_doc_path('file'), max_count => 250, timeout => '120m', ); my $files = $self->es->scroll_helper( - index => $self->index->name, - type => 'file', - search_type => 'scan', - scroll => '15s', - fields => [qw< id >], - size => 500, - body => { - query => { term => { distribution => $dist } } + es_doc_path('file'), + scroll => '15s', + body => { + query => { term => { distribution => $dist } }, + _source => false, + size => 500, + sort => '_doc', }, ); while ( my $file = $files->next ) { - my $id = $file->{fields}{id}[0]; + my $id = $file->{_id}; my $cnt = $dist_fav_count{$dist}; log_debug {"Updating file id $id with fav_count $cnt"}; - $bulk->update( - { - id => $file->{fields}{id}[0], - doc => { dist_fav_count => $cnt }, - } - ); + $bulk->update( { + id => $file->{_id}, + doc => { dist_fav_count => $cnt }, + } ); } $bulk->flush; diff --git a/lib/MetaCPAN/Script/First.pm b/lib/MetaCPAN/Script/First.pm index 5f2b7598e..71b2c3a79 100644 --- a/lib/MetaCPAN/Script/First.pm +++ b/lib/MetaCPAN/Script/First.pm @@ -5,7 +5,7 @@ use warnings; use Log::Contextual qw( :log ); use Moose; -use MetaCPAN::Types qw( Str ); +use MetaCPAN::Types::TypeTiny qw( Str ); with 'MetaCPAN::Role::Script', 'MooseX::Getopt'; @@ -17,10 +17,9 @@ has distribution => ( sub run { my $self = shift; - my $distributions = $self->index->type("distribution"); + my $distributions = $self->model->doc("distribution"); $distributions - = $distributions->filter( - { term => { name => $self->distribution } } ) + = $distributions->query( { term => { name => $self->distribution } } ) if $self->distribution; $distributions = $distributions->size(500)->scroll; @@ -31,7 +30,7 @@ sub run { $release ? log_debug { "@{[ $release->name ]} by @{[ $release->author ]} was first"; - } + } : log_warn { "no release found for distribution @{[$distribution->name]}"; }; diff --git a/lib/MetaCPAN/Script/Latest.pm b/lib/MetaCPAN/Script/Latest.pm index ca7bca55e..e678806fd 100644 --- a/lib/MetaCPAN/Script/Latest.pm +++ b/lib/MetaCPAN/Script/Latest.pm @@ -5,11 +5,12 @@ use warnings; use Log::Contextual qw( :log ); use Moose; -use MooseX::Aliases; -use Parse::CPAN::Packages::Fast; -use Regexp::Common qw(time); -use Time::Local; -use MetaCPAN::Types qw( Bool Str ); +use CPAN::DistnameInfo (); +use DateTime::Format::ISO8601 (); +use MetaCPAN::ESConfig qw( es_doc_path ); +use MetaCPAN::Types::TypeTiny qw( Bool Str ); +use MetaCPAN::Util qw( true false ); +use Parse::CPAN::Packages::Fast (); with 'MetaCPAN::Role::Script', 'MooseX::Getopt'; @@ -39,7 +40,8 @@ has force => ( sub _build_packages { return Parse::CPAN::Packages::Fast->new( - shift->cpan->file(qw(modules 02packages.details.txt.gz))->stringify ); + shift->cpan->child(qw(modules 02packages.details.txt.gz)) + ->stringify ); } sub _queue_latest { @@ -47,8 +49,11 @@ sub _queue_latest { my $dist = shift || $self->distribution; log_info { "queueing " . $dist }; - $self->_add_to_queue( index_latest => - [ ( $self->force ? '--force' : () ), '--distribution', $dist ] ); + $self->_add_to_queue( + index_latest => + [ ( $self->force ? '--force' : () ), '--distribution', $dist ], + { attempts => 3 } + ); } sub run { @@ -59,7 +64,7 @@ sub run { } my $p = $self->packages; - $self->index->refresh; + $self->es->indices->refresh; # If a distribution name is passed get all the package names # from 02packages that match that distribution so we can limit @@ -82,107 +87,138 @@ sub run { return; } - my @module_filters = { term => { 'module.indexed' => 1 } }; - push @module_filters, @filter - ? { terms => { "module.name" => \@filter } } - : { exists => { field => "module.name" } }; - - # This query will be used to produce a (scrolled) list of - # 'file' type records where the module.name matches the - # distribution name and which are released & - # indexed (the 'leading' module) - my $query = { - bool => { - must => [ - { - nested => { - path => 'module', - filter => { bool => { must => \@module_filters } } - } - }, - { term => { 'maturity' => 'released' } }, - ], - must_not => [ - { term => { status => 'backpan' } }, - { term => { distribution => 'perl' } } - ] - } - }; + my %upgrade; + my %downgrade; + my %queued_distributions; - my $scroll - = $self->index->type('file')->filter($query) - ->source( - [qw< author date distribution module.name release status >] ) - ->size(100)->raw->scroll; + my $total = @filter; + my $found_total = 0; - my ( %downgrade, %upgrade ); - log_debug { 'Found ' . $scroll->total . ' modules' }; + my @module_filters; + if (@filter) { + while (@filter) { + my @modules = splice @filter, 0, 500; - my $i = 0; + push @module_filters, + [ + { term => { 'module.indexed' => true } }, + { terms => { "module.name" => \@modules } }, + ]; + } + } + else { + push @module_filters, + [ + { term => { 'module.indexed' => true } }, + { exists => { field => "module.name" } }, + ]; + } + for my $filter (@module_filters) { - my @modules_to_purge; - my %queued_distributions; + # This query will be used to produce a (scrolled) list of + # 'file' type records where the module.name matches the + # distribution name and which are released & + # indexed (the 'leading' module) + my $query = { + bool => { + must => [ + { + nested => { + path => 'module', + query => { bool => { must => $filter } } + } + }, + { term => { 'maturity' => 'released' } }, + ], + must_not => [ + { term => { status => 'backpan' } }, + { term => { distribution => 'perl' } } + ] + } + }; - # For each file... - while ( my $file = $scroll->next ) { - $i++; - log_debug { "$i of " . $scroll->total } unless ( $i % 1000 ); - my $file_data = $file->{_source}; + log_debug { + 'Searching for ' . @$filter . ' of ' . $total . ' modules' + } + if @module_filters > 1; + + my $scroll = $self->es->scroll_helper( { + es_doc_path('file'), + size => 100, + body => { + query => $query, + _source => [ + qw(author date distribution download_url module.name release status) + ], + sort => '_doc', + }, + } ); + + $found_total += $scroll->total; + + log_debug { 'Found ' . $scroll->total . ' modules' }; + log_debug { 'Found ' . $found_total . 'total modules' } + if @$filter != $total and $filter == $module_filters[-1]; + + my $i = 0; + + # For each file... + while ( my $file = $scroll->next ) { + $i++; + log_debug { "$i of " . $scroll->total } unless ( $i % 100 ); + my $file_data = $file->{_source}; # Convert module name into Parse::CPAN::Packages::Fast::Package object. - my @modules = grep {defined} - map { - eval { $p->package( $_->{name} ) } - } @{ $file_data->{module} }; + my @modules = grep {defined} + map { + eval { $p->package( $_->{name} ) } + } @{ $file_data->{module} }; - push @modules_to_purge, @modules; + $file_data->{date} + = DateTime::Format::ISO8601->parse_datetime( + $file_data->{date} ); - # For each of the packages in this file... - foreach my $module (@modules) { + # For each of the packages in this file... + foreach my $module (@modules) { # Get P:C:P:F:Distribution (CPAN::DistnameInfo) object for package. - my $dist = $module->distribution; - - if ( $self->queue ) { - my $d = $dist->dist; - $self->_queue_latest($d) - unless exists $queued_distributions{$d}; - $queued_distributions{$d} = 1; - next; - } - - # If 02packages has the same author/release for this package... - - # NOTE: CPAN::DistnameInfo doesn't parse some weird uploads - # (like /\.pm\.gz$/) so distvname might not be present. - # I assume cpanid always will be. - if ( defined( $dist->distvname ) - && $dist->distvname eq $file_data->{release} - && $dist->cpanid eq $file_data->{author} ) - { - my $upgrade = $upgrade{ $file_data->{distribution} }; - - # If multiple versions of a dist appear in 02packages - # only mark the most recent upload as latest. - next - if ( - $upgrade - && $self->compare_dates( - $upgrade->{date}, $file_data->{date} - ) - ); - $upgrade{ $file_data->{distribution} } = $file_data; - } - elsif ( $file_data->{status} eq 'latest' ) { - $downgrade{ $file_data->{release} } = $file_data; + my $dist = $module->distribution; + + if ( $self->queue ) { + my $d = $dist->dist; + $self->_queue_latest($d) + unless exists $queued_distributions{$d}; + $queued_distributions{$d} = 1; + next; + } + + # If 02packages has the same author/release for this package... + + # NOTE: CPAN::DistnameInfo doesn't parse some weird uploads + # (like /\.pm\.gz$/) so distvname might not be present. + # I assume cpanid always will be. + if ( defined( $dist->distvname ) + && $dist->distvname eq $file_data->{release} + && $dist->cpanid eq $file_data->{author} ) + { + my $upgrade = $upgrade{ $file_data->{distribution} }; + + # If multiple versions of a dist appear in 02packages + # only mark the most recent upload as latest. + next + if $upgrade && $upgrade->{date} > $file_data->{date}; + $upgrade{ $file_data->{distribution} } = $file_data; + } + elsif ( $file_data->{status} eq 'latest' ) { + $downgrade{ $file_data->{release} } = $file_data; + } } } } - my $bulk = $self->es->bulk_helper( - index => $self->index->name, - type => 'file' - ); + my $bulk = $self->es->bulk_helper( es_doc_path('file') ); + + my %to_purge; while ( my ( $dist, $file_data ) = each %upgrade ) { @@ -190,6 +226,8 @@ sub run { # This just means that it hasn't changed (query includes 'latest'). next if ( !$self->force and $file_data->{status} eq 'latest' ); + $to_purge{ $file_data->{download_url} } = 1; + $self->reindex( $bulk, $file_data, 'latest' ); } @@ -205,17 +243,16 @@ sub run { && $upgrade{ $file_data->{distribution} }->{release} eq $file_data->{release} ); + $to_purge{ $file_data->{download_url} } = 1; + $self->reindex( $bulk, $file_data, 'cpan' ); } $bulk->flush; - $self->index->refresh; - - # We just want the CPAN::DistnameInfo - my @module_to_purge_dists = map { $_->distribution } @modules_to_purge; + $self->es->indices->refresh; # Call Fastly to purge - $self->purge_cpan_distnameinfos( \@module_to_purge_dists ); - + $self->purge_cpan_distnameinfos( [ + map CPAN::DistnameInfo->new($_), keys %to_purge ] ); } # Update the status for the release and all the files. @@ -223,31 +260,56 @@ sub reindex { my ( $self, $bulk, $source, $status ) = @_; # Update the status on the release. - my $release = $self->index->type('release')->get( - { - author => $source->{author}, - name => $source->{release}, - } - ); + my $releases = $self->es->search( { + es_doc_path('release'), + body => { + query => { + bool => { + must => [ + { term => { author => $source->{author} } }, + { term => { name => $source->{release} } }, + ], + }, + }, + }, + _source => false, + } ); + my $release = $releases->{hits}{hits}[0]{_id}; - $release->_set_status($status); log_info { $status eq 'latest' ? 'Upgrading ' : 'Downgrading ', - 'release ', $release->name || q[]; + 'release ', $source->{release}, "($release)"; }; - $release->put unless ( $self->dry_run ); + + if ( !$self->dry_run ) { + $self->es->update( { + es_doc_path('release'), + id => $release, + body => { + doc => { + status => $status, + }, + }, + } ); + } # Get all the files for the release. - my $scroll = $self->index->type("file")->search_type('scan')->filter( - { - bool => { - must => [ - { term => { 'release' => $source->{release} } }, - { term => { 'author' => $source->{author} } } - ] - } - } - )->size(100)->source( [ 'status', 'file' ] )->raw->scroll; + my $scroll = $self->es->scroll_helper( + es_doc_path('file'), + size => 100, + body => { + query => { + bool => { + must => [ + { term => { 'release' => $source->{release} } }, + { term => { 'author' => $source->{author} } }, + ], + }, + }, + _source => [ 'status', 'file' ], + sort => '_doc', + }, + ); while ( my $row = $scroll->next ) { my $source = $row->{_source}; @@ -263,16 +325,6 @@ sub reindex { } -sub compare_dates { - my ( $self, $d1, $d2 ) = @_; - for ( $d1, $d2 ) { - if ( $_ =~ /$RE{time}{iso}{-keep}/ ) { - $_ = timelocal( $7, $6, $5, $4, $3 - 1, $2 ); - } - } - return $d1 > $d2; -} - __PACKAGE__->meta->make_immutable; 1; diff --git a/lib/MetaCPAN/Script/Mapping.pm b/lib/MetaCPAN/Script/Mapping.pm index 65e819f45..128c78b76 100644 --- a/lib/MetaCPAN/Script/Mapping.pm +++ b/lib/MetaCPAN/Script/Mapping.pm @@ -2,25 +2,11 @@ package MetaCPAN::Script::Mapping; use Moose; -use Cpanel::JSON::XS qw( decode_json ); -use DateTime (); -use Log::Contextual qw( :log ); -use MetaCPAN::Script::Mapping::CPAN::Author (); -use MetaCPAN::Script::Mapping::CPAN::Distribution (); -use MetaCPAN::Script::Mapping::CPAN::Favorite (); -use MetaCPAN::Script::Mapping::CPAN::File (); -use MetaCPAN::Script::Mapping::CPAN::Mirror (); -use MetaCPAN::Script::Mapping::CPAN::Permission (); -use MetaCPAN::Script::Mapping::CPAN::Package (); -use MetaCPAN::Script::Mapping::CPAN::Rating (); -use MetaCPAN::Script::Mapping::CPAN::Release (); -use MetaCPAN::Script::Mapping::DeployStatement (); -use MetaCPAN::Script::Mapping::User::Account (); -use MetaCPAN::Script::Mapping::User::Identity (); -use MetaCPAN::Script::Mapping::User::Session (); -use MetaCPAN::Script::Mapping::Contributor (); -use MetaCPAN::Script::Mapping::Cover (); -use MetaCPAN::Types qw( Bool Str ); +use Cpanel::JSON::XS (); +use Log::Contextual qw( :log ); +use MetaCPAN::ESConfig qw( es_config ); +use MetaCPAN::Types::TypeTiny qw( Bool HashRef Int ); +use Time::HiRes qw( sleep time ); use constant { EXPECTED => 1, @@ -37,425 +23,566 @@ has arg_deploy_mapping => ( documentation => 'delete index if it exists already', ); -has arg_list_types => ( - init_arg => 'list_types', +has arg_delete_all => ( + init_arg => 'all', is => 'ro', isa => Bool, default => 0, - documentation => 'list available index type names', + documentation => + 'delete ALL existing indices (only effective in combination with "--delete")', ); -has arg_create_index => ( - init_arg => 'create_index', - is => 'ro', - isa => Str, - default => "", - documentation => 'create a new empty index (copy mappings)', -); - -has arg_update_index => ( - init_arg => 'update_index', - is => 'ro', - isa => Str, - default => "", - documentation => 'update existing index (add mappings)', -); - -has patch_mapping => ( - is => 'ro', - isa => Str, - default => "{}", - documentation => 'type mapping patches', -); - -has skip_existing_mapping => ( +has arg_verify_mapping => ( + init_arg => 'verify', is => 'ro', isa => Bool, default => 0, - documentation => 'do NOT copy mappings other than patch_mapping', -); - -has copy_to_index => ( - is => 'ro', - isa => Str, - default => "", - documentation => 'index to copy type to', -); - -has arg_copy_type => ( - init_arg => 'copy_type', - is => 'ro', - isa => Str, - default => "", - documentation => 'type to copy', + documentation => 'verify deployed index structure against definition', ); -has copy_query => ( - is => 'ro', - isa => Str, - default => "", - documentation => 'match query (default: monthly time slices, ' - . ' if provided must be a valid json query OR "match_all")', -); - -has reindex => ( +has arg_cluster_info => ( + init_arg => 'show_cluster_info', is => 'ro', isa => Bool, default => 0, - documentation => 'reindex data from source index for exact mapping types', + documentation => 'show basic info about cluster and indices', ); -has arg_delete_index => ( - init_arg => 'delete_index', +has arg_await_timeout => ( + init_arg => 'await', is => 'ro', - isa => Str, - default => "", - documentation => 'delete an existing index', + isa => Int, + default => 15, + documentation => + 'seconds before connection is considered failed with timeout', ); -has delete_from_type => ( - is => 'ro', - isa => Str, - default => "", - documentation => 'delete data from an existing type', +has cluster_info => ( + isa => HashRef, + traits => ['Hash'], + is => 'rw', + lazy => 1, + default => sub { {} }, +); + +has indices_info => ( + isa => HashRef, + traits => ['Hash'], + is => 'rw', + lazy => 1, + default => sub { {} }, ); sub run { my $self = shift; - $self->create_index if $self->arg_create_index; - $self->delete_index if $self->arg_delete_index; - $self->update_index if $self->arg_update_index; - $self->copy_type if $self->copy_to_index; - $self->empty_type if $self->delete_from_type; - $self->list_types if $self->arg_list_types; - $self->deploy_mapping if $self->arg_deploy_mapping; -} -sub _check_index_exists { - my ( $self, $name, $expected ) = @_; - my $exists = $self->es->indices->exists( index => $name ); + # Wait for the ElasticSearch Engine to become ready + if ( $self->await ) { + if ( $self->arg_deploy_mapping ) { + if ( $self->arg_delete_all ) { + $self->check_health; + $self->delete_all; + } + unless ( $self->deploy_mapping ) { + $self->print_error("Indices Re-creation has failed!"); + $self->exit_code(1); + } + } - if ( $exists and !$expected ) { - log_error {"Index already exists: $name"}; - exit 0; - } + if ( $self->arg_verify_mapping ) { + $self->check_health; + unless ( $self->indices_valid( $self->_build_index_config ) ) { + $self->print_error("Indices Verification has failed!"); + $self->exit_code(1); + } + } - if ( !$exists and $expected ) { - log_error {"Index doesn't exists: $name"}; - exit 0; + if ( $self->arg_cluster_info ) { + $self->check_health; + $self->show_info; + } } + +# The run() method is expected to communicate Success to the superior execution level + return ( $self->exit_code == 0 ? 1 : 0 ); } -sub delete_index { - my $self = shift; - my $name = $self->arg_delete_index; +sub delete_all { + my $self = $_[0]; + my $runtime_environment = 'production'; - $self->_check_index_exists( $name, EXPECTED ); - $self->are_you_sure("Index $name will be deleted !!!"); + $runtime_environment = $ENV{'PLACK_ENV'} + if ( defined $ENV{'PLACK_ENV'} ); + $runtime_environment = $ENV{'MOJO_MODE'} + if ( defined $ENV{'MOJO_MODE'} ); - $self->_delete_index($name); + my $is_development + = $ENV{HARNESS_ACTIVE} + || $runtime_environment eq 'development' + || $runtime_environment eq 'testing'; + + if ($is_development) { + foreach my $name ( grep !/\A\./, keys %{ $self->indices_info } ) { + $self->_delete_index($name); + } + } + else { + #Set System Error: 1 - EPERM - Operation not permitted + $self->exit_code(1); + $self->print_error("Operation not permitted!"); + $self->handle_error( + "Operation not permitted in environment: $runtime_environment", + 1 ); + } } sub _delete_index { my ( $self, $name ) = @_; + log_info {"Deleting index: $name"}; - $self->es->indices->delete( index => $name ); + my $idx = $self->es->indices; + $idx->delete( index => $name ); + + my $exists; + my $end = time + 2; + while ( time < $end ) { + $exists = $idx->exists( index => $name ) or last; + sleep 0.1; + } + if ($exists) { + log_error {"Failed to delete index: $name"}; + } + return $exists; } -sub update_index { +sub show_info { + my $self = $_[0]; + my $info_rs = { + 'cluster_info' => \%{ $self->cluster_info }, + 'indices_info' => \%{ $self->indices_info }, + }; + log_info { Cpanel::JSON::XS->new->utf8->pretty->encode($info_rs) }; +} + +sub _build_index_config { + my $self = $_[0]; + my $docs = es_config->documents; + my $indices = {}; + my $api_version = $self->es->api_version; + for my $name ( sort keys %$docs ) { + my $doc = $docs->{$name}; + my $index = $doc->{index} + or die "no index defined for $name documents"; + die "$index specified for multiple documents" + if $indices->{$index}; + my $mapping = es_config->mapping( $name, $api_version ); + my $settings = es_config->index_settings( $name, $api_version ); + if ( $api_version le '6_0' ) { + my $type = $doc->{type} + or die "no type defined for $name documents"; + $mapping = { $type => $mapping }; + } + $indices->{$index} = { + settings => $settings, + mappings => $mapping, + }; + } + + return $indices; +} + +sub deploy_mapping { my $self = shift; - my $name = $self->arg_update_index; - $self->_check_index_exists( $name, EXPECTED ); - $self->are_you_sure("Index $name will be updated !!!"); + $self->are_you_sure( + 'this will delete EVERYTHING and re-create the (empty) indexes'); - die "update_index requires patch_mapping\n" - unless $self->patch_mapping; + # Deserialize the Index Mapping Structure + my $rindices = $self->_build_index_config; - my $patch_mapping = decode_json $self->patch_mapping; - my @patch_types = sort keys %{$patch_mapping}; - my $dep = $self->index->deployment_statement; - my $existing_mapping = delete $dep->{mappings}; - my $mapping = +{ map { $_ => $patch_mapping->{$_} } @patch_types }; + my $es = $self->es; - log_info {"Updating mapping for index: $name"}; + # recreate the indices and apply the mapping - for my $type ( sort keys %{$mapping} ) { - log_info {"Adding mapping to index: $type"}; - $self->es->indices->put_mapping( - index => $self->index->name, - type => $type, - body => { $type => $mapping->{$type} }, - ); - } + for my $idx ( sort keys %$rindices ) { + $self->_delete_index($idx) + if $es->indices->exists( index => $idx ); - log_info {"Done."}; -} + log_info {"Creating index: $idx"}; -sub create_index { - my $self = shift; + $es->indices->create( index => $idx, body => $rindices->{$idx} ); + } - my $dst_idx = $self->arg_create_index; - $self->_check_index_exists( $dst_idx, NOT_EXPECTED ); + $self->check_health(1); - my $patch_mapping = decode_json $self->patch_mapping; - my @patch_types = sort keys %{$patch_mapping}; - my $dep = $self->index->deployment_statement; - delete $dep->{mappings}; - my $mapping = +{}; + # done + log_info {"Done."}; - # create the new index with the copied settings - log_info {"Creating index: $dst_idx"}; - $self->es->indices->create( index => $dst_idx, body => $dep ); + return $self->indices_valid($rindices); +} - # override with new type mapping - if ( $self->patch_mapping ) { - for my $type (@patch_types) { - log_info {"Patching mapping for type: $type"}; - $mapping->{$type} = $patch_mapping->{$type}; +sub _compare_mapping { + my ( $self, $sname, $rdeploy, $rmodel ) = @_; + my $imatch = 0; + + if ( defined $rdeploy && defined $rmodel ) { + my $json_parser = Cpanel::JSON::XS->new->allow_nonref; + my ( $deploy_type, $deploy_value ); + my ( $model_type, $model_value ); + + $imatch = 1; + + if ( ref $rdeploy eq 'HASH' ) { + foreach my $sfield ( sort keys %$rdeploy ) { + if ( defined $rdeploy->{$sfield} + && defined $rmodel->{$sfield} ) + { + $deploy_type = ref( $rdeploy->{$sfield} ); + $model_type = ref( $rmodel->{$sfield} ); + $deploy_value = $rdeploy->{$sfield}; + $model_value = $rmodel->{$sfield}; + + if ( $deploy_type eq 'JSON::PP::Boolean' ) { + $deploy_type = ''; + $deploy_value + = $json_parser->encode( $rdeploy->{$sfield} ); + } + + if ( $model_type eq 'JSON::PP::Boolean' ) { + $model_type = ''; + $model_value + = $json_parser->encode( $rmodel->{$sfield} ); + } + + if ( $deploy_type ne '' ) { + if ( $deploy_type eq 'HASH' + || $deploy_type eq 'ARRAY' ) + { + $imatch = ( + $imatch && $self->_compare_mapping( + $sname . '.' . $sfield, $deploy_value, + $model_value + ) + ); + } + else { # No Hash nor Array + if ( ${$deploy_value} ne ${$model_value} ) { + log_error { + 'Mismatch field: ' + . $sname . '.' + . $sfield . ' (' + . ${$deploy_value} . ' <> ' + . ${$model_value} . ')' + }; + $imatch = 0; + } + } + } + else { # Scalar Value + if ( + $sfield eq 'type' + && $model_value eq 'string' + && ( $deploy_value eq 'text' + || $deploy_value eq 'keyword' ) + ) + { + # ES5 automatically converts string types to text + # or keyword. once we upgrade to ES5 and update + # our mappings, this special case can be removed. + } + elsif ($sfield eq 'index' + && $model_value eq 'no' + && $deploy_value eq 'false' ) + { + # another ES5 string automatic conversion + } + elsif ( $deploy_value ne $model_value ) { + log_error { + 'Mismatch field: ' + . $sname . '.' + . $sfield . ' (' + . $deploy_value . ' <> ' + . $model_value . ')' + }; + $imatch = 0; + } + } + } + else { + unless ( defined $rdeploy->{$sfield} ) { + log_error { + 'Missing field: ' . $sname . '.' . $sfield + }; + $imatch = 0; + + } + + unless ( defined $rmodel->{$sfield} ) { + if ( $sfield eq 'payloads' + && $rmodel->{type} + && $rmodel->{type} eq 'completion' + && !$rdeploy->{$sfield} ) + { + # ES5 doesn't allow payloads option. we've removed + # it from our mapping. but it gets a default + # value. ignore the default. + } + else { + log_error { + 'Missing definition: ' . $sname . '.' + . $sfield + }; + $imatch = 0; + } + } + } + } + } + elsif ( ref $rdeploy eq 'ARRAY' ) { + foreach my $iindex (@$rdeploy) { + if ( defined $rdeploy->[$iindex] + && defined $rmodel->[$iindex] ) + { + $deploy_type = ref( $rdeploy->[$iindex] ); + $model_type = ref( $rmodel->[$iindex] ); + $deploy_value = $rdeploy->[$iindex]; + $model_value = $rmodel->[$iindex]; + + if ( $deploy_type eq 'JSON::PP::Boolean' ) { + $deploy_type = ''; + $deploy_value + = $json_parser->encode( $rdeploy->[$iindex] ); + } + + if ( $model_type eq 'JSON::PP::Boolean' ) { + $model_type = ''; + $model_value + = $json_parser->encode( $rmodel->[$iindex] ); + } + + if ( $deploy_type eq '' ) { # Reference Value + if ( $deploy_type eq 'HASH' + || $deploy_type eq 'ARRAY' ) + { + $imatch = ( + $imatch && $self->_compare_mapping( + $sname . '[' . $iindex . ']', + $deploy_value, + $model_value + ) + ); + } + else { # No Hash nor Array + if ( ${$deploy_value} ne ${$model_value} ) { + log_error { + 'Mismatch field: ' + . $sname . '[' + . $iindex . '] (' + . ${$deploy_value} . ' <> ' + . ${$model_value} . ')' + }; + $imatch = 0; + } + } + } + else { # Scalar Value + if ( $deploy_value ne $model_value ) { + log_error { + 'Mismatch field: ' + . $sname . '[' + . $iindex . '] (' + . $deploy_value . ' <> ' + . $model_value . ')' + }; + $imatch = 0; + } + } + } + else { # Missing Field + unless ( defined $rdeploy->[$iindex] ) { + log_error { + 'Missing field: ' . $sname . '[' . $iindex . ']' + }; + $imatch = 0; + + } + unless ( defined $rmodel->[$iindex] ) { + log_error { + 'Missing definition: ' . $sname . '[' . $iindex + . ']' + }; + $imatch = 0; + } + } + } } } - - # add the mappings to the index - for my $type ( sort keys %{$mapping} ) { - log_info {"Adding mapping to index: $type"}; - $self->es->indices->put_mapping( - index => $dst_idx, - type => $type, - body => { $type => $mapping->{$type} }, - ); + else { # Missing Field + unless ( defined $rdeploy ) { + log_error { 'Missing field: ' . $sname }; + $imatch = 0; + } + unless ( defined $rmodel ) { + log_error { 'Missing definition: ' . $sname }; + $imatch = 0; + } } - # copy the data to the non-altered types - if ( $self->reindex ) { - for my $type ( - grep { !exists $patch_mapping->{$_} } - sort keys %{$mapping} - ) - { - log_info {"Re-indexing data to index $dst_idx from type: $type"}; - $self->copy_type( $dst_idx, $type ); + if ( $self->{'logger'}->is_debug ) { + if ($imatch) { + log_debug {"field '$sname': ok"}; + } + else { + log_debug {"field '$sname': failed!"}; } } - log_info { - "Done. you can now fill the data for the altered types: (" - . join( ',', @patch_types ) . ")" - } - if @patch_types; + return $imatch; } -sub copy_type { - my ( $self, $index, $type ) = @_; - $index //= $self->copy_to_index; - - $self->_check_index_exists( $index, EXPECTED ); - $type //= $self->arg_copy_type; - $type or die "can't copy without a type\n"; - - my $arg_query = $self->copy_query; - my $query - = $arg_query eq 'match_all' - ? +{ match_all => {} } - : undef; - - if ( $arg_query and !$query ) { - eval { - $query = decode_json $arg_query; - 1; - } or do { - my $err = $@ || 'zombie error'; - die $err; - }; +sub indices_valid { + my ( $self, $config_indices ) = @_; + my $valid = 0; + + if ( defined $config_indices && ref $config_indices eq 'HASH' ) { + my $deploy_indices = $self->es->indices->get_mapping; + $valid = 1; + + for my $idx ( sort keys %$config_indices ) { + my $config_mappings = $config_indices->{$idx} + && $config_indices->{$idx}->{'mappings'}; + my $deploy_mappings = $deploy_indices->{$idx} + && $deploy_indices->{$idx}->{'mappings'}; + if ( !$deploy_mappings ) { + log_error {"Missing index: $idx"}; + $valid = 0; + next; + } + + log_info { + "Verifying index: $idx" + }; + + if ( $self->_compare_mapping( + $idx, $deploy_mappings, $config_mappings + ) ) + { + log_info { + "Correct index: $idx (mapping deployed)" + }; + } + else { + log_error { + "Broken index: $idx (mapping does not match definition)" + }; + $valid = 0; + } + } } - return $self->_copy_slice( $query, $index, $type ) if $query; + if ($valid) { + log_info {"Verification indices: ok"}; + } + else { + log_info {"Verification indices: failed"}; + } - # else ... do copy by monthly slices + return $valid; +} - my $dt = DateTime->new( year => 1994, month => 1 ); - my $end_time = DateTime->now()->add( months => 1 ); +sub _get_indices_info { + my ( $self, $irefresh ) = @_; - while ( $dt < $end_time ) { - my $gte = $dt->strftime("%Y-%m"); - $dt->add( months => 1 ); - my $lt = $dt->strftime("%Y-%m"); + if ( $irefresh || scalar( keys %{ $self->indices_info } ) == 0 ) { + my $sinfo_rs = $self->es->cat->indices( h => [ 'index', 'health' ] ); + my $sindices_parsing = qr/^([^[:space:]]+) +([^[:space:]]+)/m; - my $q = +{ range => { date => { gte => $gte, lt => $lt } } }; + $self->indices_info( {} ); - log_info {"copying data for month: $gte"}; - eval { - $self->_copy_slice( $q, $index, $type ); - 1; - } or do { - my $err = $@ || 'zombie error'; - warn $err; - }; + while ( $sinfo_rs =~ /$sindices_parsing/g ) { + $self->indices_info->{$1} + = { 'index_name' => $1, 'health' => $2 }; + } } } -sub _copy_slice { - my ( $self, $query, $index, $type ) = @_; - - my $scroll = $self->es->scroll_helper( - search_type => 'scan', - size => 250, - scroll => '10m', - index => $self->index->name, - type => $type, - body => { - query => { - filtered => { - query => $query - } - } - }, - ); +sub check_health { + my ( $self, $irefresh ) = @_; + my $ihealth = 0; - my $bulk = $self->es->bulk_helper( - index => $index, - type => $type, - max_count => 500, - ); + $irefresh = 0 unless ( defined $irefresh ); - while ( my $search = $scroll->next ) { - $bulk->create( - { - id => $search->{_id}, - source => $search->{_source} - } - ); - } + $ihealth = $self->await; - $bulk->flush; -} + if ($ihealth) { + $self->_get_indices_info($irefresh); -sub empty_type { - my $self = shift; - my $type = $self->delete_from_type; - log_info {"Emptying type: $type"}; - - my $bulk = $self->es->bulk_helper( - index => $self->index->name, - type => $type, - max_count => 500, - ); - - my $scroll = $self->es->scroll_helper( - search_type => 'scan', - size => 250, - scroll => '10m', - index => $self->index->name, - type => $type, - body => { query => { match_all => {} } }, - ); - - my @ids; - while ( my $search = $scroll->next ) { - push @ids => $search->{_id}; - log_debug { "deleting id=" . $search->{_id} }; - if ( @ids == 500 ) { - $bulk->delete_ids(@ids); - @ids = (); + foreach ( keys %{ $self->indices_info } ) { + $ihealth = 0 + if ( $self->indices_info->{$_}->{'health'} eq 'red' ); } } - $bulk->delete_ids(@ids); - $bulk->flush; + return $ihealth; } -sub list_types { - my $self = shift; - print "$_\n" for sort keys %{ $self->index->types }; -} - -sub deploy_mapping { - my $self = shift; - my $cpan_index = 'cpan_v1_01'; +sub await { + my $self = $_[0]; + my $iready = 0; - $self->are_you_sure( - 'this will delete EVERYTHING and re-create the (empty) indexes'); + if ( scalar( keys %{ $self->cluster_info } ) == 0 ) { + my $es = $self->es; + my $iseconds = 0; - my %mappings = ( - $cpan_index => { - author => - decode_json(MetaCPAN::Script::Mapping::CPAN::Author::mapping), - distribution => - decode_json(MetaCPAN::Script::Mapping::CPAN::Distribution::mapping - ), - favorite => - decode_json(MetaCPAN::Script::Mapping::CPAN::Favorite::mapping - ), - file => - decode_json(MetaCPAN::Script::Mapping::CPAN::File::mapping), - mirror => - decode_json(MetaCPAN::Script::Mapping::CPAN::Mirror::mapping), - permission => - decode_json(MetaCPAN::Script::Mapping::CPAN::Permission::mapping - ), - package => - decode_json(MetaCPAN::Script::Mapping::CPAN::Package::mapping - ), - rating => - decode_json(MetaCPAN::Script::Mapping::CPAN::Rating::mapping), - release => - decode_json(MetaCPAN::Script::Mapping::CPAN::Release::mapping - ), - }, - - user => { - account => - decode_json(MetaCPAN::Script::Mapping::User::Account::mapping - ), - identity => - decode_json(MetaCPAN::Script::Mapping::User::Identity::mapping - ), - session => - decode_json(MetaCPAN::Script::Mapping::User::Session::mapping - ), - }, - contributor => { - contributor => - decode_json(MetaCPAN::Script::Mapping::Contributor::mapping), - }, - cover => { - cover => decode_json(MetaCPAN::Script::Mapping::Cover::mapping), - }, - ); - - my $deploy_statement - = decode_json(MetaCPAN::Script::Mapping::DeployStatement::mapping); + log_info {"Awaiting Elasticsearch ..."}; - my $es = $self->es; + do { + eval { + $iready = $es->ping; - # recreate the indices and apply the mapping + if ($iready) { + log_info { + "Awaiting $iseconds / " + . $self->arg_await_timeout + . " : ready" + }; - for my $idx ( sort keys %mappings ) { - $self->_delete_index($idx) if $es->indices->exists( index => $idx ); + $self->cluster_info( \%{ $es->info } ); + } + }; - log_info {"Creating index: $idx"}; - $es->indices->create( index => $idx, body => $deploy_statement ); - - for my $type ( sort keys %{ $mappings{$idx} } ) { - log_info {"Adding mapping: $idx/$type"}; - $es->indices->put_mapping( - index => $idx, - type => $type, - body => { $type => $mappings{$idx}{$type} }, - ); - } - } + if ($@) { + if ( $iseconds < $self->arg_await_timeout ) { + log_info { + "Awaiting $iseconds / " + . $self->arg_await_timeout + . " : unavailable - sleeping ..." + }; - # create alias + sleep(1); - $es->indices->put_alias( - index => $cpan_index, - name => 'cpan', - ); + $iseconds++; + } + else { + log_error { + "Awaiting $iseconds / " + . $self->arg_await_timeout + . " : unavailable - timeout!" + }; + + #Set System Error: 112 - EHOSTDOWN - Host is down + $self->exit_code(112); + $self->handle_error( $@, 1 ); + } + } + } while ( !$iready && $iseconds <= $self->arg_await_timeout ); + } + else { + #ElasticSearch Service is available + $iready = 1; + } - # done - log_info {"Done."}; - 1; + return $iready; } __PACKAGE__->meta->make_immutable; @@ -463,21 +590,175 @@ __PACKAGE__->meta->make_immutable; __END__ +=pod + +=head1 NAME + +MetaCPAN::Script::Mapping - Script to set the index and mapping the types + =head1 SYNOPSIS + # bin/metacpan mapping --show_cluster_info # show basic info about the cluster and indices # bin/metacpan mapping --delete - # bin/metacpan mapping --list_types - # bin/metacpan mapping --delete_index xxx - # bin/metacpan mapping --create_index xxx --reindex - # bin/metacpan mapping --create_index xxx --reindex --patch_mapping '{"distribution":{"dynamic":"false","properties":{"name":{"index":"not_analyzed","ignore_above":2048,"type":"string"},"river":{"properties":{"total":{"type":"integer"},"immediate":{"type":"integer"},"bucket":{"type":"integer"}},"dynamic":"true"},"bugs":{"properties":{"rt":{"dynamic":"true","properties":{"rejected":{"type":"integer"},"closed":{"type":"integer"},"open":{"type":"integer"},"active":{"type":"integer"},"patched":{"type":"integer"},"source":{"type":"string","ignore_above":2048,"index":"not_analyzed"},"resolved":{"type":"integer"},"stalled":{"type":"integer"},"new":{"type":"integer"}}},"github":{"dynamic":"true","properties":{"active":{"type":"integer"},"open":{"type":"integer"},"closed":{"type":"integer"},"source":{"type":"string","index":"not_analyzed","ignore_above":2048}}}},"dynamic":"true"}}}}' - # bin/metacpan mapping --create_index xxx --patch_mapping '{...mapping...}' --skip_existing_mapping - # bin/metacpan mapping --update_index xxx --patch_mapping '{...mapping...}' - # bin/metacpan mapping --copy_to_index xxx --copy_type release - # bin/metacpan mapping --copy_to_index xxx --copy_type release --copy_query '{"range":{"date":{"gte":"2016-01","lt":"2017-01"}}}' - # bin/metacpan mapping --delete_from_type xxx # empty the type + # bin/metacpan mapping --delete --all # deletes ALL indices in the cluster + # bin/metacpan mapping --verify # compare deployed indices with project definitions =head1 DESCRIPTION This is the index mapping handling script. Used rarely, but carries the most important task of setting the index and mapping the types. + +=head1 OPTIONS + +This Script accepts the following options + +=over 4 + +=item Option C<--show_cluster_info> + +This option makes the Script show basic information about the I Cluster +and its indices. +This information has to be collected with the C Method. +On Script start-up it is empty. + + bin/metacpan mapping --show_cluster_info + +See L> + +=item Option C<--delete> + +This option makes the Script delete all indices configured in the project and re-create them emtpy. +It verifies the index integrity of the indices calling the methods +C and C. +If the C Method fails it will report an error. + + bin/metacpan mapping --delete + +B If the mapping deployment fails it exits the Script with B C< 1 >. + +See L> + +See L> + +See L> + +=item Option C<--all> + +This option is only effective in combination with Option C<--delete>. +It uses the information gathered by C to delete +B indices in the I Cluster. +This option is usefull to reconstruct a broken I Cluster + + bin/metacpan mapping --delete --all + +B It will throw an exceptions when not performed in an development or +testing environment. + +See L