Take one module fix mid-train
A patch release of one module does not need the whole project to move. The update stays inside the train the lock names, touches one module directory and one entry of the lock, and refuses as soon as a newer train is waiting.
Before you start
The module is one you required yourself. It has a line under requires in grim.json, and that line is the name you pass. A module that came in as a dependency of another cannot be moved alone.
Commit what you are working on. The update merges the new release into the module's directory under src/ and rewrites grim.lock, and it refuses to run over uncommitted changes to tracked files. A clean tree also keeps the commit of step four down to the fix.
Bring the stack up. A single-module update runs nothing in the container, and the migrations and the suite of the later steps need it.
$ git status --short
$ grim upThe ritual, in order
Five steps. Only the second changes the project, and the fifth is repeated on every other machine that has the project.
Read the plan
Nothing is written. The dry run of
grim updatewith a module name checks that the module can be had, looks for a newer train, and prints the one row that would move.$ grim update cart --dry-run Checking for updates... Train 2.4 (core 2.4.2 → 2.4.2) cart 2.4.0 → 2.4.1 (~2.4) Dry run — no changes applied.The row reads: the module, the version in the lock, the newest release on train
2.4that the constraint in brackets allows.Everything is up to date on train 2.4.in its place means the fix has no release on your train yet.The headline names core with the same version on both sides of the arrow. That is how a single-module plan says core stays where it is. No core row in the table means no core change.
Take the fix
The same plan, applied. The new release is merged into
src/Cart/against the one you installed, so edits of your own in the module survive, andgrim.lockis written again.$ grim update cart … Applying updates... ✓ 1 item(s) updated … cart 2.4.0 → 2.4.1: 3 written, 0 removed, 0 merged, 0 conflict(s) Review with git status and git diff, then commit it as: chore(grim): cart 2.4.0 → 2.4.1Core and the other units are not touched, and neither
composer installnor the migrations run. In the lock, the entry ofcartgets the new version and commit. Every other module, every theme, the train and the core version are carried over as they were.When you had edited a file the fix also changes, the merge leaves conflict markers in it, lists it under
conflict(s)and exits non-zero, asgit mergedoes. Resolve the markers before step four.Run the module's migrations
Optional. A fix that ships a migration needs it applied by hand, because a single-module update leaves the container alone.
grim artisanruns it in the app container.$ grim artisan migrateNothing to migrate.is the normal answer for a fix that only changed code.Test, then commit the lock
The project tracks the module as plain files, so the fix is in its diff next to the lock. Commit both once
grim testagrees.$ grim test $ git status --short $ git add grim.lock src/Cart $ git commit -m "chore(grim): cart 2.4.0 → 2.4.1"The status lists files under
src/Cart/andgrim.lock, and nothing else. In the lock, one entry has a new version and commit.Land it on the other machines
A colleague gets the fix from your commit, not from running the update again.
git pullbrings the module's files and the lock together, at the release you tested. Only the migrations are left, because nothing runs them on pull.$ git pull $ grim artisan migrateA newer release published in the meantime changes nothing: the commit is what lands.
grim installleaves a module directory that is already in the project as it is.
What you have now
One module and its entry in the lock moved. The train and everything else on it are the same as before.
{
"train": "2.4",
"core_version": "2.4.2",
"modules": {
"cart": { "version": "2.4.1" }
}
}Nothing is deployed yet. The fix reaches a server the way every change does, as a new image built from this commit.
When it does not work
“Train 2.5 available; run grim update (train)”
The core constraint in grim.json allows a newer train than the one in the lock, and a module is never moved alone across that line. Either take the whole train with Move a project to a new train, or pin the project to its train with "core": "2.4.*" and run the single-module update again. The pin is a decision to stay behind, so write it down in the commit.
“Module "payments" not found in grim.json”
The name is not under requires. Either it is spelled differently there, and only the spelling of grim.json is accepted, or the module is a dependency of another one. grim why shows which. A dependency moves with a bare grim update: while no newer train exists, that brings every unit to its newest release on the current train. Read its dry run first.
“grim.lock does not record a train”
The lock was written before trains existed, so there is no train to stay inside. Run grim update --dry-run and then grim update once. The lock it writes names the train, and single-module updates work from then on.
The suite fails with the fix in
Until you commit, the old release is still in git. The tree was clean when the update started, so restoring it undoes the update.
$ git checkout .
$ git status --shortsrc/Cart/ and grim.lock are back at the old release. Files the fix added stay behind as untracked, and the status lists them for you to delete. A migration the fix applied is not rolled back, so look at what step three ran before you go on.
Next recipe
Add, trace and remove modules
Find a module in the catalogue, require it on the project's train, trace what came along with it, and later remove it, sweep the leftovers and write the lock again.
Read itSpells used here
grim update
Board the newest train
Move core, every module and every theme onto the newest release train grim.json allows, or a single module within the train it is on.
grim artisan
Run artisan in the container
Run an artisan command inside the app container, where the app's PHP, extensions and environment are.
grim test
Run the test suite
Run the project's tests in the app container against a separate test database that grim creates and migrates for you.
grim install
Assemble the whole project
Turn grim.json into a working project by fetching core, every module and theme, writing grim.lock, building the image and starting the stack.
grim why
Ask why a module is here
Show the chain of requirements that leads from grim.json to an installed module, and what that module requires in turn.