Skip to content

Commit 15cbe84

Browse files
committed
Harden CLI args and configuration handling
1 parent d11f86b commit 15cbe84

17 files changed

Lines changed: 140 additions & 29 deletions

File tree

src/org/elixir_lang/ESpec.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.elixir_lang
22

33
import com.intellij.execution.configurations.GeneralCommandLine
4+
import com.intellij.openapi.project.Project
45
import com.intellij.openapi.projectRoots.Sdk
56
import org.elixir_lang.espec.Modules
67

@@ -10,14 +11,16 @@ object ESpec {
1011
elixirSdk: Sdk,
1112
erlArgumentList: kotlin.collections.List<String> = emptyList(),
1213
elixirArgumentList: kotlin.collections.List<String> = emptyList(),
13-
mixArgumentList: kotlin.collections.List<String> = emptyList()
14+
mixArgumentList: kotlin.collections.List<String> = emptyList(),
15+
project: Project? = null
1416
): GeneralCommandLine {
1517
val commandLine = org.elixir_lang.Mix.commandLine(
1618
environment,
1719
workingDirectory,
1820
elixirSdk,
1921
Modules.erlParametersList() + erlArgumentList,
20-
Modules.elixirParametersList() + elixirArgumentList
22+
Modules.elixirParametersList() + elixirArgumentList,
23+
project = project
2124
)
2225
commandLine.addParameters(mixArgumentList)
2326
addESpec(commandLine)

src/org/elixir_lang/Elixir.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.elixir_lang
22

33
import com.intellij.execution.configurations.GeneralCommandLine
4+
import com.intellij.openapi.project.Project
45
import com.intellij.openapi.projectRoots.Sdk
56
import org.elixir_lang.cli.CliArguments
67
import org.elixir_lang.jps.shared.cli.CliArgs
@@ -17,8 +18,15 @@ object Elixir {
1718
workingDirectory: String?,
1819
elixirSdk: Sdk,
1920
erlArgumentList: kotlin.collections.List<String> = emptyList(),
21+
project: Project? = null,
2022
): GeneralCommandLine {
21-
val args: CliArgs = CliArguments.args(elixirSdk, CliTool.ELIXIR, extraErlangArguments = erlArgumentList) ?: throw RuntimeException("Unable to compute CLI arguments for SDK $elixirSdk")
23+
val args: CliArgs =
24+
CliArguments.argsOrThrow(
25+
elixirSdk,
26+
CliTool.ELIXIR,
27+
extraErlangArguments = erlArgumentList,
28+
project = project,
29+
)
2230
val commandLine = baseCommandLine(false, environment, workingDirectory)
2331
commandLine.exePath = args.exePath
2432
commandLine.addParameters(args.arguments)

src/org/elixir_lang/ExUnit.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.elixir_lang
22

33
import com.intellij.execution.configurations.GeneralCommandLine
4+
import com.intellij.openapi.project.Project
45
import com.intellij.openapi.projectRoots.Sdk
56
import org.elixir_lang.exunit.ElixirModules
67

@@ -11,14 +12,16 @@ object ExUnit {
1112
elixirSdk: Sdk,
1213
erlArgumentList: kotlin.collections.List<String> = emptyList(),
1314
elixirArgumentList: kotlin.collections.List<String> = emptyList(),
14-
mixArgumentList: kotlin.collections.List<String> = emptyList()
15+
mixArgumentList: kotlin.collections.List<String> = emptyList(),
16+
project: Project? = null
1517
): GeneralCommandLine {
1618
val commandLine = Mix.commandLine(
1719
environment,
1820
workingDirectory,
1921
elixirSdk,
2022
erlArgumentList,
21-
ElixirModules.parametersList() + elixirArgumentList
23+
ElixirModules.parametersList() + elixirArgumentList,
24+
project = project
2225
)
2326
commandLine.addParameters(mixArgumentList)
2427
addExUnit(commandLine)

src/org/elixir_lang/IEx.kt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.elixir_lang
22

33
import com.intellij.execution.configurations.GeneralCommandLine
4+
import com.intellij.openapi.project.Project
45
import com.intellij.openapi.projectRoots.Sdk
56
import org.elixir_lang.cli.CliArguments
67
import org.elixir_lang.jps.shared.cli.CliArgs
@@ -12,9 +13,16 @@ object IEx {
1213
environment: Map<String, String>,
1314
workingDirectory: String?,
1415
elixirSdk: Sdk,
15-
erlArgumentList: kotlin.collections.List<String>
16+
erlArgumentList: kotlin.collections.List<String>,
17+
project: Project? = null,
1618
): GeneralCommandLine {
17-
val args: CliArgs = CliArguments.args(elixirSdk, CliTool.IEX, extraErlangArguments = erlArgumentList) ?: throw RuntimeException("Unable to compute CLI arguments for SDK $elixirSdk")
19+
val args: CliArgs =
20+
CliArguments.argsOrThrow(
21+
elixirSdk,
22+
CliTool.IEX,
23+
extraErlangArguments = erlArgumentList,
24+
project = project,
25+
)
1826
val commandLine = baseCommandLine(true, environment, workingDirectory)
1927
commandLine.exePath = args.exePath
2028
commandLine.addParameters(args.arguments)

src/org/elixir_lang/Mix.kt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.elixir_lang
22

33
import com.intellij.execution.configurations.GeneralCommandLine
4+
import com.intellij.openapi.project.Project
45
import com.intellij.openapi.projectRoots.Sdk
56
import org.elixir_lang.cli.CliArguments
67
import org.elixir_lang.jps.shared.cli.CliArgs
@@ -16,12 +17,20 @@ object Mix {
1617
elixirSdk: Sdk,
1718
erlParameters: kotlin.collections.List<String> = emptyList(),
1819
elixirParameters: kotlin.collections.List<String> = emptyList(),
19-
pty: Boolean = false
20+
pty: Boolean = false,
21+
project: Project? = null
2022
): GeneralCommandLine {
2123
val updatedEnvironment = environment.toMutableMap()
2224
SdkPaths.maybeUpdateMixHome(updatedEnvironment, elixirSdk.homePath)
2325

24-
val args: CliArgs = CliArguments.args(elixirSdk, CliTool.MIX, extraElixirArguments = elixirParameters, extraErlangArguments = erlParameters) ?: throw RuntimeException("Unable to compute CLI arguments for SDK $elixirSdk")
26+
val args: CliArgs =
27+
CliArguments.argsOrThrow(
28+
elixirSdk,
29+
CliTool.MIX,
30+
extraElixirArguments = elixirParameters,
31+
extraErlangArguments = erlParameters,
32+
project = project,
33+
)
2534
val commandLine = baseCommandLine(pty, updatedEnvironment, workingDirectory)
2635
commandLine.exePath = args.exePath
2736
commandLine.addParameters(args.arguments)

src/org/elixir_lang/cli/CliArguments.kt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
package org.elixir_lang.cli
22

3+
import com.intellij.execution.ExecutionException
34
import com.intellij.execution.wsl.WslPath
5+
import com.intellij.openapi.project.Project
46
import com.intellij.openapi.projectRoots.Sdk
57
import com.intellij.util.system.OS
8+
import org.elixir_lang.notification.setup_sdk.Notifier
69
import org.elixir_lang.jps.shared.cli.CliArgs
710
import org.elixir_lang.jps.shared.cli.CliTool
811
import org.elixir_lang.sdk.erlang_dependent.getErlangSdk
12+
import org.elixir_lang.sdk.erlang_dependent.Type as ErlangDependentType
913
import org.elixir_lang.jps.shared.cli.CliArguments as SharedCliArguments
1014

15+
class MissingErlangSdkException(sdkName: String) :
16+
ExecutionException("Elixir SDK '$sdkName' is missing its Erlang SDK dependency")
1117

1218
object CliArguments {
1319
fun args(
@@ -28,6 +34,38 @@ object CliArguments {
2834
)
2935
}
3036

37+
fun argsOrThrow(
38+
elixirSdk: Sdk,
39+
tool: CliTool,
40+
extraElixirArguments: List<String> = emptyList(),
41+
extraErlangArguments: List<String> = emptyList(),
42+
os: OS = effectiveOS(elixirSdk),
43+
project: Project? = null,
44+
): CliArgs {
45+
val elixirHomePath =
46+
elixirSdk.homePath
47+
?: throw ExecutionException("Elixir SDK home path is not configured")
48+
val erlangSdk = elixirSdk.getErlangSdk()
49+
val erlangHomePath = erlangSdk?.homePath
50+
if (erlangHomePath.isNullOrBlank()) {
51+
elixirSdk.putUserData(ErlangDependentType.MISSING_ERLANG_SDK_KEY, true)
52+
Notifier.elixirSdkMissingErlangDependency(project, elixirSdk.name)
53+
throw MissingErlangSdkException(elixirSdk.name)
54+
} else {
55+
elixirSdk.putUserData(ErlangDependentType.MISSING_ERLANG_SDK_KEY, null)
56+
}
57+
58+
return SharedCliArguments.args(
59+
elixirHomePath,
60+
elixirSdk.versionString,
61+
erlangHomePath,
62+
tool,
63+
extraElixirArguments,
64+
extraErlangArguments,
65+
os
66+
) ?: throw ExecutionException("Unable to compute CLI arguments for SDK ${elixirSdk.name}")
67+
}
68+
3169
private fun effectiveOS(elixirSdk: Sdk): OS {
3270
if (OS.CURRENT == OS.Windows) {
3371
elixirSdk.homePath?.let { if (WslPath.isWslUncPath(it)) return OS.Linux }

src/org/elixir_lang/dialyzer/service/DialyzerServiceImpl.kt

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import com.intellij.openapi.components.Service
99
import com.intellij.openapi.components.Storage
1010
import com.intellij.openapi.diagnostic.Logger
1111
import com.intellij.openapi.module.Module
12+
import com.intellij.openapi.project.Project
1213
import com.intellij.openapi.projectRoots.Sdk
1314
import com.intellij.openapi.util.Key
1415
import org.elixir_lang.Elixir.elixirSdkHasErlangSdk
@@ -42,7 +43,7 @@ class DialyzerServiceImpl : DialyzerService {
4243

4344
return if (sdk != null) {
4445
if (elixirSdkHasErlangSdk(sdk)) {
45-
dialyzerWarnings(workingDirectory, sdk)
46+
dialyzerWarnings(workingDirectory, sdk, module.project)
4647
} else {
4748
val project = module.project
4849
Notifier.error(
@@ -66,18 +67,26 @@ class DialyzerServiceImpl : DialyzerService {
6667
}
6768
}
6869

69-
private fun dialyzerWarnings(workingDirectory: String, elixirSdk: Sdk): List<DialyzerWarn> = try {
70-
parseDialyzerOutput(run(workingDirectory, elixirSdk))
70+
private fun dialyzerWarnings(workingDirectory: String, elixirSdk: Sdk, project: Project): List<DialyzerWarn> = try {
71+
parseDialyzerOutput(run(workingDirectory, elixirSdk, project))
7172
} catch (ex: Exception) {
7273
throw DialyzerException("Error while running Dialyzer: ${ex.message}", ex)
7374
}
7475

75-
private fun run(workingDirectory: String, elixirSdk: Sdk): Pair<String, String> {
76+
private fun run(workingDirectory: String, elixirSdk: Sdk, project: Project): Pair<String, String> {
7677
log.info("Dialyzer starting...")
7778
val erlArgumentList = ParametersList.parse(erlArguments).toList()
7879
val elixirArgumentList = ParametersList.parse(elixirArguments).toList()
7980
val mixArgumentList = ParametersList.parse(mixArguments).toList()
80-
val commandLine = Mix.commandLine(emptyMap(), workingDirectory, elixirSdk, erlArgumentList, elixirArgumentList)
81+
val commandLine =
82+
Mix.commandLine(
83+
emptyMap(),
84+
workingDirectory,
85+
elixirSdk,
86+
erlArgumentList,
87+
elixirArgumentList,
88+
project = project,
89+
)
8190
commandLine.addParameters(mixArgumentList)
8291

8392
val processHandler = ProcessHandlerFactory.getInstance().createColoredProcessHandler(commandLine)
@@ -126,4 +135,3 @@ class DialyzerServiceImpl : DialyzerService {
126135
erlArguments = state.erlArguments
127136
}
128137
}
129-

src/org/elixir_lang/elixir/Configuration.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ class Configuration(name: String, project: Project, configurationFactory: Config
7373
environment = envs,
7474
workingDirectory = workingDirectory,
7575
elixirSdk = sdk,
76-
erlArgumentList = erlArgumentList
76+
erlArgumentList = erlArgumentList,
77+
project = project,
7778
)
7879
commandLine.addParameters(elixirArgumentList)
7980

src/org/elixir_lang/espec/Configuration.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ class Configuration(name: String, project: Project) :
9999
sdk,
100100
erlArgumentList,
101101
elixirArgumentList,
102-
mixArgumentList
102+
mixArgumentList,
103+
project = project,
103104
)
104105
commandLine.addParameters(mixESpecArgumentList)
105106

src/org/elixir_lang/exunit/Configuration.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ class Configuration(name: String, project: Project) :
9999
sdk,
100100
erlArgumentList,
101101
elixirArgumentList,
102-
mixArgumentList
102+
mixArgumentList,
103+
project = project,
103104
)
104105
commandLine.addParameters(mixTestArgumentList)
105106

0 commit comments

Comments
 (0)