mirror of
https://github.com/httprunner/httprunner.git
synced 2026-07-07 23:41:22 +08:00
refactor: hrp build
This commit is contained in:
@@ -5,7 +5,6 @@ import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
@@ -31,6 +30,11 @@ const (
|
||||
regexGoFunctionContent = `func [\s\S]*?\n}`
|
||||
)
|
||||
|
||||
const (
|
||||
genDebugTalkGo = "debugtalk_gen.go"
|
||||
genDebugTalkPy = "debugtalk_gen.py"
|
||||
)
|
||||
|
||||
//go:embed templates/debugtalkPythonTemplate
|
||||
var pyTemplate string
|
||||
|
||||
@@ -55,7 +59,7 @@ type Regexps struct {
|
||||
}
|
||||
|
||||
func (t *TemplateContent) parseGoContent(path string) error {
|
||||
log.Info().Msg(fmt.Sprintf("start to parse %v", path))
|
||||
log.Info().Str("path", path).Msg("start to parse debugtalk.go")
|
||||
|
||||
content, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
@@ -108,7 +112,7 @@ func (t *TemplateContent) parseGoContent(path string) error {
|
||||
func (t *TemplateContent) parsePyContent(path string) error {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %s\n", err)
|
||||
log.Error().Err(err).Str("path", path).Msg("failed to open file")
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
@@ -191,38 +195,34 @@ func buildGo(path string, output string) error {
|
||||
},
|
||||
}
|
||||
|
||||
// create temp dir for building
|
||||
tempDir, err := ioutil.TempDir("", "hrp_build")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pluginDir := filepath.Dir(path)
|
||||
|
||||
// check go sdk in tempDir
|
||||
if err := builtin.ExecCommandInDir(exec.Command("go", "version"), tempDir); err != nil {
|
||||
if err := builtin.ExecCommandInDir(exec.Command("go", "version"), pluginDir); err != nil {
|
||||
return errors.Wrap(err, "go sdk not installed")
|
||||
}
|
||||
|
||||
// create pluginDir
|
||||
pluginDir := filepath.Join(tempDir, "plugin")
|
||||
if err := builtin.CreateFolder(pluginDir); err != nil {
|
||||
return err
|
||||
}
|
||||
// parse debugtalk.go in pluginDir
|
||||
err = templateContent.parseGoContent(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// generate debugtalk.go in pluginDir
|
||||
err = templateContent.genDebugTalk(filepath.Join(pluginDir, "debugtalk.go"), goTemplate)
|
||||
err := templateContent.parseGoContent(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// create go mod
|
||||
if err := builtin.ExecCommandInDir(exec.Command("go", "mod", "init", "plugin"), pluginDir); err != nil {
|
||||
// generate debugtalk.go in pluginDir
|
||||
err = templateContent.genDebugTalk(filepath.Join(pluginDir, genDebugTalkGo), goTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// create go mod if not exists
|
||||
goModFile := filepath.Join(pluginDir, "go.mod")
|
||||
if !builtin.IsFilePathExists(goModFile) {
|
||||
err = builtin.ExecCommandInDir(exec.Command("go", "mod", "init", "plugin"), pluginDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// download plugin dependency
|
||||
// funplugin version should be locked
|
||||
funplugin := fmt.Sprintf("github.com/httprunner/funplugin@%s", shared.Version)
|
||||
@@ -242,10 +242,11 @@ func buildGo(path string, output string) error {
|
||||
}
|
||||
|
||||
// build plugin debugtalk.bin
|
||||
if err := builtin.ExecCommandInDir(exec.Command("go", "build", "-o", outputPath, "debugtalk.go"), pluginDir); err != nil {
|
||||
cmd := exec.Command("go", "build", "-o", outputPath, genDebugTalkGo, filepath.Base(path))
|
||||
if err := builtin.ExecCommandInDir(cmd, pluginDir); err != nil {
|
||||
return err
|
||||
}
|
||||
log.Info().Msg(fmt.Sprintf("build %s to %s successfully", path, outputPath))
|
||||
log.Info().Str("output", outputPath).Str("plugin", path).Msg("build plugin successfully")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -266,9 +267,9 @@ func buildPy(path string, output string) error {
|
||||
// generate debugtalk.py
|
||||
if output == "" {
|
||||
dir, _ := os.Getwd()
|
||||
output = filepath.Join(dir, "debugtalk_gen.py")
|
||||
output = filepath.Join(dir, genDebugTalkPy)
|
||||
} else if builtin.IsFolderPathExists(output) {
|
||||
output = filepath.Join(output, "debugtalk_gen.py")
|
||||
output = filepath.Join(output, genDebugTalkPy)
|
||||
}
|
||||
err = templateContent.genDebugTalk(output, pyTemplate)
|
||||
if err != nil {
|
||||
@@ -295,7 +296,7 @@ func Run(arg string, output string) (err error) {
|
||||
return errors.New("type error, expected .py or .go")
|
||||
}
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg(fmt.Sprintf("failed to build %s", arg))
|
||||
log.Error().Err(err).Str("arg", arg).Msg("build plugin failed")
|
||||
os.Exit(1)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -4,23 +4,24 @@ import (
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/httprunner/httprunner/v4/hrp/internal/builtin"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/httprunner/httprunner/v4/hrp/internal/builtin"
|
||||
)
|
||||
|
||||
func TestRun(t *testing.T) {
|
||||
err := Run("plugin/debugtalk.go", "./debugtalk_gen.bin")
|
||||
err := Run("../scaffold/templates/plugin/debugtalk.go", "./debugtalk.bin")
|
||||
if !assert.Nil(t, err) {
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
err = Run("plugin/debugtalk.py", "./debugtalk_gen.py")
|
||||
genDebugTalkPy := "../scaffold/templates/plugin/debugtalk_gen.py"
|
||||
err = Run("../scaffold/templates/plugin/debugtalk.py", genDebugTalkPy)
|
||||
if !assert.Nil(t, err) {
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
contentBytes, err := builtin.ReadFile("./debugtalk_gen.py")
|
||||
contentBytes, err := builtin.ReadFile(genDebugTalkPy)
|
||||
if !assert.Nil(t, err) {
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
package noplugin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func SumTwoInt(a, b int) int {
|
||||
return a + b
|
||||
}
|
||||
|
||||
func SumInts(args ...int) int {
|
||||
var sum int
|
||||
for _, arg := range args {
|
||||
sum += arg
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
func Sum(args ...interface{}) (interface{}, error) {
|
||||
var sum float64
|
||||
for _, arg := range args {
|
||||
switch v := arg.(type) {
|
||||
case int:
|
||||
sum += float64(v)
|
||||
case float64:
|
||||
sum += v
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected type: %T", arg)
|
||||
}
|
||||
}
|
||||
return sum, nil
|
||||
}
|
||||
|
||||
func SetupHookExample(args string) string {
|
||||
return fmt.Sprintf("step name: %v, setup...", args)
|
||||
}
|
||||
|
||||
func TeardownHookExample(args string) string {
|
||||
return fmt.Sprintf("step name: %v, teardown...", args)
|
||||
}
|
||||
|
||||
func GetVersion() string {
|
||||
return "v0.4"
|
||||
}
|
||||
@@ -1,15 +1,10 @@
|
||||
// NOTE: Generated By hrp {{ .Version }}, DO NOT EDIT!
|
||||
package main
|
||||
|
||||
import (
|
||||
{{- range $import := .Imports }}
|
||||
{{ $import -}}
|
||||
{{ end }}
|
||||
"github.com/httprunner/funplugin/fungo"
|
||||
)
|
||||
|
||||
{{ range $function := .Functions }}
|
||||
{{ $function }}
|
||||
{{ end }}
|
||||
|
||||
func main() {
|
||||
{{- range $functionName := .FunctionNames }}
|
||||
fungo.Register("{{ $functionName }}", {{ $functionName }})
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/httprunner/funplugin/shared"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
@@ -196,24 +195,7 @@ func createGoPlugin(projectName string) error {
|
||||
err := CopyFile("templates/plugin/debugtalk.go",
|
||||
filepath.Join(projectName, "plugin", "debugtalk.go"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// create go mod
|
||||
if err := builtin.ExecCommandInDir(exec.Command("go", "mod", "init", "plugin"), pluginDir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// download plugin dependency
|
||||
// funplugin version should be locked
|
||||
funplugin := fmt.Sprintf("github.com/httprunner/funplugin@%s", shared.Version)
|
||||
if err := builtin.ExecCommandInDir(exec.Command("go", "get", funplugin), pluginDir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// build plugin debugtalk.bin
|
||||
if err := builtin.ExecCommandInDir(exec.Command("go", "build", "-o", filepath.Join("..", "debugtalk.bin"), "debugtalk.go"), pluginDir); err != nil {
|
||||
return err
|
||||
return errors.Wrap(err, "copy debugtalk.go failed")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -3,8 +3,8 @@ import time
|
||||
from typing import List
|
||||
|
||||
|
||||
def get_version():
|
||||
return "v0.4"
|
||||
def get_user_agent():
|
||||
return "hrp/funppy"
|
||||
|
||||
|
||||
def sleep(n_secs):
|
||||
@@ -2,8 +2,6 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/httprunner/funplugin/fungo"
|
||||
)
|
||||
|
||||
func SumTwoInt(a, b int) int {
|
||||
@@ -41,17 +39,6 @@ func TeardownHookExample(args string) string {
|
||||
return fmt.Sprintf("step name: %v, teardown...", args)
|
||||
}
|
||||
|
||||
func GetVersion() string {
|
||||
return fungo.Version
|
||||
}
|
||||
|
||||
func main() {
|
||||
fungo.Register("get_version", GetVersion)
|
||||
fungo.Register("sum_ints", SumInts)
|
||||
fungo.Register("sum_two_int", SumTwoInt)
|
||||
fungo.Register("sum_two", SumTwoInt)
|
||||
fungo.Register("sum", Sum)
|
||||
fungo.Register("setup_hook_example", SetupHookExample)
|
||||
fungo.Register("teardown_hook_example", TeardownHookExample)
|
||||
fungo.Serve()
|
||||
func GetUserAgent() string {
|
||||
return "hrp/fungo"
|
||||
}
|
||||
|
||||
@@ -2,11 +2,9 @@ import logging
|
||||
import time
|
||||
from typing import List
|
||||
|
||||
import funppy
|
||||
|
||||
|
||||
def get_version():
|
||||
return funppy.__version__
|
||||
def get_user_agent():
|
||||
return "hrp/funppy"
|
||||
|
||||
|
||||
def sleep(n_secs):
|
||||
@@ -57,17 +55,3 @@ def setup_hook_example(name):
|
||||
def teardown_hook_example(name):
|
||||
logging.warning("teardown_hook_example")
|
||||
return f"teardown_hook_example: {name}"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
funppy.register("get_version", get_version)
|
||||
funppy.register("sum", sum)
|
||||
funppy.register("sum_ints", sum_ints)
|
||||
funppy.register("concatenate", concatenate)
|
||||
funppy.register("sum_two_int", sum_two_int)
|
||||
funppy.register("sum_two", sum_two_int)
|
||||
funppy.register("sum_two_string", sum_two_string)
|
||||
funppy.register("sum_strings", sum_strings)
|
||||
funppy.register("setup_hook_example", setup_hook_example)
|
||||
funppy.register("teardown_hook_example", teardown_hook_example)
|
||||
funppy.serve()
|
||||
|
||||
16
hrp/internal/scaffold/templates/plugin/debugtalk_gen.go
Normal file
16
hrp/internal/scaffold/templates/plugin/debugtalk_gen.go
Normal file
@@ -0,0 +1,16 @@
|
||||
// NOTE: Generated By hrp v4.1.0, DO NOT EDIT!
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/httprunner/funplugin/fungo"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fungo.Register("SumTwoInt", SumTwoInt)
|
||||
fungo.Register("SumInts", SumInts)
|
||||
fungo.Register("Sum", Sum)
|
||||
fungo.Register("SetupHookExample", SetupHookExample)
|
||||
fungo.Register("TeardownHookExample", TeardownHookExample)
|
||||
fungo.Register("GetUserAgent", GetUserAgent)
|
||||
fungo.Serve()
|
||||
}
|
||||
75
hrp/internal/scaffold/templates/plugin/debugtalk_gen.py
Normal file
75
hrp/internal/scaffold/templates/plugin/debugtalk_gen.py
Normal file
@@ -0,0 +1,75 @@
|
||||
# NOTE: Generated By hrp v4.1.0, DO NOT EDIT!
|
||||
|
||||
import logging
|
||||
import time
|
||||
import funppy
|
||||
|
||||
from typing import List
|
||||
|
||||
|
||||
def get_user_agent():
|
||||
return "hrp/funppy"
|
||||
|
||||
|
||||
def sleep(n_secs):
|
||||
time.sleep(n_secs)
|
||||
|
||||
|
||||
def sum(*args):
|
||||
result = 0
|
||||
for arg in args:
|
||||
result += arg
|
||||
return result
|
||||
|
||||
|
||||
def sum_ints(*args: List[int]) -> int:
|
||||
result = 0
|
||||
for arg in args:
|
||||
result += arg
|
||||
return result
|
||||
|
||||
|
||||
def sum_two_int(a: int, b: int) -> int:
|
||||
return a + b
|
||||
|
||||
|
||||
def sum_two_string(a: str, b: str) -> str:
|
||||
return a + b
|
||||
|
||||
|
||||
def sum_strings(*args: List[str]) -> str:
|
||||
result = ""
|
||||
for arg in args:
|
||||
result += arg
|
||||
return result
|
||||
|
||||
|
||||
def concatenate(*args: List[str]) -> str:
|
||||
result = ""
|
||||
for arg in args:
|
||||
result += str(arg)
|
||||
return result
|
||||
|
||||
|
||||
def setup_hook_example(name):
|
||||
logging.warning("setup_hook_example")
|
||||
return f"setup_hook_example: {name}"
|
||||
|
||||
|
||||
def teardown_hook_example(name):
|
||||
logging.warning("teardown_hook_example")
|
||||
return f"teardown_hook_example: {name}"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
funppy.register("get_user_agent", get_user_agent)
|
||||
funppy.register("sleep", sleep)
|
||||
funppy.register("sum", sum)
|
||||
funppy.register("sum_ints", sum_ints)
|
||||
funppy.register("sum_two_int", sum_two_int)
|
||||
funppy.register("sum_two_string", sum_two_string)
|
||||
funppy.register("sum_strings", sum_strings)
|
||||
funppy.register("concatenate", concatenate)
|
||||
funppy.register("setup_hook_example", setup_hook_example)
|
||||
funppy.register("teardown_hook_example", teardown_hook_example)
|
||||
funppy.serve()
|
||||
@@ -24,7 +24,7 @@ teststeps:
|
||||
method: POST
|
||||
url: /post
|
||||
headers:
|
||||
User-Agent: funplugin/${get_version()}
|
||||
User-Agent: ${get_user_agent()}
|
||||
Content-Type: "application/x-www-form-urlencoded"
|
||||
body: "foo1=$foo1&foo2=$foo3"
|
||||
validate:
|
||||
|
||||
@@ -43,7 +43,7 @@ class TestCaseDemoRefTestcase(HttpRunner):
|
||||
.post("/post")
|
||||
.with_headers(
|
||||
**{
|
||||
"User-Agent": "funplugin/${get_version()}",
|
||||
"User-Agent": "${get_user_agent()}",
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
}
|
||||
)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"expect_foo2": "config_bar2"
|
||||
},
|
||||
"headers": {
|
||||
"User-Agent": "funplugin/${get_version()}"
|
||||
"User-Agent": "${get_user_agent()}"
|
||||
},
|
||||
"base_url": "https://postman-echo.com",
|
||||
"verify": false,
|
||||
|
||||
@@ -6,7 +6,7 @@ config:
|
||||
expect_foo1: config_bar1
|
||||
expect_foo2: config_bar2
|
||||
headers:
|
||||
User-Agent: funplugin/${get_version()}
|
||||
User-Agent: ${get_user_agent()}
|
||||
verify: False
|
||||
export: ["foo3"]
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ class TestCaseDemoRequests(HttpRunner):
|
||||
)
|
||||
.get("/get")
|
||||
.with_params(**{"foo1": "$foo1", "foo2": "$foo2", "sum_v": "$sum_v"})
|
||||
.with_headers(**{"User-Agent": "funplugin/${get_version()}"})
|
||||
.with_headers(**{"User-Agent": "${get_user_agent()}"})
|
||||
.extract()
|
||||
.with_jmespath("body.args.foo2", "foo3")
|
||||
.validate()
|
||||
@@ -45,7 +45,7 @@ class TestCaseDemoRequests(HttpRunner):
|
||||
.post("/post")
|
||||
.with_headers(
|
||||
**{
|
||||
"User-Agent": "funplugin/${get_version()}",
|
||||
"User-Agent": "${get_user_agent()}",
|
||||
"Content-Type": "text/plain",
|
||||
}
|
||||
)
|
||||
@@ -65,7 +65,7 @@ class TestCaseDemoRequests(HttpRunner):
|
||||
.post("/post")
|
||||
.with_headers(
|
||||
**{
|
||||
"User-Agent": "funplugin/${get_version()}",
|
||||
"User-Agent": "${get_user_agent()}",
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user