App-Project-Doctor

 view release on metacpan or  search on metacpan

lib/App/Project/Doctor.pm  view on Meta::CPAN

package App::Project::Doctor;

# This is the top-level orchestrator for the project health-check tool.
# It finds the distribution root, loads check plugins, runs them in order,
# and returns a Report containing all of the resulting findings.

use strict;
use warnings;
use autodie qw(:all);

# croak dies with the caller's file/line; carp warns at the caller's location.
use Carp qw(croak carp);
# Readonly makes constants truly immutable at runtime.
use Readonly;
# File::Spec builds OS-portable paths (handles Windows backslashes, etc.).
use File::Spec;
# dirname() extracts the parent directory from a path when walking up the tree.
use File::Basename qw(dirname);
# Params::Get normalises @_ so both hash and hashref calling styles work.
use Params::Get;
# validate_strict enforces parameter schemas and throws immediately on failure.
use Params::Validate::Strict qw(validate_strict);
use Object::Configure;	# Allow the object to be configured at runtime

our $VERSION = '0.02';

=head1 NAME

App::Project::Doctor - Unified pre-release health check for Perl CPAN distributions

=head1 VERSION

0.02

=head1 SYNOPSIS

  # Command line
  project-doctor [--check=Tests,CI] [--skip=Meta] [--fix] [PATH]

  # Programmatic
  use App::Project::Doctor;

  my $doctor = App::Project::Doctor->new(path => '/path/to/my-dist');
  my $report = $doctor->run;
  print $report->render_text;
  exit $report->exit_code;

=head1 DESCRIPTION

Orchestrates a suite of diagnostic checks against a Perl CPAN distribution,
combining L<App::Workflow::Lint>, L<App::GHGen::Generator>, L<App::makefilepl2cpanfile>
into a single interactive pre-upload tool.

Each enabled C<App::Project::Doctor::Check::*> plugin receives an
L<App::Project::Doctor::Context> and returns a list of
L<App::Project::Doctor::Finding> objects which are collected into an
L<App::Project::Doctor::Report>.

=head1 CONSTRUCTOR

=head2 new( %args )

=head3 API SPECIFICATION

=head4 Input

  path    : String    -- start path for root detection    default '.'
  checks  : ArrayRef  -- check name suffixes to run       default all
  skip    : ArrayRef  -- check names to exclude           default []
  verbose : Bool                                          default 0

=head4 Output

Blessed hashref of type C<App::Project::Doctor>.

=head1 ACCESSORS

C<path>, C<checks>, C<skip>, C<verbose> -- read-only.

=head1 METHODS

=head2 run

=head3 API SPECIFICATION

=head4 Input

None.

=head4 Output

L<App::Project::Doctor::Report>.

=head3 MESSAGES

  Code | Trigger                         | Resolution
  -----|----------------------------------|----------------------------------------
  DR01 | Cannot detect distribution root  | Run from within a distribution directory
  DR02 | A check class cannot be loaded   | Install the check's prerequisites

=head1 CHECKS

In default execution order:

  Tests           t/ exists, .t files present, prove passes
  CI              At least one CI configuration present
  GitHubActions   Workflow YAML validates via App::Workflow::Lint
  Meta            META.yml/json parsed and complete
  Pod             All .pm files have valid POD
  Dependencies    Used modules declared as prerequisites
  License         LICENSE file present and consistent with META
  Security        strict/warnings everywhere; no hardcoded secrets



( run in 1.353 second using v1.01-cache-2.11-cpan-b16cb0d3907 )