Skip to content

Conversation

@samiuelson
Copy link
Contributor

@samiuelson samiuelson commented Dec 11, 2025

Description

This PR modularizes the SelectedSite class by moving it (along with supporting utilities and extensions) from the main WooCommerce module to the libs/commons module. SelectedSite is one of the core classes used by a great number of classes, moving it to libs/commons enables better code reuse and reduces coupling, unlocking further modularization possibilities 👉 #15094

Test Steps

  • Verify CI is green
  • Smoke test the app

Images/gif

N/A

  • I have considered if this change warrants release notes and have added them to RELEASE-NOTES.txt if necessary. Use the "[Internal]" label for non-user-facing changes.

- Move `SiteComponent`, `SiteScope`, and `SiteCoroutineScope` definitions to `libs/commons`.
- Move `SelectedSite` and `SiteConnectionType` to `libs/commons`.
- Rename `SiteComponent.kt` to `SiteComponentEntryPoint.kt` in the app module to reflect the removal of the component definition.
- Configure `libs/commons` build to support Hilt and expose FluxC dependencies.
@samiuelson samiuelson force-pushed the hack-modularize-selected-site branch from f605018 to 185bdcc Compare December 11, 2025 13:01
@wpmobilebot
Copy link
Collaborator

wpmobilebot commented Dec 11, 2025

Project dependencies changes

