feat(sync): public mdfluence.sync library API - #87
Open
geopanther wants to merge 14 commits into
Open
Conversation
Cover apply_title_prefix (set/None/empty, None parent_title), prefix realization in get_pages_from_directory, and --title override re-applying prefix. Tests precede implementation (TDD).
Add mdfluence.sync.apply_title_prefix(page, prefix) as an args-free helper. get_pages_from_directory now realizes the title prefix on every page (title + parent_title) at the end of collection, so collected pages are upsert-ready. Remove the duplicate prefix f-strings from pre_process_page and apply the prefix once in collect_pages_to_upload for the stdin and single-file paths, re-applying after a --title override.
Add plan.md describing the TDD roadmap for exposing the mdfluence.sync library surface (apply_title_prefix, prefix realization, PublishOptions, Reporter/NullReporter, publish() hooks) for embedding mdfluence as a library.
Move the title-prefix helper out of the sync module so document code no longer depends on sync, removing a cross-module import cycle risk.
The CLI already passes a possibly-None update message, so type the upsert_page parameter as Optional[str] to match runtime behaviour.
Move pre_process_page, validate_relative_links, build_document_path_to_page_map and update_pages_with_relative_links from __main__ into mdfluence.sync, decoupled from argparse via a new PublishOptions dataclass and from the TUI via a Reporter protocol with a NullReporter default. Add publish() with prepare_pages and parent_resolver hooks, extract default_parent_resolver, and raise RelativeLinkError instead of exiting so the library never calls sys.exit. Rewire main() onto PublishOptions and catch RelativeLinkError at the CLI boundary.
Re-export MinimalConfluence, Page, get_pages_from_directory, publish, PublishOptions, Reporter, NullReporter, RelativeLinkError and apply_title_prefix so downstream code can embed mdfluence as a library.
main() duplicated the entire upload loop that publish() already implements, risking divergence. Make the CLI a thin caller of publish() via an on_page_upserted hook (emits page URL / JSON) and boundary error handling. Decouple the reporter from the work: publish() no longer wraps mutations in a `with reporter:` scope. The reporter is a pure observer, mutations are gated solely by PublishOptions, and the caller owns the reporter's display lifecycle (the CLI runs `with tui: publish(...)`). Drop __enter__/__exit__ from the Reporter protocol accordingly. Add tests for the on_page_upserted hook, page-error propagation, and that publish() treats the reporter as a pure observer.
Parent resolution moved to default_parent_resolver, so pre_process_page no longer reads space_info. Remove the dead parameter and update the tests that passed it.
apply_title_prefix is defined in mdfluence.document to avoid an import cycle but advertised on the mdfluence.sync surface. Add a comment at the import so the split home is not surprising to future readers.
plan.md was a TDD roadmap for building the sync library API. The work is now implemented, so the plan is stale dev scaffolding rather than shippable documentation. Remove it from the repo root.
block_code wrote PNG bytes to a temp dir inline, mixing the markup-rendering concern with filesystem persistence. Move that persistence into a new diagrams.write_diagram_png helper so the renderer stays a pure markup transformer. The temp dirs backing rendered diagrams were also never cleaned up; they are now tracked and removed at process exit via an atexit hook, after the upload step has read them.
Move the re, anchor and alerts imports out of heading() and block_alert() up to module scope. There is no import cycle (anchor, diagrams and plugins.alerts do not import the renderer), so the function-local imports only obscured the module's dependencies.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Exposes a stable
mdfluence.synclibrary surface so downstream tools (e.g. gitfluence) can embed mdfluence as a library instead of shelling out to the CLI. Orchestration helpers are moved out of__main__, decoupled from argparse and the TUI, and a publicpublish()entry point with extension hooks is added.No ticket reference provided (personal repo).
What changed
PublishOptionsdataclass — replaces the argparseNamespacedependency in orchestration helpers.Reporterprotocol +NullReporter— decouples the upload loop fromMd2cfTUI; library callers get silent progress reporting by default.publish(confluence, pages, options, reporter=None, prepare_pages=None, parent_resolver=None)— public entry point with one-timeprepare_pagesand per-pageparent_resolverhooks;default_parent_resolverextracted.pre_process_page,validate_relative_links,build_document_path_to_page_map,update_pages_with_relative_linksfrom__main__intomdfluence.sync.RelativeLinkError— the library raises a typed error instead of callingsys.exit; the CLI catches it at its boundary.apply_title_prefixnow realizes the prefix during directory collection (title + parent_title + anchors); hosted inmdfluence.documentto avoid an import cycle.fix(upsert)—upsert_pagemessagetypedOptional[str]to match runtime behaviour.mdfluence:MinimalConfluence,Page,get_pages_from_directory,publish,PublishOptions,Reporter,NullReporter,RelativeLinkError,apply_title_prefix.main()buildsPublishOptionsfrom args.How to test
Written test-first (TDD). Run the suite:
tytype checker andruffare clean.test_package/unit/test_sync.py(PublishOptions, Reporter/NullReporter, moved helpers,publish()hooks, public surface); title-prefix tests intest_document.py.Notes
__main__— no CLI behaviour change.publish()never callssys.exit; callers decide how to handleRelativeLinkError/HTTPError.