digidem / digidem/comapeo-core-react-native
Expo config plugin: programmatically merge backup-rules exclusions into host app manifest
Nobody has claimed this yet.
- Dominant language
- Kotlin
- Stars
- 1
- Forks
- 0
- Avg merge
- 8h 24m
- Merged PRs (30d)
- 9
Description
Context
@comapeo/core-react-native is published as an Expo module. The
library currently declares android:dataExtractionRules and
android:fullBackupContent on its <application> element to exclude
the rootkey-bearing SharedPreferences from cloud backup and
device-to-device transfer (see android/src/main/AndroidManifest.xml,
PR #36, comment thread on backup-rules merge conflict).
Host apps that already declare these attributes get a manifest-merger
conflict and must manually:
- Merge the library's exclusions into their own backup-rules XML.
- Add
tools:replace="android:dataExtractionRules,android:fullBackupContent"to their<application>tag.
This is documented in README.md > Configure for Android > Backup-rules merge conflict but it's still a friction point at integration time
and easy to forget when iterating.
Proposal
An Expo config plugin that runs at expo prebuild time and:
- Adds the library's backup-rules XML files to the host app's
res/xml/directory (or makes them resolvable via the library
AAR — they're already there, but the plugin can verify). - Reads the host app's existing backup-rules XML if any.
- Default Expo template apps don't set these → plugin sets the
attributes on the host's<application>and copies our XML files
in. No conflict because the host had no prior declaration. - Host already has rules → plugin parses the host's XML, merges our
<exclude domain="sharedpref" path="comapeo-core.xml" />entries
into the right sections (<cloud-backup>,<device-transfer>,
<full-backup-content>), writes the merged XML back, and ensures
the<application>attributes still point at it.
- Default Expo template apps don't set these → plugin sets the
- Removes the attributes from the library's own
AndroidManifest.xml so there's never a merge conflict —
responsibility shifts entirely to the host manifest, which the
plugin owns at prebuild time.
For non-Expo (bare-RN-without-Expo) consumers, the README path stays
the canonical fix.
Why this is worth doing
- Eliminates a build-time integration step for the largest class of
consumers (managed-Expo apps). - Removes the manifest-merger conflict for any consumer that has its
own backup rules — friction point disappears entirely. - Keeps secure-by-default: forgetting to register the plugin is the
only way to lose the exclusion, and that's discoverable via a
smoke test (the encrypted SharedPreferences ends up in backups).
Cost
Roughly 100–150 LOC of plugin code plus tests:
withDangerousModfor the XML file copy / merge step.withAndroidManifestfor the<application>attribute add /
tools:replacehandling.- An XML-merge helper that's safe against repeated invocations
(expo prebuildruns are idempotent in the rest of the toolchain;
this plugin should be too). - A test fixture covering: (a) host with no rules, (b) host with
rules that already have our exclusions, (c) host with rules that
conflict.
Acceptance
- Plugin lives in
plugins/(or wherever published Expo plugins
go in this repo) and is auto-registered when the package is
installed. -
expo prebuild --cleanon a fresh Expo template + this module
produces a host manifest with our exclusions, no conflicts. -
expo prebuild --cleanon an Expo template that ALREADY has
backup rules merges our exclusions in non-destructively. - Re-running prebuild is idempotent — no duplicate
<exclude>
entries, no togglingtools:replace. - Library's own
AndroidManifest.xmlno longer declares the
backup attributes once the plugin path is verified end-to-end. -
README.md > Configure for Androidupdates to reflect that
Expo consumers need do nothing; bare-RN consumers follow the
manual path.
Open questions
- Should the plugin be opt-in (consumer adds it to their
app.json
plugins array) or auto-registered (viaexpo-module.config.json)?
Auto is friendlier; opt-in is more explicit. - What should the plugin do if it detects an existing
tools:replace="android:dataExtractionRules"on the host? Mostly:
nothing, because the host has explicitly opted out of merging.
Log a warning suggesting they include our exclusions. - How do bare-RN consumers (no Expo) interact with this? They
continue to follow the README path; the plugin doesn't apply.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with android/src/main/AndroidManifest.xml, README.md’s Configure for Android section, and the repository’s Expo module configuration to determine where published plugins belong and how they are registered. Review the proposed withDangerousMod and withAndroidManifest responsibilities, then define fixtures for hosts with no rules, existing exclusions, and conflicts. Done means the acceptance checks pass, including clean and repeated expo prebuild runs and the README update.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- android, react-native
- Domain
- build-system, mobile
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100