Files
httprunner/hrp/internal/scaffold/main.go

195 lines
5.0 KiB
Go

package scaffold
import (
"embed"
"fmt"
"os"
"os/exec"
"path/filepath"
"github.com/pkg/errors"
"github.com/rs/zerolog/log"
"github.com/httprunner/funplugin/shared"
"github.com/httprunner/httprunner/hrp/internal/builtin"
"github.com/httprunner/httprunner/hrp/internal/sdk"
)
type PluginType string
const (
Ignore PluginType = "ignore"
Py PluginType = "py"
Go PluginType = "go"
)
//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, force bool) error {
// report event
sdk.SendEvent(sdk.EventTracking{
Category: "Scaffold",
Action: "hrp startproject",
})
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, "reports")); err != nil {
return err
}
if err := builtin.CreateFile(filepath.Join(projectName, "reports", ".keep"), ""); 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 demo testcases
if pluginType == Ignore {
err := CopyFile("templates/testcases/demo_without_funplugin.json",
filepath.Join(projectName, "testcases", "demo_without_funplugin.json"))
if err != nil {
return err
}
log.Info().Msg("skip creating function plugin")
return nil
}
err = CopyFile("templates/testcases/demo_with_funplugin.json",
filepath.Join(projectName, "testcases", "demo_with_funplugin.json"))
if err != nil {
return err
}
err = CopyFile("templates/testcases/demo_requests.yml",
filepath.Join(projectName, "testcases", "demo_requests.yml"))
if err != nil {
return err
}
err = CopyFile("templates/testcases/demo_ref_testcase.yml",
filepath.Join(projectName, "testcases", "demo_ref_testcase.yml"))
if err != nil {
return err
}
// create debugtalk function plugin
switch pluginType {
case Py:
return createPythonPlugin(projectName)
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 := builtin.ExecCommandInDir(exec.Command("go", "version"), projectName); 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", "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 nil
}
func createPythonPlugin(projectName string) error {
log.Info().Msg("start to create hashicorp python plugin")
// create debugtalk.py
pluginFile := filepath.Join(projectName, "debugtalk.py")
err := CopyFile("templates/plugin/debugtalk.py", pluginFile)
if err != nil {
return errors.Wrap(err, "copy file failed")
}
_, err = builtin.EnsurePython3Venv(fmt.Sprintf("funppy==%s", shared.Version))
if err != nil {
return err
}
return nil
}