1+ import java.io.PrintWriter
2+ import java.nio.file.Files.*
3+ import java.nio.file.Path
4+ import java.nio.file.StandardCopyOption.REPLACE_EXISTING
5+
6+ description = " Robocode Tank Royale sample bots for Python"
7+
8+ version = libs.versions.tankroyale.get()
9+
10+ plugins {
11+ base // for the clean and build task
12+ }
13+
14+ val archiveDir = layout.buildDirectory.dir(" archive" )
15+ val archiveDirPath = archiveDir.get().asFile.toPath()
16+
17+ fun Path.botName () = fileName.toString()
18+
19+ // Shared helpers provided by parent sample-bots/build.gradle.kts
20+ @Suppress(" UNCHECKED_CAST" )
21+ val isBotProjectDir = rootProject.extra[" isBotProjectDir" ] as (Path ) -> Boolean
22+ @Suppress(" UNCHECKED_CAST" )
23+ val copyBotFiles = rootProject.extra[" copyBotFiles" ] as (Path , Path ) -> Unit
24+
25+ private fun writeShellScript (writer : PrintWriter , botName : String ) {
26+ val shellScript = """
27+ #!/bin/sh
28+ ../deps/install-dependencies.sh
29+
30+ cd -- "${' $' } (dirname -- "${' $' } 0")"
31+ if command -v python3 >/dev/null 2>&1; then
32+ PY=python3
33+ elif command -v python >/dev/null 2>&1; then
34+ PY=python
35+ else
36+ echo "Error: Python not found. Please install python3 or python." >&2
37+ exit 1
38+ fi
39+
40+ exec "${' $' } PY" $botName .py
41+ """ .trimIndent()
42+
43+ writer.print (shellScript)
44+ }
45+
46+ private fun writeBatchScript (writer : PrintWriter , botName : String ) {
47+ // Important: We need to add the `>nul` redirection to avoid cmd processes halting
48+ val batchScript = """
49+ call ..\deps\install-dependencies.cmd
50+
51+ cd /d "%~dp0"
52+ set "PY="
53+ where python3 >nul 2>nul && set "PY=python3"
54+ if not defined PY (
55+ where python >nul 2>nul && set "PY=python"
56+ )
57+ if not defined PY (
58+ echo Error: Python not found. Please install Python 3.
59+ exit /b 1
60+ )
61+ %PY% $botName .py >nul
62+ """ .trimIndent()
63+
64+ writer.print (batchScript)
65+ }
66+
67+ private fun createScriptFile (projectDir : Path , botArchivePath : Path , fileExt : String , newLine : String ) {
68+ val botName = projectDir.botName()
69+ val file = botArchivePath.resolve(" $botName .$fileExt " ).toFile()
70+ val printWriter = object : PrintWriter (file) {
71+ override fun println () {
72+ write(newLine)
73+ }
74+ }
75+
76+ printWriter.use { writer ->
77+ when (fileExt) {
78+ " sh" -> writeShellScript(writer, botName)
79+ " cmd" -> writeBatchScript(writer, botName)
80+ }
81+ }
82+ }
83+
84+ tasks {
85+ fun prepareBotFiles () {
86+ list(projectDir.toPath()).forEach { botDir ->
87+ if (isDirectory(botDir) && isBotProjectDir(botDir)) {
88+ val botArchivePath: Path = archiveDirPath.resolve(botDir.botName())
89+
90+ mkdir(botArchivePath)
91+ copyBotFiles(botDir, botArchivePath)
92+
93+ if (! botDir.toString().endsWith(" Team" )) {
94+ createScriptFile(botDir, botArchivePath, " cmd" , " \r\n " )
95+ createScriptFile(botDir, botArchivePath, " sh" , " \n " )
96+ }
97+ }
98+ }
99+ }
100+
101+ fun prepareDepsDir () {
102+ // Create a deps folder and copy dependency installers + requirements.txt
103+ val depsDir = archiveDirPath.resolve(" deps" )
104+ mkdir(depsDir)
105+
106+ // Copy install-dependencies scripts from assets
107+ val assetsDir = project.projectDir.toPath().resolve(" assets" )
108+ copy(assetsDir.resolve(" install-dependencies.cmd" ), depsDir.resolve(" install-dependencies.cmd" ), REPLACE_EXISTING )
109+ copy(assetsDir.resolve(" install-dependencies.sh" ), depsDir.resolve(" install-dependencies.sh" ), REPLACE_EXISTING )
110+
111+ // Copy requirements.txt from bot-api/python into deps
112+ val requirements = rootProject.projectDir.toPath().resolve(" bot-api/python/requirements.txt" )
113+ if (exists(requirements)) {
114+ copy(requirements, depsDir.resolve(" requirements.txt" ), REPLACE_EXISTING )
115+ } else {
116+ throw GradleException (" requirements.txt not found at: ${requirements.toAbsolutePath()} " )
117+ }
118+ }
119+
120+ named(" build" ) {
121+ doLast {
122+ prepareBotFiles()
123+ prepareDepsDir()
124+ }
125+ }
126+ }
0 commit comments