:question:Is it planed to improve the improve the ...
# konsist
p
Is it planed to improve the improve the issue report? At the moment I only get a list of files that violating the rule but no additional information about this. ArchUnit is giving me some context which is especially helpful when introducing a new rule and there are a lot of issues.
i
Please post some concrete examples on how this works in ArchUnit, How this work now in Konsist and what you would like to see. BTW I guess this is not what you are asking for exactly, but the next version will allow adding additional message to
assert
where for example you can post tips to fix the issue. See PR desc https://github.com/LemonAppDev/konsist/pull/495
p
Here is a sample, that I currently use: Konsist:
Copy code
@Test
    fun `Konsist - adapter package should not access domain package`(){
        Konsist.scopeFromProduction()
            .files
            .withPackage("com.poisonedyouth.financemanagement.security.adapter..")
            .assert {
                it.hasNoImports("com.poisonedyouth.financemanagement.security.domain..")
            }
    }
Failure:
Copy code
com.lemonappdev.konsist.core.exception.KoCheckFailedException: Assert 'Konsist - adapter package should not access domain package' has failed. Invalid files (1):
projects\workspace\private\finance-management\src\main\kotlin\com\poisonedyouth\financemanagement\security\adapter\persistence\ExposedUserCredentialsRepository.kt (ExposedUserCredentialsRepository FileDeclaration)
	at app//com.lemonappdev.konsist.core.verify.KoDeclarationAndProviderAssertCoreKt.getResult(KoDeclarationAndProviderAssertCore.kt:119)
	at app//com.lemonappdev.konsist.core.verify.KoDeclarationAndProviderAssertCoreKt.assert(KoDeclarationAndProviderAssertCore.kt:35)
	at app//com.lemonappdev.konsist.api.verify.KoDeclarationAndProviderAssertKt.assert(KoDeclarationAndProviderAssert.kt:13)
	at app//com.poisonedyouth.financemanagement.konsist.VerifyArchitecture.Konsist - adapter package should not access domain package(VerifyArchitecture.kt:29)
	at java.base@17.0.5/java.lang.reflect.Method.invoke(Method.java:568)
	at java.base@17.0.5/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base@17.0.5/java.util.ArrayList.forEach(ArrayList.java:1511)
ArchUnit:
Copy code
@Test
    fun `ArchUnit - adapter package should not access domain package`(){
        val rule = noClasses()
            .that()
            .resideInAnyPackage("com.poisonedyouth.financemanagement.security.adapter..")
            .should()
            .accessClassesThat()
            .resideInAnyPackage(
                "com.poisonedyouth.financemanagement.security.domain.."
            )
        val allClasses = ClassFileImporter().importPackages("com.poisonedyouth.financemanagement")

        // then
        assertNoViolation(rule.evaluate(allClasses))
    }
