Skip to content

Commit 06e82ef

Browse files
committed
deprecate UI some more
1 parent fe1de71 commit 06e82ef

4 files changed

Lines changed: 141 additions & 85 deletions

File tree

src/main/kotlin/config/WurstProjectConfig.kt

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import ui.UiManager
1616
import java.io.IOException
1717
import java.nio.file.Files
1818
import java.nio.file.Path
19+
import java.nio.file.Paths
1920
import java.nio.file.StandardOpenOption
2021
import javax.swing.JOptionPane
2122
/**
@@ -168,7 +169,7 @@ object WurstProjectConfig {
168169

169170
jsonNode.put("wurst.wurstJar", absolutePath)
170171

171-
if (!gamePath.isBlank()) {
172+
if (isValidGamePath(gamePath)) {
172173
jsonNode.put("wurst.wc3path", gamePath)
173174
}
174175
val schemaNode = MAPPER.createObjectNode()
@@ -177,6 +178,18 @@ object WurstProjectConfig {
177178
return MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(jsonNode)
178179
}
179180

181+
private fun isValidGamePath(gamePath: String): Boolean {
182+
if (gamePath.isBlank()) {
183+
return false
184+
}
185+
return try {
186+
val path = Paths.get(gamePath)
187+
Files.exists(path) && Files.isDirectory(path)
188+
} catch (_: Exception) {
189+
false
190+
}
191+
}
192+
180193
fun handleUpdate(projectRoot: Path, gamePath: Path?, config: WurstProjectConfigData) {
181194
Log.print("Updating project...\n")
182195
try {

src/main/kotlin/file/YamlHelper.kt

Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator
1010
import com.fasterxml.jackson.module.kotlin.KotlinModule
1111
import config.WurstProjectConfigData
1212
import mu.KotlinLogging
13+
import java.io.IOException
1314
import java.nio.file.Files
1415
import java.nio.file.Path
16+
import java.nio.file.StandardCopyOption
1517

1618
object YamlHelper {
1719
private var mapper: ObjectMapper
@@ -31,20 +33,69 @@ object YamlHelper {
3133

3234

3335
fun loadProjectConfig(path: Path): WurstProjectConfigData {
34-
Files.newBufferedReader(path).use {
35-
try {
36-
return mapper.readValue(it, WurstProjectConfigData::class.java)
37-
} catch (e: Exception) {
38-
log.error("The project's wurst.build file could not be read. Input malformed or corrupt.", e)
39-
throw YamlException("The project's wurst.build file could not be read. Input malformed or corrupt.")
40-
}
36+
val content = Files.readString(path)
37+
if (isEffectivelyEmptyYaml(content)) {
38+
val fallback = fallbackConfig(path)
39+
persistRecoveredConfig(path, fallback, backupOriginal = false)
40+
return fallback
41+
}
42+
43+
return try {
44+
val config = mapper.readValue(content, WurstProjectConfigData::class.java)
45+
normalizeConfig(config, path)
46+
} catch (e: Exception) {
47+
log.warn("The project's wurst.build file could not be read. Recovering with defaults.", e)
48+
val fallback = fallbackConfig(path)
49+
persistRecoveredConfig(path, fallback, backupOriginal = true)
50+
fallback
4151
}
4252
}
4353

4454
fun dumpProjectConfig(configData: WurstProjectConfigData): String {
45-
return mapper.writeValueAsString(configData)
55+
val normalized = normalizeConfig(configData, null)
56+
val yaml = mapper.writeValueAsString(normalized).trim()
57+
if (isEffectivelyEmptyYaml(yaml)) {
58+
return defaultYaml(normalized.projectName)
59+
}
60+
return yaml + "\n"
61+
}
62+
63+
private fun normalizeConfig(configData: WurstProjectConfigData, sourcePath: Path?): WurstProjectConfigData {
64+
if (configData.projectName.isBlank()) {
65+
configData.projectName = sourcePath?.parent?.fileName?.toString() ?: "unnamed"
66+
}
67+
return configData
68+
}
69+
70+
private fun fallbackConfig(path: Path): WurstProjectConfigData {
71+
val projectName = path.parent?.fileName?.toString() ?: "unnamed"
72+
return WurstProjectConfigData(projectName)
73+
}
74+
75+
private fun defaultYaml(projectName: String): String {
76+
return "projectName: \"$projectName\"\n" +
77+
"dependencies: []\n"
78+
}
79+
80+
private fun isEffectivelyEmptyYaml(content: String): Boolean {
81+
val stripped = content
82+
.replace("\uFEFF", "")
83+
.lines()
84+
.filter { it.trim().isNotEmpty() && !it.trim().startsWith("#") }
85+
.joinToString("\n") { it.trim() }
86+
return stripped.isEmpty() || stripped == "--- {}" || stripped == "{}" || stripped == "---"
4687
}
4788

48-
class YamlException(msg: String): RuntimeException(msg)
89+
private fun persistRecoveredConfig(path: Path, config: WurstProjectConfigData, backupOriginal: Boolean) {
90+
try {
91+
if (backupOriginal && Files.exists(path)) {
92+
val backupPath = path.resolveSibling(path.fileName.toString() + ".bak")
93+
Files.copy(path, backupPath, StandardCopyOption.REPLACE_EXISTING)
94+
}
95+
Files.writeString(path, dumpProjectConfig(config))
96+
} catch (e: IOException) {
97+
log.warn("Could not persist recovered wurst.build at <$path>.", e)
98+
}
99+
}
49100
}
50101

src/main/kotlin/ui/MainWindow.kt

Lines changed: 39 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,9 @@ import config.WurstProjectBuildMapData
55
import config.WurstProjectConfig
66
import config.WurstProjectConfigData
77
import de.ralleytn.simple.registry.Registry
8-
import file.CompileTimeInfo
98
import file.SetupApp
10-
import global.InstallationManager
119
import global.Log
1210
import mu.KotlinLogging
13-
import net.ConnectionManager
14-
import net.NetStatus
1511
import tablelayout.Table
1612
import workers.*
1713
import java.awt.*
@@ -40,6 +36,7 @@ import kotlin.system.exitProcess
4036

4137
object MainWindow : JFrame() {
4238
private val log = KotlinLogging.logger {}
39+
private const val GAME_PATH_PLACEHOLDER = "Select your wc3 installation folder (optional)"
4340
private val exitIcon by lazy { ImageIcon(ImageIO.read(javaClass.classLoader.getResource("exitup.png"))) }
4441
private val minIcon by lazy { ImageIcon(ImageIO.read(javaClass.classLoader.getResource("minimizeup.png"))) }
4542
private val exitIconDown by lazy { ImageIcon(ImageIO.read(javaClass.classLoader.getResource("exitdown.png"))) }
@@ -84,17 +81,7 @@ object MainWindow : JFrame() {
8481
}
8582
})
8683
isVisible = true
87-
OnlineCheckWorker("http://google.com") {if (ConnectionManager.netStatus == NetStatus.SERVER_CONTACT) executeListener()}.execute()
88-
OnlineCheckWorker("http://bing.com") {if (ConnectionManager.netStatus == NetStatus.SERVER_CONTACT) executeListener()}.execute()
89-
OnlineCheckWorker("http://baidu.com") {if (ConnectionManager.netStatus == NetStatus.SERVER_CONTACT) executeListener()}.execute()
90-
}
91-
92-
private var hasExecuted = false
93-
private fun executeListener() {
94-
if (!hasExecuted) {
95-
hasExecuted = true
96-
WurstBuildCheckWorker().execute()
97-
}
84+
log.warn("GUI mode is deprecated. Use the VSCode extension for compiler/update management.")
9885
}
9986

10087
class UI : JPanel() {
@@ -104,22 +91,22 @@ object MainWindow : JFrame() {
10491
private val title = JPanel()
10592
private val windowLabel = JLabel(" Wurst Setup")
10693
var lblWelcome: JLabel = JLabel("Welcome to the Wurst Setup")
107-
var lblCurrentVersion: JLabel = JLabel("Installed Compiler Build: ")
108-
var lblCurVerNumber: JLabel = JLabel("(not installed)")
109-
var lblLatestVer: JLabel = JLabel("Latest Build: ")
110-
var lblLatestVerNumber: JLabel = JLabel("(unknown)")
94+
var lblCurrentVersion: JLabel = JLabel("GUI Status:")
95+
var lblCurVerNumber: JLabel = JLabel("Deprecated - use VSCode extension for updates.")
96+
var lblLatestVer: JLabel = JLabel("")
97+
var lblLatestVerNumber: JLabel = JLabel("")
11198
var progressBar: JProgressBar = JProgressBar()
11299
var btnCreate: SetupButton = SetupButton("Create Project")
113100
var btnUpdate: SetupButton = SetupButton("Install WurstScript")
114101
var importButton: SetupButton = SetupButton("Open Project")
115102
var btnAdvanced: SetupButton = SetupButton("Add")
116-
var jTextArea = JTextArea("Ready version: " + CompileTimeInfo.version + "\n")
103+
var jTextArea = JTextArea("GUI mode is deprecated.\nUse the VSCode extension for compiler and update management.\n")
117104
var projectNameTF: JTextField = JTextField("MyWurstProject")
118105
var projectRootTF: JTextField = JTextField("projectRoot")
119106
var dependencyTF: JTextField = JTextField("wurstStdlib2")
120107
private val exit = JButton(exitIcon)
121108
private val minimize = JButton(minIcon)
122-
private val gamePathTF = JTextField("Select your wc3 installation folder (optional)")
109+
private val gamePathTF = JTextField(GAME_PATH_PLACEHOLDER)
123110

124111
private var selectedConfig: WurstProjectConfigData? = null
125112
var dependencies: MutableList<String> = ArrayList(Arrays.asList("https://github.com/wurstscript/wurstStdlib2"))
@@ -402,57 +389,19 @@ object MainWindow : JFrame() {
402389
SwingUtilities.invokeLater {
403390
progressBar.isIndeterminate = false
404391
if (!disabled) {
405-
importButton.isEnabled = true
406-
}
407-
when (ConnectionManager.netStatus) {
408-
NetStatus.CLIENT_OFFLINE, NetStatus.SERVER_OFFLINE -> {
409-
lblLatestVerNumber.text = "(loading..)"
410-
lblLatestVerNumber.foreground = Color.DARK_GRAY
411-
btnCreate.isEnabled = false
412-
btnUpdate.isEnabled = false
413-
}
414-
NetStatus.ONLINE -> {
415-
lblLatestVerNumber.text = InstallationManager.latestCompilerVersion.toString()
416-
lblLatestVerNumber.foreground = Color.decode("#005719")
417-
if (!disabled) {
418-
btnUpdate.isEnabled = true
419-
}
420-
}
421-
NetStatus.SERVER_CONTACT -> {
422-
lblLatestVerNumber.text = "Loading.."
423-
btnUpdate.isEnabled = false
424-
}
425-
}
426-
when (InstallationManager.status) {
427-
InstallationManager.InstallationStatus.NOT_INSTALLED -> {
428-
btnUpdate.text = "Install WurstScript"
429-
btnCreate.isEnabled = false
430-
lblCurVerNumber.foreground = Color.DARK_GRAY
431-
}
432-
InstallationManager.InstallationStatus.INSTALLED_UPTODATE -> {
433-
lblCurVerNumber.text = getVersionString()
434-
lblCurVerNumber.foreground = Color.decode("#005719")
435-
if (!disabled) {
436-
btnCreate.isEnabled = true
437-
}
438-
btnUpdate.text = "Compiler up to date"
439-
btnUpdate.isEnabled = false
440-
}
441-
InstallationManager.InstallationStatus.INSTALLED_UNKNOWN, InstallationManager.InstallationStatus.INSTALLED_OUTDATED -> {
442-
lblCurVerNumber.text = getVersionString()
443-
lblCurVerNumber.foreground = Color.decode("#702D2D")
444-
if (!disabled) {
445-
btnCreate.isEnabled = true
446-
}
447-
btnUpdate.text = "Update WurstScript"
448-
}
392+
importButton.isEnabled = true
393+
btnCreate.isEnabled = projectNameTF.text.isNotBlank()
449394
}
395+
lblCurrentVersion.text = "GUI Status:"
396+
lblCurVerNumber.text = "Deprecated - use VSCode extension for updates."
397+
lblCurVerNumber.foreground = Color.DARK_GRAY
398+
lblLatestVer.text = ""
399+
lblLatestVerNumber.text = ""
400+
btnUpdate.text = "Compiler updates moved to VSCode extension"
401+
btnUpdate.isEnabled = false
450402
}
451403
}
452404

453-
private fun getVersionString() =
454-
if (InstallationManager.currentCompilerVersion > 0) InstallationManager.currentCompilerVersion.toString() else "(unofficial build)"
455-
456405
private var disabled = false
457406

458407
fun enableButtons() {
@@ -531,9 +480,8 @@ object MainWindow : JFrame() {
531480
private fun handleCreateProject() {
532481
SwingUtilities.invokeLater { progressBar.isIndeterminate = true }
533482
disableButtons()
534-
val gamePath = gamePathTF.text
535483
val projectRoot = Paths.get(projectRootTF.text)
536-
val gameRoot = if (gamePath.isNotEmpty()) Paths.get(gamePath) else null
484+
val gameRoot = resolveOptionalGameRoot()
537485
val config = WurstProjectConfigData("MyProjectName",
538486
java.util.ArrayList(mutableListOf("https://github.com/wurstscript/wurstStdlib2")),
539487
buildMapData = WurstProjectBuildMapData(name = "MyMapName", fileName = "MyMapFile", author = System.getProperty("user.name")))
@@ -553,7 +501,7 @@ object MainWindow : JFrame() {
553501
}
554502

555503
private fun handleUpdateProject() {
556-
val gameRoot = Paths.get(gamePathTF.text)
504+
val gameRoot = resolveOptionalGameRoot()
557505
val projectRoot = Paths.get(projectRootTF.text)
558506
if (selectedConfig != null) {
559507
dependencies.forEach { e -> if (selectedConfig?.dependencies?.contains(e) == false) selectedConfig?.dependencies?.add(e) }
@@ -562,11 +510,27 @@ object MainWindow : JFrame() {
562510
}
563511
}
564512

513+
private fun resolveOptionalGameRoot(): java.nio.file.Path? {
514+
val rawPath = gamePathTF.text.trim()
515+
if (rawPath.isBlank() || rawPath == GAME_PATH_PLACEHOLDER) {
516+
return null
517+
}
518+
return try {
519+
val path = Paths.get(rawPath)
520+
if (Files.exists(path) && Files.isDirectory(path)) path else null
521+
} catch (_: Exception) {
522+
null
523+
}
524+
}
525+
565526
private fun handleWurstUpdate() {
566-
log.debug("handle wurst update")
567-
SwingUtilities.invokeLater { progressBar.isIndeterminate = true }
568-
disableButtons()
569-
CompilerUpdateWorker().execute()
527+
log.info("GUI compiler updates are deprecated. Use the VSCode extension.")
528+
JOptionPane.showMessageDialog(
529+
this,
530+
"Compiler updates in WurstSetup GUI are deprecated.\nUse the VSCode extension for install/update management.",
531+
"Deprecated",
532+
JOptionPane.INFORMATION_MESSAGE
533+
)
570534
}
571535

572536
}

src/test/kotlin/YamlHelperTests.kt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import config.WurstProjectConfigData
2+
import file.YamlHelper
3+
import org.testng.Assert
4+
import org.testng.annotations.Test
5+
import java.nio.file.Files
6+
7+
class YamlHelperTests {
8+
9+
@Test
10+
fun testDumpDoesNotProduceEmptyConfig() {
11+
val dumped = YamlHelper.dumpProjectConfig(WurstProjectConfigData())
12+
Assert.assertFalse(dumped.trim() == "--- {}" || dumped.trim() == "{}" || dumped.trim() == "---")
13+
Assert.assertTrue(dumped.contains("projectName:"))
14+
Assert.assertTrue(dumped.contains("dependencies:"))
15+
}
16+
17+
@Test
18+
fun testLoadMalformedConfigRecoversWithDefaults() {
19+
val dir = Files.createTempDirectory("wurstsetup-yaml-test")
20+
val buildFile = dir.resolve("wurst.build")
21+
Files.writeString(buildFile, ":\n - [broken")
22+
23+
val loaded = YamlHelper.loadProjectConfig(buildFile)
24+
Assert.assertEquals(loaded.projectName, dir.fileName.toString())
25+
Assert.assertTrue(Files.exists(buildFile))
26+
Assert.assertTrue(Files.exists(dir.resolve("wurst.build.bak")))
27+
}
28+
}

0 commit comments

Comments
 (0)