list
+ New Dependencies
androidx.preference:preference-ktx:1.2.1
tree
-+--- project :libs:fluxc
-|    +--- org.wordpress:wellsql:2.0.0
-|    |    +--- androidx.annotation:annotation:1.2.0 -> 1.9.1 (*)
-|    |    \--- org.wordpress.wellsql:wellsql-annotations:2.0.0
-|    +--- project :libs:fluxc-annotations
-|    +--- org.greenrobot:eventbus:3.3.1 (*)
-|    +--- org.greenrobot:eventbus-java:3.3.1
-|    +--- com.squareup.okhttp3:okhttp:5.2.3 (*)
-|    +--- com.android.volley:volley:1.2.1
-|    +--- com.google.code.gson:gson:2.13.2
-|    |    \--- com.google.errorprone:error_prone_annotations:2.41.0
-|    +--- com.google.dagger:dagger:2.57.2
-|    |    +--- jakarta.inject:jakarta.inject-api:2.0.1
-|    |    +--- javax.inject:javax.inject:1
-|    |    \--- org.jspecify:jspecify:1.0.0
-|    +--- org.jetbrains.kotlin:kotlin-stdlib:2.2.21 (*)
-|    +--- androidx.exifinterface:exifinterface:1.4.2
-|    |    +--- androidx.annotation:annotation:1.8.1 -> 1.9.1 (*)
-|    |    \--- org.jspecify:jspecify:1.0.0
-|    +--- androidx.security:security-crypto:1.1.0
-|    |    +--- androidx.annotation:annotation:1.8.1 -> 1.9.1 (*)
-|    |    +--- androidx.collection:collection:1.4.2 -> 1.5.0 (*)
-|    |    +--- com.google.crypto.tink:tink-android:1.8.0
-|    |    |    \--- com.google.code.gson:gson:2.8.9 -> 2.13.2 (*)
-|    |    \--- org.jspecify:jspecify:1.0.0
-|    +--- androidx.core:core-ktx:1.17.0 (*)
-|    +--- org.wordpress:utils:3.15.0 (*)
-|    +--- com.squareup.okhttp3:okhttp-urlconnection:5.2.3
-|    |    +--- com.squareup.okhttp3:okhttp:5.2.3 (*)
-|    |    +--- com.squareup.okhttp3:okhttp-java-net-cookiejar:5.2.3
-|    |    |    +--- com.squareup.okhttp3:okhttp:5.2.3 (*)
-|    |    |    \--- org.jetbrains.kotlin:kotlin-stdlib:2.2.20 -> 2.2.21 (*)
-|    |    \--- org.jetbrains.kotlin:kotlin-stdlib:2.2.20 -> 2.2.21 (*)
-|    +--- com.squareup.okhttp3:okhttp-tls:5.2.3
-|    |    +--- com.squareup.okhttp3:okhttp:5.2.3 (*)
-|    |    +--- com.squareup.okio:okio:3.16.4 (*)
-|    |    \--- org.jetbrains.kotlin:kotlin-stdlib:2.2.20 -> 2.2.21 (*)
-|    +--- org.apache.commons:commons-text:1.14.0 (*)
-|    +--- androidx.paging:paging-runtime:2.1.2
-|    |    +--- androidx.paging:paging-common:2.1.2
-|    |    |    +--- androidx.annotation:annotation:1.0.0 -> 1.9.1 (*)
-|    |    |    \--- androidx.arch.core:core-common:2.0.0 -> 2.2.0 (*)
-|    |    +--- androidx.arch.core:core-runtime:2.0.0 -> 2.2.0 (*)
-|    |    +--- androidx.lifecycle:lifecycle-runtime:2.0.0 -> 2.10.0 (*)
-|    |    +--- androidx.lifecycle:lifecycle-livedata:2.0.0 -> 2.10.0 (*)
-|    |    \--- androidx.recyclerview:recyclerview:1.0.0 -> 1.4.0 (*)
-|    +--- androidx.room:room-runtime:2.8.4 (*)
-|    +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2 (*)
-|    +--- org.jetbrains.kotlin:kotlin-parcelize-runtime:2.2.21
-|    |    \--- org.jetbrains.kotlin:kotlin-stdlib:2.2.21 (*)
-|    \--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2 (*)
++--- project :libs:login
+|    \--- project :libs:fluxc
+|         +--- org.wordpress:wellsql:2.0.0
+|         |    +--- androidx.annotation:annotation:1.2.0 -> 1.9.1 (*)
+|         |    \--- org.wordpress.wellsql:wellsql-annotations:2.0.0
+|         +--- project :libs:fluxc-annotations
+|         +--- org.greenrobot:eventbus:3.3.1 (*)
+|         +--- org.greenrobot:eventbus-java:3.3.1
+|         +--- com.squareup.okhttp3:okhttp:5.2.3 (*)
+|         +--- com.android.volley:volley:1.2.1
+|         +--- com.google.code.gson:gson:2.13.2
+|         |    \--- com.google.errorprone:error_prone_annotations:2.41.0
+|         +--- com.google.dagger:dagger:2.57.2
+|         |    +--- jakarta.inject:jakarta.inject-api:2.0.1
+|         |    +--- javax.inject:javax.inject:1
+|         |    \--- org.jspecify:jspecify:1.0.0
+|         +--- org.jetbrains.kotlin:kotlin-stdlib:2.2.21 (*)
+|         +--- androidx.exifinterface:exifinterface:1.4.2
+|         |    +--- androidx.annotation:annotation:1.8.1 -> 1.9.1 (*)
+|         |    \--- org.jspecify:jspecify:1.0.0
+|         +--- androidx.security:security-crypto:1.1.0
+|         |    +--- androidx.annotation:annotation:1.8.1 -> 1.9.1 (*)
+|         |    +--- androidx.collection:collection:1.4.2 -> 1.5.0 (*)
+|         |    +--- com.google.crypto.tink:tink-android:1.8.0
+|         |    |    \--- com.google.code.gson:gson:2.8.9 -> 2.13.2 (*)
+|         |    \--- org.jspecify:jspecify:1.0.0
+|         +--- androidx.core:core-ktx:1.17.0 (*)
+|         +--- org.wordpress:utils:3.15.0 (*)
+|         +--- com.squareup.okhttp3:okhttp-urlconnection:5.2.3
+|         |    +--- com.squareup.okhttp3:okhttp:5.2.3 (*)
+|         |    +--- com.squareup.okhttp3:okhttp-java-net-cookiejar:5.2.3
+|         |    |    +--- com.squareup.okhttp3:okhttp:5.2.3 (*)
+|         |    |    \--- org.jetbrains.kotlin:kotlin-stdlib:2.2.20 -> 2.2.21 (*)
+|         |    \--- org.jetbrains.kotlin:kotlin-stdlib:2.2.20 -> 2.2.21 (*)
+|         +--- com.squareup.okhttp3:okhttp-tls:5.2.3
+|         |    +--- com.squareup.okhttp3:okhttp:5.2.3 (*)
+|         |    +--- com.squareup.okio:okio:3.16.4 (*)
+|         |    \--- org.jetbrains.kotlin:kotlin-stdlib:2.2.20 -> 2.2.21 (*)
+|         +--- org.apache.commons:commons-text:1.14.0 (*)
+|         +--- androidx.paging:paging-runtime:2.1.2
+|         |    +--- androidx.paging:paging-common:2.1.2
+|         |    |    +--- androidx.annotation:annotation:1.0.0 -> 1.9.1 (*)
+|         |    |    \--- androidx.arch.core:core-common:2.0.0 -> 2.2.0 (*)
+|         |    +--- androidx.arch.core:core-runtime:2.0.0 -> 2.2.0 (*)
+|         |    +--- androidx.lifecycle:lifecycle-runtime:2.0.0 -> 2.10.0 (*)
+|         |    +--- androidx.lifecycle:lifecycle-livedata:2.0.0 -> 2.10.0 (*)
+|         |    \--- androidx.recyclerview:recyclerview:1.0.0 -> 1.4.0 (*)
+|         +--- androidx.room:room-runtime:2.8.4 (*)
+|         +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2 (*)
+|         +--- org.jetbrains.kotlin:kotlin-parcelize-runtime:2.2.21
+|         |    \--- org.jetbrains.kotlin:kotlin-stdlib:2.2.21 (*)
+|         \--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2 (*)
-+--- project :libs:fluxc-plugin
-|    +--- project :libs:fluxc (*)
-|    +--- project :libs:fluxc-annotations
-|    +--- com.google.code.gson:gson:2.13.2 (*)
-|    +--- com.google.dagger:dagger:2.57.2 (*)
-|    +--- org.jetbrains.kotlin:kotlin-stdlib:2.2.21 (*)
-|    +--- org.wordpress:utils:3.15.0 (*)
-|    +--- androidx.core:core-ktx:1.17.0 (*)
-|    +--- org.wordpress:wellsql:2.0.0 (*)
-|    +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2 (*)
-|    +--- androidx.room:room-runtime:2.8.4 (*)
-|    \--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2 (*)
+\--- project :libs:pos
+|    \--- project :libs:commons
+|         +--- project :libs:fluxc (*)
+|         +--- project :libs:fluxc-plugin
+|         |    +--- project :libs:fluxc (*)
+|         |    +--- project :libs:fluxc-annotations
+|         |    +--- com.google.code.gson:gson:2.13.2 (*)
+|         |    +--- com.google.dagger:dagger:2.57.2 (*)
+|         |    +--- org.jetbrains.kotlin:kotlin-stdlib:2.2.21 (*)
+|         |    +--- org.wordpress:utils:3.15.0 (*)
+|         |    +--- androidx.core:core-ktx:1.17.0 (*)
+|         |    +--- org.wordpress:wellsql:2.0.0 (*)
+|         |    +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2 (*)
+|         |    +--- androidx.room:room-runtime:2.8.4 (*)
+|         |    \--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2 (*)
+|         +--- androidx.core:core-ktx:1.17.0 (*)
+|         +--- androidx.compose.ui:ui -> 1.9.4 (*)
+|         +--- androidx.preference:preference-ktx:1.2.1
+|         |    +--- androidx.preference:preference:1.2.1 (*)
+|         |    +--- androidx.core:core-ktx:1.1.0 -> 1.17.0 (*)
+|         |    +--- androidx.fragment:fragment-ktx:1.3.6 -> 1.8.9 (*)
+|         |    \--- org.jetbrains.kotlin:kotlin-stdlib:1.6.0 -> 2.2.21 (*)
+|         +--- org.greenrobot:eventbus:3.3.1 (*)
+|         \--- org.apache.commons:commons-text:1.14.0 (*)
-\--- project :libs:login
-     \--- project :libs:fluxc (*)