Failure:
Copy code
java.lang.AssertionError: Architecture Violation [Priority: MEDIUM] - Rule 'no classes that reside in any package ['com.poisonedyouth.financemanagement.security.adapter..'] should access classes that reside in any package ['com.poisonedyouth.financemanagement.security.domain..']' was violated (6 times):
Method <com.poisonedyouth.financemanagement.security.adapter.persistence.ExposedUserCredentialsRepository$create$1$1$1.invoke(com.poisonedyouth.financemanagement.security.adapter.persistence.UserCredentialsTable, org.jetbrains.exposed.sql.statements.InsertStatement)> calls method <com.poisonedyouth.financemanagement.security.domain.UserCredentials.getPassword()> in (ExposedUserCredentialsRepository.kt:26)
Method <com.poisonedyouth.financemanagement.security.adapter.persistence.ExposedUserCredentialsRepository$create$1$1$1.invoke(com.poisonedyouth.financemanagement.security.adapter.persistence.UserCredentialsTable, org.jetbrains.exposed.sql.statements.InsertStatement)> calls method <com.poisonedyouth.financemanagement.security.domain.UserCredentials.getUserId-hrrTlGk()> in (ExposedUserCredentialsRepository.kt:25)
Method <com.poisonedyouth.financemanagement.security.adapter.persistence.ExposedUserCredentialsRepository$findById$1.invoke(org.jetbrains.exposed.sql.Transaction)> calls constructor <com.poisonedyouth.financemanagement.security.domain.UserCredentials.<init>(java.util.UUID, java.lang.String, kotlin.jvm.internal.DefaultConstructorMarker)> in (ExposedUserCredentialsRepository.kt:57)
Method <com.poisonedyouth.financemanagement.security.adapter.persistence.ExposedUserCredentialsRepository$update$1$updateResult$1$1.invoke(org.jetbrains.exposed.sql.SqlExpressionBuilder)> calls method <com.poisonedyouth.financemanagement.security.domain.UserCredentials.getUserId-hrrTlGk()> in (ExposedUserCredentialsRepository.kt:34)
Method <com.poisonedyouth.financemanagement.security.adapter.persistence.ExposedUserCredentialsRepository$update$1$updateResult$1$2.invoke(com.poisonedyouth.financemanagement.security.adapter.persistence.UserCredentialsTable, org.jetbrains.exposed.sql.statements.UpdateStatement)> calls method <com.poisonedyouth.financemanagement.security.domain.UserCredentials.getPassword()> in (ExposedUserCredentialsRepository.kt:35)
Method <com.poisonedyouth.financemanagement.security.adapter.persistence.ExposedUserCredentialsRepository$update$1.invoke(org.jetbrains.exposed.sql.Transaction)> calls method <com.poisonedyouth.financemanagement.security.domain.UserCredentials.getUserId-hrrTlGk()> in (ExposedUserCredentialsRepository.kt:40)
	at com.tngtech.archunit.lang.ArchRule$Assertions.assertNoViolation(ArchRule.java:94)
	at com.poisonedyouth.financemanagement.konsist.VerifyArchitecture.ArchUnit - adapter package should not access domain package(VerifyArchitecture.kt:47)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
i
Few things: 1. Konsist simple API will result in less detailed error messages (at least at the moment). Thats being said ArchUnit and Konsist differs in loggin approach - as opossed to ArchUnit Konsit displays full path to the file allowing you to click the link in InteliJ IDEA, and quickly navigate to incorrect declaration 2. Due to underlying design decision Konsist will not present logs in the same way as ArchUnit (at least for now) 3. More detailed reports are on our backlog BTW to assert architectural layers consider using
assertArchitecture
https://docs.konsist.lemonappdev.com/writing-tests/architecture-assert
p
I don't expect to have a ArchUnit in Kotlin, its just helpful to have more details about what failed. I will check if the custom messages that will be available soon can help in my case. Question about
assertArchitecturre
- how can I implement
notDependsOn(layer)
?
i
Not possible ATM. We have considered this before but the conclusion was that these 'positive' dependencies should be enough to express architectural constrains. Can you give me an example of architecture where this would be helpful?
p
I have a legacy application with a single module containing multiple domains and I want to prevent that parts of one domain are depending on parts of another domain. Dependencies in general are allowed but not inside a specified layer
i
This does build a full picture for me. Perhaps you could create a diagram with layers and a few classes, a then discuss your case. I just want to make sure I will get it right
p
I will add a repository skeleton for this (will come back next week)
👍 1
This is a sample structure that shows the separate top-level packages inside a single module. There are multiple domains (e.g.
account
and
user
) whose dependencies should be enforced in 2 different ways: • Inside the single domain. • Across different domains. As an example. The
user
domain is allowed to use the
account
domain but not the other direction. It is important to mention that the account domain is allowed to access other domains like
transaction
. So the
dependsOnNothing
function is not completely correct. I hope you understand, what my intention is.
i
thx for sharing I will take a look 👀
FYI I am Busy with other, stuff, but this is in my backlog together with few other architecture related tickets. Stay tuned.
p
Thank you very much. No stress
🙂 1