Files
pmg/internal/runner/execute.go
T
Sahilb315 da098a51a8 feat: Add proxy_install_only config to restrict proxy to download commands
Introduces proxy_install_only (default: false) which, when enabled,
skips the proxy for package manager commands that do not download
packages (e.g. npm ls, pip list), avoiding unnecessary MITM overhead.

- Add ProxyInstallOnly to Config and config template
- Add IsKnownDownloadCommand / MayDownloadPackages to ParsedCommand
- Add DownloadCommands to npm and pypi PM configs covering update,
  ci, audit, dlx, exec, x, download, run and equivalents per PM
- Extract shared runner.Execute used by both proxy flow and guard
- Proxy flow short-circuits to runner.Execute for non-download commands
  when proxy_install_only=true
2026-04-13 20:15:50 +05:30

60 lines
1.5 KiB
Go

package runner
import (
"context"
"fmt"
"os"
"os/exec"
"github.com/safedep/dry/log"
"github.com/safedep/pmg/packagemanager"
"github.com/safedep/pmg/sandbox/executor"
"github.com/safedep/pmg/usefulerror"
)
// Execute runs a package manager command without proxy or guard analysis.
// It applies sandbox policy if configured, then executes the command directly.
func Execute(ctx context.Context, pc *packagemanager.ParsedCommand, pmName string, dryRun bool) error {
if len(pc.Command.Exe) == 0 {
return fmt.Errorf("no command to execute")
}
if dryRun {
log.Debugf("Dry run, skipping command execution")
return nil
}
cmd := exec.CommandContext(ctx, pc.Command.Exe, pc.Command.Args...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
result, err := executor.ApplySandbox(ctx, cmd, pmName)
if err != nil {
return fmt.Errorf("failed to apply sandbox: %w", err)
}
defer func() {
if err := result.Close(); err != nil {
log.Errorf("failed to close sandbox: %v", err)
}
}()
if result.ShouldRun() {
if err := cmd.Run(); err != nil {
humanError := "Failed to execute package manager command"
if exitErr, ok := err.(*exec.ExitError); ok {
humanError = fmt.Sprintf("Package manager command exited with code: %d", exitErr.ExitCode())
}
return usefulerror.Useful().
WithCode(usefulerror.ErrCodePackageManagerExecutionFailed).
WithHumanError(humanError).
WithHelp("Check the package manager command and its arguments").
Wrap(err)
}
}
return nil
}