NAME

CPAN::InGit::Server - A Mojolicious::Controller that serves the ArchiveTrees from a git repo

DESCRIPTION

This controller serves paths that can be used directly as a CPAN Mirror by tools like 'cpanm'. By default, it serves all branches, but you can also configure it to serve only a single branch. It serves content directly from the Git repo and does not need a working directory checked out.

ATTRIBUTES

cpan_repo

Reference to the CPAN::InGit object from which files will be served

archive_tree

Reference to an ArchvieTree object. If set, the controller will serve only the tree of this branch from whatever path it was rooted at. If not set, this attribute will be lazy-built from attribute branch_name and cached in branch_cache. The lazy-building of this attribute may return undef, and should be checked before dispatching to an action.

branch_name

Name of branch to be lazy-loaded by the archive_tree accessor.

branch_cache

A hashref or Tree::RB::XS object storing a cache of ArchiveTree objects. This needs to be supplied in the stash if you are loading branches by name at runtime, or else it will be creating an ArchiveTree object on every request.

branch_head_only

If true, this prevents serving files from a Git::Raw tree which is not the HEAD of a branch. By default, any Git sha-1, tag, or branch name may be used so long as it references a tree that meets the requirements for an ArchiveTree.

METHODS

check_branch_exists

This checks that the "branch_name" could be successfully resolved to a "archive_tree". It returns true, or sets a 404 error and returns undef, and can be used as ->under(\&check_branch_exists).

serve_package_details

Serve modules/02packages.details.txt.gz.

serve_author_file

Serve all files under authors/id/.... (All files in that path of the git branch are considered public) This performs automatic creation of .tar.gz files if a directory and matching .meta file exist, allowing distributions to be unpacked within the git repo, but served as .tar.gz files.

render_gzipped

Serve content after gzipping it and setting the content type to application/gzip.

ROUTES

Cpan Mirror Paths

A functioning CPAN mirror requires a file /modules/02packages.details.txt.gz which lists the full contents of the latest version of every module. That file also lists the author paths for each module, which are relative to /authors/id/

In CPAN::InGit, /modules/02packages.details.txt is stored uncompressed, and gzipped as it is served. Each author dist is stored as a .tar.gz file and a metadata file with extension .meta and may also optionally be unpacked at a directory of the same name minus the .tar.gz extension. A special author "local" is used for custom overrides of upstream packages.

Summary:

/:branch/modules/02packages.details.txt                 # index of the mirror
/:branch/authors/id/D/DP/DPARIS/Crypt-DES-2.07.tar.gz   # copy of upstream
/:branch/authors/id/D/DP/DPARIS/Crypt-DES-2.07.meta     # extracted metadata
/:branch/authors/id/local/Crypt-DES-2.07_01/...         # untarred customized dist
/:branch/authors/id/local/Crypt-DES-2.07_01.meta        # untarred customized dist's metadata

mount

my $route= app->routes->any('/pan');
my $repo= CPAN::InGit->new(git_repo => '/path/to/.git');
CPAN::InGit::Server->mount($route, $repo, %options);
# %options:
#   archive_tree => $ArchiveTree_obj,
#   branch_cache => $branch_cache,

This class method sets up the routes for serving the mirror under a provided route. $route is the route under which you want to serve the 'PAN.

If you specify 'branch', that branch will be directly mounted at the route without the '/:branch' selector portion of the paths.

VERSION

version 0.000_001

AUTHOR

Michael Conrad <mike@nrdvana.net>

COPYRIGHT AND LICENSE

This software is copyright (c) 2025 by Michael Conrad, and IntelliTree Solutions.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.