Skip to content
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
2 changes: 0 additions & 2 deletions app/detekt-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@
<CurrentIssues>
<ID>ForbiddenImport:AcsMissingScreen.kt$import androidx.compose.material3.MaterialTheme</ID>
<ID>ForbiddenImport:CrashReportScreen.kt$import androidx.compose.material3.MaterialTheme</ID>
<ID>LambdaParameterInRestartableEffect:AslNavHost.kt$onOpenProjectConsumed</ID>
<ID>LongMethod:AslNavHost.kt$@Composable fun AslNavHost( startDestination: String, openProjectId: String? = null, onOpenProjectConsumed: () -&gt; Unit = {}, navController: NavHostController = rememberNavController(), )</ID>
<ID>MatchingDeclarationName:BlockingErrorScreen.kt$BlockingErrorType</ID>
<ID>ParameterNaming:AslNavHost.kt$onOpenProjectConsumed</ID>
<ID>WildcardImport:ExampleUnitTest.kt$import org.junit.Assert.*</ID>
</CurrentIssues>
</SmellBaseline>
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberUpdatedState
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
Expand Down Expand Up @@ -44,6 +45,7 @@ fun AslNavHost(
onOpenProjectConsumed: () -> Unit = {},
navController: NavHostController = rememberNavController(),
) {
val currentOnOpenProjectConsumed by rememberUpdatedState(onOpenProjectConsumed)
LaunchedEffect(openProjectId) {
val id = openProjectId ?: return@LaunchedEffect

Expand All @@ -52,7 +54,7 @@ fun AslNavHost(
launchSingleTop = true
}
}
onOpenProjectConsumed()
currentOnOpenProjectConsumed()
}
NavHost(
navController = navController,
Expand Down Expand Up @@ -180,7 +182,13 @@ fun AslNavHost(
val target = runCatching {
GitDiffTarget.valueOf(backStackEntry.arguments?.getString("target").orEmpty())
}.getOrDefault(GitDiffTarget.INDEX_TO_WORKTREE)
GitDiffRoute(projectId, path, target, commitId, onBack = { navController.popBackStack() })
GitDiffRoute(
projectId = projectId,
path = path,
target = target,
onBack = { navController.popBackStack() },
commitId = commitId,
)
}

composable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package com.ahmadkharfan.androidstudiolite

import org.junit.Test

import org.junit.Assert.*
import org.junit.Assert.assertEquals

class ExampleUnitTest {
@Test
Expand Down
7 changes: 0 additions & 7 deletions data/ai/detekt-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,6 @@
<ID>CyclomaticComplexMethod:AgentReplyParser.kt$AgentReplyParser$fun toActionOrNull(element: JsonElement): AgentAction?</ID>
<ID>InstanceOfCheckForException:AiLlmGateway.kt$AiLlmGateway$e is AiLlmException</ID>
<ID>LoopWithTooManyJumpStatements:AgentReplySalvage.kt$AgentReplySalvage$while</ID>
<ID>NewLineAtEndOfFile:AnthropicProvider.kt$com.ahmadkharfan.androidstudiolite.data.ai.llm.AnthropicProvider.kt</ID>
<ID>NewLineAtEndOfFile:GeminiProvider.kt$com.ahmadkharfan.androidstudiolite.data.ai.llm.GeminiProvider.kt</ID>
<ID>NewLineAtEndOfFile:LlmHttp.kt$com.ahmadkharfan.androidstudiolite.data.ai.llm.LlmHttp.kt</ID>
<ID>NewLineAtEndOfFile:LlmProvider.kt$com.ahmadkharfan.androidstudiolite.data.ai.llm.LlmProvider.kt</ID>
<ID>NewLineAtEndOfFile:LlmProviderRegistry.kt$com.ahmadkharfan.androidstudiolite.data.ai.llm.LlmProviderRegistry.kt</ID>
<ID>NewLineAtEndOfFile:LlmProviderRegistryTest.kt$com.ahmadkharfan.androidstudiolite.data.ai.llm.LlmProviderRegistryTest.kt</ID>
<ID>NewLineAtEndOfFile:OpenAiCompatProvider.kt$com.ahmadkharfan.androidstudiolite.data.ai.llm.OpenAiCompatProvider.kt</ID>
<ID>TooGenericExceptionCaught:AiLlmGateway.kt$AiLlmGateway$e: Exception</ID>
</CurrentIssues>
</SmellBaseline>
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,4 @@ private data class AnthropicMessage(val role: String, val content: String)
private data class AnthropicResponse(val content: List<AnthropicContentBlock>)

@Serializable
private data class AnthropicContentBlock(val type: String, val text: String = "")
private data class AnthropicContentBlock(val type: String, val text: String = "")
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,4 @@ private data class GeminiCandidate(val content: GeminiContent? = null)
private data class GeminiModelsResponse(val models: List<GeminiModelInfo> = emptyList())

@Serializable
private data class GeminiModelInfo(val name: String)
private data class GeminiModelInfo(val name: String)
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,4 @@ internal fun llmErrorMessage(body: String, code: Int): String {
?: root["message"]?.jsonPrimitive?.contentOrNull
?: body.take(200)
}.getOrDefault(body.take(200)).let { "HTTP $code: $it" }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ internal interface LlmProvider {
fun stream(request: LlmChatRequest, onDelta: (String) -> Unit)

fun listModels(apiKey: String, baseUrl: String?): List<String>
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ internal class LlmProviderRegistry(http: LlmHttpClient) {
providers[providerId] ?: throw AiLlmException("Unknown provider: $providerId")

fun find(providerId: String): LlmProvider? = providers[providerId]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,4 @@ private data class OpenAiMessage(val role: String, val content: String)
private data class OpenAiChatResponse(val choices: List<OpenAiChoice> = emptyList())

@Serializable
private data class OpenAiChoice(val message: OpenAiMessage? = null)
private data class OpenAiChoice(val message: OpenAiMessage? = null)
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,4 @@ class LlmErrorMessageTest {
assertEquals("HTTP 500: not json", llmErrorMessage("not json", 500))
assertEquals("HTTP 503", llmErrorMessage("", 503))
}
}
}
14 changes: 0 additions & 14 deletions data/build/detekt-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,6 @@
<ID>ComplexCondition:GradleScriptScanner.kt$GToken$s.length &gt;= 2 &amp;&amp; (s[0] == '"' || s[0] == '\'') &amp;&amp; s.last() == s[0]</ID>
<ID>ComplexCondition:GradleScriptScanner.kt$GradleScriptScanner.GradleTokenizer$end &lt; text.length &amp;&amp; (text[end].isLetterOrDigit() || text[end] == '.' || text[end] == '_')</ID>
<ID>ComplexCondition:VersionCatalogParser.kt$VersionCatalogParser$t.length &gt;= 2 &amp;&amp; (t.first() == '"' || t.first() == '\'') &amp;&amp; t.last() == t.first()</ID>
<ID>ConstructorParameterNaming:GitHubDeviceFlowAuthenticator.kt$GitHubDeviceFlowAuthenticator.AccessTokenResponse$val access_token: String? = null</ID>
<ID>ConstructorParameterNaming:GitHubDeviceFlowAuthenticator.kt$GitHubDeviceFlowAuthenticator.AccessTokenResponse$val error_description: String? = null</ID>
<ID>ConstructorParameterNaming:GitHubDeviceFlowAuthenticator.kt$GitHubDeviceFlowAuthenticator.DeviceCodeResponse$val device_code: String? = null</ID>
<ID>ConstructorParameterNaming:GitHubDeviceFlowAuthenticator.kt$GitHubDeviceFlowAuthenticator.DeviceCodeResponse$val expires_in: Int? = null</ID>
<ID>ConstructorParameterNaming:GitHubDeviceFlowAuthenticator.kt$GitHubDeviceFlowAuthenticator.DeviceCodeResponse$val user_code: String? = null</ID>
<ID>ConstructorParameterNaming:GitHubDeviceFlowAuthenticator.kt$GitHubDeviceFlowAuthenticator.DeviceCodeResponse$val verification_uri: String? = null</ID>
<ID>CyclomaticComplexMethod:BuildGradleParser.kt$BuildGradleParser$private fun parseAndroid(tokens: List&lt;GToken&gt;): ParsedAndroidBlock?</ID>
<ID>CyclomaticComplexMethod:GradleProjectReader.kt$GradleProjectReader$private fun moduleType(script: ParsedBuildScript, catalog: VersionCatalog?): ModuleType</ID>
<ID>CyclomaticComplexMethod:MiniJson.kt$MiniJson.Parser$private fun parseString(): String</ID>
Expand All @@ -23,8 +17,6 @@
<ID>LoopWithTooManyJumpStatements:MiniJson.kt$MiniJson.Parser$while</ID>
<ID>LoopWithTooManyJumpStatements:SelfSignedCertGenerator.kt$SelfSignedCertGenerator$while</ID>
<ID>LoopWithTooManyJumpStatements:VersionCatalogParser.kt$VersionCatalogParser$for</ID>
<ID>SwallowedException:KeystoreFiles.kt$KeystoreFiles$e: UnrecoverableKeyException</ID>
<ID>SwallowedException:KeystoreFiles.kt$KeystoreFiles$e: java.io.IOException</ID>
<ID>ThrowsCount:ArtifactDownloader.kt$ArtifactDownloader$private fun validateArtifact(file: File, expectation: ArtifactExpectation)</ID>
<ID>ThrowsCount:KeystoreFiles.kt$KeystoreFiles$fun import(storeFile: File, storePassword: String, keyAlias: String, keyPassword: String): SigningConfig</ID>
<ID>ThrowsCount:RemoteClient.kt$RemoteClient$private suspend fun executeWithRetry(request: Request, allowUnauthorizedThrow: Boolean): ResponseSnapshot</ID>
Expand All @@ -33,11 +25,5 @@
<ID>TooGenericExceptionCaught:PlayIntegrityTokenProvider.kt$PlayIntegrityTokenProvider$e: Throwable</ID>
<ID>TooGenericExceptionCaught:RemoteBuildSystem.kt$RemoteBuildSystem$t: Throwable</ID>
<ID>TooGenericExceptionCaught:RemoteClient.kt$RemoteClient$t: Throwable</ID>
<ID>UnusedParameter:DependenciesBlockEditor.kt$DependenciesBlockEditor$text: String</ID>
<ID>UseCheckOrError:RemoteBuildSystem.kt$RemoteBuildSystem$throw IllegalStateException("Configure a release keystore in Settings before building a release artifact.")</ID>
<ID>UseCheckOrError:RemoteBuildSystem.kt$RemoteBuildSystem$throw IllegalStateException("The configured release keystore is missing or unreadable.")</ID>
<ID>UseRequire:MiniJson.kt$MiniJson.Parser$throw IllegalArgumentException("Expected '$c' at $i")</ID>
<ID>UseRequire:MiniJson.kt$MiniJson.Parser$throw IllegalArgumentException("Invalid literal at $i")</ID>
<ID>UseRequire:MiniJson.kt$MiniJson.Parser$throw IllegalArgumentException("Unexpected end of JSON")</ID>
</CurrentIssues>
</SmellBaseline>
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ internal object KeystoreFiles {
try {
params.storeFile.outputStream().use { keyStore.store(it, params.storePassword.toCharArray()) }
} catch (e: java.io.IOException) {
throw KeystoreException(KeystoreError.Io(e.message ?: "Could not write keystore"))
throw KeystoreException(KeystoreError.Io(e.message ?: "Could not write keystore"), e)
}
return SigningConfig(
storeFile = params.storeFile,
Expand Down Expand Up @@ -71,7 +71,7 @@ internal object KeystoreFiles {
throw KeystoreException(KeystoreError.InvalidParams("Alias '$keyAlias' is not a private-key entry"))
}
} catch (e: UnrecoverableKeyException) {
throw KeystoreException(KeystoreError.WrongKeyPassword)
throw KeystoreException(KeystoreError.WrongKeyPassword, e)
}
return SigningConfig(storeFile, storePassword, keyAlias, keyPassword, isDebug = false)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ object DependenciesBlockEditor {
sb.append("\n\ndependencies {\n ").append(line).append("\n}\n")
Result.Changed(sb.toString())
} else {
val insertOffset = insertionOffset(tokens, body, text)
val insertOffset = insertionOffset(tokens, body)
val indent = detectIndent(text, tokens, body)
val edited = StringBuilder(text)
.insert(insertOffset, "\n$indent$line")
Expand Down Expand Up @@ -74,7 +74,6 @@ object DependenciesBlockEditor {
private fun insertionOffset(
tokens: List<com.ahmadkharfan.androidstudiolite.data.gradle.parse.GToken>,
body: IntRange,
text: String,
): Int {

for (i in body.last downTo body.first) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ object MiniJson {

fun parseValue(): Any? {
skipWs()
if (i >= s.length) throw IllegalArgumentException("Unexpected end of JSON")
require(i < s.length) { "Unexpected end of JSON" }
return when (s[i]) {
'{' -> parseObject()
'[' -> parseArray()
Expand Down Expand Up @@ -85,19 +85,26 @@ object MiniJson {
return s.substring(start, i).toDouble()
}

private fun parseBoolean(): Boolean =
if (s.startsWith("true", i)) { i += 4; true }
else if (s.startsWith("false", i)) { i += 5; false }
else throw IllegalArgumentException("Invalid literal at $i")
private fun parseBoolean(): Boolean {
if (s.startsWith("true", i)) {
i += 4
return true
}
require(s.startsWith("false", i)) { "Invalid literal at $i" }
i += 5
return false
}

private fun parseNull(): Any? =
if (s.startsWith("null", i)) { i += 4; null }
else throw IllegalArgumentException("Invalid literal at $i")
private fun parseNull(): Any? {
require(s.startsWith("null", i)) { "Invalid literal at $i" }
i += 4
return null
}

private fun skipWs() { while (i < s.length && s[i].isWhitespace()) i++ }
private fun peek(): Char = if (i < s.length) s[i] else '\u0000'
private fun expect(c: Char) {
if (peek() != c) throw IllegalArgumentException("Expected '$c' at $i")
require(peek() == c) { "Expected '$c' at $i" }
i++
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,9 +239,9 @@ class RemoteBuildSystem internal constructor(
if (request.buildType.equals("release", ignoreCase = true) ||
(request.buildType == null && RemoteBuildRequestFactory.isReleaseVariant(request.variantName))) {
val config = releaseSigningResolver()
?: throw IllegalStateException("Configure a release keystore in Settings before building a release artifact.")
?: error("Configure a release keystore in Settings before building a release artifact.")
RemoteBuildRequestFactory.releaseSigningMaterial(config, encodeBase64 = encodeBase64)
?: throw IllegalStateException("The configured release keystore is missing or unreadable.")
?: error("The configured release keystore is missing or unreadable.")
} else {
null
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.FlowCollector
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import okhttp3.FormBody
Expand Down Expand Up @@ -184,27 +185,19 @@ class GitHubDeviceFlowAuthenticator(

@Serializable
private data class DeviceCodeResponse(
val device_code: String? = null,
val user_code: String? = null,
val verification_uri: String? = null,
val expires_in: Int? = null,
@SerialName("device_code") val deviceCode: String? = null,
@SerialName("user_code") val userCode: String? = null,
@SerialName("verification_uri") val verificationUri: String? = null,
@SerialName("expires_in") val expiresIn: Int? = null,
val interval: Int? = null,
) {
val deviceCode get() = device_code
val userCode get() = user_code
val verificationUri get() = verification_uri
val expiresIn get() = expires_in
}
)

@Serializable
private data class AccessTokenResponse(
val access_token: String? = null,
@SerialName("access_token") val accessToken: String? = null,
val error: String? = null,
val error_description: String? = null,
) {
val accessToken get() = access_token
val errorDescription get() = error_description
}
@SerialName("error_description") val errorDescription: String? = null,
)

@Serializable
private data class GitHubUser(val login: String? = null)
Expand Down
2 changes: 0 additions & 2 deletions designsystem/detekt-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
<SmellBaseline>
<ManuallySuppressedIssues/>
<CurrentIssues>
<ID>ComposableParamOrder:Appear.kt$AslStaggeredAppear</ID>
<ID>ComposableParamOrder:StatusChip.kt$AslStatusChip</ID>
<ID>CyclomaticComplexMethod:ApiKeyCard.kt$@Composable fun AslApiKeyCard( provider: String, value: String, onValueChange: (String) -&gt; Unit, modifier: Modifier = Modifier, providerIcon: String = "sparkles", description: String? = null, placeholder: String = "sk-…", status: AslApiKeyStatus = AslApiKeyStatus.None, errorMessage: String? = null, onTest: (String) -&gt; Unit = {}, testing: Boolean = false, onCollapse: (() -&gt; Unit)? = null, )</ID>
<ID>CyclomaticComplexMethod:AslMarkdownText.kt$@Composable fun AslMarkdownText( markdown: String, modifier: Modifier = Modifier, onCopyCode: (String) -&gt; Unit = {}, )</ID>
<ID>CyclomaticComplexMethod:BottomToolPanel.kt$@Composable fun AslBottomToolPanel( tabs: List&lt;AslBottomPanelTab&gt;, activeId: String?, modifier: Modifier = Modifier, contentHeight: Dp = 0.dp, defaultContentHeight: Dp = 260.dp, onContentHeightChange: (Dp) -&gt; Unit = {}, onSelect: (String) -&gt; Unit = {}, onToggle: () -&gt; Unit = {}, content: @Composable () -&gt; Unit = {}, )</ID>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import com.ahmadkharfan.androidstudiolite.designsystem.theme.AslMotion

@Composable
fun AslStaggeredAppear(
index: Int = 0,
modifier: Modifier = Modifier,
index: Int = 0,
staggerMillis: Int = 45,
content: @Composable () -> Unit,
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ private fun spec(status: AslStatus): StatusSpec = when (status) {

@Composable
fun AslStatusChip(
status: AslStatus = AslStatus.Success,
modifier: Modifier = Modifier,
status: AslStatus = AslStatus.Success,
label: String? = null,
) {
val colors = AslTheme.colors
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,7 @@ sealed interface KeystoreError {
data class Io(val message: String) : KeystoreError
}

class KeystoreException(val error: KeystoreError) : Exception(error.toString())
class KeystoreException(
val error: KeystoreError,
cause: Throwable? = null,
) : Exception(error.toString(), cause)
2 changes: 0 additions & 2 deletions feature/editor/detekt-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@
<ID>ForbiddenImport:AssetsScreen.kt$import androidx.compose.material3.MaterialTheme</ID>
<ID>ForbiddenImport:FileTreeSearchPanel.kt$import androidx.compose.material3.MaterialTheme</ID>
<ID>ForbiddenImport:VariantsScreen.kt$import androidx.compose.material3.MaterialTheme</ID>
<ID>LambdaParameterInRestartableEffect:AslEditableCodeEditor.kt$onVolumeKey</ID>
<ID>LambdaParameterInRestartableEffect:EditorScreen.kt$onConflictPathOpened</ID>
<ID>LongMethod:AiChatScreen.kt$@Composable private fun AiChatScreen( uiState: AiChatUiState, interactionListener: AiChatInteractionListener, onClose: () -&gt; Unit, onOpenAiAgentSettings: () -&gt; Unit, )</ID>
<ID>LongMethod:AiChatScreen.kt$@Composable private fun ChatControlsSheet( uiState: AiChatUiState, interactionListener: AiChatInteractionListener, )</ID>
<ID>LongMethod:AslEditableCodeEditor.kt$@Composable fun AslEditableCodeEditor( session: EditorSession, fontSizeSp: Int, tabSize: Int, onEdited: () -&gt; Unit, onCaretMoved: (line: Int, column: Int) -&gt; Unit, modifier: Modifier = Modifier, colorSchemeId: String = "darcula", fontFamilyId: String = "jetbrains", gitLineStatus: Map&lt;Int, AslLineGit&gt; = emptyMap(), breakpoints: Set&lt;Int&gt; = emptySet(), findQuery: String = "", findCurrentMatch: Int = 0, revealNonce: Int = 0, revealOffset: Int = 0, enableVolumeKeys: Boolean = true, projectIndex: ProjectSymbolIndex = ProjectSymbolIndex.EMPTY, )</ID>
Expand Down
Loading
Loading