Avoid double-quailfying venv folder path (#6599)

* Avoid double-quailfying venv folder path

* Replace `path` with `filepath`

* Add a Python integration test to cover venv auto-creation

* Merged

* Fix spelling

Co-authored-by: Justin Van Patten <jvp@justinvp.com>

* Make AbsPath and RelPath test variants

* Fix issue on Windows backslash paths

* Debug windows test failure: more logging and aggressive YAML escaping

* Use filepath.IsAbs instead of path.IsAbs

Co-authored-by: Justin Van Patten <jvp@justinvp.com>
This commit is contained in:
Anton Tayanovskyy 2021-03-24 15:51:46 -04:00 committed by GitHub
parent 19c055315d
commit 4e5828a890
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 100 additions and 6 deletions

View file

@ -14,9 +14,13 @@
- Nodejs: `LocalWorkspace.pulumiVersion` - [#6580](https://github.com/pulumi/pulumi/pull/6580)
- Python: `LocalWorkspace.pulumi_version` - [#6589](https://github.com/pulumi/pulumi/pull/6589)
- Dotnet: `LocalWorkspace.PulumiVersion` - [#6590](https://github.com/pulumi/pulumi/pull/6590)
### Bug Fixes
- [sdk/python] Fix automatic venv creation
[#6599](https://github.com/pulumi/pulumi/pull/6599)
- [automation/python] Fix Settings file save
[#6605](https://github.com/pulumi/pulumi/pull/6605)

View file

@ -31,7 +31,6 @@ import (
"math/rand"
"os"
"os/exec"
"path"
"path/filepath"
"strconv"
"strings"
@ -191,7 +190,7 @@ func (host *pythonLanguageHost) prepareVirtualEnvironment(ctx context.Context, c
}
// Make sure it's an absolute path.
if !path.IsAbs(virtualenv) {
if !filepath.IsAbs(virtualenv) {
virtualenv = filepath.Join(cwd, virtualenv)
}
@ -520,7 +519,7 @@ func (host *pythonLanguageHost) Run(ctx context.Context, req *pulumirpc.RunReque
var virtualenv string
if host.virtualenv != "" {
virtualenv = host.virtualenv
if !path.IsAbs(virtualenv) {
if !filepath.IsAbs(virtualenv) {
cwd, err := os.Getwd()
if err != nil {
return nil, errors.Wrap(err, "getting the working directory")

View file

@ -218,7 +218,10 @@ func InstallDependenciesWithWriters(root, venvDir string, showOutput bool, infoW
print("Creating virtual environment...")
// Create the virtual environment by running `python -m venv <venvDir>`.
venvDir = filepath.Join(root, venvDir)
if !filepath.IsAbs(venvDir) {
venvDir = filepath.Join(root, venvDir)
}
cmd, err := Command("-m", "venv", venvDir)
if err != nil {
return err

View file

@ -6,14 +6,19 @@ package ints
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"runtime"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/pulumi/pulumi/pkg/v2/testing/integration"
"github.com/pulumi/pulumi/sdk/v2/go/common/resource"
"github.com/stretchr/testify/assert"
ptesting "github.com/pulumi/pulumi/sdk/v2/go/common/testing"
"github.com/pulumi/pulumi/sdk/v2/python"
)
// TestEmptyPython simply tests that we can run an empty Python project.
@ -400,3 +405,67 @@ func TestGetResourcePython(t *testing.T) {
AllowEmptyPreviewChanges: true,
})
}
// Regresses https://github.com/pulumi/pulumi/issues/6471
func TestAutomaticVenvCreation(t *testing.T) {
// Do not use integration.ProgramTest to avoid automatic venv
// handling by test harness; we actually are testing venv
// handling by the pulumi CLI itself.
check := func(t *testing.T, venvPathTemplate string) {
e := ptesting.NewEnvironment(t)
defer func() {
if !t.Failed() {
e.DeleteEnvironment()
}
}()
venvPath := strings.ReplaceAll(venvPathTemplate, "${root}", e.RootPath)
t.Logf("venvPath = %s (IsAbs = %v)", venvPath, filepath.IsAbs(venvPath))
e.ImportDirectory(filepath.Join("python", "venv"))
// replace "virtualenv: venv" with "virtualenv: ${venvPath}" in Pulumi.yaml
pulumiYaml := filepath.Join(e.RootPath, "Pulumi.yaml")
oldYaml, err := ioutil.ReadFile(pulumiYaml)
if err != nil {
t.Error(err)
return
}
newYaml := []byte(strings.ReplaceAll(string(oldYaml),
"virtualenv: venv",
fmt.Sprintf("virtualenv: >-\n %s", venvPath)))
if err := ioutil.WriteFile(pulumiYaml, newYaml, 0644); err != nil {
t.Error(err)
return
}
t.Logf("Wrote Pulumi.yaml:\n%s\n", string(newYaml))
e.RunCommand("pulumi", "login", "--cloud-url", e.LocalURL())
e.RunCommand("pulumi", "stack", "init", "teststack")
e.RunCommand("pulumi", "preview")
var absVenvPath string
if filepath.IsAbs(venvPath) {
absVenvPath = venvPath
} else {
absVenvPath = filepath.Join(e.RootPath, venvPath)
}
if !python.IsVirtualEnv(absVenvPath) {
t.Errorf("Expected a virtual environment to be created at %s but it is not there",
absVenvPath)
}
}
t.Run("RelativePath", func(t *testing.T) {
check(t, "venv")
})
t.Run("AbsolutePath", func(t *testing.T) {
check(t, filepath.Join("${root}", "absvenv"))
})
}

View file

@ -0,0 +1,5 @@
*.pyc
/.pulumi/
/dist/
/*.egg-info
venv/

View file

@ -0,0 +1,6 @@
name: pulumi-python-venv
description: A simple Python Pulumi program that needs a venv to run.
runtime:
name: python
options:
virtualenv: venv

View file

@ -0,0 +1,7 @@
# Copyright 2016-2020, Pulumi Corporation. All rights reserved.
"""An example program that needs a venv to run"""
import pulumi
pulumi.export('foo', 'bar')

View file

@ -0,0 +1 @@
pulumi