Skip to content

Commit ca7471e

Browse files
committed
Resolve buildPython to an absolute path manually; remove support for passing it as a space-separated string (closes #1411)
1 parent e61c87f commit ca7471e

File tree

14 files changed

+200
-220
lines changed

14 files changed

+200
-220
lines changed

product/gradle-plugin/src/main/kotlin/PythonTasks.kt

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import org.gradle.api.file.*
1111
import org.gradle.api.provider.Provider
1212
import org.gradle.api.tasks.*
1313
import org.gradle.kotlin.dsl.*
14+
import org.gradle.process.*
1415
import org.gradle.process.internal.*
1516
import org.json.*
1617
import java.io.*
@@ -70,7 +71,7 @@ internal class TaskBuilder(
7071

7172
if (bpInfo != null) {
7273
doLast {
73-
plugin.execOps.exec {
74+
exec {
7475
commandLine(bpInfo.commandLine)
7576
args("-m", "venv", "--without-pip", project.file(outputDir))
7677
}
@@ -85,7 +86,7 @@ internal class TaskBuilder(
8586

8687
// Pre-generate the __pycache__ directories to avoid the outputDir
8788
// contents changing and breaking the up to date checks.
88-
plugin.execOps.exec {
89+
exec {
8990
commandLine(bpInfo.commandLine)
9091
args("-Wignore", "-m", "compileall", "-qq",
9192
project.file(outputDir))
@@ -590,7 +591,7 @@ internal class TaskBuilder(
590591

591592
fun execBuildPython(args: List<String>) {
592593
try {
593-
plugin.execOps.exec {
594+
exec {
594595
executable(buildPackagesTask.get().pythonExecutable)
595596
this.args(args)
596597
}
@@ -615,13 +616,6 @@ internal class TaskBuilder(
615616
val bps = sequence {
616617
if (bpSetting != null) {
617618
yield(bpSetting)
618-
619-
// For convenience, buildPython may also be set to a single
620-
// space-separated string. If the user needs spaces within arguments,
621-
// then they'll have to use the multi-string form.
622-
if (bpSetting.size == 1 && bpSetting[0].contains(' ')) {
623-
yield(bpSetting[0].split(Regex("""\s+""")))
624-
}
625619
} else {
626620
// Trying the `python3` and `py -3` commands is usually unnecessary, but
627621
// might be useful in some situations.
@@ -644,20 +638,21 @@ internal class TaskBuilder(
644638
val stdout = ByteArrayOutputStream()
645639
val stderr = ByteArrayOutputStream()
646640
try {
647-
plugin.execOps.exec {
641+
exec {
648642
commandLine(bp)
649643
args(checkScript, version)
650644
standardOutput = stdout
651645
errorOutput = stderr
652646
}
653647
return BuildPythonInfo(bp, stdout.toString())
654648
} catch (e: ExecException) {
649+
// Prefer stderr over an exception message.
655650
if (stderr.size() > 0 && !gotStderr) {
656-
// Prefer stderr over an exception message.
657651
error = stderr.toString().trim()
658652
gotStderr = true
653+
654+
// Prefer an earlier error over a later one.
659655
} else if (error == null) {
660-
// Prefer the error for the original command over the split form.
661656
error = e.message ?: e.javaClass.name
662657
}
663658
}
@@ -671,6 +666,47 @@ internal class TaskBuilder(
671666
"Couldn't find Python $version.", BUILD_PYTHON_ADVICE)
672667
}
673668
}
669+
670+
// To reduce differences between platforms, and make testing easier, we resolve
671+
// executables to absolute paths manually (#1411).
672+
fun exec(configure: ExecSpec.() -> Unit) {
673+
plugin.execOps.exec {
674+
configure()
675+
var execFile = File(executable)
676+
if (!execFile.isAbsolute) {
677+
execFile = File(project.projectDir, executable)
678+
}
679+
680+
if (execFile.exists()) {
681+
setExecutable(execFile)
682+
} else {
683+
// If the executable contains no slashes, search the PATH.
684+
if (File.separator in executable || "/" in executable) {
685+
throw ExecException("'$execFile' does not exist")
686+
}
687+
688+
// For consistency between machines, we don't use the PATHEXT variable.
689+
val exts =
690+
if (osName() == "windows") listOf(".exe", ".bat") else listOf("")
691+
692+
outer@ for (dir in System.getenv("PATH").split(File.pathSeparator)) {
693+
for (ext in exts) {
694+
execFile = File(dir, executable + ext)
695+
if (execFile.exists()) {
696+
break@outer
697+
}
698+
}
699+
}
700+
if (execFile.exists()) {
701+
setExecutable(execFile)
702+
} else {
703+
throw ExecException(
704+
"Couldn't find '$executable' on the PATH " +
705+
"or in the project directory")
706+
}
707+
}
708+
}
709+
}
674710
}
675711

676712

product/gradle-plugin/src/main/resources/com/chaquo/python/check_build_python.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
# Be careful about what syntax and APIs are used in this file: it should give the
22
# correct error message on old Python versions going as far back as possible.
33

4-
import platform
54
import sys
65

76

87
expected = sys.argv[1]
9-
actual = platform.python_version()
10-
if not actual.startswith(expected + "."):
8+
actual = "{}.{}".format(*sys.version_info[:2])
9+
if actual != expected:
1110
# Our stderr will be appended to the message "$bpSetting is not a valid Python
1211
# $version command: ".
1312
sys.exit("it is version {}".format(actual))

product/gradle-plugin/src/test/integration/data/BuildPython/args_1/app/build.gradle

Lines changed: 0 additions & 25 deletions
This file was deleted.

product/gradle-plugin/src/test/integration/data/BuildPython/args_2/app/build.gradle

Lines changed: 0 additions & 25 deletions
This file was deleted.

product/gradle-plugin/src/test/integration/data/BuildPython/override/app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ android {
1414
versionCode 1
1515
versionName "0.0.1"
1616
python {
17-
buildPython System.getenv("buildpython").split("\s+")
17+
buildPython property("buildpython").split("----")
1818
pip {
1919
install "six"
2020
}

product/gradle-plugin/src/test/integration/data/BuildPython/silent_failure/app/build.gradle

Lines changed: 0 additions & 26 deletions
This file was deleted.

product/gradle-plugin/src/test/integration/data/BuildPython/space/app/build.gradle

Lines changed: 0 additions & 24 deletions
This file was deleted.
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
@echo off
2-
echo Hello Chaquopy
2+
echo Here's the stderr >&2
3+
exit 1
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
#!/bin/sh
2-
echo Hello Chaquopy
2+
echo "Here's the stderr" >&2
3+
exit 1

0 commit comments

Comments
 (0)