name: polylith-migrate-extract-to-base
description: "[Internal sub-skill of polylith-migrate-orchestrator. Do not load directly — load polylith-migrate-orchestrator first, which drives all phases.] Extract all application code from projects/<PROJECT>/ into a temporary migration base."
Skill: polylith-migrate-extract-to-base
Goal
Extract all application code from projects/<PROJECT>/ into a temporary migration base (bases/<TARGET_TOP_NS>/<INITIAL_BASE_NAME>/).
Inputs
From migration/<PROJECT>/state.md:
PROJECT_DIRORIG_TOP_NSTARGET_TOP_NS(default:ORIG_TOP_NS)INITIAL_BASE_NAMERUN_TEST_CMD(optional:RUN_LINT_CMD,RUN_TYPECHECK_CMD)
From migration/<PROJECT>/manifest.md:
- Directory tree and module map.
All inputs from
state.mdare assumed to satisfy the validation rules inpolylith-migrate-discover(### Validation rules). Validate before proceeding.
Steps
1. Create the Base Directory
- Create
bases/<TARGET_TOP_NS>/<INITIAL_BASE_NAME>/.
2. Move Application Code
- Move application packages/modules from
projects/<PROJECT>/to the base:- For
src/layout: Moveprojects/<PROJECT>/src/<pkg>/under the base. - For flat layout: Move
projects/<PROJECT>/<pkg>/under the base.
- For
- Leave non-code files (Dockerfiles, k8s manifests, deploy scripts,
pyproject.toml) inprojects/<PROJECT>/.
3. Update pyproject.toml
- Add the base to
[tool.polylith.bricks]:[tool.polylith.bricks] "../../bases/<TARGET_TOP_NS>/<INITIAL_BASE_NAME>" = "<TARGET_TOP_NS>/<INITIAL_BASE_NAME>"
4. Fix Imports
- Update imports minimally to ensure tests and linting pass.
5. Update manifest.md
- Reflect the new structure in
migration/<PROJECT>/manifest.md.
6. Handle Namespace Changes
If TARGET_TOP_NS != ORIG_TOP_NS, the migration orchestrator will handle this in subsequent phases:
polylith-migrate-generate-shimwill create a compatibility shim atprojects/${PROJECT}/${ORIG_TOP_NS}/__init__.pythat re-exports from${TARGET_TOP_NS}.${INITIAL_BASE_NAME}.polylith-migrate-automate-import-updateswill update imports in the new base location (atbases/${TARGET_TOP_NS}/${INITIAL_BASE_NAME}/) to reference the new namespace.polylith-migrate-update-testswill update test files to use the compatibility shim.
7. Use Shims if Needed
- If imports break during this phase, add minimal temporary shims to re-export names from the new brick API.
- Track shims in
migration/shims.md. - Note that comprehensive shim generation will be handled in the
polylith-migrate-generate-shimphase.
Verify
RUN_TEST_CMDsucceeds with the same pass/fail counts as the pre-migration baseline recorded inpolylith-migrate-discover.- If set,
RUN_LINT_CMDandRUN_TYPECHECK_CMDsucceed. - Run
POLY_CMD_PREFIX checkto validate the workspace structure. - Run
POLY_CMD_PREFIX syncto synchronize the[tool.polylith.bricks]table with actual imports.
Common failure modes
| Symptom | Likely cause | Remediation |
|---|---|---|
ModuleNotFoundError: No module named '<ORIG_TOP_NS>.<x>' after move |
TARGET_TOP_NS != ORIG_TOP_NS and imports weren't rewritten or shimmed. |
This is resolved by later phases per SHIM_STRATEGY (chosen in polylith-migrate-analyze-imports): shimless rewrites every reference in polylith-migrate-automate-import-updates (phase 4); shim adds a re-export shim under ORIG_TOP_NS in the phase 4b sub-track (polylith-migrate-generate-shim). To keep this phase green in the meantime, add a minimal temporary shim and record it in migration/shims.md (step 7). |
RUN_TEST_CMD collects 0 tests after the move |
Test files moved but pytest rootdir / testpaths still points at the old projects/<PROJECT>/tests location. |
Update pyproject.toml [tool.pytest.ini_options].testpaths or pass explicit dirs in RUN_TEST_CMD. (Note: polylith-migrate-prepare-project moves tests properly — if extract-to-base touched tests at all, consider undoing that part.) |
poly check reports "brick imports another brick that is not in [tool.polylith.bricks]" |
Step 3 only added the base; imports inside the base may pull in components not yet listed. | Run POLY_CMD_PREFIX sync --quiet to populate the rest, then re-run check. |
Editable install / build fails (error: package directory '<x>' does not exist) |
The base move broke the previous [tool.setuptools] or [tool.hatch.build] packages setting in projects/<PROJECT>/pyproject.toml. |
Update packages to point at the new <TARGET_TOP_NS> namespace, or remove the explicit packages setting and let Polylith's build hook handle it. |
| Verification fails and you can't quickly diagnose | Phase commit not yet made. | git reset --hard HEAD to roll back to the previous phase's commit and consult the user. |
Commit
After verification passes, commit this phase to the migration branch:
git add -A && git commit -m "migrate(<PROJECT>): phase <N> — extract-to-base"
Substitute <PROJECT>, <N>, and <phase-name> from state.md and the orchestrator's phase table. Do not proceed to the next phase without a clean commit — the per-phase commit is the rollback point for the next phase's failure-mode tables.