Skip to content

Commit 9060b84

Browse files
authored
Spotless updates and lint (#55)
* Chore: Code maintenance, dependency updates, and build config This commit bundles several updates: 1. **Apply Spotless Formatting:** * Ran `./gradlew :androidApp:spotlessApply` to enforce code style consistency. 2. **Configure ktlint via `.editorconfig`:** * Added `.editorconfig` to the Fruitties project. * Configured ktlint to ignore function naming rules for Composable functions. * Disabled the standard multiline expression wrapping rule to allow for better readability in specific assignment cases. 3. **Update Dependencies:** * Updated various dependencies in `libs.versions.toml`: * agp: 8.9.1 * androidx-activityCompose: 1.10.1 * androidx-paging: 3.3.6 * androidx-room: to 2.7.0 * androidx-lifecycle: 2.9.0-beta01 * compose: 1.7.8 * compose-material3: 1.3.2 * dataStore: 1.1.4 * kotlin: 2.1.10 * ksp: 2.1.10-1.0.30 * pagingComposeAndroid: 3.3.6 * skie: 0.10.1 * sqlite: 2.5.0 4. **Set iOS Framework Bundle ID:** * Explicitly set the `bundleId` for iOS frameworks to `com.example.fruitties.ios` using `binaryOptions["bundleId"]`. * This resolves the compiler warning: "Please specify the bundle ID explicitly using the -Xbinary=bundleId=<id> compiler flag."
1 parent 028b24e commit 9060b84

File tree

21 files changed

+196
-77
lines changed

21 files changed

+196
-77
lines changed

Fruitties/.editorconfig

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
[*.{kt,kts}]
2+
# Kotlin style typically requires functions to start with a lowercase letter.
3+
# Composable functions should start with a capital letter.
4+
ktlint_function_naming_ignore_when_annotated_with = Composable
5+
6+
# ktlint always puts a new line after a multi-line assignment, like this:
7+
# val colors =
8+
# if (darkTheme) {
9+
# darkColorScheme(
10+
# primary = Color(0xFFBB86FC),
11+
# secondary = Color(0xFF03DAC5),
12+
# tertiary = Color(0xFF3700B3),
13+
# )
14+
# } else {
15+
# lightColorScheme(
16+
# primary = Color(0xFF6200EE),
17+
# secondary = Color(0xFF03DAC5),
18+
# tertiary = Color(0xFF3700B3),
19+
# )
20+
# }
21+
# But we actually prefer to keep some multi-line assignments on the same line, like this:
22+
# val colors = if (darkTheme) {
23+
# darkColorScheme(
24+
# primary = Color(0xFFBB86FC),
25+
# secondary = Color(0xFF03DAC5),
26+
# tertiary = Color(0xFF3700B3),
27+
# )
28+
# } else {
29+
# lightColorScheme(
30+
# primary = Color(0xFF6200EE),
31+
# secondary = Color(0xFF03DAC5),
32+
# tertiary = Color(0xFF3700B3),
33+
# )
34+
# }
35+
ktlint_standard_multiline-expression-wrapping = disabled

Fruitties/androidApp/src/main/AndroidManifest.xml

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
<uses-permission android:name="android.permission.INTERNET" />
1919
<application
2020
android:allowBackup="false"
21+
android:fullBackupContent="@xml/full_backup_content"
22+
android:dataExtractionRules="@xml/data_extraction_rules"
2123
android:supportsRtl="true"
2224
android:theme="@style/AppTheme"
2325
android:name=".di.App">

Fruitties/androidApp/src/main/java/com/example/fruitties/android/di/App.kt

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import com.example.fruitties.di.Factory
2323
class App : Application() {
2424
/** AppContainer instance used by the rest of classes to obtain dependencies */
2525
lateinit var container: AppContainer
26+
2627
override fun onCreate() {
2728
super.onCreate()
2829
container = AppContainer(Factory(this))

Fruitties/androidApp/src/main/java/com/example/fruitties/android/ui/ListScreen.kt

+8-5
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ fun ListScreen() {
9191
topBar = {
9292
CenterAlignedTopAppBar(
9393
title = {
94-
Text(text = stringResource(R.string.frutties),)
94+
Text(text = stringResource(R.string.frutties))
9595
},
9696
colors = TopAppBarColors(
9797
containerColor = MaterialTheme.colorScheme.primary,
@@ -105,7 +105,7 @@ fun ListScreen() {
105105
contentWindowInsets = WindowInsets.safeDrawing.only(
106106
// Do not include Bottom so scrolled content is drawn below system bars.
107107
// Include Horizontal because some devices have camera cutouts on the side.
108-
WindowInsetsSides.Top + WindowInsetsSides.Horizontal
108+
WindowInsetsSides.Top + WindowInsetsSides.Horizontal,
109109
),
110110
) { paddingValues ->
111111
Column(
@@ -145,8 +145,8 @@ fun ListScreen() {
145145
item {
146146
Spacer(
147147
Modifier.windowInsetsBottomHeight(
148-
WindowInsets.systemBars
149-
)
148+
WindowInsets.systemBars,
149+
),
150150
)
151151
}
152152
}
@@ -216,7 +216,10 @@ fun FruittieItem(
216216
}
217217

218218
@Composable
219-
fun CartDetailsView(cart: List<CartItemDetails>, modifier: Modifier = Modifier) {
219+
fun CartDetailsView(
220+
cart: List<CartItemDetails>,
221+
modifier: Modifier = Modifier,
222+
) {
220223
Column(
221224
modifier.padding(horizontal = 32.dp),
222225
) {

Fruitties/androidApp/src/main/res/values/strings.xml

-3
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,5 @@
1616
-->
1717
<resources>
1818
<string name="frutties">"Frutties"</string>
19-
<string name="save">Save</string>
2019
<string name="add">Add</string>
21-
<string name="loading">Loading</string>
22-
<string name="retry">Retry</string>
2320
</resources>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
Copyright 2025 The Android Open Source Project
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
-->
17+
<data-extraction-rules>
18+
<cloud-backup>
19+
<exclude domain="file" />
20+
<exclude domain="database" />
21+
<exclude domain="sharedpref" />
22+
<exclude domain="external" />
23+
<exclude domain="root" />
24+
<exclude domain="device_file" />
25+
<exclude domain="device_database" />
26+
<exclude domain="device_sharedpref" />
27+
<exclude domain="device_root" />
28+
</cloud-backup>
29+
<device-transfer>
30+
<exclude domain="file" />
31+
<exclude domain="database" />
32+
<exclude domain="sharedpref" />
33+
<exclude domain="external" />
34+
<exclude domain="root" />
35+
<exclude domain="device_file" />
36+
<exclude domain="device_database" />
37+
<exclude domain="device_sharedpref" />
38+
<exclude domain="device_root" />
39+
</device-transfer>
40+
</data-extraction-rules>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
Copyright 2025 The Android Open Source Project
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
-->
17+
<full-backup-content>
18+
<exclude domain="root" />
19+
<exclude domain="file" />
20+
<exclude domain="database" />
21+
<exclude domain="sharedpref" />
22+
<exclude domain="external" />
23+
</full-backup-content>

Fruitties/gradle/libs.versions.toml

+5-9
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,20 @@
1616
agp = "8.9.1"
1717
androidx-activityCompose = "1.10.1"
1818
androidx-paging = "3.3.6"
19-
androidx-room = "2.7.0-rc03"
20-
androidx-lifecycle = "2.9.0-alpha13"
19+
androidx-room = "2.7.0"
20+
androidx-lifecycle = "2.9.0-beta01"
2121
atomicfu = "0.27.0"
2222
compose = "1.7.8"
23-
compose-material3 = "1.3.1"
23+
compose-material3 = "1.3.2"
2424
dataStore = "1.1.4"
2525
kotlin = "2.1.10"
2626
kotlinx-coroutines = "1.10.1"
2727
kotlinxDatetime = "0.6.1"
28-
ksp = "2.1.10-1.0.29"
28+
ksp = "2.1.10-1.0.30"
2929
ktorVersion = "3.0.3"
3030
pagingComposeAndroid = "3.3.6"
3131
skie = "0.10.1"
32-
sqlite = "2.5.0-rc03"
32+
sqlite = "2.5.0"
3333
spotless = "7.0.2"
3434
okio = "3.10.2"
3535
runner = "1.6.2"
@@ -54,10 +54,7 @@ compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview"
5454
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
5555
kotlinx-atomicfu = { module = "org.jetbrains.kotlinx:atomicfu", version.ref = "atomicfu" }
5656
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" }
57-
kotlinx-coroutines-core-iosarm64 = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core-iossimulatorarm64", version.ref = "kotlinx-coroutines" }
58-
kotlinx-coroutines-core-iossimulatorarm64 = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core-iossimulatorarm64", version.ref = "kotlinx-coroutines" }
5957
kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinxDatetime" }
60-
ktor-client-android = { module = "io.ktor:ktor-client-android", version.ref = "ktorVersion" }
6158
ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktorVersion" }
6259
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktorVersion" }
6360
ktor-client-darwin = { module = "io.ktor:ktor-client-darwin", version.ref = "ktorVersion" }
@@ -77,7 +74,6 @@ androidLibrary = { id = "com.android.library", version.ref = "agp" }
7774
kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
7875
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
7976
androidKmpLibrary = { id = "com.android.kotlin.multiplatform.library", version.ref = "agp" }
80-
kotlinCocoapods = { id = "org.jetbrains.kotlin.native.cocoapods", version.ref = "kotlin" }
8177
kotlinxSerialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
8278
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
8379
skie = { id = "co.touchlab.skie", version.ref = "skie" }

Fruitties/iosApp/iosApp.xcodeproj/project.pbxproj

+2-2
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@
333333
"-framework",
334334
shared,
335335
);
336-
PRODUCT_BUNDLE_IDENTIFIER = orgIdentifier.iosApp;
336+
PRODUCT_BUNDLE_IDENTIFIER = com.example.fruitties.ios;
337337
PRODUCT_NAME = "$(TARGET_NAME)";
338338
SWIFT_VERSION = 5.0;
339339
TARGETED_DEVICE_FAMILY = "1,2";
@@ -362,7 +362,7 @@
362362
"-framework",
363363
shared,
364364
);
365-
PRODUCT_BUNDLE_IDENTIFIER = orgIdentifier.iosApp;
365+
PRODUCT_BUNDLE_IDENTIFIER = com.example.fruitties.ios;
366366
PRODUCT_NAME = "$(TARGET_NAME)";
367367
SWIFT_VERSION = 5.0;
368368
TARGETED_DEVICE_FAMILY = "1,2";

Fruitties/iosApp/iosApp/Info.plist

+3-3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
<key>UIApplicationSupportsMultipleScenes</key>
2626
<false/>
2727
</dict>
28+
<key>UILaunchScreen</key>
29+
<dict/>
2830
<key>UIRequiredDeviceCapabilities</key>
2931
<array>
3032
<string>armv7</string>
@@ -42,7 +44,5 @@
4244
<string>UIInterfaceOrientationLandscapeLeft</string>
4345
<string>UIInterfaceOrientationLandscapeRight</string>
4446
</array>
45-
<key>UILaunchScreen</key>
46-
<dict/>
4747
</dict>
48-
</plist>
48+
</plist>

Fruitties/shared/build.gradle.kts

-3
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
17-
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
1816

1917
plugins {
2018
alias(libs.plugins.kotlinMultiplatform)
@@ -138,7 +136,6 @@ kotlin {
138136
}
139137
}
140138
}
141-
142139
}
143140

144141
dependencies {

Fruitties/shared/src/androidMain/kotlin/com/example/fruitties/di/Factory.android.kt

+16-14
Original file line numberDiff line numberDiff line change
@@ -20,29 +20,31 @@ import androidx.room.Room
2020
import androidx.sqlite.driver.bundled.BundledSQLiteDriver
2121
import com.example.fruitties.database.AppDatabase
2222
import com.example.fruitties.database.CartDataStore
23-
import com.example.fruitties.database.dbFileName
23+
import com.example.fruitties.database.DB_FILE_NAME
2424
import com.example.fruitties.network.FruittieApi
2525
import kotlinx.coroutines.Dispatchers
2626

27-
actual class Factory(private val app: Application) {
27+
actual class Factory(
28+
private val app: Application,
29+
) {
2830
actual fun createRoomDatabase(): AppDatabase {
29-
val dbFile = app.getDatabasePath(dbFileName)
30-
return Room.databaseBuilder<AppDatabase>(
31-
context = app,
32-
name = dbFile.absolutePath,
33-
)
34-
.setDriver(BundledSQLiteDriver())
31+
val dbFile = app.getDatabasePath(DB_FILE_NAME)
32+
return Room
33+
.databaseBuilder<AppDatabase>(
34+
context = app,
35+
name = dbFile.absolutePath,
36+
).setDriver(BundledSQLiteDriver())
3537
.setQueryCoroutineContext(Dispatchers.IO)
3638
.build()
3739
}
3840

39-
actual fun createCartDataStore(): CartDataStore {
40-
return CartDataStore {
41-
app.filesDir.resolve(
42-
"cart.json",
43-
).absolutePath
41+
actual fun createCartDataStore(): CartDataStore =
42+
CartDataStore {
43+
app.filesDir
44+
.resolve(
45+
"cart.json",
46+
).absolutePath
4447
}
45-
}
4648

4749
actual fun createApi(): FruittieApi = commonCreateApi()
4850
}

Fruitties/shared/src/commonMain/kotlin/com/example/fruitties/DataRepository.kt

+1-3
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,7 @@ class DataRepository(
5757
return loadData()
5858
}
5959

60-
fun loadData(): Flow<List<Fruittie>> {
61-
return database.fruittieDao().getAllAsFlow()
62-
}
60+
fun loadData(): Flow<List<Fruittie>> = database.fruittieDao().getAllAsFlow()
6361

6462
suspend fun refreshData() {
6563
val response = api.getData()

Fruitties/shared/src/commonMain/kotlin/com/example/fruitties/database/AppDatabase.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,5 @@ abstract class AppDatabase : RoomDatabase() {
3232
expect object AppDatabaseConstructor : RoomDatabaseConstructor<AppDatabase> {
3333
override fun initialize(): AppDatabase
3434
}
35-
internal const val dbFileName = "fruits.db"
35+
36+
internal const val DB_FILE_NAME = "fruits.db"

Fruitties/shared/src/commonMain/kotlin/com/example/fruitties/database/CartDataStore.kt

+17-5
Original file line numberDiff line numberDiff line change
@@ -33,22 +33,28 @@ import okio.use
3333
data class Cart(
3434
val items: List<CartItem>,
3535
)
36+
3637
@Serializable
3738
data class CartItem(
3839
val id: Long,
3940
val count: Int,
4041
)
42+
4143
internal object CartJsonSerializer : OkioSerializer<Cart> {
4244
override val defaultValue: Cart = Cart(emptyList())
43-
override suspend fun readFrom(source: BufferedSource): Cart {
44-
return json.decodeFromString<Cart>(source.readUtf8())
45-
}
46-
override suspend fun writeTo(t: Cart, sink: BufferedSink) {
45+
46+
override suspend fun readFrom(source: BufferedSource): Cart = json.decodeFromString<Cart>(source.readUtf8())
47+
48+
override suspend fun writeTo(
49+
t: Cart,
50+
sink: BufferedSink,
51+
) {
4752
sink.use {
4853
it.writeUtf8(json.encodeToString(Cart.serializer(), t))
4954
}
5055
}
5156
}
57+
5258
class CartDataStore(
5359
private val produceFilePath: () -> String,
5460
) {
@@ -63,9 +69,15 @@ class CartDataStore(
6369
)
6470
val cart: Flow<Cart>
6571
get() = db.data
72+
6673
suspend fun add(fruittie: Fruittie) = update(fruittie, 1)
74+
6775
suspend fun remove(fruittie: Fruittie) = update(fruittie, -1)
68-
suspend fun update(fruittie: Fruittie, diff: Int) {
76+
77+
suspend fun update(
78+
fruittie: Fruittie,
79+
diff: Int,
80+
) {
6981
db.updateData { prevCart ->
7082
val newItems = mutableListOf<CartItem>()
7183
var found = false

Fruitties/shared/src/commonMain/kotlin/com/example/fruitties/database/FruittieDao.kt

+1-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import kotlinx.coroutines.flow.Flow
2525

2626
@Dao
2727
interface FruittieDao {
28-
2928
@Insert(onConflict = OnConflictStrategy.REPLACE)
3029
suspend fun insert(fruittie: Fruittie)
3130

@@ -46,5 +45,5 @@ interface FruittieDao {
4645
@MapColumn(columnName = "id")
4746
Long,
4847
Fruittie,
49-
>
48+
>
5049
}

0 commit comments

Comments
 (0)