drago-ex / project-tools
Installation and cleanup tools for Drago projects.
Requires
- php: >=8.3
- composer-runtime-api: ^2.0
README
Tools for automatic installation and cleanup of project resources from Composer packages.
Features
drago-install: Automatically copies or replaces files/directories from vendor packages to your project root.drago-clean: Cleans up redundant resource folders invendor/drago-exto prevent class duplication or namespace collisions.drago-setup: Collects and runs setup commands provided by installed Drago packages.
Installation
Add the package to your project:
composer require drago-ex/project-tools
For component development, add it to require-dev:
composer require --dev drago-ex/project-tools
Configuration
In your package's composer.json, define what should be installed:
"extra": { "drago-project": { "install": { "copy": { "resources/Permission": "app/Core/Permission", "resources/assets": "assets/naja" }, "replace-once": true, "replace-priority": 100, "replace": { "resources/config/overrides.neon": "app/config/overrides.neon" } } } }
Global Options
To allow installation from packages with the default type library, enable this flag in your root composer.json:
"extra": { "drago-project": { "allow-library-install": true } }
Note: For security, only packages of type drago-project-resource are allowed to install resources by default. Use this flag to enable mirroring for standard libraries.
Sections:
copy: Copies files only if they do not already exist in the destination. Safe for initial setup.replace: Always overwrites the destination files. Useful for core updates or shared assets.
Skipping Packages
To skip a specific package during installation, add it to the packages map in your root composer.json:
"extra": { "drago-project": { "packages": { "vendor/package-name": { "skip": true } } } }
When skip is set to true, the package is ignored entirely - neither copy nor replace will run for it.
Skipping Only Copy or Replace
You can also skip only one install section for a package:
"extra": { "drago-project": { "packages": { "vendor/package-name": { "skip-copy": true, "skip-replace": true } } } }
skip-copy: Skips only the packagecopysection.skip-replace: Skips only the packagereplacesection.skip: Skips the whole package and has priority over section skips.
This is useful for preset packages where files should be overwritten once during initial project composition, but not overwritten again on later Composer updates.
Install Once
Packages that contain replace rules can mark themselves as replace-once:
"extra": { "drago-project": { "install": { "replace-once": true, "replace": { "resources/app": "app", "resources/assets": "assets" } } } }
After a successful replace run, drago-install writes this to the root project composer.json:
"extra": { "drago-project": { "packages": { "vendor/package-name": { "skip-replace": true } } } }
The next run keeps the package installed, but skips its replace section. The safer copy section can still run unless skip-copy or skip is also enabled.
replace-once is not applied in --dev mode.
Replace Priority
The installer runs in two phases:
- All package
copysections are processed first. - Package
replacesections are processed afterwards and sorted by priority.
Priority is configured in the package composer.json:
"extra": { "drago-project": { "install": { "replace-priority": 200 } } }
Lower priority runs earlier, higher priority runs later. This means higher-priority overlays win when multiple packages replace the same file.
Default priority is 100.
Example:
drago-ex/project-backend priority 100
drago-ex/project-backend-ui priority 200
netis-cms/project-preset priority 300
In this example, project-backend-ui can override backend files, and netis-cms/project-preset can override both.
Usage
Automation
Add these scripts to your composer.json to automate the process:
"scripts": { "post-install-cmd": [ "drago-install", "drago-clean" ], "post-update-cmd": [ "drago-install", "drago-clean" ] }
Manual Execution
You can also run the commands manually from your terminal:
vendor/bin/drago-install vendor/bin/drago-clean vendor/bin/drago-setup
Options
--verboseor-v: Show detailed file-by-file progress during installation.--dev: Switches the destination directory toresources/in the current working directory. Useful for testing installation logic during package development.
Setup Commands
Packages can expose setup commands in extra.drago-project.commands.
These commands can be used for database migrations, generated permission classes or any other post-installation task.
"extra": { "drago-project": { "commands-priority": 10, "commands": { "db:migrate-auth": "php vendor/bin/migration db:migrate vendor/drago-ex/project-auth/migrations", "create:auth-permission": "php vendor/bin/create-auth-permission" } } }
Run the setup tool from the project root:
vendor/bin/drago-setup
Inside Docker, run it as the web user:
docker compose exec -u www-data server php vendor/bin/drago-setup
Command Priority
The package-level commands-priority value controls the order of setup commands from that package.
Lower priority runs earlier. Default priority is 100.
Commands are sorted in two groups:
- Commands with labels starting with
db:run first. Use this prefix for database migrations and other database setup tasks. - All other commands run afterwards, for example
create:*,generate:*orget:*.
Inside each group, commands are sorted by commands-priority first and by command label alphabetically second.
This keeps migrations before application setup while still making the console order predictable.
Command values can be plain strings. Object values are also supported for readability.
Supported object keys are run, command and bin; run is the preferred form.
Setup Interaction
- Select specific tasks by number, for example
1,3. - Enter
ato run all tasks sequentially. - Enter
qto quit.
drago-setup does not inspect the database or Nette container.
It only discovers package commands and executes the selected shell command.
Database-specific behavior, such as creating the migrations table, belongs to the migration command itself.
How it works
drago-installscans all installed packages for theextra.drago-project.installconfiguration.- It resolves relative paths against the package root and the current working directory.
- It skips packages listed under
extra.drago-project.packagesin the rootcomposer.jsonwith"skip": true. - It runs all
copysections first. - It runs
replacesections afterwards, sorted byinstall.replace-priority. - It can skip only
copyorreplacesections withskip-copyandskip-replace. - It respects the
allow-library-installflag in your rootcomposer.json(defaults tofalsefor libraries). - Packages marked with
install.replace-onceautomatically addskip-replace: trueto the rootcomposer.jsonafter a successful replace run. drago-cleanspecifically targetsvendor/drago-exand removesresourcesdirectories to keep your vendor clean after files have been mirrored to your project.drago-setupscans installed packages forextra.drago-project.commandsand runs selected setup commands in priority order.