Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enforce resourcePrefix on Android library modules #123

Merged
merged 4 commits into from
Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ internal open class NavigationRobot(
private val schedule by composeTestRule.stringResource(R.string.schedule)
private val home by composeTestRule.stringResource(R.string.home)
private val contactMe by composeTestRule.stringResource(R.string.contact_me)
private val backDescription by composeTestRule.stringResource(FeatureTeacherscheduleR.string.content_description_back)
private val backDescription by composeTestRule.stringResource(
FeatureTeacherscheduleR.string.feature_teacherschedule_content_description_back,
)

private val back by lazy {
composeTestRule.onNodeWithContentDescription(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ internal open class HomeEndToEndRobot(
}

// The strings used for matching in these tests
private val menuDescription by composeTestRule.stringResource(FeatureHomeR.string.menu)
private val menuDescription by composeTestRule.stringResource(FeatureHomeR.string.feature_home_menu)

private val menuButton by lazy {
composeTestRule.onNode(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ internal open class LoginEndToEndRobotRobot(
}

// The strings used for matching in these tests
private val loginDescription by composeTestRule.stringResource(FeatureLoginR.string.content_description_login)
private val loginDescription by composeTestRule.stringResource(FeatureLoginR.string.feature_login_content_description_login)

private val loginButton by lazy {
composeTestRule.onNode(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ internal open class ScheduleEndToEndRobot(
) = ReadOnlyProperty<Any?, String> { _, _ -> activity.getString(resId) }

// The strings used for matching in these tests
private val scheduleTopAppBarTag by composeTestRule.stringResource(FeatureTeacherScheduleR.string.tag_schedule_top_app_bar)
private val scheduleTopAppBarTag by composeTestRule.stringResource(
FeatureTeacherScheduleR.string.feature_teacherschedule_tag_schedule_top_app_bar,
)

private val scheduleTopAppBar by lazy {
composeTestRule.onNodeWithTag(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ internal open class WelcomeEndToEndRobot(
) = ReadOnlyProperty<Any?, String> { _, _ -> activity.getString(resId) }

// The strings used for matching in these tests
private val welcomeTitleString by composeTestRule.stringResource(FeatureLoginR.string.welcome_title)
private val getStartedString by composeTestRule.stringResource(FeatureLoginR.string.get_started)
private val welcomeTitleString by composeTestRule.stringResource(FeatureLoginR.string.feature_login_welcome_title)
private val getStartedString by composeTestRule.stringResource(FeatureLoginR.string.feature_login_get_started)

private val welcomeTitle by lazy {
composeTestRule.onNodeWithContentDescription(
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:label="@string/feature_teacherschedule_app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Tl.Splash"
Expand Down
4 changes: 4 additions & 0 deletions build-logic/convention/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ gradlePlugin {
id = "tl.android.application.flavors"
implementationClass = "AndroidApplicationFlavorsConventionPlugin"
}
register("androidLint") {
id = "tl.android.lint"
implementationClass = "AndroidLintConventionPlugin"
}
register("jvmLibrary") {
id = "tl.jvm.library"
implementationClass = "JvmLibraryConventionPlugin"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class AndroidApplicationConventionPlugin : Plugin<Project> {
with(pluginManager) {
apply("com.android.application")
apply("org.jetbrains.kotlin.android")
apply("tl.android.lint")
}

extensions.configure<ApplicationExtension> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,19 @@ class AndroidLibraryConventionPlugin : Plugin<Project> {
with(pluginManager) {
apply("com.android.library")
apply("org.jetbrains.kotlin.android")
apply("tl.android.lint")
}

extensions.configure<LibraryExtension> {
configureKotlinAndroid(this)
defaultConfig.targetSdk = 34
configureFlavors(this)
configureGradleManagedDevices(this)
// The resource prefix is derived from the module name,
// so resources inside ":core:module1" must be prefixed with "core_module1_"
resourcePrefix =
path.split("""\W""".toRegex()).drop(1).distinct().joinToString(separator = "_")
.lowercase() + "_"
}
extensions.configure<LibraryAndroidComponentsExtension> {
configurePrintApksTask(this)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import com.android.build.api.dsl.ApplicationExtension
import com.android.build.api.dsl.LibraryExtension
import com.android.build.api.dsl.Lint
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure

class AndroidLintConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
when {
pluginManager.hasPlugin("com.android.application") ->
configure<ApplicationExtension> { lint(Lint::configure) }

pluginManager.hasPlugin("com.android.library") ->
configure<LibraryExtension> { lint(Lint::configure) }

else -> {
pluginManager.apply("com.android.lint")
configure<Lint>(Lint::configure)
}
}
}
}
}

private fun Lint.configure() {
xmlReport = true
checkDependencies = true
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class JvmLibraryConventionPlugin : Plugin<Project> {
with(target) {
with(pluginManager) {
apply("org.jetbrains.kotlin.jvm")
apply("tl.android.lint")
}
configureKotlinJvm()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ class UiTextTest {
) = ReadOnlyProperty<Any?, String> { _, _ -> activity.getString(resId) }

// The strings used for matching in these tests
private val testString by composeTestRule.stringResource(R.string.generic_hello)
private val formattedStringSingle by composeTestRule.stringResource(R.string.greeting_with_name)
private val formattedStringMultiple by composeTestRule.stringResource(R.string.greeting_with_name_and_weather)
private val testString by composeTestRule.stringResource(R.string.core_common_generic_hello)
private val formattedStringSingle by composeTestRule.stringResource(R.string.core_common_greeting_with_name)
private val formattedStringMultiple by composeTestRule.stringResource(R.string.core_common_greeting_with_name_and_weather)

@Composable
fun TestUiTextContent(uiText: UiText): String {
Expand All @@ -64,7 +64,7 @@ class UiTextTest {
*/
@Test
fun stringResource_returnsExpectedValue_withoutArgs() {
val uiText = UiText.StringResource(R.string.generic_hello)
val uiText = UiText.StringResource(R.string.core_common_generic_hello)

composeTestRule.setContent {
TestUiTextContent(uiText)
Expand All @@ -81,7 +81,7 @@ class UiTextTest {
val argName = "Alice"
val uiText =
UiText.StringResource(
R.string.greeting_with_name,
R.string.core_common_greeting_with_name,
listOf(UiText.StringResource.Args.DynamicString(argName)),
)

Expand All @@ -105,7 +105,7 @@ class UiTextTest {
val argWeather = "sunny"
val uiText =
UiText.StringResource(
R.string.greeting_with_name_and_weather,
R.string.core_common_greeting_with_name_and_weather,
listOf(
UiText.StringResource.Args.DynamicString(argName),
UiText.StringResource.Args.DynamicString(argWeather),
Expand Down Expand Up @@ -133,7 +133,7 @@ class UiTextTest {
val argWeather = "sunny"
val uiText =
UiText.StringResource(
R.string.greeting_with_name_and_weather,
R.string.core_common_greeting_with_name_and_weather,
listOf(
UiText.StringResource.Args.UiTextArg(argName),
UiText.StringResource.Args.DynamicString(argWeather),
Expand Down
6 changes: 3 additions & 3 deletions core/common/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="generic_hello" translatable="false">Hello</string>
<string name="greeting_with_name" translatable="false">Hello, %s!</string>
<string name="greeting_with_name_and_weather" translatable="false">Hello, %1$s! It\'s a %2$s day today.</string>
<string name="core_common_generic_hello" translatable="false">Hello</string>
<string name="core_common_greeting_with_name" translatable="false">Hello, %s!</string>
<string name="core_common_greeting_with_name_and_weather" translatable="false">Hello, %1$s! It\'s a %2$s day today.</string>
</resources>
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.wei.teachlink.core.datastore

import android.util.Log
import androidx.datastore.core.DataStore
import com.wei.teachlink.core.model.data.DarkThemeConfig
import com.wei.teachlink.core.model.data.LanguageConfig
import com.wei.teachlink.core.model.data.ThemeBrand
import com.wei.teachlink.core.model.data.UserData
import kotlinx.coroutines.flow.map
import timber.log.Timber
import java.io.IOException
import javax.inject.Inject

Expand All @@ -24,18 +24,33 @@ constructor(
useDynamicColor = it.useDynamicColor,
themeBrand =
when (it.themeBrand) {
null, ThemeBrandProto.THEME_BRAND_UNSPECIFIED, ThemeBrandProto.UNRECOGNIZED, ThemeBrandProto.THEME_BRAND_DEFAULT -> ThemeBrand.DEFAULT
null,
ThemeBrandProto.THEME_BRAND_UNSPECIFIED,
ThemeBrandProto.UNRECOGNIZED,
ThemeBrandProto.THEME_BRAND_DEFAULT,
-> ThemeBrand.DEFAULT

ThemeBrandProto.THEME_BRAND_ANDROID -> ThemeBrand.ANDROID
},
darkThemeConfig =
when (it.darkThemeConfig) {
null, DarkThemeConfigProto.DARK_THEME_CONFIG_UNSPECIFIED, DarkThemeConfigProto.UNRECOGNIZED, DarkThemeConfigProto.DARK_THEME_CONFIG_FOLLOW_SYSTEM -> DarkThemeConfig.FOLLOW_SYSTEM
null,
DarkThemeConfigProto.DARK_THEME_CONFIG_UNSPECIFIED,
DarkThemeConfigProto.UNRECOGNIZED,
DarkThemeConfigProto.DARK_THEME_CONFIG_FOLLOW_SYSTEM,
-> DarkThemeConfig.FOLLOW_SYSTEM

DarkThemeConfigProto.DARK_THEME_CONFIG_LIGHT -> DarkThemeConfig.LIGHT
DarkThemeConfigProto.DARK_THEME_CONFIG_DARK -> DarkThemeConfig.DARK
},
languageConfig =
when (it.languageConfig) {
null, LanguageConfigProto.LANGUAGE_CONFIG_UNSPECIFIED, LanguageConfigProto.UNRECOGNIZED, LanguageConfigProto.LANGUAGE_CONFIG_FOLLOW_SYSTEM -> LanguageConfig.FOLLOW_SYSTEM
null,
LanguageConfigProto.LANGUAGE_CONFIG_UNSPECIFIED,
LanguageConfigProto.UNRECOGNIZED,
LanguageConfigProto.LANGUAGE_CONFIG_FOLLOW_SYSTEM,
-> LanguageConfig.FOLLOW_SYSTEM

LanguageConfigProto.LANGUAGE_CONFIG_ENGLISH -> LanguageConfig.ENGLISH
LanguageConfigProto.LANGUAGE_CONFIG_CHINESE -> LanguageConfig.CHINESE
},
Expand All @@ -50,7 +65,7 @@ constructor(
}
}
} catch (ioException: IOException) {
Log.e("TlPreferences", "Failed to update user preferences", ioException)
Timber.tag("TlPreferences").e(ioException, "Failed to update user preferences")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ fun FunctionalityNotAvailablePopup(onDismiss: () -> Unit) {
AlertDialog(
onDismissRequest = onDismiss,
text = {
val functionalityNotAvailable = stringResource(R.string.functionality_not_available)
val functionalityNotAvailable = stringResource(R.string.core_designsystem_functionality_not_available)
Text(
text = functionalityNotAvailable,
style = MaterialTheme.typography.bodyMedium,
modifier = Modifier.semantics { contentDescription = functionalityNotAvailable },
)
},
confirmButton = {
val close = stringResource(id = R.string.close)
val close = stringResource(id = R.string.core_designsystem_close)
TextButton(onClick = onDismiss) {
Text(
text = close,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
package com.wei.teachlink.core.designsystem.management.states.topappbar.scrollflags

import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.saveable.mapSaver
import androidx.compose.runtime.setValue
import androidx.compose.runtime.structuralEqualityPolicy
import com.wei.teachlink.core.designsystem.management.states.topappbar.ScrollFlagState

class EnterAlwaysCollapsedState(
heightRange: IntRange,
scrollOffset: Float = 0f,
) : ScrollFlagState(heightRange) {
override var mScrollOffset by mutableStateOf(
override var mScrollOffset by mutableFloatStateOf(
value = scrollOffset.coerceIn(0f, maxHeight.toFloat()),
policy = structuralEqualityPolicy(),
)

override val offset: Float
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
package com.wei.teachlink.core.designsystem.management.states.topappbar.scrollflags

import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.saveable.mapSaver
import androidx.compose.runtime.setValue
import androidx.compose.runtime.structuralEqualityPolicy
import com.wei.teachlink.core.designsystem.management.states.topappbar.ScrollFlagState

class EnterAlwaysState(
heightRange: IntRange,
scrollOffset: Float = 0f,
) : ScrollFlagState(heightRange) {
override var mScrollOffset by mutableStateOf(
override var mScrollOffset by mutableFloatStateOf(
value = scrollOffset.coerceIn(0f, maxHeight.toFloat()),
policy = structuralEqualityPolicy(),
)

override val offset: Float
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
package com.wei.teachlink.core.designsystem.management.states.topappbar.scrollflags

import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.saveable.mapSaver
import androidx.compose.runtime.setValue
import androidx.compose.runtime.structuralEqualityPolicy
import com.wei.teachlink.core.designsystem.management.states.topappbar.FixedScrollFlagState

class ExitUntilCollapsedState(
heightRange: IntRange,
scrollOffset: Float = 0f,
) : FixedScrollFlagState(heightRange) {
override var mScrollOffset by mutableStateOf(
override var mScrollOffset by mutableFloatStateOf(
value = scrollOffset.coerceIn(0f, rangeDifference.toFloat()),
policy = structuralEqualityPolicy(),
)

override var scrollOffset: Float
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
package com.wei.teachlink.core.designsystem.management.states.topappbar.scrollflags

import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.saveable.mapSaver
import androidx.compose.runtime.setValue
import androidx.compose.runtime.structuralEqualityPolicy
import com.wei.teachlink.core.designsystem.management.states.topappbar.ScrollFlagState

class ScrollState(
heightRange: IntRange,
scrollOffset: Float = 0f,
) : ScrollFlagState(heightRange) {
override var mScrollOffset by mutableStateOf(
override var mScrollOffset by mutableFloatStateOf(
value = scrollOffset.coerceIn(0f, maxHeight.toFloat()),
policy = structuralEqualityPolicy(),
)

override val offset: Float
Expand Down
4 changes: 2 additions & 2 deletions core/designsystem/src/main/res/values-zh-rTW/strings.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="close">CLOSE</string>
<string name="functionality_not_available">功能尚未上線 🙈</string>
<string name="core_designsystem_close">CLOSE</string>
<string name="core_designsystem_functionality_not_available">功能尚未上線 🙈</string>
</resources>
4 changes: 2 additions & 2 deletions core/designsystem/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="close">CLOSE</string>
<string name="functionality_not_available">Functionality not available 🙈</string>
<string name="core_designsystem_close">CLOSE</string>
<string name="core_designsystem_functionality_not_available">Functionality not available 🙈</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ internal open class ContactMeScreenRobot(
@StringRes resId: Int,
) = ReadOnlyProperty<Any?, String> { _, _ -> activity.getString(resId) }

private val profilePictureDescription by composeTestRule.stringResource(R.string.profile_picture)
private val linkedinString by composeTestRule.stringResource(R.string.linkedin)
private val emailString by composeTestRule.stringResource(R.string.email)
private val timezoneString by composeTestRule.stringResource(R.string.timezone)
private val callDescription by composeTestRule.stringResource(R.string.call)
private val profilePictureDescription by composeTestRule.stringResource(R.string.feature_contactme_profile_picture)
private val linkedinString by composeTestRule.stringResource(R.string.feature_contactme_linkedin)
private val emailString by composeTestRule.stringResource(R.string.feature_contactme_email)
private val timezoneString by composeTestRule.stringResource(R.string.feature_contactme_timezone)
private val callDescription by composeTestRule.stringResource(R.string.feature_contactme_call)

private val profilePicture by lazy {
composeTestRule.onNodeWithContentDescription(
Expand Down
Loading
Loading