internal/dload
DLoad simplifies downloading and managing binary artifacts in PHP projects. Auto-install tools like RoadRunner or Temporal with version constraints, cross-platform support, and optional custom builds—keeping binaries out of VCS and onboarding fast.
## Getting Started
### Minimal Setup
1. **Install the package** in your Laravel project:
```bash
composer require internal/dload -W
Initialize configuration (interactive mode):
./vendor/bin/dload init
This generates a dload.xml file in your project root with default tools (e.g., RoadRunner, Temporal).
First download (e.g., RoadRunner):
./vendor/bin/dload get rr
The binary will be placed in your project root (or a custom path).
composer.json to auto-download on install/update:
{
"scripts": {
"post-install-cmd": "dload get --no-interaction -v || echo 'Failed to download binaries'",
"post-update-cmd": "dload get --no-interaction -v || echo 'Failed to download binaries'"
}
}
// app/Console/Commands/SetupBinaries.php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Symfony\Component\Process\Process;
class SetupBinaries extends Command
{
protected $signature = 'binaries:setup';
protected $description = 'Download required binaries via DLoad';
public function handle()
{
$process = new Process(['vendor/bin/dload', 'get']);
$process->run();
$this->output->writeln($process->getOutput());
}
}
<!-- dload.xml -->
<actions>
<download software="rr" version="^2025.1" extract-path="./bin" />
<download software="temporal" version="^1.3" extract-path="./tools" />
<download software="phpstan" type="phar" extract-path="./tools" />
</actions>
# .github/workflows/setup.yml
name: Setup Binaries
on: [push, pull_request]
jobs:
setup:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
- run: composer install -W
- run: ./vendor/bin/dload get --no-interaction
// app/Providers/DLoadServiceProvider.php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Symfony\Component\Process\Process;
class DLoadServiceProvider extends ServiceProvider
{
public function boot()
{
if ($this->app->environment('local')) {
$this->ensureBinariesDownloaded();
}
}
protected function ensureBinariesDownloaded()
{
$process = new Process(['vendor/bin/dload', 'get', '--no-interaction']);
$process->run();
if (!$process->isSuccessful()) {
$this->logBinaryDownloadError($process->getErrorOutput());
}
}
}
For tools not in DLoad’s built-in registry (e.g., buf):
<registry overwrite="false">
<software name="Buf" alias="buf" description="Buf CLI tool">
<repository type="github" uri="bufbuild/buf" asset-pattern="/^buf-.*/" />
<binary name="buf" pattern="/^buf(-.*)?(\.exe)?$/" version-command="--version" />
</software>
</registry>
<actions>
<download software="buf" extract-path="./bin" />
</actions>
For PHP tools like phpstan or psalm:
<actions>
<download software="phpstan" type="phar" extract-path="./tools" />
<download software="psalm" type="phar" version="^5.0" extract-path="./tools" />
</actions>
Binary Permissions:
composer.json:
"scripts": {
"post-dload": "chmod +x ./bin/*"
}
Version Constraints:
@beta, @alpha) are case-sensitive and must match the release metadata.dload show <tool> to verify available versions.Cross-Platform Paths:
extract-path uses forward slashes in XML, but Windows may fail if paths contain spaces.<download software="rr" extract-path="./binaries/RoadRunner" />
PHAR vs. Archive:
type="phar" prevents unpacking, while type="archive" forces it. Mismatches cause silent failures.dload show --all to inspect tool definitions.CI/CD Rate Limits:
--no-interaction and cache binaries:
- name: Cache binaries
uses: actions/cache@v3
with:
path: ./bin
key: ${{ runner.os }}-binaries-${{ hashFiles('dload.xml') }}
Dry Run:
./vendor/bin/dload get --dry-run
Shows what would be downloaded without actually fetching.
Verbose Output:
./vendor/bin/dload get -vvv
Reveals API calls, asset filtering, and platform matching.
Inspect Registry:
./vendor/bin/dload software --verbose
Lists all available tools with their metadata.
Validate XML:
xmllint --schema vendor/internal/dload/dload.xsd dload.xml --noout
Catches schema violations early.
Custom Download Handlers:
Extend DLoad’s registry by creating a custom handler class (see vendor/internal/dload/src/Handler/ for examples). Implement SoftwareHandlerInterface to support new repositories (e.g., GitLab, custom S3 buckets).
Pre/Post-Download Hooks: Use Laravel’s service provider boot method to run scripts after downloads:
public function boot()
{
if ($this->app->runningInConsole()) {
$this->callPostDownloadHooks();
}
}
protected function callPostDownloadHooks()
{
$process = new Process(['./vendor/bin/dload', 'get']);
$process->run();
if ($process->isSuccessful()) {
$this->runCustomScripts();
}
}
Dynamic Configuration:
Generate dload.xml dynamically in a Laravel command or event listener:
// app/Console/Commands/GenerateDLoadConfig.php
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
class GenerateDLoadConfig extends Command
{
protected $signature = 'dload:generate';
protected $description = 'Generate dload.xml based on environment';
public function handle()
{
$config = $this->getConfigForEnvironment();
File::put('dload.xml', $config);
}
protected function getConfigForEnvironment()
{
if (app()->environment('production')) {
return $this->getProductionConfig();
}
return $this->getDevelopmentConfig();
}
}
Environment-Specific Binaries:
Use Laravel’s environment files (.env) to switch configurations:
<!-- dload.xml -->
<actions>
<download software="rr"
version="{env('RR_VERSION', '^2025.1')}"
extract-path="./bin" />
</actions>
Combine with a custom env() helper to parse XML attributes dynamically.
Version Pinning:
Avoid ^ in versions for production to prevent unexpected updates:
<download software="rr" version="2025.1.3" /> <!-- Exact version -->
Binary Paths:
Use extract-path to organize tools (e.g., ./bin, ./tools):
<download software="rr" extract-path="./bin" />
<download software="phpstan" type="phar" extract-path="./tools" />
**CI/CD Optimization
How can I help you explore Laravel packages today?