summaryrefslogtreecommitdiff
path: root/config
diff options
context:
space:
mode:
authorClaude <noreply@anthropic.com>2026-09-21 08:13:49 +0000
committerClaude <noreply@anthropic.com>2026-09-21 08:13:49 +0000
commit5876025559ba0ad287d3a7a4d9fa0246509e668e (patch)
treec918d01e2b74d205ee00fe96926232475840ff97 /config
Scaffold Listen, with a podcast-native feed parser
Sibling to FeeDreader, not a shared module. That was a considered call: its FeedParser only inspects <enclosure> while hunting for a thumbnail, and its FilterRuleEngine is 46 lines of title substring matching that doesn't generalise to queue rules, so only Opml.kt would genuinely have transferred. The parser is the piece everything else sits on, so it goes first, test-first: 18 tests covering audio/video enclosure selection, iTunes durations in both second and clock form, season/episode numbers, podcast:chapters for the skip feature, RFC 5005 archive paging for drip subscriptions, and episode identity falling back to the enclosure URL when a guid is missing. Two things worth recording: - Built on XmlPullParserFactory rather than android.util.Xml. The latter returns null off-device, which is why FeeDreader's 297-line parser has no tests at all. Both resolve to the same KXmlParser on Android. - SimpleDateFormat with isLenient=false rejects "Tue, 02 Sep 2026 06:00:00 GMT" -- an entirely ordinary RFC 822 date. Left strict, every pubDate in the app would have been null and episode ordering would have been silently wrong everywhere. minSdk is 29, deliberately not FeeDreader's 36, which would restrict the app to Android 16 and newer. Permissions: INTERNET and ACCESS_NETWORK_STATE for feeds; FOREGROUND_SERVICE, FOREGROUND_SERVICE_MEDIA_PLAYBACK, POST_NOTIFICATIONS and WAKE_LOCK because Android requires a foreground service with a notification to play audio in the background. That notification is the transport control, not an alert -- Listen posts no new-episode notifications by design. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018AwnALZL6bD4VBtATDVv3B
Diffstat (limited to 'config')
-rw-r--r--config/detekt/detekt.yml20
1 files changed, 20 insertions, 0 deletions
diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml
new file mode 100644
index 0000000..a5b1129
--- /dev/null
+++ b/config/detekt/detekt.yml
@@ -0,0 +1,20 @@
+# Builds on detekt's default ruleset (see app/build.gradle.kts: buildUponDefaultConfig = true).
+# Only overrides/additions relative to the defaults belong here -- keep this file small so
+# upgrading detekt pulls in sane new defaults automatically instead of us silently diverging.
+
+style:
+ ReturnCount:
+ max: 5 # the feed parser is guard-clause heavy on purpose -- an enclosure with no URL, no
+ # type, or a non-playable type each bail out early. Forcing those into nested conditionals
+ # to satisfy a limit of 2 would make the code harder to read, not easier.
+ MaxLineLength:
+ maxLineLength: 140 # several files carry long, deliberate rationale comments (see
+ # ReaderExtractor.kt) -- 120 (detekt's default) wrapped mid-explanation too aggressively.
+ ForbiddenComment:
+ active: false # this codebase deliberately doesn't use TODO/FIXME markers (see CLAUDE.md
+ # "why these checks") -- nothing to forbid.
+
+naming:
+ FunctionNaming:
+ ignoreAnnotated: ["Composable"] # Jetpack Compose's own naming convention is PascalCase for
+ # composable functions -- that's the correct style here, not a violation.