This story is to implement discovery of Old Butler parent repositories by following the _parent symlink as described below. There is a little special case behavior to implement too, in the case of an outputRoot input argument for an initialized CameraMapper
It is easy to create the list of parent repositories with New Butler repositories. Each repository has a RepositoryCfg file which has a parent list. Elements of the parent list can be either URI to the repository root or cfgRoot of parent RepositoryCfg files, or can be a RepositoryCfg repr string that describes a parent repository. The Repr string typically contains overrides or additions to a RepositoryCfg that exists elsewhere at root or repoCfg.
To create the list, Butler need simply load the RepositoryCfg, get its parents, load those, and so on. This is already implemented.
Generating a list of parents of an Old Butler repository is usually easy as well: if a repository is determined to be an Old Butler repository (it is probably enough to say it is Old if the repository does not have a RepositoryCfg.yaml file) then it can be searched for a _parent symlink. If one is found, add that repo to be created as a parent. It should also be searched for a _parent symlink, and so on until a repo without a _parent symlink is found.
There is one known special case where following the _parent symlinks will sometimes not work, because the _parent symlink is created during CameraMapper init, after repository discovery.
This occurs when the CameraMapper is instantiated by Butler and an outputRoot input argument is passed in for the CameraMapper. Butler builds its list of input and output repositories early during Butler init, this includes finding Old Butler input repositories by following _parent symlinks. Butler then initializes a Repository class for each repository, which in turn will init the CameraMapper (if it’s not already an instance). During CameraMapper init, outputRoot gets used as root, and a new _parent symlink is created in the new root linking to the original root. That is to say, root becomes ``_parent`` and outputRoot becomes root. But because this happens during CameraMapper init, it happens too late to be discovered by Butler’s repository-discovery _parent search mechanism.
To solve this specific use case, if mapperArgs contains ‘outputRoot’ then butler will create 2 RepositoryCfgs. root will be an input repository, and outputRoot will be a read-write output repository.