-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathkotlin.bat
More file actions
executable file
·257 lines (222 loc) · 11.1 KB
/
kotlin.bat
File metadata and controls
executable file
·257 lines (222 loc) · 11.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
@echo off
@rem
@rem Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
@rem
@rem Possible environment variables:
@rem KOTLIN_CLI_DOWNLOAD_ROOT Maven repository to download the Kotlin CLI dist from
@rem default: https://packages.jetbrains.team/maven/p/amper/amper
@rem KOTLIN_CLI_JRE_DOWNLOAD_ROOT Url prefix to download the Kotlin CLI JRE from.
@rem default: https:/
@rem KOTLIN_CLI_BOOTSTRAP_CACHE_DIR Cache directory to store the extracted JRE and Kotlin CLI distribution
@rem KOTLIN_CLI_JAVA_HOME JRE to run the Kotlin CLI itself (optional, does not affect compilation)
@rem KOTLIN_CLI_JAVA_OPTIONS JVM options to pass to the JVM running the Kotlin CLI (does not affect the user's application)
@rem KOTLIN_CLI_NO_WELCOME_BANNER Disables the first-run welcome message if set to a non-empty value
setlocal
@rem The version of the Kotlin Toolchain distribution to provision and use
set kotlin_cli_version=0.11.0
@rem Establish chain of trust from here by specifying the exact checksum of the Kotlin Toolchain distribution to be run
set kotlin_cli_sha256=ff872a5bf42ad1a8fac90ccca6ac38a4d4a6aafefc39167860f66a77b1653d74
if not defined KOTLIN_CLI_DOWNLOAD_ROOT set KOTLIN_CLI_DOWNLOAD_ROOT=https://packages.jetbrains.team/maven/p/amper/amper
if not defined KOTLIN_CLI_BOOTSTRAP_CACHE_DIR set KOTLIN_CLI_BOOTSTRAP_CACHE_DIR=%LOCALAPPDATA%\JetBrains\Kotlin\cli
@rem remove trailing \ if present
if [%KOTLIN_CLI_BOOTSTRAP_CACHE_DIR:~-1%] EQU [\] set KOTLIN_CLI_BOOTSTRAP_CACHE_DIR=%KOTLIN_CLI_BOOTSTRAP_CACHE_DIR:~0,-1%
goto :after_function_declarations
REM ********** Download and extract any zip or .tar.gz archive **********
:download_and_extract
setlocal
set moniker=%~1
set url=%~2
set target_dir=%~3
set sha=%~4
set sha_size=%~5
set show_banner_on_cache_miss=%~6
set flag_file=%target_dir%\.flag
if exist "%flag_file%" (
set /p current_flag=<"%flag_file%"
if "%current_flag%" == "%sha%" exit /b
)
setlocal enableDelayedExpansion
set NL=^
@rem two empty lines required above for the NL character
@rem We have to build the welcome banner here as an env var because we
@rem can't pass a multiline string through the single line powershell
set welcome_banner=!NL! ^
Welcome to !NL! ^
!NL! ^
@@@ @@@@ @@@ @@@ !NL! ^
@@@ @@@@ @@@ @@@ @@@ !NL! ^
@@@ #@@@^" ,@@@ @@@ !NL! ^
@@@ ,@@@%% ,@@@@@@@, @@@@@@@@@@ @@@ @@@ @@@ ,@@@@@, !NL! ^
@@@ @@@@ @@@@@%%^"%%@@@@@ @@@@@@@@@@ @@@ @@@ @@@@@@%%%%@@@@@ !NL! ^
@@@@@@%% @@@%% %%@@@ @@@ @@@ @@@ @@@@ %%@@%% !NL! ^
@@@ @@@@= #@@@ @@@# @@@ @@@ @@@ @@@ @@@ !NL! ^
@@@ @@@@ #@@@ @@@# @@@ @@@ @@@ @@@ @@@ !NL! ^
@@@ *@@@%% @@@@ @@@@ @@@ @@@ @@@ @@@ @@@ !NL! ^
@@@ %%@@@= %%@@@@*,*@@@@%% @@@@### @@@ @@@ @@@ @@@ !NL! ^
@@@ @@@@ ^"@@@@@@@^" %%@@@@@ @@@ @@@ @@@ @@@ !NL!
@rem This multiline string is actually passed as a single line to powershell, meaning #-comments are not possible.
@rem So here are a few comments about the code below:
@rem - we need to support both .zip and .tar.gz archives (for the Kotlin Toolchain distribution and the JRE)
@rem - tar should be present in all Windows machines since 2018 (and usable from both cmd and powershell)
@rem - tar requires the destination dir to exist
@rem - We use (New-Object Net.WebClient).DownloadFile instead of Invoke-WebRequest for performance. See the issue
@rem https://github.com/PowerShell/PowerShell/issues/16914, which is still not fixed in Windows PowerShell 5.1
@rem - DownloadFile requires the directories in the destination file's path to exist
set download_and_extract_ps1= ^
Set-StrictMode -Version 3.0; ^
$ErrorActionPreference = 'Stop'; ^
^
$createdNew = $false; ^
$lock = New-Object System.Threading.Mutex($true, ('Global\kotlin-cli-bootstrap.' + '%target_dir%'.GetHashCode().ToString()), [ref]$createdNew); ^
if (-not $createdNew) { ^
Write-Host 'Another Kotlin CLI instance is bootstrapping. Waiting for our turn...'; ^
[void]$lock.WaitOne(); ^
} ^
^
try { ^
if ((Get-Content '%flag_file%' -ErrorAction Ignore) -ne '%sha%') { ^
if (('%show_banner_on_cache_miss%' -eq 'true') -and [string]::IsNullOrEmpty('%KOTLIN_CLI_NO_WELCOME_BANNER%')) { ^
Write-Host \"$env:welcome_banner\"; ^
Write-Host ''; ^
Write-Host 'This is the first run of the Kotlin CLI v%kotlin_cli_version%, so we need to download the Kotlin Toolchain.'; ^
Write-Host 'Please give us a few seconds now, subsequent runs will be faster.'; ^
Write-Host ''; ^
} ^
$temp_file = '%KOTLIN_CLI_BOOTSTRAP_CACHE_DIR%\' + [System.IO.Path]::GetRandomFileName(); ^
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; ^
Write-Host 'Downloading %moniker%...'; ^
[void](New-Item '%KOTLIN_CLI_BOOTSTRAP_CACHE_DIR%' -ItemType Directory -Force); ^
if (Get-Command curl.exe -errorAction SilentlyContinue) { ^
curl.exe -L --silent --show-error --fail --output $temp_file '%url%'; ^
} else { ^
(New-Object Net.WebClient).DownloadFile('%url%', $temp_file); ^
} ^
^
$actualSha = (Get-FileHash -Algorithm SHA%sha_size% -Path $temp_file).Hash.ToString(); ^
if ($actualSha -ne '%sha%') { ^
$writeErr = if ($Host.Name -eq 'ConsoleHost') { [Console]::Error.WriteLine } else { $host.ui.WriteErrorLine } ^
$writeErr.Invoke(\"ERROR: Checksum mismatch for $temp_file (downloaded from %url%): expected checksum %sha% but got $actualSha\"); ^
exit 1; ^
} ^
^
if (Test-Path '%target_dir%') { ^
Remove-Item '%target_dir%' -Recurse; ^
} ^
if ($temp_file -like '*.zip') { ^
Add-Type -A 'System.IO.Compression.FileSystem'; ^
[IO.Compression.ZipFile]::ExtractToDirectory($temp_file, '%target_dir%'); ^
} else { ^
[void](New-Item '%target_dir%' -ItemType Directory -Force); ^
tar -xzf $temp_file -C '%target_dir%'; ^
} ^
Remove-Item $temp_file; ^
^
Set-Content '%flag_file%' -Value '%sha%'; ^
Write-Host 'Download complete.'; ^
Write-Host ''; ^
} ^
} ^
finally { ^
$lock.ReleaseMutex(); ^
}
rem We reset the PSModulePath in case this batch script was called from PowerShell Core
rem See https://github.com/PowerShell/PowerShell/issues/18108#issuecomment-2269703022
set PSModulePath=
set powershell=%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe
"%powershell%" -NonInteractive -NoProfile -NoLogo -Command %download_and_extract_ps1%
if errorlevel 1 exit /b 1
exit /b 0
:find_project_context
@rem Search upwards for a kotlin.bat wrapper file and/or project.yaml
@rem Sets wrapper_script to the found wrapper path, or empty string if not found.
@rem Returns errorlevel 0 if a valid wrapper (that is not this script itself) was found, 1 otherwise.
set wrapper_script=
set this_script=%~f0
set project_dir=%CD%
:find_loop
set wrapper_candidate=%project_dir%\kotlin.bat
if "%this_script%"=="%wrapper_candidate%" (
@rem Found itself (local wrapper case), no need to update any version or search further.
exit /b 1
)
if exist "%wrapper_candidate%" (
@rem Found a wrapper — check that a project context exists alongside it
if exist "%project_dir%\project.yaml" (
set wrapper_script=%wrapper_candidate%
exit /b 0
)
if exist "%project_dir%\module.yaml" (
set wrapper_script=%wrapper_candidate%
exit /b 0
)
echo WARNING: Found wrapper script '%wrapper_candidate%', but no project.yaml or module.yaml near it. Skipping. >&2
@rem Continue the search
goto :find_next_parent
)
if exist "%project_dir%\project.yaml" (
@rem Found project.yaml but no wrapper alongside it
echo WARNING: Found a project.yaml in '%project_dir%', but the wrapper script is missing; using Kotlin Toolchain v$kotlin_cli_version. >&2
exit /b 1
)
:find_next_parent
@rem Move to parent directory
for %%P in ("%project_dir%\..") do set parent_dir=%%~fP
if "%parent_dir%"=="%project_dir%" (
@rem Reached the root, stop searching
exit /b 1
)
set project_dir=%parent_dir%
goto :find_loop
:parse_project_context
@rem Parse kotlin_cli_version and kotlin_cli_sha256 from the found wrapper_script without executing it.
set parsed_kotlin_cli_version=
set parsed_kotlin_cli_sha256=
for /f "tokens=2 delims==" %%A in ('findstr /r /c:"^set kotlin_cli_version=[A-Za-z0-9._+-]*$" "%wrapper_script%"') do (
if not defined parsed_kotlin_cli_version set parsed_kotlin_cli_version=%%A
)
for /f "tokens=2 delims==" %%A in ('findstr /r /c:"^set kotlin_cli_sha256=[0-9a-fA-F]*$" "%wrapper_script%"') do (
if not defined parsed_kotlin_cli_sha256 set parsed_kotlin_cli_sha256=%%A
)
if not defined parsed_kotlin_cli_version (
echo ERROR: Suspicious local wrapper script: failed to detect the distribution version in '%wrapper_script%' >&2
exit /b 1
)
if not defined parsed_kotlin_cli_sha256 (
echo ERROR: Suspicious local wrapper script: failed to detect the distribution checksum in '%wrapper_script%' >&2
exit /b 1
)
@rem Overwrite builtin values and proceed
set kotlin_cli_version=%parsed_kotlin_cli_version%
set kotlin_cli_sha256=%parsed_kotlin_cli_sha256%
exit /b 0
:fail
echo ERROR: Kotlin CLI bootstrap failed, see errors above
exit /b 1
:after_function_declarations
REM ********** Project-local version detection **********
if defined KOTLIN_CLI_WRAPPER_ALWAYS_USE_INTRINSIC_VERSION goto :after_local_version_detection
call :find_project_context
if errorlevel 1 goto :after_local_version_detection
call :parse_project_context
if errorlevel 1 goto fail
:after_local_version_detection
REM ********** Provision the Kotlin Toolchain distribution **********
set kotlin_cli_url=%KOTLIN_CLI_DOWNLOAD_ROOT%/org/jetbrains/kotlin/kotlin-cli/%kotlin_cli_version%/kotlin-cli-%kotlin_cli_version%-dist.tgz
set kotlin_cli_target_dir=%KOTLIN_CLI_BOOTSTRAP_CACHE_DIR%\kotlin-cli-%kotlin_cli_version%
call :download_and_extract "Kotlin Toolchain distribution v%kotlin_cli_version%" "%kotlin_cli_url%" "%kotlin_cli_target_dir%" "%kotlin_cli_sha256%" "256" "true"
if errorlevel 1 goto fail
REM ********** Launch the Kotlin CLI **********
rem Determine the correct busybox binary based on architecture
if "%PROCESSOR_ARCHITECTURE%"=="ARM64" (
set busybox_exe=%kotlin_cli_target_dir%\bin\busybox64a.exe
) else if "%PROCESSOR_ARCHITECTURE%"=="AMD64" (
set busybox_exe=%kotlin_cli_target_dir%\bin\busybox64u.exe
) else (
echo Unsupported architecture %PROCESSOR_ARCHITECTURE% >&2
goto fail
)
rem We use busybox here because it doesn't reinterpret the user-passed command-line arguments (that we pass via %*).
rem Also this way we can use the unified launcher script (.sh)
set KOTLIN_CLI_WRAPPER_PATH=%~f0
"%busybox_exe%" sh "%kotlin_cli_target_dir%\bin\launcher.sh" %*
exit /B %ERRORLEVEL%