rmb32 / barn-paths
Finds or makes a barn (a project with a .barn/ folder) and says where each app keeps its files inside it
Requires
- php: ^8.5
Requires (Dev)
- deptrac/deptrac: ^4.7
- infection/infection: ^0.35.4
- phpstan/phpstan: ^2.2
- phpunit/phpunit: ^12.0
- squizlabs/php_codesniffer: ^4.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-11-06 09:59:35 UTC
README
Find the barn a directory belongs to, make a new one, and say where each app keeps its files inside it.
A barn is any project with a .barn/ folder at its root. Each app that works in a barn keeps its
settings and records in a folder of its own inside it, whether one app is used or all of them, and adds
nothing else to the project's root:
my-shop/
.barn/
barn/
settings.json # the project's name
barnspec/
settings.json # the requirements app's settings
... # and its records
barnark/ # the architecture app's records
barncept/
concepts/ # saved concepts
composer.json
src/
tests/
An app with nothing to keep has no folder. Every path stored inside those files stays relative to the
barn's root (my-shop/), not to .barn/.
Requirements
- PHP 8.5+
Installation
composer require rmb32/barn-paths
Finding a barn
locate() walks up from a directory to the nearest one holding a .barn/ folder, so it works from
anywhere inside the project. It returns null outside a barn:
use Rmb32\BarnPaths\Api\Factory\BarnLocatorFactory;
$barn = new BarnLocatorFactory()->create()->locate(getcwd());
if ($barn === null) {
// say so, and offer to make one
}
The root it returns is a real path, with symlinks and .. resolved. The walk doesn't stop at a git
repository's root.
Making a barn
create() makes the .barn/ folder in an existing directory and nothing else; each app makes its own
folder inside when it first writes:
use Rmb32\BarnPaths\Api\Exception\InsideAnotherBarn;
use Rmb32\BarnPaths\Api\Factory\BarnCreatorFactory;
$creator = new BarnCreatorFactory()->create();
try {
$barn = $creator->create('/home/sam/my-shop');
} catch (InsideAnotherBarn $refusal) {
// ask whether to make a separate barn inside $refusal->enclosingBarn->root, and if so:
$barn = $creator->create('/home/sam/my-shop', insideAnotherBarn: true);
}
It refuses with a checked exception, so the caller can say why:
| Exception | When | Carries |
|---|---|---|
BarnAlreadyThere | the directory already has .barn/ | barn |
InsideAnotherBarn | a barn was found further up, and insideAnotherBarn wasn't set | root, enclosingBarn |
BarnNotCreated | the directory doesn't exist or is a file, or .barn/ couldn't be made in it | root |
The paths
BarnPaths holds absolute paths for one barn:
| Property | Path |
|---|---|
root | the project root |
directory | .barn |
barnSettings | .barn/barn/settings.json |
barnspecData | .barn/barnspec |
barnspecSettings | .barn/barnspec/settings.json |
barnarkDirectory | .barn/barnark |
barnceptConcepts | .barn/barncept/concepts |
Its constants (BarnPaths::BARN_SETTINGS, BarnPaths::BARNSPEC_DATA and so on) hold the same paths
relative to the root, for messages and for writing paths into files.
BarnPaths::at() gives the paths for a root you already know, and exists() says whether its .barn/
folder is there.
Used in Barn
Barn builds barns; its apps read and write their files at the paths this package gives them.
Internals · History · Known issues
License
Proprietary. See LICENSE. Copyright (c) Roger Barnfather.