Skip to content
Open
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
2 changes: 1 addition & 1 deletion .github/workflows/publish_snapshot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
shell: bash
run: ./gradlew build
- name: Build & publish snapshot
run: ./gradlew publish --no-daemon --no-parallel --stacktrace
run: ./gradlew publish --no-daemon --no-parallel --stacktrace -PVERSION_NAME=6.X.X-SNAPSHOT
env:
ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.MAVEN_CENTRAL_REPOSITORY_USERNAME }}
ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.MAVEN_CENTRAL_REPOSITORY_PASSWORD }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import com.android.tools.lint.detector.api.CURRENT_API
import com.android.tools.lint.detector.api.Issue

class MvvmIssueRegistry : IssueRegistry() {

override val issues: List<Issue> = listOf(
WrongEventNameDetector.ISSUE_MUSSING_SUFFIX,
WrongEventNameDetector.ISSUE_MISSPELL
)
override val issues: List<Issue> =
listOf(
WrongEventNameDetector.ISSUE_MUSSING_SUFFIX,
WrongEventNameDetector.ISSUE_MISSPELL,
)

override val api = CURRENT_API
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,34 +12,39 @@ import org.jetbrains.uast.UClass
import java.util.EnumSet
import java.util.regex.Pattern

class WrongEventNameDetector : Detector(), Detector.UastScanner {

class WrongEventNameDetector :
Detector(),
Detector.UastScanner {
companion object {
val ISSUE_MUSSING_SUFFIX = Issue.create(
id = "MvvmEventNameMissingSuffix",
briefDescription = "Wrong event name",
explanation = "Event names should end with 'Event' suffix",
category = Category.CORRECTNESS,
priority = 5,
severity = Severity.WARNING,
implementation = Implementation(
WrongEventNameDetector::class.java,
EnumSet.of(Scope.JAVA_FILE, Scope.TEST_SOURCES)
val ISSUE_MUSSING_SUFFIX =
Issue.create(
id = "MvvmEventNameMissingSuffix",
briefDescription = "Wrong event name",
explanation = "Event names should end with 'Event' suffix",
category = Category.CORRECTNESS,
priority = 5,
severity = Severity.WARNING,
implementation =
Implementation(
WrongEventNameDetector::class.java,
EnumSet.of(Scope.JAVA_FILE, Scope.TEST_SOURCES),
),
)
)

val ISSUE_MISSPELL = Issue.create(
id = "MvvmEventNameMisspell",
briefDescription = "Misspelled event name",
explanation = "Event name looks misspelled",
category = Category.CORRECTNESS,
priority = 3,
severity = Severity.WARNING,
implementation = Implementation(
WrongEventNameDetector::class.java,
EnumSet.of(Scope.JAVA_FILE, Scope.TEST_SOURCES)
val ISSUE_MISSPELL =
Issue.create(
id = "MvvmEventNameMisspell",
briefDescription = "Misspelled event name",
explanation = "Event name looks misspelled",
category = Category.CORRECTNESS,
priority = 3,
severity = Severity.WARNING,
implementation =
Implementation(
WrongEventNameDetector::class.java,
EnumSet.of(Scope.JAVA_FILE, Scope.TEST_SOURCES),
),
)
)

private const val MVVM_EVENT_QUALIFIED_NAME = "app.futured.arkitekt.core.event.Event"
private val PATTERN_MISSPELL = Pattern.compile("Event[a-z]+")
Expand All @@ -50,32 +55,37 @@ class WrongEventNameDetector : Detector(), Detector.UastScanner {

override fun applicableSuperClasses() = listOf(MVVM_EVENT_QUALIFIED_NAME)

override fun visitClass(context: JavaContext, declaration: UClass) {
override fun visitClass(
context: JavaContext,
declaration: UClass,
) {
super.visitClass(context, declaration)

val className = declaration.name

val isMvvmLibraryEvent = context.evaluator.getQualifiedName(declaration) == MVVM_EVENT_QUALIFIED_NAME
val directlyExtendsMvvmEvent = declaration.javaPsi.superClass?.let {
context.evaluator.getQualifiedName(it)
} == MVVM_EVENT_QUALIFIED_NAME
val directlyExtendsMvvmEvent =
declaration.javaPsi.superClass?.let {
context.evaluator.getQualifiedName(it)
} == MVVM_EVENT_QUALIFIED_NAME

val isEligibleForDetection = isMvvmLibraryEvent.not() && directlyExtendsMvvmEvent.not()

if (className != null && isEligibleForDetection) {
when {
PATTERN_MISSPELL.matcher(className).find() -> {
val suggestedName = PATTERN_SUFFIX.matcher(className).let {
it.find()
it.group(1)
}
val suggestedName =
PATTERN_SUFFIX.matcher(className).let {
it.find()
it.group(1)
}

context.report(
issue = ISSUE_MISSPELL,
scopeClass = declaration,
location = context.getNameLocation(declaration),
message = "Event name is misspelled. Suggested name: $suggestedName",
quickfixData = createQuickFix(className, suggestedName)
quickfixData = createQuickFix(className, suggestedName),
)
}

Expand All @@ -87,14 +97,18 @@ class WrongEventNameDetector : Detector(), Detector.UastScanner {
scopeClass = declaration,
location = context.getNameLocation(declaration),
message = "Event names should end with 'Event' suffix. Suggested name: $suggestedName",
quickfixData = createQuickFix(className, suggestedName)
quickfixData = createQuickFix(className, suggestedName),
)
}
}
}
}

private fun createQuickFix(declarationName: String, replacement: String) = LintFix.create()
private fun createQuickFix(
declarationName: String,
replacement: String,
) = LintFix
.create()
.name("Replace with $replacement")
.replace()
.text(declarationName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,18 @@ import com.android.tools.lint.detector.api.Issue
import org.junit.Test

class WrongEventNameDetectorTest : LintDetectorTest() {
override fun getDetector(): Detector = WrongEventNameDetector()

override fun getDetector(): Detector {
return WrongEventNameDetector()
}

override fun getIssues(): MutableList<Issue> {
return mutableListOf(WrongEventNameDetector.ISSUE_MUSSING_SUFFIX, WrongEventNameDetector.ISSUE_MISSPELL)
}
override fun getIssues(): MutableList<Issue> = mutableListOf(WrongEventNameDetector.ISSUE_MUSSING_SUFFIX, WrongEventNameDetector.ISSUE_MISSPELL)

private val eventStub = kotlin(
"""
private val eventStub =
kotlin(
"""
package app.futured.arkitekt.core.event

abstract class Event<T : ViewState>
"""
).indented()
""",
).indented()

@Test
fun testMissingSuffixWarning() {
Expand All @@ -41,10 +37,9 @@ class WrongEventNameDetectorTest : LintDetectorTest() {
object ShowFormEvent : MainEvent()

object ShowForm : MainEvent()
"""
).indented()
)
.allowMissingSdk()
""",
).indented(),
).allowMissingSdk()
.issues(WrongEventNameDetector.ISSUE_MUSSING_SUFFIX)
.run()
.expectWarningCount(2)
Expand All @@ -70,10 +65,9 @@ class WrongEventNameDetectorTest : LintDetectorTest() {
object ShowFormEvents : MainEvent()

object ShowEventDataFormEvents : MainEvent()
"""
).indented()
)
.allowMissingSdk()
""",
).indented(),
).allowMissingSdk()
.issues(WrongEventNameDetector.ISSUE_MISSPELL)
.run()
.expectWarningCount(3)
Expand All @@ -95,15 +89,13 @@ class WrongEventNameDetectorTest : LintDetectorTest() {
object ShowFormEvent : MainEvent()

object SendEventDataEvent : MainEvent()
"""
).indented()
)
.allowMissingSdk()
""",
).indented(),
).allowMissingSdk()
.issues(
WrongEventNameDetector.ISSUE_MUSSING_SUFFIX,
WrongEventNameDetector.ISSUE_MISSPELL
)
.run()
WrongEventNameDetector.ISSUE_MISSPELL,
).run()
.expectClean()
}
}
33 changes: 19 additions & 14 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ allprojects {
}

subprojects {
group = ProjectSettings.group
version = findProperty("VERSION_NAME") as String? ?: ProjectSettings.version

apply(plugin = Deps.Plugins.ktlint)

ktlint {
Expand All @@ -59,7 +62,7 @@ subprojects {
if (hasKey && hasPassword) {
useInMemoryPgpKeys(
project.properties["SIGNING_PRIVATE_KEY"].toString(),
project.properties["SIGNING_PASSWORD"].toString()
project.properties["SIGNING_PASSWORD"].toString(),
)
}
}
Expand All @@ -70,19 +73,21 @@ subprojects {
detekt {
autoCorrect = false
version = Versions.detekt
source = files(
"example/src/main/java",
"core/src/main/java",
"compose/src/main/java",
"core-test/src/main/java",
"cr-usecases/src/commonMain/kotlin",
"cr-usecases-test/src/main/java",
"decompose/src/commonMain/kotlin",
"decompose/src/androidMain/kotlin",
"decompose-annotation/src/commonMain/kotlin",
"decompose-processor/src/jvmMain/kotlin",
"arkitekt-lint/src/main/java"
source.setFrom(
files(
"example/src/main/java",
"core/src/main/java",
"compose/src/main/java",
"core-test/src/main/java",
"cr-usecases/src/commonMain/kotlin",
"cr-usecases-test/src/main/java",
"decompose/src/commonMain/kotlin",
"decompose/src/androidMain/kotlin",
"decompose-annotation/src/commonMain/kotlin",
"decompose-processor/src/jvmMain/kotlin",
"arkitekt-lint/src/main/java",
),
)
// filters = ".*/resources/.*,.*/build/.*"
config = files("detekt.yml")
config.setFrom(files("detekt.yml"))
}
6 changes: 3 additions & 3 deletions buildSrc/src/main/kotlin/Versions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ object Versions {
const val gradlePlugin = "8.13.0"

// plugins
const val detekt = "1.20.0"
const val ktlint = "10.3.0"
const val ktlintExtension = "0.39.0"
const val detekt = "1.23.8"
const val ktlint = "14.0.1"
const val ktlintExtension = "1.8.0" // todo 1.7.0
const val mavenPublish = "0.34.0"
const val dokka = "1.6.10"

Expand Down
3 changes: 1 addition & 2 deletions compose/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ mavenPublishing {
coordinates(
groupId = ProjectSettings.group,
artifactId = "compose",
version = project.findProperty("VERSION_NAME") as String? ?: "6.X.X-SNAPSHOT"
version = project.findProperty("VERSION_NAME") as String? ?: "6.X.X-SNAPSHOT",
)
pom {
name = "Arkitekt Compose"
Expand Down Expand Up @@ -81,5 +81,4 @@ dependencies {

implementation(platform(Deps.Compose.bom))
implementation(Deps.Compose.runtime)

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import app.futured.arkitekt.core.ViewState
import app.futured.arkitekt.crusecases.CoroutineScopeOwner
import kotlinx.coroutines.CoroutineScope

abstract class BaseViewModel<S : ViewState>() : BaseCoreViewModel<S>(), CoroutineScopeOwner {
abstract class BaseViewModel<S : ViewState> :
BaseCoreViewModel<S>(),
CoroutineScopeOwner {
override val coroutineScope: CoroutineScope = viewModelScope
}
2 changes: 1 addition & 1 deletion core-test/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ mavenPublishing {
coordinates(
groupId = ProjectSettings.group,
artifactId = "core-test",
version = project.findProperty("VERSION_NAME") as String? ?: "6.X.X-SNAPSHOT"
version = project.findProperty("VERSION_NAME") as String? ?: "6.X.X-SNAPSHOT",
)
pom {
name = "Arkitekt Core Test"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,20 @@ import org.junit.runners.model.Statement

@ExperimentalCoroutinesApi
class CoroutineScopeRule : TestRule {

@ExperimentalCoroutinesApi
class TestCoroutineScopeOwner : CoroutineScopeOwner {

val testDispatcher = UnconfinedTestDispatcher()

override val coroutineScope = TestScope(testDispatcher)

override fun getWorkerDispatcher(): CoroutineDispatcher = testDispatcher
}

override fun apply(base: Statement, description: Description): Statement {
return object : Statement() {
override fun apply(
base: Statement,
description: Description,
): Statement =
object : Statement() {
@Throws(Throwable::class)
override fun evaluate() {
val scopeOwner = TestCoroutineScopeOwner()
Expand All @@ -37,5 +38,4 @@ class CoroutineScopeRule : TestRule {
Dispatchers.resetMain() // reset main dispatcher to the original Main dispatcher
}
}
}
}
Loading
Loading