forked from Gitlink/gitlink-cli
107 lines
2.5 KiB
Go
107 lines
2.5 KiB
Go
package engine
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os/exec"
|
|
"strings"
|
|
|
|
"github.com/gitlink-org/gitlink-cli/shortcuts/common"
|
|
wf "github.com/gitlink-org/gitlink-cli/shortcuts/workflow"
|
|
"github.com/gitlink-org/gitlink-cli/shortcuts/workflow/snapshot"
|
|
)
|
|
|
|
// ExecuteStep dispatches a step to the right executor based on its Type.
|
|
func ExecuteStep(ctx *common.RuntimeContext, step wf.StepDef, dryRun bool) *wf.StepResult {
|
|
sr := &wf.StepResult{
|
|
Step: step.Name,
|
|
Purpose: step.Purpose,
|
|
Type: step.Type,
|
|
}
|
|
|
|
switch step.Type {
|
|
case wf.StepTypeAPI:
|
|
executeAPIStep(ctx, step, sr)
|
|
case wf.StepTypeCommand:
|
|
executeCommandStep(ctx, step, sr)
|
|
case wf.StepTypeSkill:
|
|
executeSkillStep(ctx, step, sr, dryRun)
|
|
default:
|
|
sr.OK = false
|
|
sr.Error = fmt.Sprintf("unknown step type: %q", step.Type)
|
|
}
|
|
return sr
|
|
}
|
|
|
|
func executeAPIStep(ctx *common.RuntimeContext, step wf.StepDef, sr *wf.StepResult) {
|
|
path := wf.ResolvePath(step.Target, ctx.Owner, ctx.Repo)
|
|
env, err := ctx.CallAPIWithQuery(step.Method, path, step.Query)
|
|
if err != nil {
|
|
sr.OK = false
|
|
sr.Error = err.Error()
|
|
} else {
|
|
sr.OK = env.OK
|
|
sr.Data = env.Data
|
|
}
|
|
}
|
|
|
|
func executeCommandStep(ctx *common.RuntimeContext, step wf.StepDef, sr *wf.StepResult) {
|
|
if strings.HasPrefix(step.Target, "workflow-internal:") {
|
|
executeInternalCommandStep(ctx, step, sr)
|
|
return
|
|
}
|
|
|
|
parts := wf.ParseCommandTarget(step.Target)
|
|
if len(parts) == 0 {
|
|
sr.OK = false
|
|
sr.Error = fmt.Sprintf("empty command target: %q", step.Target)
|
|
return
|
|
}
|
|
|
|
bin := wf.ResolveCLIBinary()
|
|
|
|
args := append(parts, "--format", "json")
|
|
if ctx.Owner != "" {
|
|
args = append(args, "--owner", ctx.Owner)
|
|
}
|
|
if ctx.Repo != "" {
|
|
args = append(args, "--repo", ctx.Repo)
|
|
}
|
|
|
|
cmd := exec.Command(bin, args...)
|
|
cmd.Stderr = nil
|
|
|
|
out, err := cmd.Output()
|
|
if err != nil {
|
|
sr.OK = false
|
|
sr.Error = fmt.Sprintf("command failed: %v", err)
|
|
return
|
|
}
|
|
|
|
var data interface{}
|
|
if err := json.Unmarshal(out, &data); err != nil {
|
|
sr.OK = true
|
|
sr.Data = strings.TrimSpace(string(out))
|
|
} else {
|
|
sr.OK = true
|
|
sr.Data = data
|
|
}
|
|
}
|
|
|
|
func executeInternalCommandStep(ctx *common.RuntimeContext, step wf.StepDef, sr *wf.StepResult) {
|
|
switch strings.TrimPrefix(step.Target, "workflow-internal:") {
|
|
case "multi-repo-snapshot":
|
|
snap, err := snapshot.BuildMultiRepoSnapshot(ctx)
|
|
if err != nil {
|
|
sr.OK = false
|
|
sr.Error = err.Error()
|
|
return
|
|
}
|
|
sr.OK = true
|
|
sr.Data = snap
|
|
default:
|
|
sr.OK = false
|
|
sr.Error = fmt.Sprintf("unknown internal workflow command: %q", step.Target)
|
|
}
|
|
}
|