Files
kandev/apps/backend/internal/agentctl/server/process/managed_runtime.go
T

76 lines
2.3 KiB
Go

package process
import (
"context"
"errors"
"path/filepath"
"strings"
"github.com/kandev/kandev/internal/agent/managedruntime"
tools "github.com/kandev/kandev/internal/tools/installer"
)
// RepairManagedRuntimeCache resolves npm's cache in the instance environment
// and removes only the execution tree for one exact managed package spec.
func (m *Manager) RepairManagedRuntimeCache(ctx context.Context, packageSpec string) error {
return m.RepairManagedRuntimeCacheWithEnvironment(ctx, packageSpec, nil, nil)
}
// RepairManagedRuntimeCacheWithEnvironment applies the failed process's
// environment contract while resolving npm's cache.
func (m *Manager) RepairManagedRuntimeCacheWithEnvironment(
ctx context.Context,
packageSpec string,
overrides map[string]string,
stripEnv []string,
) error {
if err := managedruntime.ValidateExactPackageSpec(packageSpec); err != nil {
return err
}
env, err := mergeAgentEnvIntoShellConfigWithError(m.agentEnvSnapshot(), overrides)
if err != nil {
return errors.New("resolve agent environment for managed runtime repair")
}
args := append(managedruntime.NPMProjectPrefixArgs(), "config", "get", "cache")
if err := managedruntime.PrepareNPMProjectPrefix(args); err != nil {
return errors.New("prepare managed npm project prefix")
}
output, err := m.Output(ctx, tools.CommandSpec{
Path: "npm",
Args: args,
Dir: m.cfg.WorkDir,
Env: env,
StripEnv: stripEnv,
})
if err != nil {
if ctx.Err() != nil {
return ctx.Err()
}
return errors.New("resolve npm cache for managed runtime repair")
}
cacheRoot, err := npmCacheRootFromOutput(output)
if err != nil {
return err
}
if err := managedruntime.RemoveNpxExecutionTree(cacheRoot, packageSpec); err != nil {
if ctx.Err() != nil {
return ctx.Err()
}
return errors.New("remove managed runtime npm execution tree")
}
m.ClearStderrBuffer()
return nil
}
func npmCacheRootFromOutput(output []byte) (string, error) {
lines := strings.Split(strings.TrimSpace(string(output)), "\n")
if len(lines) != 1 {
return "", errors.New("npm cache path was not returned")
}
candidate := strings.TrimSpace(lines[0])
if candidate == "" || !filepath.IsAbs(candidate) {
return "", errors.New("npm cache path was not returned")
}
return candidate, nil
}