mirror of
https://github.com/Glitchy-Sheep/boosty-downloader.git
synced 2026-10-15 05:41:48 +00:00
[PR #184] [MERGED] [application] Declare ports and build the app in a composition root #183
Labels
No labels
api-drift
bug
ci
documentation
enhancement
enhancement
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Glitchy-Sheep/boosty-downloader#183
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/Glitchy-Sheep/boosty-downloader/pull/184
Author: @Glitchy-Sheep
Created: 9/13/2026
Status: ✅ Merged
Merged: 9/13/2026
Merged by: @Glitchy-Sheep
Base:
main← Head:refactor/composition-root📝 Commits (2)
d0db42b[application] Declare ports for the reporter, the post cache and the failure loge884583[cli] Build the app in a composition root and drop application/di📊 Changes
26 files changed (+413 additions, -382 deletions)
View changed files
➖
boosty_downloader/application/di/__init__.py(+0 -0)➖
boosty_downloader/application/di/app_environment.py(+0 -149)➖
boosty_downloader/application/di/download_context.py(+0 -35)➖
boosty_downloader/application/di/initialized_app.py(+0 -102)➕
boosty_downloader/application/download_context.py(+40 -0)📝
boosty_downloader/application/download_plan.py(+2 -4)➕
boosty_downloader/application/ports.py(+73 -0)📝
boosty_downloader/application/post_retry.py(+1 -1)📝
boosty_downloader/application/use_cases/download_all_posts.py(+1 -1)📝
boosty_downloader/application/use_cases/download_single_post.py(+1 -1)📝
boosty_downloader/application/use_cases/download_specific_post.py(+1 -1)📝
boosty_downloader/application/use_cases/plan_download.py(+2 -4)📝
boosty_downloader/cli/commands/check.py(+15 -9)📝
boosty_downloader/cli/commands/download.py(+34 -30)➕
boosty_downloader/cli/composition_root.py(+158 -0)📝
boosty_downloader/cli/console_progress_reporter.py(+6 -5)➕
boosty_downloader/cli/update_check.py(+43 -0)📝
test/e2e/credentials_scope_test.py(+13 -10)📝
test/e2e/download_flow_test.py(+5 -3)📝
test/unit/file_downloader/extension_guessing_test.py(+1 -1)...and 6 more files
📄 Description
📝 Summary
Audit stage 3, part 1 of 3: the application layer stops importing cli, and the app is built in one place.
🔧 What changes
application/ports.pydeclares three Protocols with the methods the use cases actually call:ProgressReporter(8 methods),PostCache(4) andFailureLog(1). Implementations in cli and infrastructure match structurally and do not import the ports.DownloadContextmoves out ofapplication/diintoapplication/download_context.pyand is typed with the ports instead of the rich reporter,SQLitePostCacheandFailedDownloadsLogger.cli/composition_root.pyis the new composition root:load_settingsreads config.yaml and applies the CLI overrides,open_appopens the API session (with credentials), the media session (without), the reporter and the cache, and hands them out asApp.application/di/(AppConfig->AppEnvironment->Environment) is deleted. Thedownloadandcheckcommands read the same way: settings -> update check ->open_app-> use case -> view.cli/update_check.pyand is called by the commands.ConsoleProgressReporter, so the port and its implementation do not share a name.Behaviour
No user-facing change: same start order, same two sessions, same cache location rules (a CLI directory wins over the config value, the cache lands next to the posts unless
--cache-diris set).🧪 Tests
cast; pyright checks them against the ports (two fakes were missinginfoand got it).credentials_scope_testbuilds the app throughopen_app, so it checks the real wiring: token and cookie go to the API only.task cigreen locally: ruff, pyright strict, 238 tests + e2e.check,download --dry-run -f post_contentand the realdownload -f post_contentagree on the media count and size; the cache file lands under--cache-dir.⏭️ Next
PR 2: cache reset on a corrupted file and
clean-cachethrough a use case. PR 3:DownloadContentTypeFilterinto domain and an import-linter layers contract in CI.✅ Checklist
--helpand README if neededdocs/if the download flow or dev process changed## Unreleasedin CHANGELOG.md (or theci/skip-changeloglabel if not user-facing)🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.