Overview of Carmel CPAN Artifact Repository Manager
mastercpanfile.snapshot and easy deployment to production via rollouts or packaging.repository·master·Indexed 41 days ago
https://github.com/miyagawa/carmelA CPAN module manager for reproducible development and production deployment. Carmel manages dependencies by storing build artifacts in a central repository and using a cpanfile.snapshot to pin exact versions. It provides a CLI for installing, updating, and executing commands with pinned dependencies, as well as tools for rolling out dependencies to a local directory or packaging them for vendor caches.
cpanfile.snapshot and easy deployment to production via rollouts or packaging.Carmel stores build artifacts in a central repository, typically at $HOME/.carmel/{version}-{archname}/builds.
When you run carmel install, it computes the best versions satisfying cpanfile, installs them via cpanm into this central repository, and records the mapping in cpanfile.snapshot.
When running via carmel exec, Carmel dynamically prepends the necessary build directories to the Perl @INC array, allowing you to run applications with pinned dependencies without manually managing PERL5LIB.
Carmel is a dependency manager for Perl that uses cpanfile to declare dependencies and cpanfile.snapshot to pin them. It is designed as a drop-in replacement for Carton but with improved state management.
local directory (which can lead to conflicts), Carmel manages all dependencies in a central repository under $HOME/.carmel. Nothing is installed in your project directory during development.carmel install after pulling changes to cpanfile.snapshot always installs the correct dependencies. Carton may fail to update if the existing local directory already satisfies the cpanfile requirements, even if it doesn't match the snapshot.cpanfile.snapshot, you can undo changes by simply reverting the snapshot file. Carton requires deleting the entire local directory to undo changes.cpm installs dependencies to a local directory, whereas Carmel uses a build cache. You can use carmel rollout to copy Carmel's managed dependencies into a local directory if needed.cpm installs modules in parallel for speed.cpm cannot manage cpanfile.snapshot on its own, but it can read it. A common workflow is using Carmel for development and cpm install to build a perl5 library path from the existing cpanfile and cpanfile.snapshot.While Carmel manages dependencies in $HOME/.carmel to avoid polluting your project directory, you can explicitly create a local directory containing your project's dependencies by using the carmel rollout command. This is useful when you need a standard local directory for specific deployment or build tasks.
# Example command to populate the local directory
carmel rolloutUse the update command to modify the versions pinned in your snapshot:
carmel update <Module>: Updates a specific module to the latest version from CPAN (and updates its dependencies if necessary).carmel update <Module>@<Version>: Pins a module to a specific version.carmel update: Updates all modules listed in your cpanfile to their latest versions.# Update a specific module
carmel update Plack
# Pin modules to specific versions
carmel update DBI@1.633 Plack@1.0000
# Update everything in the snapshot
carmel updateIf you want to vendor your dependencies for use with cpanm on a target machine (e.g., in a CI/CD pipeline or a restricted environment), use carmel package. This creates a directory containing tarballs and CPAN-style package indexes.
# Create a vendor cache
carmel package
# On the target machine, use cpanm to install from the vendor cache
cpanm -L ./local --from $PWD/vendor/cache -nq --installdeps .To avoid requiring Carmel on production hosts or dealing with large @INC overhead, use carmel rollout. This command extracts all files from the pinned dependencies into a standard Perl library directory structure (defaults to ./local). This directory can then be used like a local::lib path.
# Roll out dependencies to the ./local directory
carmel rollout
# Run your application using the rolled-out path
perl -Ilocal/lib/perl5 local/bin/starman -p 8080 myapp.psgiIn a development workflow, use carmel install to set up your environment or update it when cpanfile changes. This command updates your build artifacts and saves the specific versions used to cpanfile.snapshot. You should commit both cpanfile and cpanfile.snapshot to your version control system to ensure consistency across machines.
To run your application using the exact versions pinned in your snapshot, use carmel exec.
# Setup environment
carmel install
# Run an application (e.g., Starman) with pinned dependencies
carmel exec starman -p 8080 myapp.psgi
# Run a perl command directly
carmel exec perl -e 'use Carmel::Preload;'The carmel executable is used to manage Perl dependencies and environments via cpanfile and cpanfile.snapshot. It provides a suite of commands for loading modules, managing snapshots, and running scripts within a controlled environment.
Based on the internal CLI logic, the tool operates by interpreting commands passed to Carmel::App. Common usage patterns include running commands within specific directories or executing scripts using the artifacts managed by carmel.
Conflicts can occur when a new dependency requires a version of a module that contradicts what is currently pinned in cpanfile.snapshot.
Recommendation: Always run carmel install before making changes to your cpanfile. This ensures the build cache is prepared. If a conflict occurs, use carmel update <Module> to force an update of the conflicting module.
If you see the error Can't find an artifact for Foo, it means a dependency was missed during the initial carmel install. This is a known issue with certain modules. Check the Carmel issue tracker for known problematic modules.
Carmel does not support Perl's Taint mode (-T). Running with -T will result in an error: Insecure dependency in require while running with -T switch.
The following commands are available in the carmel CLI:
| Command | Description |
|---|---|
install | Installs modules from cpanfile and updates cpanfile.snapshot |
list | Lists all modules to be loaded |
tree | Lists all modules in a tree structure |
show <Module> | Shows the installation location of a module |
update <Module> | Updates a specific module to the latest version |
update | Updates all modules in the snapshot |
update <Mod>@<Ver> | Pins modules to specific versions |
diff | Shows diffs for cpanfile.snapshot in a readable format |
exec <cmd> | Runs a command using modules from artifacts |
rollout | Rolls out build artifacts into a ./local directory |
package | Packages tarballs and index into ./vendor/cache |
export | Prints environment variables (like PATH) for shell scripting |
find <Module> | Finds a module in a repository |
find <Module> "<Query>" | Finds a module matching a version query |
For developers integrating carmel into testing frameworks or automation scripts, the xt::CLI module provides a TestCLI class to simulate and capture CLI execution.
Key methods for programmatic execution include:
run(@args): Executes a carmel command and captures stdout, stderr, and the exit_code.cmd(@args): Executes a system command and captures output.run_in_dir($dir, @args): Executes a carmel command within a specific subdirectory.cmd_in_dir($dir, @args): Executes a system command within a specific subdirectory.run_ok(@args): Runs a command and asserts that the exit_code is 0.run_fails(@args): Runs a command and asserts that the exit_code is non-zero.use xt::CLI;
my $cli = cli(clean => 1);
$cli->write_cpanfile("module A", "module B");
$cli->run_ok("list");