Skip to content

Commit

Permalink
support user home dir reference (~) in python.envPath (only in extens…
Browse files Browse the repository at this point in the history
…ion)
  • Loading branch information
xvik committed Apr 5, 2024
1 parent 20e6ef2 commit 6c16257
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 50 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
Venv is installed by default since python 3.3 which removes requirement to install virtualenv. (#77)
Fallback to virtualenv when venv not found. All current environments created with virtualenv
will still be working correctly.
* Add user home dir ("~/") support for the environment path (python.envPath)
* To use different python for PythonTask useCustomPython = true must be declared now
(otherwise, pythonPath select by checkPython task would be used (and task's pythonPath ignored))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,9 @@ class PythonExtension {
* <p>
* If multiple env required (e.g. to use different python versions or to separate pip initialization (e.g.
* for incompatible modules)) declare env path manually in each module.
* <p>
* User home directory reference will be automatically resolved in path ("~/somewhere/"). This might be useful
* for CI environments where environment directory should be cached, but it can't be located inside project.
*/
String envPath
/**
Expand Down
24 changes: 16 additions & 8 deletions src/main/groovy/ru/vyarus/gradle/plugin/python/PythonPlugin.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import ru.vyarus.gradle.plugin.python.task.pip.BasePipTask
import ru.vyarus.gradle.plugin.python.task.pip.PipInstallTask
import ru.vyarus.gradle.plugin.python.task.pip.PipListTask
import ru.vyarus.gradle.plugin.python.task.pip.PipUpdatesTask
import ru.vyarus.gradle.plugin.python.util.CliUtils
import ru.vyarus.gradle.plugin.python.util.RequirementsReader

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

project.tasks.register('cleanPython', Delete) {
it.with {
group = 'python'
description = 'Removes existing python environment (virtualenv)'
delete extension.envPath
onlyIf { project.file(extension.envPath).exists() }
project.tasks.register('cleanPython', Delete) { task ->
task.group = 'python'
task.description = 'Removes existing python environment (virtualenv)'

String path = CliUtils.resolveHomeReference(extension.envPath)
File dir = project.file(path)
boolean exists = dir.exists()
task.delete path
task.onlyIf { exists}
task.doLast {
if (exists) {
task.logger.lifecycle('[python] Environment removed: {}', dir.absolutePath)
}
}
}

Expand Down Expand Up @@ -201,7 +209,7 @@ abstract class PythonPlugin implements Plugin<Project> {
task.showInstalledVersions.convention(extension.showInstalledVersions)
task.alwaysInstallModules.convention(extension.alwaysInstallModules)
task.options.convention([])
task.envPath.convention(extension.envPath)
task.envPath.convention(CliUtils.resolveHomeReference(extension.envPath))
}

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

project.tasks.withType(CheckPythonTask).configureEach { task ->
task.scope.convention(extension.scope)
task.envPath.convention(extension.envPath)
task.envPath.convention(CliUtils.resolveHomeReference(extension.envPath))
task.minPythonVersion.convention(extension.minPythonVersion)
task.minPipVersion.convention(extension.minPipVersion)
task.useVenv.convention(extension.useVenv)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import java.nio.file.Paths
*
* @author Vyacheslav Rusakov
* @since 19.09.2023
* @param <T> actual tool type
* @param <T> actual tool type
*/
@CompileStatic
abstract class VirtualTool<T extends VirtualTool> {
Expand All @@ -26,12 +26,14 @@ abstract class VirtualTool<T extends VirtualTool> {
protected VirtualTool(Environment environment, String pythonPath, String binary, String path) {
this.env = environment
this.python = new Python(environment, pythonPath, binary).logLevel(LogLevel.LIFECYCLE)
this.path = path
if (!path) {
throw new IllegalArgumentException('Virtual environment path not set')
}
this.location = environment.file(path)
environment.debug("${getClass().simpleName} environment init for path '${path}' (python path: '${pythonPath}')")
// for direct tool usage support
this.path = CliUtils.resolveHomeReference(path)
this.location = environment.file(this.path)
environment.debug("${getClass().simpleName} environment init for path '${this.path}' " +
"(python path: '${pythonPath}')")
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ class SimpleEnvironment extends GradleEnvironment {
this(new File(''), false)
}

SimpleEnvironment(File projectDir, boolean debug) {
SimpleEnvironment(File projectDir, boolean debug = false) {
this(ProjectBuilder.builder()
.withProjectDir(projectDir)
.build(), debug)
}

SimpleEnvironment(Project project, boolean debug) {
SimpleEnvironment(Project project, boolean debug = false) {
super(project.logger,
project.projectDir,
project.projectDir,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,20 @@ final class CliUtils {
return Os.isFamily(Os.FAMILY_UNIX) && !Os.isFamily(Os.FAMILY_MAC)
}

/**
* Resolve use home reference (~) in path into correct user directory.
*
* @param path path to resolve
* @return resolved path
*/
static String resolveHomeReference(String path) {
String res = path
if (res.startsWith('~')) {
res = System.getProperty('user.home') + res.substring(1)
}
return res
}

private static boolean isPositionMatch(String[] ver, String[] req, int pos) {
boolean valid = (ver[pos] as Integer) >= (req[pos] as Integer)
if (valid && ver[pos] == req[pos] && req.length > pos + 1) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package ru.vyarus.gradle.plugin.python

import org.gradle.testkit.runner.BuildResult
import org.gradle.testkit.runner.TaskOutcome
import ru.vyarus.gradle.plugin.python.cmd.Venv
import ru.vyarus.gradle.plugin.python.cmd.env.SimpleEnvironment
import ru.vyarus.gradle.plugin.python.util.CliUtils
import spock.lang.TempDir

Expand Down Expand Up @@ -44,4 +46,53 @@ class AbsoluteVirtualenvLocationKitTest extends AbstractKitTest {
then: "virtualenv created at correct path"
result.output.contains("${CliUtils.canonicalPath(envDir)}${File.separator}")
}

def "Check user home recognition"() {
setup:
File dir = new File(CliUtils.resolveHomeReference("~/.testuserdir"))
dir.mkdirs()

build """
plugins {
id 'ru.vyarus.use-python'
}
python {
envPath = "~/.testuserdir"
pip 'extract-msg:0.28.0'
}
tasks.register('sample', PythonTask) {
command = '-c print(\\'samplee\\')'
}
"""

when: "run task"
BuildResult result = run(':sample')

then: "task successful"
result.task(':sample').outcome == TaskOutcome.SUCCESS
result.output =~ /extract-msg\s+0.28.0/
result.output.contains('samplee')

then: "virtualenv created at correct path"
result.output.contains("${CliUtils.canonicalPath(dir)}")

when: "test virtualenv direct support"
Venv env = new Venv(new SimpleEnvironment(testProjectDir), "~/.testuserdir")
then: "created"
env.exists()

when: "cleanup directory"
result = run(':cleanPython')

then: "ok"
result.task(":cleanPython").outcome == TaskOutcome.SUCCESS
result.output.contains("${CliUtils.canonicalPath(dir)}")

cleanup:
dir.deleteDir()
}
}

This file was deleted.

0 comments on commit 6c16257

Please sign in to comment.