internal/dload
DLoad is a PHP tool to download and manage binary artifacts (RoadRunner, Temporal, custom tools) for your projects. It automates installs, pins versions, handles cross-platform builds, and keeps binaries out of VCS via CLI and config.
Installation:
composer require internal/dload -W
Add to composer.json scripts for automatic execution:
"scripts": {
"post-update-cmd": "dload get --no-interaction -v || \"echo can't dload binaries\""
}
First Use Case: Initialize a basic configuration:
./vendor/bin/dload init --no-interaction
This creates dload.xml with default RoadRunner and Temporal packages.
Immediate Execution: Download dependencies:
./vendor/bin/dload get
Binaries will be placed in ./bin/ by default.
dload.xml (auto-generated in project root)./vendor/bin/dload for command help./vendor/bin/dload software# Initialize with interactive prompts
./vendor/bin/dload init
# Download all configured binaries
./vendor/bin/dload get
# Add to composer scripts for automatic execution
composer require internal/dload -W
<!-- dload.xml -->
<actions>
<download software="rr" version="2025.1.0" />
<download software="temporal" version="^1.3@beta" />
</actions>
# .github/workflows/ci.yml
- name: Install dependencies
run: composer install -n --prefer-dist
- name: Download binaries
run: ./vendor/bin/dload get --no-interaction --path=./bin
<!-- dload.xml -->
<actions>
<velox config-file="./velox.toml">
<plugin name="temporal" />
<plugin name="kv" />
</velox>
</actions>
// app/Providers/DLoadServiceProvider.php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Internal\DLoad\DLoad;
class DLoadServiceProvider extends ServiceProvider
{
public function boot()
{
$dload = new DLoad(config_path('dload.xml'));
$dload->get(); // Execute during boot
// Register binaries as Laravel commands
$this->registerBinaries();
}
protected function registerBinaries()
{
if (file_exists($rr = base_path('bin/rr'))) {
$this->app->singleton('roadrunner', function () {
return new \RoadRunner\RoadRunner($rr);
});
}
}
}
// app/Console/Commands/DownloadBinaries.php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Internal\DLoad\DLoad;
class DownloadBinaries extends Command
{
protected $signature = 'binaries:download {--config= : Path to config file}';
protected $description = 'Download project binaries using DLoad';
public function handle()
{
$config = $this->option('config') ?? config_path('dload.xml');
$dload = new DLoad($config);
$this->info("Downloading binaries from {$config}...");
$dload->get();
$this->info('Binaries downloaded successfully!');
}
}
// config/dload.php
return [
'path' => env('DLOAD_PATH', base_path('bin')),
'temp_dir' => storage_path('dload_temp'),
'default_software' => [
'rr' => '^2025.1',
'temporal' => '^1.3',
],
];
// In a service or controller
use Internal\DLoad\DLoad;
public function setupEnvironment()
{
$config = [
'actions' => [
'download' => [
['software' => 'rr', 'version' => env('RR_VERSION', '^2025.1')],
['software' => 'frontend', 'extract-path' => public_path('assets')],
],
],
];
$dload = new DLoad();
$dload->setConfig($config);
$dload->get();
}
Binary Path Conflicts
/usr/local/bin--path or configure temp-dir in XML:
<dload temp-dir="./runtime">
Permission Denied
--force flag or manually set permissions after downloadVersion Constraint Mismatch
^1.0.0 may pull unstable releases if no stable version exists@stable suffix:
<download software="tool" version="^1.0.0@stable" />
Missing Go for Velox Builds
velox actions fail with "Go not found"<velox config-file="./velox.toml" velox-version="2025.1.1" />
PHAR vs Archive Confusion
type="phar":
<download software="psalm" type="phar" />
Verbose Output
./vendor/bin/dload get -vvv
Dry Run
./vendor/bin/dload get --dry-run
Configuration Validation
./vendor/bin/dload init --validate
Manual Download Testing
$dload = new DLoad();
$dload->setConfig($config);
$result = $dload->get(['--verbose' => true]);
dd($result->getErrors());
Custom Software Registry Extend the registry by creating a service provider:
// app/Providers/DLoadRegistryProvider.php
use Internal\DLoad\Registry\SoftwareRegistry;
class DLoadRegistryProvider extends ServiceProvider
{
public function boot()
{
$registry = app(SoftwareRegistry::class);
$registry->addSoftware([
'name' => 'custom-tool',
'repository' => 'https://example.com/releases',
'binary' => ['name' => 'tool', 'pattern' => '/^tool-.*/'],
]);
}
}
Pre/Post Download Hooks
$dload = new DLoad();
$dload->on('beforeDownload', function ($software) {
// Add custom logic before download
});
$dload->on('afterDownload', function ($software, $path) {
// Modify binary path or permissions
chmod($path, 0755);
});
Custom Download Handlers
Implement Internal\DLoad\Handlers\HandlerInterface:
class CustomHandler implements HandlerInterface
{
public function handle(DownloadAction $action, DLoad $dload)
{
// Custom download logic
return new DownloadResult(true, 'Custom handler executed');
}
}
Register the handler:
$dload->addHandler(new CustomHandler(), 'custom');
Configuration Overrides Use environment variables to override XML settings:
$dload = new DLoad();
$dload->setConfigPath(env('DLOAD_CONFIG', config_path('dload.xml')));
$dload->setTempDir(env('DLOAD_TEMP_DIR', storage_path('dload_temp')));
XML Schema Validation
dload.xml:
./vendor/bin/dload init --validate
xsi:noNamespaceSchemaLocation1.0 without ^ or ~)Path Resolution
extract-path are resolved from the download directoryCross-Platform Issues
\\).exe) are auto-added on WindowsHow can I help you explore Laravel packages today?