NAME

Chandra::Pack - Bundle Chandra apps into distributable packages

SYNOPSIS

use Chandra::Pack;

# Configure credentials (once, persists to ~/.chandra/pack.conf)
Chandra::Pack->config(
    identity    => 'Developer ID Application: Your Name',
    apple_id    => 'you@example.com',
    team_id     => 'ABCD1234',
    save        => 1,
);

my $packer = Chandra::Pack->new(
    script     => 'app.pl',
    name       => 'My App',
    version    => '1.0.0',
    icon       => 'icon.png',
    assets     => 'assets/',
    output     => 'dist/',
    identifier => 'com.example.myapp',
    distribute => 1,  # Full release pipeline
);

# Build with distribution (sign, notarize, DMG on macOS; AppImage on Linux)
$packer->build(sub {
    my ($result) = @_;
    print "Built: $result->{path}\n" if $result->{success};
    print "DMG: $result->{dmg_path}\n" if $result->{dmg_path};
});

DESCRIPTION

Chandra::Pack bundles a Perl script and its dependencies into a distributable application package. It creates .app bundles on macOS, AppImage-style directories on Linux, and portable directories on Windows.

When distribute => 1 is set, the full release pipeline runs:

  • macOS: codesign → notarize → staple → DMG

  • Linux: AppImage (via appimagetool)

  • Windows: Directory build (installer support planned)

CLASS METHODS

config(%args)

Configure credentials for signing and notarization. Call once before building. Settings can be persisted to ~/.chandra/pack.conf.

Chandra::Pack->config(
    # macOS signing/notarization
    identity         => 'Developer ID Application: ...',
    apple_id         => 'your@email.com',
    team_id          => 'ABCD1234',
    notary_keychain  => 'notary-profile',  # from notarytool store-credentials
    
    # Persist to disk
    save             => 1,
);

Environment variables are used as fallbacks:

CHANDRA_IDENTITY
CHANDRA_APPLE_ID
CHANDRA_TEAM_ID
CHANDRA_NOTARY_KEYCHAIN
CHANDRA_NOTARY_PASSWORD

INSTANCE METHODS

new(%args)

my $packer = Chandra::Pack->new(
    script     => 'app.pl',       # required
    name       => 'My App',       # default: derived from script name
    version    => '1.0.0',        # default: 0.0.1
    icon       => 'icon.png',     # optional
    assets     => 'assets/',      # optional
    output     => 'dist/',        # default: .
    platform   => 'macos',        # default: current platform
    identifier => 'com.x.myapp',  # default: org.perl.<name>
    perl       => '/usr/bin/perl',# default: current perl
    include    => ['DBI'],        # extra modules to include
    exclude    => ['Test::More'], # modules to skip
    distribute => 1,              # run full distribution pipeline
);

scan_deps

Returns a list of hashrefs with module and file keys for all detected dependencies.

build($callback)

Build for the configured platform. Calls $callback with a result hashref containing success, path, platform, and size.

When distribute => 1:

  • macOS: adds signed, notarized, dmg_path

  • Linux: adds appimage_path

build_macos

Build a macOS .app bundle. With distribute => 1, also signs, notarizes, and creates a DMG.

build_linux

Build a Linux AppImage-style directory. With distribute => 1, runs appimagetool to create a standalone AppImage.

build_windows

Build a Windows portable directory.

DISTRIBUTION DETAILS

macOS Code Signing

Uses hardened runtime with entitlements for JIT and unsigned memory (required for Perl). Ad-hoc signing (identity => '-') skips notarization but still works locally.

macOS Notarization

Requires Apple Developer account. Store credentials once with:

xcrun notarytool store-credentials notary-profile \
    --apple-id your@email.com \
    --team-id ABCD1234 \
    --password your-app-specific-password

Then configure:

Chandra::Pack->config(notary_keychain => 'notary-profile');

Linux AppImage

Requires appimagetool in PATH. Install from: https://github.com/AppImage/AppImageKit/releases

SEE ALSO

Chandra::App

1 POD Error

The following errors were encountered while parsing the POD:

Around line 912:

Non-ASCII character seen before =encoding in '→'. Assuming UTF-8