Skip to content

Commit 5bf0792

Browse files
committed
chore: refactor code around signature name
Instead of deriving the signature name from the cli name it is now coded into settings store just like the default cli name
1 parent 5dcdff0 commit 5bf0792

File tree

5 files changed

+149
-45
lines changed

5 files changed

+149
-45
lines changed

src/main/kotlin/com/coder/toolbox/cli/downloader/CoderDownloadService.kt

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -154,11 +154,8 @@ class CoderDownloadService(
154154
}
155155

156156
private suspend fun downloadSignature(url: URL, showTextProgress: (String) -> Unit): DownloadResult {
157-
val defaultCliNameWithoutExt = context.settingsStore.defaultCliBinaryNameByOsAndArch.split('.').first()
158-
val signatureName = "$defaultCliNameWithoutExt.asc"
159-
160-
val signatureURL = url.withLastSegment(signatureName)
161-
val localSignaturePath = localBinaryPath.parent.resolve(signatureName)
157+
val signatureURL = url.withLastSegment(context.settingsStore.defaultSignatureNameByOsAndArch)
158+
val localSignaturePath = localBinaryPath.parent.resolve(context.settingsStore.defaultSignatureNameByOsAndArch)
162159
context.logger.info("Downloading signature from $signatureURL")
163160

164161
val response = downloadApi.downloadSignature(

src/main/kotlin/com/coder/toolbox/settings/ReadOnlyCoderSettings.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ interface ReadOnlyCoderSettings {
4343
*/
4444
val binaryName: String
4545

46+
/**
47+
* Default CLI signature name based on OS and architecture
48+
*/
49+
val defaultSignatureNameByOsAndArch: String
50+
4651
/**
4752
* Where to save plugin data like the Coder binary (if not configured with
4853
* binaryDirectory) and the deployment URL and session token.

src/main/kotlin/com/coder/toolbox/store/CoderSettingsStore.kt

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class CoderSettingsStore(
4141
get() = store[ALLOW_UNSIGNED_BINARY_EXEC]?.toBooleanStrictOrNull() ?: false
4242
override val defaultCliBinaryNameByOsAndArch: String get() = getCoderCLIForOS(getOS(), getArch())
4343
override val binaryName: String get() = store[BINARY_NAME] ?: getCoderCLIForOS(getOS(), getArch())
44+
override val defaultSignatureNameByOsAndArch: String get() = getCoderSignatureForOS(getOS(), getArch())
4445
override val dataDirectory: String? get() = store[DATA_DIRECTORY]
4546
override val globalDataDirectory: String get() = getDefaultGlobalDataDir().normalize().toString()
4647
override val globalConfigDir: String get() = getDefaultGlobalConfigDir().normalize().toString()
@@ -243,41 +244,59 @@ class CoderSettingsStore(
243244
}
244245

245246
/**
246-
* Return the name of the binary (with extension) for the provided OS and
247-
* architecture.
247+
* Return the name of the binary (with extension) for the provided OS and architecture.
248248
*/
249249
private fun getCoderCLIForOS(
250250
os: OS?,
251251
arch: Arch?,
252252
): String {
253-
logger.info("Resolving binary for $os $arch")
253+
logger.debug("Resolving binary for $os $arch")
254+
return buildCoderFileName(os, arch)
255+
}
256+
257+
/**
258+
* Return the name of the signature file (.asc) for the provided OS and architecture.
259+
*/
260+
private fun getCoderSignatureForOS(
261+
os: OS?,
262+
arch: Arch?,
263+
): String {
264+
logger.debug("Resolving signature for $os $arch")
265+
return buildCoderFileName(os, arch, true)
266+
}
267+
268+
/**
269+
* Build the coder file name based on OS, architecture, and whether it's a signature file.
270+
*/
271+
private fun buildCoderFileName(
272+
os: OS?,
273+
arch: Arch?,
274+
isSignature: Boolean = false
275+
): String {
254276
if (os == null) {
255277
logger.error("Could not resolve client OS and architecture, defaulting to WINDOWS AMD64")
256-
return "coder-windows-amd64.exe"
278+
return if (isSignature) "coder-windows-amd64.asc" else "coder-windows-amd64.exe"
257279
}
258-
return when (os) {
259-
OS.WINDOWS ->
260-
when (arch) {
261-
Arch.AMD64 -> "coder-windows-amd64.exe"
262-
Arch.ARM64 -> "coder-windows-arm64.exe"
263-
else -> "coder-windows-amd64.exe"
264-
}
265280

266-
OS.LINUX ->
267-
when (arch) {
268-
Arch.AMD64 -> "coder-linux-amd64"
269-
Arch.ARM64 -> "coder-linux-arm64"
270-
Arch.ARMV7 -> "coder-linux-armv7"
271-
else -> "coder-linux-amd64"
272-
}
281+
val osName = when (os) {
282+
OS.WINDOWS -> "windows"
283+
OS.LINUX -> "linux"
284+
OS.MAC -> "darwin"
285+
}
273286

274-
OS.MAC ->
275-
when (arch) {
276-
Arch.AMD64 -> "coder-darwin-amd64"
277-
Arch.ARM64 -> "coder-darwin-arm64"
278-
else -> "coder-darwin-amd64"
279-
}
287+
val archName = when (arch) {
288+
Arch.AMD64 -> "amd64"
289+
Arch.ARM64 -> "arm64"
290+
Arch.ARMV7 -> "armv7"
291+
else -> "amd64" // default fallback
280292
}
293+
294+
val extension = if (isSignature) ".asc" else when (os) {
295+
OS.WINDOWS -> ".exe"
296+
OS.LINUX, OS.MAC -> ""
297+
}
298+
299+
return "coder-$osName-$archName$extension"
281300
}
282301

283302
/**

src/main/kotlin/com/coder/toolbox/util/OS.kt

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,19 @@
11
package com.coder.toolbox.util
22

3-
import java.util.*
3+
import java.util.Locale
44

55
fun getOS(): OS? = OS.from(System.getProperty("os.name"))
66

7-
fun getArch(): Arch? = Arch.from(System.getProperty("os.arch").lowercase(Locale.getDefault()))
7+
fun getArch(): Arch? = Arch.from(System.getProperty("os.arch")?.lowercase(Locale.getDefault()))
88

99
enum class OS {
1010
WINDOWS,
1111
LINUX,
1212
MAC;
1313

14-
/**
15-
* The name of the current desktop environment.
16-
* For Linux systems it can be GNOME, KDE, XFCE, LXDE, and so on,
17-
* while for macOS it will be Aqua and Windows Shell for Windows.
18-
*/
19-
fun getDesktopEnvironment(): String? =
20-
when (this) {
21-
WINDOWS -> "Windows Shell"
22-
MAC -> "Aqua"
23-
LINUX -> System.getenv("XDG_CURRENT_DESKTOP")
24-
}
25-
2614
companion object {
27-
fun from(os: String): OS? = when {
15+
fun from(os: String?): OS? = when {
16+
os.isNullOrBlank() -> null
2817
os.contains("win", true) -> {
2918
WINDOWS
3019
}
@@ -49,7 +38,8 @@ enum class Arch {
4938
;
5039

5140
companion object {
52-
fun from(arch: String): Arch? = when {
41+
fun from(arch: String?): Arch? = when {
42+
arch.isNullOrBlank() -> null
5343
arch.contains("amd64", true) || arch.contains("x86_64", true) -> AMD64
5444
arch.contains("arm64", true) || arch.contains("aarch64", true) -> ARM64
5545
arch.contains("armv7", true) -> ARMV7
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package com.coder.toolbox.store
2+
3+
import com.coder.toolbox.settings.Environment
4+
import com.coder.toolbox.util.pluginTestSettingsStore
5+
import com.jetbrains.toolbox.api.core.diagnostics.Logger
6+
import io.mockk.mockk
7+
import org.junit.jupiter.api.Assertions.assertEquals
8+
import kotlin.test.AfterTest
9+
import kotlin.test.BeforeTest
10+
import kotlin.test.Test
11+
12+
class CoderSettingsStoreTest {
13+
private var originalOsName: String? = null
14+
private var originalOsArch: String? = null
15+
16+
private lateinit var store: CoderSettingsStore
17+
18+
@BeforeTest
19+
fun setUp() {
20+
originalOsName = System.getProperty("os.name")
21+
originalOsArch = System.getProperty("os.arch")
22+
23+
store = CoderSettingsStore(
24+
pluginTestSettingsStore(),
25+
Environment(),
26+
mockk<Logger>(relaxed = true)
27+
)
28+
}
29+
30+
@AfterTest
31+
fun tearDown() {
32+
System.setProperty("os.name", originalOsName)
33+
System.setProperty("os.arch", originalOsArch)
34+
}
35+
36+
@Test
37+
fun `Default CLI and signature for Windows AMD64`() =
38+
assertBinaryAndSignature("Windows 10", "amd64", "coder-windows-amd64.exe", "coder-windows-amd64.asc")
39+
40+
@Test
41+
fun `Default CLI and signature for Windows ARM64`() =
42+
assertBinaryAndSignature("Windows 10", "aarch64", "coder-windows-arm64.exe", "coder-windows-arm64.asc")
43+
44+
@Test
45+
fun `Default CLI and signature for Windows ARMV7`() =
46+
assertBinaryAndSignature("Windows 10", "armv7l", "coder-windows-armv7.exe", "coder-windows-armv7.asc")
47+
48+
@Test
49+
fun `Default CLI and signature for Linux AMD64`() =
50+
assertBinaryAndSignature("Linux", "x86_64", "coder-linux-amd64", "coder-linux-amd64.asc")
51+
52+
@Test
53+
fun `Default CLI and signature for Linux ARM64`() =
54+
assertBinaryAndSignature("Linux", "aarch64", "coder-linux-arm64", "coder-linux-arm64.asc")
55+
56+
@Test
57+
fun `Default CLI and signature for Linux ARMV7`() =
58+
assertBinaryAndSignature("Linux", "armv7l", "coder-linux-armv7", "coder-linux-armv7.asc")
59+
60+
@Test
61+
fun `Default CLI and signature for Mac AMD64`() =
62+
assertBinaryAndSignature("Mac OS X", "x86_64", "coder-darwin-amd64", "coder-darwin-amd64.asc")
63+
64+
@Test
65+
fun `Default CLI and signature for Mac ARM64`() =
66+
assertBinaryAndSignature("Mac OS X", "aarch64", "coder-darwin-arm64", "coder-darwin-arm64.asc")
67+
68+
@Test
69+
fun `Default CLI and signature for Mac ARMV7`() =
70+
assertBinaryAndSignature("Mac OS X", "armv7l", "coder-darwin-armv7", "coder-darwin-armv7.asc")
71+
72+
@Test
73+
fun `Default CLI and signature for unknown OS and Arch`() =
74+
assertBinaryAndSignature(null, null, "coder-windows-amd64.exe", "coder-windows-amd64.asc")
75+
76+
@Test
77+
fun `Default CLI and signature for unknown Arch fallback on Linux`() =
78+
assertBinaryAndSignature("Linux", "mips64", "coder-linux-amd64", "coder-linux-amd64.asc")
79+
80+
private fun assertBinaryAndSignature(
81+
osName: String?,
82+
arch: String?,
83+
expectedBinary: String,
84+
expectedSignature: String
85+
) {
86+
if (osName == null) System.clearProperty("os.name") else System.setProperty("os.name", osName)
87+
if (arch == null) System.clearProperty("os.arch") else System.setProperty("os.arch", arch)
88+
89+
assertEquals(expectedBinary, store.defaultCliBinaryNameByOsAndArch)
90+
assertEquals(expectedSignature, store.defaultSignatureNameByOsAndArch)
91+
}
92+
93+
}

0 commit comments

Comments
 (0)