mirror of
https://github.com/httprunner/httprunner.git
synced 2026-05-07 06:03:13 +08:00
221 lines
5.9 KiB
Go
221 lines
5.9 KiB
Go
package scaffold
|
|
|
|
import (
|
|
"embed"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"github.com/httprunner/funplugin/myexec"
|
|
"github.com/pkg/errors"
|
|
"github.com/rs/zerolog/log"
|
|
|
|
hrp "github.com/httprunner/httprunner/v5"
|
|
"github.com/httprunner/httprunner/v5/code"
|
|
"github.com/httprunner/httprunner/v5/internal/builtin"
|
|
"github.com/httprunner/httprunner/v5/internal/config"
|
|
"github.com/httprunner/httprunner/v5/internal/sdk"
|
|
"github.com/httprunner/httprunner/v5/internal/version"
|
|
)
|
|
|
|
type PluginType string
|
|
|
|
const (
|
|
Empty PluginType = "empty"
|
|
Ignore PluginType = "ignore"
|
|
Py PluginType = "py"
|
|
Go PluginType = "go"
|
|
)
|
|
|
|
type ProjectInfo struct {
|
|
ProjectName string `json:"project_name,omitempty" yaml:"project_name,omitempty"`
|
|
CreateTime time.Time `json:"create_time,omitempty" yaml:"create_time,omitempty"`
|
|
Version string `json:"hrp_version,omitempty" yaml:"hrp_version,omitempty"`
|
|
}
|
|
|
|
//go:embed templates/*
|
|
var templatesDir embed.FS
|
|
|
|
// CopyFile copies a file from templates dir to scaffold project
|
|
func CopyFile(templateFile, targetFile string) error {
|
|
log.Info().Str("path", targetFile).Msg("create file")
|
|
content, err := templatesDir.ReadFile(templateFile)
|
|
if err != nil {
|
|
return errors.Wrap(err, "template file not found")
|
|
}
|
|
|
|
err = os.WriteFile(targetFile, content, 0o644)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("create file failed")
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func CreateScaffold(projectName string, pluginType PluginType, venv string, force bool) error {
|
|
// report GA event
|
|
startTime := time.Now()
|
|
defer func() {
|
|
sdk.SendGA4Event("hrp_startproject", map[string]interface{}{
|
|
"pluginType": string(pluginType),
|
|
"force": force,
|
|
"engagement_time_msec": time.Since(startTime).Milliseconds(),
|
|
})
|
|
}()
|
|
|
|
log.Info().
|
|
Str("projectName", projectName).
|
|
Str("pluginType", string(pluginType)).
|
|
Bool("force", force).
|
|
Msg("create new scaffold project")
|
|
|
|
// check if projectName exists
|
|
if _, err := os.Stat(projectName); err == nil {
|
|
if !force {
|
|
log.Warn().Str("projectName", projectName).
|
|
Msg("project name already exists, please specify a new one.")
|
|
return fmt.Errorf("project name already exists")
|
|
}
|
|
|
|
log.Warn().Str("projectName", projectName).
|
|
Msg("project name already exists, remove first !!!")
|
|
os.RemoveAll(projectName)
|
|
}
|
|
|
|
// create project folders
|
|
if err := builtin.CreateFolder(projectName); err != nil {
|
|
return err
|
|
}
|
|
if err := builtin.CreateFolder(filepath.Join(projectName, "har")); err != nil {
|
|
return err
|
|
}
|
|
if err := builtin.CreateFile(filepath.Join(projectName, "har", ".keep"), ""); err != nil {
|
|
return err
|
|
}
|
|
if err := builtin.CreateFolder(filepath.Join(projectName, "testcases")); err != nil {
|
|
return err
|
|
}
|
|
if err := builtin.CreateFolder(filepath.Join(projectName, config.ResultsDirName)); err != nil {
|
|
return err
|
|
}
|
|
if err := builtin.CreateFile(filepath.Join(projectName, config.ResultsDirName, ".keep"), ""); err != nil {
|
|
return err
|
|
}
|
|
|
|
projectInfo := &ProjectInfo{
|
|
ProjectName: filepath.Base(projectName),
|
|
CreateTime: time.Now(),
|
|
Version: version.VERSION,
|
|
}
|
|
|
|
// dump project information to file
|
|
err := builtin.Dump2JSON(projectInfo, filepath.Join(projectName, "proj.json"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// create .gitignore
|
|
err = CopyFile("templates/gitignore", filepath.Join(projectName, ".gitignore"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// create .env
|
|
err = CopyFile("templates/env", filepath.Join(projectName, ".env"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// create project testcases
|
|
if pluginType == Empty {
|
|
// create empty project
|
|
err := CopyFile("templates/testcases/demo_empty_request.json",
|
|
filepath.Join(projectName, "testcases", "requests.json"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
} else if pluginType == Ignore {
|
|
// create project without funplugin
|
|
err := CopyFile("templates/testcases/demo_without_funplugin.json",
|
|
filepath.Join(projectName, "testcases", "requests.json"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
log.Info().Msg("skip creating function plugin")
|
|
return nil
|
|
}
|
|
|
|
// create project with funplugin
|
|
err = CopyFile("templates/testcases/demo_with_funplugin.json",
|
|
filepath.Join(projectName, "testcases", "demo.json"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = CopyFile("templates/testcases/demo_requests.json",
|
|
filepath.Join(projectName, "testcases", "requests.json"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = CopyFile("templates/testcases/demo_requests.yml",
|
|
filepath.Join(projectName, "testcases", "requests.yml"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = CopyFile("templates/testcases/demo_ref_testcase.yml",
|
|
filepath.Join(projectName, "testcases", "ref_testcase.yml"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// create debugtalk function plugin
|
|
switch pluginType {
|
|
case Py:
|
|
return createPythonPlugin(projectName, venv)
|
|
case Go:
|
|
return createGoPlugin(projectName)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func createGoPlugin(projectName string) error {
|
|
log.Info().Msg("start to create hashicorp go plugin")
|
|
// check go sdk
|
|
if err := myexec.RunCommand("go", "version"); err != nil {
|
|
return errors.Wrap(err, "go sdk not installed")
|
|
}
|
|
|
|
// create debugtalk.go
|
|
pluginDir := filepath.Join(projectName, "plugin")
|
|
if err := builtin.CreateFolder(pluginDir); err != nil {
|
|
return err
|
|
}
|
|
err := CopyFile("templates/plugin/debugtalk.go",
|
|
filepath.Join(projectName, "plugin", hrp.PluginGoSourceFile))
|
|
if err != nil {
|
|
return errors.Wrap(err, "copy debugtalk.go failed")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func createPythonPlugin(projectName, venv string) error {
|
|
log.Info().Msg("start to create hashicorp python plugin")
|
|
|
|
// create debugtalk.py
|
|
pluginFile := filepath.Join(projectName, hrp.PluginPySourceFile)
|
|
err := CopyFile("templates/plugin/debugtalk.py", pluginFile)
|
|
if err != nil {
|
|
return errors.Wrap(err, "copy file failed")
|
|
}
|
|
|
|
packages := []string{"funppy", "httprunner"}
|
|
_, err = myexec.EnsurePython3Venv(venv, packages...)
|
|
if err != nil {
|
|
return errors.Wrap(code.InvalidPython3Venv, err.Error())
|
|
}
|
|
|
|
return nil
|
|
}
|