Skip to content

Commit 6c16257

Browse files
committed
support user home dir reference (~) in python.envPath (only in extension)
1 parent 20e6ef2 commit 6c16257

File tree

8 files changed

+93
-50
lines changed

8 files changed

+93
-50
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
Venv is installed by default since python 3.3 which removes requirement to install virtualenv. (#77)
2020
Fallback to virtualenv when venv not found. All current environments created with virtualenv
2121
will still be working correctly.
22+
* Add user home dir ("~/") support for the environment path (python.envPath)
2223
* To use different python for PythonTask useCustomPython = true must be declared now
2324
(otherwise, pythonPath select by checkPython task would be used (and task's pythonPath ignored))
2425

src/main/groovy/ru/vyarus/gradle/plugin/python/PythonExtension.groovy

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,9 @@ class PythonExtension {
187187
* <p>
188188
* If multiple env required (e.g. to use different python versions or to separate pip initialization (e.g.
189189
* for incompatible modules)) declare env path manually in each module.
190+
* <p>
191+
* User home directory reference will be automatically resolved in path ("~/somewhere/"). This might be useful
192+
* for CI environments where environment directory should be cached, but it can't be located inside project.
190193
*/
191194
String envPath
192195
/**

src/main/groovy/ru/vyarus/gradle/plugin/python/PythonPlugin.groovy

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import ru.vyarus.gradle.plugin.python.task.pip.BasePipTask
1919
import ru.vyarus.gradle.plugin.python.task.pip.PipInstallTask
2020
import ru.vyarus.gradle.plugin.python.task.pip.PipListTask
2121
import ru.vyarus.gradle.plugin.python.task.pip.PipUpdatesTask
22+
import ru.vyarus.gradle.plugin.python.util.CliUtils
2223
import ru.vyarus.gradle.plugin.python.util.RequirementsReader
2324

2425
import javax.inject.Inject
@@ -123,12 +124,19 @@ abstract class PythonPlugin implements Plugin<Project> {
123124
it.description = 'Show all installed modules'
124125
}
125126

126-
project.tasks.register('cleanPython', Delete) {
127-
it.with {
128-
group = 'python'
129-
description = 'Removes existing python environment (virtualenv)'
130-
delete extension.envPath
131-
onlyIf { project.file(extension.envPath).exists() }
127+
project.tasks.register('cleanPython', Delete) { task ->
128+
task.group = 'python'
129+
task.description = 'Removes existing python environment (virtualenv)'
130+
131+
String path = CliUtils.resolveHomeReference(extension.envPath)
132+
File dir = project.file(path)
133+
boolean exists = dir.exists()
134+
task.delete path
135+
task.onlyIf { exists}
136+
task.doLast {
137+
if (exists) {
138+
task.logger.lifecycle('[python] Environment removed: {}', dir.absolutePath)
139+
}
132140
}
133141
}
134142

@@ -201,7 +209,7 @@ abstract class PythonPlugin implements Plugin<Project> {
201209
task.showInstalledVersions.convention(extension.showInstalledVersions)
202210
task.alwaysInstallModules.convention(extension.alwaysInstallModules)
203211
task.options.convention([])
204-
task.envPath.convention(extension.envPath)
212+
task.envPath.convention(CliUtils.resolveHomeReference(extension.envPath))
205213
}
206214

207215
project.tasks.withType(PipListTask).configureEach { task ->
@@ -214,7 +222,7 @@ abstract class PythonPlugin implements Plugin<Project> {
214222

215223
project.tasks.withType(CheckPythonTask).configureEach { task ->
216224
task.scope.convention(extension.scope)
217-
task.envPath.convention(extension.envPath)
225+
task.envPath.convention(CliUtils.resolveHomeReference(extension.envPath))
218226
task.minPythonVersion.convention(extension.minPythonVersion)
219227
task.minPipVersion.convention(extension.minPipVersion)
220228
task.useVenv.convention(extension.useVenv)

src/main/groovy/ru/vyarus/gradle/plugin/python/cmd/VirtualTool.groovy

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import java.nio.file.Paths
1313
*
1414
* @author Vyacheslav Rusakov
1515
* @since 19.09.2023
16-
* @param <T> actual tool type
16+
* @param <T> actual tool type
1717
*/
1818
@CompileStatic
1919
abstract class VirtualTool<T extends VirtualTool> {
@@ -26,12 +26,14 @@ abstract class VirtualTool<T extends VirtualTool> {
2626
protected VirtualTool(Environment environment, String pythonPath, String binary, String path) {
2727
this.env = environment
2828
this.python = new Python(environment, pythonPath, binary).logLevel(LogLevel.LIFECYCLE)
29-
this.path = path
3029
if (!path) {
3130
throw new IllegalArgumentException('Virtual environment path not set')
3231
}
33-
this.location = environment.file(path)
34-
environment.debug("${getClass().simpleName} environment init for path '${path}' (python path: '${pythonPath}')")
32+
// for direct tool usage support
33+
this.path = CliUtils.resolveHomeReference(path)
34+
this.location = environment.file(this.path)
35+
environment.debug("${getClass().simpleName} environment init for path '${this.path}' " +
36+
"(python path: '${pythonPath}')")
3537
}
3638

3739
/**

src/main/groovy/ru/vyarus/gradle/plugin/python/cmd/env/SimpleEnvironment.groovy

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ class SimpleEnvironment extends GradleEnvironment {
2828
this(new File(''), false)
2929
}
3030

31-
SimpleEnvironment(File projectDir, boolean debug) {
31+
SimpleEnvironment(File projectDir, boolean debug = false) {
3232
this(ProjectBuilder.builder()
3333
.withProjectDir(projectDir)
3434
.build(), debug)
3535
}
3636

37-
SimpleEnvironment(Project project, boolean debug) {
37+
SimpleEnvironment(Project project, boolean debug = false) {
3838
super(project.logger,
3939
project.projectDir,
4040
project.projectDir,

src/main/groovy/ru/vyarus/gradle/plugin/python/util/CliUtils.groovy

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,20 @@ final class CliUtils {
317317
return Os.isFamily(Os.FAMILY_UNIX) && !Os.isFamily(Os.FAMILY_MAC)
318318
}
319319

320+
/**
321+
* Resolve use home reference (~) in path into correct user directory.
322+
*
323+
* @param path path to resolve
324+
* @return resolved path
325+
*/
326+
static String resolveHomeReference(String path) {
327+
String res = path
328+
if (res.startsWith('~')) {
329+
res = System.getProperty('user.home') + res.substring(1)
330+
}
331+
return res
332+
}
333+
320334
private static boolean isPositionMatch(String[] ver, String[] req, int pos) {
321335
boolean valid = (ver[pos] as Integer) >= (req[pos] as Integer)
322336
if (valid && ver[pos] == req[pos] && req.length > pos + 1) {

src/test/groovy/ru/vyarus/gradle/plugin/python/AbsoluteVirtualenvLocationKitTest.groovy

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package ru.vyarus.gradle.plugin.python
22

33
import org.gradle.testkit.runner.BuildResult
44
import org.gradle.testkit.runner.TaskOutcome
5+
import ru.vyarus.gradle.plugin.python.cmd.Venv
6+
import ru.vyarus.gradle.plugin.python.cmd.env.SimpleEnvironment
57
import ru.vyarus.gradle.plugin.python.util.CliUtils
68
import spock.lang.TempDir
79

@@ -44,4 +46,53 @@ class AbsoluteVirtualenvLocationKitTest extends AbstractKitTest {
4446
then: "virtualenv created at correct path"
4547
result.output.contains("${CliUtils.canonicalPath(envDir)}${File.separator}")
4648
}
49+
50+
def "Check user home recognition"() {
51+
setup:
52+
File dir = new File(CliUtils.resolveHomeReference("~/.testuserdir"))
53+
dir.mkdirs()
54+
55+
build """
56+
plugins {
57+
id 'ru.vyarus.use-python'
58+
}
59+
60+
python {
61+
envPath = "~/.testuserdir"
62+
63+
pip 'extract-msg:0.28.0'
64+
}
65+
66+
tasks.register('sample', PythonTask) {
67+
command = '-c print(\\'samplee\\')'
68+
}
69+
70+
"""
71+
72+
when: "run task"
73+
BuildResult result = run(':sample')
74+
75+
then: "task successful"
76+
result.task(':sample').outcome == TaskOutcome.SUCCESS
77+
result.output =~ /extract-msg\s+0.28.0/
78+
result.output.contains('samplee')
79+
80+
then: "virtualenv created at correct path"
81+
result.output.contains("${CliUtils.canonicalPath(dir)}")
82+
83+
when: "test virtualenv direct support"
84+
Venv env = new Venv(new SimpleEnvironment(testProjectDir), "~/.testuserdir")
85+
then: "created"
86+
env.exists()
87+
88+
when: "cleanup directory"
89+
result = run(':cleanPython')
90+
91+
then: "ok"
92+
result.task(":cleanPython").outcome == TaskOutcome.SUCCESS
93+
result.output.contains("${CliUtils.canonicalPath(dir)}")
94+
95+
cleanup:
96+
dir.deleteDir()
97+
}
4798
}

src/test/groovy/ru/vyarus/gradle/plugin/python/GlobalEnvironmentKitTest.groovy

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

0 commit comments

Comments
 (0)