refactor: EnsurePython3Venv

This commit is contained in:
debugtalk
2022-06-14 11:52:18 +08:00
parent d91eba501c
commit c00dab17b3
20 changed files with 60 additions and 88 deletions
+1 -1
View File
@@ -37,4 +37,4 @@ Copyright 2017 debugtalk
* [hrp startproject](hrp_startproject.md) - create a scaffold project * [hrp startproject](hrp_startproject.md) - create a scaffold project
* [hrp wiki](hrp_wiki.md) - visit https://httprunner.com * [hrp wiki](hrp_wiki.md) - visit https://httprunner.com
###### Auto generated by spf13/cobra on 13-Jun-2022 ###### Auto generated by spf13/cobra on 14-Jun-2022
+1 -1
View File
@@ -42,4 +42,4 @@ hrp boom [flags]
* [hrp](hrp.md) - Next-Generation API Testing Solution. * [hrp](hrp.md) - Next-Generation API Testing Solution.
###### Auto generated by spf13/cobra on 13-Jun-2022 ###### Auto generated by spf13/cobra on 14-Jun-2022
+1 -1
View File
@@ -28,4 +28,4 @@ hrp build $path ... [flags]
* [hrp](hrp.md) - Next-Generation API Testing Solution. * [hrp](hrp.md) - Next-Generation API Testing Solution.
###### Auto generated by spf13/cobra on 13-Jun-2022 ###### Auto generated by spf13/cobra on 14-Jun-2022
+1 -1
View File
@@ -22,4 +22,4 @@ hrp convert $path... [flags]
* [hrp](hrp.md) - Next-Generation API Testing Solution. * [hrp](hrp.md) - Next-Generation API Testing Solution.
###### Auto generated by spf13/cobra on 13-Jun-2022 ###### Auto generated by spf13/cobra on 14-Jun-2022
+1 -1
View File
@@ -16,4 +16,4 @@ hrp pytest $path ... [flags]
* [hrp](hrp.md) - Next-Generation API Testing Solution. * [hrp](hrp.md) - Next-Generation API Testing Solution.
###### Auto generated by spf13/cobra on 13-Jun-2022 ###### Auto generated by spf13/cobra on 14-Jun-2022
+1 -1
View File
@@ -35,4 +35,4 @@ hrp run $path... [flags]
* [hrp](hrp.md) - Next-Generation API Testing Solution. * [hrp](hrp.md) - Next-Generation API Testing Solution.
###### Auto generated by spf13/cobra on 13-Jun-2022 ###### Auto generated by spf13/cobra on 14-Jun-2022
+1 -1
View File
@@ -21,4 +21,4 @@ hrp startproject $project_name [flags]
* [hrp](hrp.md) - Next-Generation API Testing Solution. * [hrp](hrp.md) - Next-Generation API Testing Solution.
###### Auto generated by spf13/cobra on 13-Jun-2022 ###### Auto generated by spf13/cobra on 14-Jun-2022
+1 -1
View File
@@ -16,4 +16,4 @@ hrp wiki [flags]
* [hrp](hrp.md) - Next-Generation API Testing Solution. * [hrp](hrp.md) - Next-Generation API Testing Solution.
###### Auto generated by spf13/cobra on 13-Jun-2022 ###### Auto generated by spf13/cobra on 14-Jun-2022
+1 -1
View File
@@ -1,5 +1,5 @@
{ {
"project_name": "demo-with-go-plugin", "project_name": "demo-with-go-plugin",
"create_time": "2022-06-13T23:42:06.381463+08:00", "create_time": "2022-06-14T11:34:25.941159+08:00",
"hrp_version": "v4.1.3" "hrp_version": "v4.1.3"
} }
+1 -1
View File
@@ -1,5 +1,5 @@
{ {
"project_name": "demo-with-py-plugin", "project_name": "demo-with-py-plugin",
"create_time": "2022-06-13T23:42:06.751991+08:00", "create_time": "2022-06-14T11:34:26.276891+08:00",
"hrp_version": "v4.1.3" "hrp_version": "v4.1.3"
} }
-7
View File
@@ -1,11 +1,9 @@
package cmd package cmd
import ( import (
"github.com/rs/zerolog/log"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/httprunner/httprunner/v4/hrp" "github.com/httprunner/httprunner/v4/hrp"
"github.com/httprunner/httprunner/v4/hrp/internal/builtin"
) )
var buildCmd = &cobra.Command{ var buildCmd = &cobra.Command{
@@ -19,11 +17,6 @@ var buildCmd = &cobra.Command{
setLogLevel(logLevel) setLogLevel(logLevel)
}, },
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
err := builtin.PrepareVenv(venv)
if err != nil {
log.Error().Err(err).Msg("prepare python3 venv failed")
return err
}
return hrp.BuildPlugin(args[0], output) return hrp.BuildPlugin(args[0], output)
}, },
} }
+7 -2
View File
@@ -2,12 +2,14 @@ package cmd
import ( import (
"errors" "errors"
"fmt"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/httprunner/httprunner/v4/hrp/internal/builtin" "github.com/httprunner/httprunner/v4/hrp/internal/builtin"
"github.com/httprunner/httprunner/v4/hrp/internal/convert" "github.com/httprunner/httprunner/v4/hrp/internal/convert"
"github.com/httprunner/httprunner/v4/hrp/internal/version"
) )
var convertCmd = &cobra.Command{ var convertCmd = &cobra.Command{
@@ -35,9 +37,12 @@ var convertCmd = &cobra.Command{
flagCount++ flagCount++
outputType = convert.OutputTypePyTest outputType = convert.OutputTypePyTest
err := builtin.PrepareVenv(venv) packages := []string{
fmt.Sprintf("httprunner==%s", version.VERSION),
}
_, err := builtin.EnsurePython3Venv(venv, packages...)
if err != nil { if err != nil {
log.Error().Err(err).Msg("prepare python3 venv failed") log.Error().Err(err).Msg("python3 venv is not ready")
return err return err
} }
} }
+8 -2
View File
@@ -1,11 +1,14 @@
package cmd package cmd
import ( import (
"fmt"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/httprunner/httprunner/v4/hrp/internal/builtin" "github.com/httprunner/httprunner/v4/hrp/internal/builtin"
"github.com/httprunner/httprunner/v4/hrp/internal/pytest" "github.com/httprunner/httprunner/v4/hrp/internal/pytest"
"github.com/httprunner/httprunner/v4/hrp/internal/version"
) )
var pytestCmd = &cobra.Command{ var pytestCmd = &cobra.Command{
@@ -17,9 +20,12 @@ var pytestCmd = &cobra.Command{
}, },
DisableFlagParsing: true, // allow to pass any args to pytest DisableFlagParsing: true, // allow to pass any args to pytest
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
err := builtin.PrepareVenv(venv) packages := []string{
fmt.Sprintf("httprunner==%s", version.VERSION),
}
_, err := builtin.EnsurePython3Venv(venv, packages...)
if err != nil { if err != nil {
log.Error().Err(err).Msg("prepare python3 venv failed") log.Error().Err(err).Msg("python3 venv is not ready")
return err return err
} }
return pytest.RunPytest(args) return pytest.RunPytest(args)
+17 -31
View File
@@ -13,13 +13,11 @@ import (
"strconv" "strconv"
"strings" "strings"
"github.com/httprunner/funplugin/fungo"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"github.com/httprunner/httprunner/v4/hrp/internal/json" "github.com/httprunner/httprunner/v4/hrp/internal/json"
"github.com/httprunner/httprunner/v4/hrp/internal/version"
) )
func Dump2JSON(data interface{}, path string) error { func Dump2JSON(data interface{}, path string) error {
@@ -89,43 +87,31 @@ func FormatResponse(raw interface{}) interface{} {
return formattedResponse return formattedResponse
} }
var Python3Executable string = "python3" // system default python3 var python3Executable string = "python3" // system default python3
func PrepareVenv(venv string) error { // EnsurePython3Venv ensures python3 venv with specified packages
// specify python3 venv // venv should be directory path of target venv
if venv != "" { func EnsurePython3Venv(venv string, packages ...string) (python3 string, err error) {
python3 := getPython3Executable(venv) // priority: specified > $HOME/.hrp/venv
if !IsFilePathExists(python3) { if venv == "" {
return errors.New("specified python3 venv is invalid") home, err := os.UserHomeDir()
if err != nil {
return "", errors.Wrap(err, "get user home dir failed")
} }
Python3Executable = python3 venv = filepath.Join(home, ".hrp", "venv")
log.Info().Str("Python3Executable", Python3Executable).Msg("set python3 executable path")
return nil
} }
python3, err = ensurePython3Venv(venv, packages...)
// not specify python3 venv, create default venv
home, err := os.UserHomeDir()
if err != nil { if err != nil {
return errors.Wrap(err, "get user home dir failed") return "", errors.Wrap(err, "prepare python3 venv failed")
} }
venv = filepath.Join(home, ".hrp", "venv") python3Executable = python3
log.Info().Str("venv", venv).Msg("create default python3 venv") log.Info().Str("Python3Executable", python3Executable).Msg("set python3 executable path")
packages := []string{ return python3, nil
fmt.Sprintf("funppy==%s", fungo.Version),
fmt.Sprintf("httprunner==%s", version.VERSION),
}
python3, err := EnsurePython3Venv(venv, packages...)
if err != nil {
return errors.Wrap(err, "create default python3 venv failed")
}
Python3Executable = python3
log.Info().Str("Python3Executable", Python3Executable).Msg("set python3 executable path")
return nil
} }
func ExecPython3Command(cmdName string, args ...string) error { func ExecPython3Command(cmdName string, args ...string) error {
args = append([]string{"-m", cmdName}, args...) args = append([]string{"-m", cmdName}, args...)
return ExecCommand(Python3Executable, args...) return ExecCommand(python3Executable, args...)
} }
func AssertPythonPackage(python3 string, pkgName, pkgVersion string) error { func AssertPythonPackage(python3 string, pkgName, pkgVersion string) error {
@@ -144,7 +130,7 @@ func AssertPythonPackage(python3 string, pkgName, pkgVersion string) error {
// check package version equality // check package version equality
version := strings.TrimSpace(string(out)) version := strings.TrimSpace(string(out))
if fmt.Sprintf("v%s", version) != pkgVersion { if strings.TrimLeft(version, "v") != strings.TrimLeft(pkgVersion, "v") {
return fmt.Errorf("python package %s version %s not matched, please upgrade to %s", return fmt.Errorf("python package %s version %s not matched, please upgrade to %s",
pkgName, version, pkgVersion) pkgName, version, pkgVersion)
} }
+6 -7
View File
@@ -1,3 +1,4 @@
//go:build darwin || linux
// +build darwin linux // +build darwin linux
package builtin package builtin
@@ -16,10 +17,8 @@ func getPython3Executable(venvDir string) string {
return filepath.Join(venvDir, "bin", "python3") return filepath.Join(venvDir, "bin", "python3")
} }
// EnsurePython3Venv ensures python3 venv for hashicorp python plugin func ensurePython3Venv(venv string, packages ...string) (python3 string, err error) {
// venvDir should be directory path of target venv python3 = getPython3Executable(venv)
func EnsurePython3Venv(venvDir string, packages ...string) (python3 string, err error) {
python3 = getPython3Executable(venvDir)
log.Info(). log.Info().
Str("python3", python3). Str("python3", python3).
@@ -35,15 +34,15 @@ func EnsurePython3Venv(venvDir string, packages ...string) (python3 string, err
} }
// check if .venv exists // check if .venv exists
if _, err := os.Stat(venvDir); err == nil { if _, err := os.Stat(venv); err == nil {
// .venv exists, remove first // .venv exists, remove first
if err := ExecCommand("rm", "-rf", venvDir); err != nil { if err := ExecCommand("rm", "-rf", venv); err != nil {
return "", errors.Wrap(err, "remove existed venv failed") return "", errors.Wrap(err, "remove existed venv failed")
} }
} }
// create python3 .venv // create python3 .venv
if err := ExecCommand("python3", "-m", "venv", venvDir); err != nil { if err := ExecCommand("python3", "-m", "venv", venv); err != nil {
return "", errors.Wrap(err, "create python3 venv failed") return "", errors.Wrap(err, "create python3 venv failed")
} }
} }
+1
View File
@@ -1,3 +1,4 @@
//go:build windows
// +build windows // +build windows
package builtin package builtin
-9
View File
@@ -1,10 +1 @@
package convert package convert
import (
"github.com/httprunner/httprunner/v4/hrp/internal/builtin"
)
func convert2PyTestScripts(paths ...string) error {
args := append([]string{"make"}, paths...)
return builtin.ExecPython3Command("httprunner", args...)
}
+3 -1
View File
@@ -1,6 +1,7 @@
package scaffold package scaffold
import ( import (
"path/filepath"
"testing" "testing"
) )
@@ -12,7 +13,8 @@ func TestGenDemoExamples(t *testing.T) {
} }
dir = "../../../examples/demo-with-py-plugin" dir = "../../../examples/demo-with-py-plugin"
err = CreateScaffold(dir, Py, "", true) venv := filepath.Join(dir, ".venv")
err = CreateScaffold(dir, Py, venv, true)
if err != nil { if err != nil {
t.Fatal() t.Fatal()
} }
-8
View File
@@ -205,14 +205,6 @@ func createPythonPlugin(projectName, venv string) error {
return errors.Wrap(err, "copy file failed") return errors.Wrap(err, "copy file failed")
} }
if venv == "" {
home, err := os.UserHomeDir()
if err != nil {
return errors.Wrap(err, "get user home dir failed")
}
venv = filepath.Join(home, ".hrp", "venv")
}
log.Info().Str("venv", venv).Msg("create python3 venv")
packages := []string{ packages := []string{
fmt.Sprintf("funppy==%s", fungo.Version), fmt.Sprintf("funppy==%s", fungo.Version),
fmt.Sprintf("httprunner==%s", version.VERSION), fmt.Sprintf("httprunner==%s", version.VERSION),
+8 -11
View File
@@ -49,20 +49,17 @@ func initPlugin(path, venv string, logOn bool) (plugin funplugin.IPlugin, err er
} }
pluginPath = genPyPluginPath pluginPath = genPyPluginPath
// priority: specified > $HOME/.hrp/venv packages := []string{
err = builtin.PrepareVenv(venv) fmt.Sprintf("funppy==%s", fungo.Version),
if err != nil {
log.Error().Err(err).Msg("prepare python3 venv failed")
return
} }
// check if funppy is ready in python3 venv python3, err := builtin.EnsurePython3Venv(venv, packages...)
err = builtin.AssertPythonPackage(builtin.Python3Executable, "funppy", fungo.Version)
if err != nil { if err != nil {
log.Error().Err(err).Str("venv", venv).Msg("python package funppy is not ready") log.Error().Err(err).
os.Exit(1) Interface("packages", packages).
Msg("python3 venv is not ready")
return nil, err
} }
pluginOptions = append(pluginOptions, funplugin.WithPython3(python3))
pluginOptions = append(pluginOptions, funplugin.WithPython3(builtin.Python3Executable))
} }
// found plugin file // found plugin file