Workspace migration API and inventory
Adopt a bounded repository
Morphir.Configuration.IO.WorkspaceMigrationService inventories, plans and applies
workspace adoption without constructing the CLI. It reuses ProjectMigration’s
mapping, raw loss ledger and independent equivalence verification. It does not
compile sources, move generated outputs, remove classic manifests or invoke
publication services.
var root = ProjectPath.normalize(Path.GetFullPath(directory));
var service = new WorkspaceMigrationService(
new FileSystemProjectTree(root), new NativeConfigurationTransactionHost());
var preview = service.Plan(root, includes: ["apps/**"], excludes: ["**/experimental"]);
if (preview.CanApply)
{
var outcome = service.Apply(preview);
// Inspect outcome.Status, Artifacts, RestoredPaths and UnresolvedPaths.
}
Omit storage for a read-only host. Supply InMemoryProjectTree or implement
IProjectTree for a mounted tree. Both use canonical absolute paths with /
separators. A mounted directory returns only immediate child directories or
links. A child outside that directory or the selected operation root blocks the
plan. Application requires storage-backed evidence and the service that created
the verified preview. Read-only and foreign-service plans cannot be applied.
Inventory rules
The absolute directory passed to Plan is the operation boundary even if the
host’s authorization boundary is larger. No ancestor is searched for projects
or workspace adoption. Inventory orders paths ordinally. It inspects shared
primary layouts and formats, including supplemental workspace JSON, without
reading personal, machine, environment or active profile overlays.
Include and exclude filters are repeated root-relative segment globs. * and
? match within one segment; ** matches zero or more segments. Absolute paths,
empty filters and .. segments are invalid. Excluded directories are pruned.
Existing workspace.exclude patterns retain their declared workspace-base
anchor and cannot be overridden by an include filter.
Filters select conversions; they do not remove existing declared members. Shared
discovery still inspects those members to verify their unchanged ownership and
selection. If a retained membership glob would enter a skipped output/dependency
tree or nested workspace, the plan reports workspace.migrate_membership_boundary
and blocks. Refine the declared membership or exclusions explicitly; migration
does not silently narrow a glob to the projects it happened to inventory.
Version control directories .git, .hg, .svn, dependency directories
node_modules, elm-stuff, vendor, .nuget, packages, and output directories
bin, obj, dist, build, target are skipped. Primary layout directories
.morphir and .config are inspected as layouts at their owner; they are not
separate projects. The declared workspace output directory is also skipped. Discovered links are reported and never followed, including
linked ancestors. A nested declared workspace is reported as a boundary and
its children are not inventoried for outer adoption. The maximum inventory is
100,000 directories; exceeding it blocks the plan instead of returning an
incomplete applicable result.
Inventory explains candidate, excluded, boundary, already migrated and skipped
link paths. Duplicate names remain distinct paths and produce a diagnostic;
explicit path selection remains unambiguous.
Reviewed membership and verification
Members preserves existing declarations, including globs, order and defaults,
and appends explicit root-relative paths for additions. A root project remains a
root project and never becomes its own glob member. An otherwise projectless
root becomes virtual. Already migrated members retain their bytes and settings.
An existing valid workspace with no conversions succeeds unchanged. An
undeclared empty root reports that adoption is impossible.
Projects contains the single-project plans and their loss ledgers. Use each
project’s Presentation for logs. The canonical Plan.Candidate and Plan.Edits
contain application values, including secrets; do not log them. Secret references
remain opaque leaves. Unsupported values cannot be dropped to make a batch pass.
The classic source contract is the same as project migration: a supported .json
manifest can contain full accepted JSON5 syntax. Legacy-shaped primaries in other
extensions are reported as blockers by the project service, rather than falsely
labeled already migrated. Canonical multi-format primaries remain readable.
Every conversion receives explicit proposed base workspace context. Verification
disables activation and compares declared profile controls separately. The
aggregate candidate excludes every converted classic source together and reruns
shared discovery and distinct-path selection. It must preserve project source
paths and non-adoption settings. Intended ownership, membership, default selection
and shared output-root changes appear separately in AdoptionEffects. They do
not authorize other value changes. Existing generated files stay where they are.
Root classic conversion uses the original target for conflict and loss checks,
then composes the reviewed member additions in the common workspace context.
Existing conflicting membership values still block. Declared workspace bases and
output roots do not reanchor the root project’s source directory. The additive
ProjectMigrationService.PlanInWorkspace API supplies component plans for this
composition; these read-only components cannot bypass aggregate application.
Application and recovery
Application validates source bytes, target bytes or absence, relevant directory listings and primary topology. It stages the entire batch before replacing any destination. Cooperating writers coordinate through the shared transaction adapter. Each file installation is atomic; the batch is not crash-atomic.
Storage-backed previews inspect pending journals without writing and expose
PendingRecovery; a pending operation makes the preview inapplicable. On failure
inspect the structured status, restored paths, unresolved paths and
owned artifacts. Pending recovery blocks overlapping shared configuration edits
and project migrations as well as subsequent workspace writes. Use the explicit
shared journal inspection and recovery APIs described in
transaction recovery. Do not remove recovery journals
or backups to bypass a guard. Preserve user changes and unresolved evidence.
CLI reports use the same plans and outcomes. See the workspace command reference, walkthrough and troubleshooting for exit codes, previews and scriptable JSON.
Supplied exclusions also control root-project conversion. For example, excluding
. leaves the classic root project in place while child adoption can still add
a workspace declaration. Root-project identity and existing ownership are
preserved. Excluding ** selects no conversions, including at the root.
Every newly adopted project is checked against its original non-adoption values, including additions to an existing workspace. A root backend or other inherited setting cannot silently change the new member. Retained members keep their prior workspace context; new members report their original standalone ownership and local output root before adoption.
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.