When developing a package, projects usually have multiple environments with related dependencies they consume or build on, defined in one or more metadata files:
fusion.json: Machines consuming the package (production)fusion.dev.php: All development machines working on the project (optional)fusion.local.php: Your local machine (optional)
Note
To illustrate and demonstrate buildable metadata, we use the Box - PHP DI Container package.
Transitions between environments are typically managed using a version control system.
Note
For version control, we use Git. Initializing a repository is optional and only needed if you want filename highlighting. The reference is only meant to illustrate dummy files, and the example itself does not require a repository.
Production Metadata
Like each new project, we start by creating the required fusion.json file in
an empty directory of your choice, with the following dummy content:
{
"name": "Package",
"description": "Example package.",
"id": "valvoid/package",
"version": "0.1.0",
"structure": {
"/state": "stateful",
"/dependencies": [
"valvoid.com/valvoid/box/1.0.0"
]
},
"environment": {
"php": {
"version": "8.1.0"
}
}
}
In addition to all required primitive,
structure, and
environment entries, our production
metadata also defines a
nested valvoid.com/valvoid/box/1.0.0 dependency
mapped to the custom dependencies directory. To pull this dependency, open a
terminal in the project directory and run the
build command:
fusion build
Once done, our project directory contains, alongside other files created by Fusion (not shown here for simplicity):
dependenciesvalvoidbox: Box package
statePrefixAutoloader.php: Indexed codesnapshot.json: Pulled version
fusion.json
Since the
trailing reference segment
1.0.0 in our dependency source is a shortcut version range
(>=1.0.0 && <2.0.0), the pulled version stored in the stateful
snapshot.json file is essential to ensure the same state across machines.
Note
Using snapshot files across machines is the recommended way to replicate a common state, for example, to simplify debugging or provide a fallback build.
We follow this recommended approach and ignore both generatable directories
while keeping the snapshot.json file tracked by excluding it in the
.gitignore file:
dependencies
state/*
!state/snapshot.json
To simulate a cloned repository replication, delete the ignored content according
to the .gitignore rules. The project directory should then contain only:
statesnapshot.json: Pulled version
.gitignorefusion.json
Open a terminal in the project directory and run the
replicate command:
fusion replicate
The project directory should now contain the same files as the previously built state.
Loadable Dependency Code
As shown above, Fusion not only pulls the dependency into our project, it also
indexes loadable code in the generated PrefixAutoloader.php file. Let's add
some basic code to verify everything works. For injectable code, create a src
directory in the root of the package, and add a file Package.php inside it with
the following code:
namespace Valvoid\Package;
class Package
{
public function getCodeType(): string
{
return "Lazy";
}
}
For executable script, create a cli.php file in the root directory with the
following content:
use Valvoid\Box\Box;
use Valvoid\Package\Package;
require __DIR__ . "/state/PrefixAutoloader.php";
$autoloader = new PrefixAutoloader;
$autoloader->register();
$box = new Box;
$package = $box->get(Package::class);
echo $package->getCodeType() . " code";
After this, the project directory looks like:
dependenciesvalvoidbox
srcPackage.php
statesnapshot.dev.jsonsnapshot.jsonPrefixAutoloader.php
.gitattributes.gitignorecli.phpfusion.json
Open a terminal in the project directory and run the lightweight
register command:
fusion register
Note
Since we already built the external package and our basic code does not exist
yet, the lightweight register command is sufficient to regenerate the stateful
PrefixAutoloader.php file. Otherwise, the `build` command would also index
our code.
Running the cli.php> script should output:
Lazy code