@wpmobilebot
Copy link
Collaborator

wpmobilebot commented Dec 11, 2025

📲 You can test the changes from this Pull Request in WooCommerce-Wear Android by scanning the QR code below to install the corresponding build.
App NameWooCommerce-Wear Android
Platform⌚️ Wear OS
FlavorJalapeno
Build TypeDebug
Commite766de2
Direct Downloadwoocommerce-wear-prototype-build-pr15086-e766de2.apk

@wpmobilebot
Copy link
Collaborator

wpmobilebot commented Dec 11, 2025

📲 You can test the changes from this Pull Request in WooCommerce Android by scanning the QR code below to install the corresponding build.

App NameWooCommerce Android
Platform📱 Mobile
FlavorJalapeno
Build TypeDebug
Commite766de2
Direct Downloadwoocommerce-prototype-build-pr15086-e766de2.apk

@wpmobilebot
Copy link
Collaborator

wpmobilebot commented Dec 11, 2025

🤖 Build Failure Analysis

This build has failures. Claude has analyzed them - check the build annotations for details.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR modularizes the SelectedSite class by moving it (along with supporting utilities and extensions) from the main WooCommerce module to the libs/commons module. This enables better code reuse and reduces coupling, allowing the commons module to be used independently or in other contexts.

  • Moves SelectedSite class and related components to the commons module
  • Consolidates string utility functions (StringUtils, StringExt, NumberExt) into commons
  • Updates ResourceProvider to have its own implementation of getQuantityString
  • Separates app-specific SiteComponentEntryPoint from the core SiteComponent

Reviewed changes

Copilot reviewed 6 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
libs/commons/src/main/java/com/woocommerce/android/tools/SelectedSite.kt New file containing the SelectedSite singleton class moved to commons module
libs/commons/src/main/java/com/woocommerce/android/tools/SiteConnectionType.kt Updated BuildConfig import to reference commons module instead of main app
libs/commons/src/main/java/com/woocommerce/android/viewmodel/ResourceProvider.kt Replaced dependency on StringUtils with inline implementation of getQuantityString
libs/commons/src/main/java/com/woocommerce/android/util/StringUtils.kt New utility object with string manipulation functions including email validation, formatting, and HTML processing
libs/commons/src/main/java/com/woocommerce/android/extensions/StringExt.kt New extension functions for String including HTML stripping, version comparison, and file size formatting
libs/commons/src/main/java/com/woocommerce/android/extensions/NumberExt.kt New extension functions for numbers including formatting and percentage conversion
libs/commons/src/main/java/com/woocommerce/android/di/SiteComponent.kt Removed app-specific entry point interface, keeping only the core component definition
WooCommerce/src/main/kotlin/com/woocommerce/android/di/SiteComponentEntryPoint.kt New file containing app-specific SiteComponent entry point moved from commons
libs/commons/build.gradle Added Hilt, Compose, EventBus, and other dependencies; exposed FluxC via api configuration
WooCommerce/build.gradle Removed FluxC dependencies as they now come transitively through commons

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@samiuelson samiuelson marked this pull request as ready for review December 12, 2025 18:32
@samiuelson samiuelson added the type: task An internally driven task. label Dec 12, 2025
@samiuelson samiuelson added this to the 23.9 milestone Dec 12, 2025
implementation(libs.automattic.tracks.android)
implementation(libs.automattic.tracks.crashlogging)

implementation(project(":libs:fluxc"))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 I'm looking for opinions on whether it's better to declare fluxc as a transitive dependency in libs/commons and remove it from the WooCommerce module (this is what I did here since think it's cleaner) or keep it as a regular dependency in both of them. cc @wzieba

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm leaning into declaring fluxc as regular dependency. I can imagine a scenario in which we add a new module that will use common but won't have to use anything from fluxc. Not having fluxc as transitive dependency would be an advantage in such a case, to not share unnecessary classes, recuding dependencies etc.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless I'm missing something I believe Fluxc will be part of common either case @wzieba. The difference is just in the WooCommerce module - whether it's declared explicitly there or its a transitive dependency.

I mean, ideally, I would also prefer not having fluxc in common, but I don't think that's what's being discussed here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok so I understand the issue as @samiuelson described it is

Option A: fluxc transitive

// libs/commonts/build.gradle
dependencies {
    api(project(":libs:fluxc"))
}

// WooCommerce/build.gradle
dependencies {
    // nothing
}

Option B: fluxc non-transitive

// libs/commonts/build.gradle
dependencies {
    implementation(project(":libs:fluxc"))
}

// WooCommerce/build.gradle
dependencies {
    implementation(project(":libs:fluxc"))
}

My opinion is that I think Option B is better, because in the future, if we introduce a new module NewModule and we'll want to use common there but we don't need to use fluxc , then with Option B we don't unnecessarily offer fluxc. This way we reduce the dependency chain.

Copy link
Contributor

@wzieba wzieba Dec 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, ideally, I would also prefer not having fluxc in common, but I don't think that's what's being discussed here.

That's also an interesting point to discuss: it depends on what common is for us. I guess we might need both: a common that includes fluxc and a common that doesn't have to and shares different types of things. But this split is still doable incrementally later, so I think I would proceed with this PR as it's a step in right direction.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, I see - makes sense, thanks for elaborating on it! I agree that option B sounds better.

@malinajirka malinajirka self-assigned this Dec 16, 2025
Copy link
Contributor

@malinajirka malinajirka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, LGTM

// Workaround for kotlinx-metadata version incompatibility:
// Kotlin 2.2.21 generates metadata v2.2.0, but AGP 8.13.2's Compose lint detector
// only supports up to v2.0.0, causing crashes when analyzing Kotlin files.
// This can be removed when AGP updates its bundled kotlinx-metadata-jvm dependency.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 I think we might want to create a linear task for this to ensure we don't forget about it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: task An internally driven task.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants