mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
refactor: Inject CommandExecutor into guard to fix dependency direction
guard depended on internal/runner, which inverted the intended layer hierarchy. Now guard defines a CommandExecutor function type and accepts it as a constructor argument. internal/flows (the composition root) creates the executor closure wrapping runner.Execute and injects it, keeping guard free of internal/ dependencies.
This commit is contained in:
+9
-6
@@ -15,11 +15,15 @@ import (
|
||||
"github.com/safedep/pmg/config"
|
||||
"github.com/safedep/pmg/extractor"
|
||||
"github.com/safedep/pmg/internal/audit"
|
||||
"github.com/safedep/pmg/internal/runner"
|
||||
"github.com/safedep/pmg/internal/ui"
|
||||
"github.com/safedep/pmg/packagemanager"
|
||||
)
|
||||
|
||||
// CommandExecutor executes a parsed package manager command directly.
|
||||
// It is injected into the guard so that callers control execution behavior
|
||||
// (e.g., dry-run, sandbox application) without guard depending on internal packages.
|
||||
type CommandExecutor func(ctx context.Context, pc *packagemanager.ParsedCommand) error
|
||||
|
||||
type PackageManagerGuardInteraction struct {
|
||||
// SetStatus is called to set the status of the guard in the UI
|
||||
SetStatus func(status string)
|
||||
@@ -96,6 +100,7 @@ type packageManagerGuard struct {
|
||||
analyzers []analyzer.PackageVersionAnalyzer
|
||||
packageManager packagemanager.PackageManager
|
||||
packageResolver packagemanager.PackageResolver
|
||||
executor CommandExecutor
|
||||
}
|
||||
|
||||
func NewPackageManagerGuard(config PackageManagerGuardConfig,
|
||||
@@ -103,6 +108,7 @@ func NewPackageManagerGuard(config PackageManagerGuardConfig,
|
||||
packageResolver packagemanager.PackageResolver,
|
||||
analyzers []analyzer.PackageVersionAnalyzer,
|
||||
interaction PackageManagerGuardInteraction,
|
||||
executor CommandExecutor,
|
||||
) (*packageManagerGuard, error) {
|
||||
return &packageManagerGuard{
|
||||
interaction: interaction,
|
||||
@@ -110,6 +116,7 @@ func NewPackageManagerGuard(config PackageManagerGuardConfig,
|
||||
packageManager: packageManager,
|
||||
packageResolver: packageResolver,
|
||||
config: config,
|
||||
executor: executor,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -252,11 +259,7 @@ func (g *packageManagerGuard) Run(ctx context.Context, args []string, parsedComm
|
||||
}
|
||||
|
||||
func (g *packageManagerGuard) continueExecution(ctx context.Context, pc *packagemanager.ParsedCommand) error {
|
||||
pmName := ""
|
||||
if g.packageManager != nil {
|
||||
pmName = g.packageManager.Name()
|
||||
}
|
||||
return runner.Execute(ctx, pc, pmName, g.config.DryRun)
|
||||
return g.executor(ctx, pc)
|
||||
}
|
||||
|
||||
func (g *packageManagerGuard) concurrentAnalyzePackages(ctx context.Context,
|
||||
|
||||
+11
-5
@@ -11,6 +11,12 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// noopExecutor is a no-op executor for use in tests that set DryRun=true
|
||||
// or otherwise don't reach actual command execution.
|
||||
var noopExecutor CommandExecutor = func(_ context.Context, _ *packagemanager.ParsedCommand) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestGuardConcurrentlyAnalyzePackagesMalwareQueryService(t *testing.T) {
|
||||
mq, err := analyzer.NewMalysisQueryAnalyzer(analyzer.MalysisQueryAnalyzerConfig{})
|
||||
if err != nil {
|
||||
@@ -20,7 +26,7 @@ func TestGuardConcurrentlyAnalyzePackagesMalwareQueryService(t *testing.T) {
|
||||
pg, err := NewPackageManagerGuard(DefaultPackageManagerGuardConfig(), nil, nil,
|
||||
[]analyzer.PackageVersionAnalyzer{mq}, PackageManagerGuardInteraction{
|
||||
ShowWarning: func(message string) {},
|
||||
})
|
||||
}, noopExecutor)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create pg: %v", err)
|
||||
}
|
||||
@@ -80,7 +86,7 @@ func TestGuardInsecureInstallation(t *testing.T) {
|
||||
}
|
||||
|
||||
pg, err := NewPackageManagerGuard(config, nil, nil,
|
||||
[]analyzer.PackageVersionAnalyzer{mq}, interaction)
|
||||
[]analyzer.PackageVersionAnalyzer{mq}, interaction, noopExecutor)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create pg: %v", err)
|
||||
}
|
||||
@@ -129,7 +135,7 @@ func TestGuardInsecureInstallation(t *testing.T) {
|
||||
}
|
||||
|
||||
pg, err := NewPackageManagerGuard(config, nil, nil,
|
||||
[]analyzer.PackageVersionAnalyzer{mq}, interaction)
|
||||
[]analyzer.PackageVersionAnalyzer{mq}, interaction, noopExecutor)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create pg: %v", err)
|
||||
}
|
||||
@@ -184,7 +190,7 @@ func TestGuardInsecureInstallation(t *testing.T) {
|
||||
}
|
||||
|
||||
pg, err := NewPackageManagerGuard(config, nil, nil,
|
||||
[]analyzer.PackageVersionAnalyzer{mq}, interaction)
|
||||
[]analyzer.PackageVersionAnalyzer{mq}, interaction, noopExecutor)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create pg: %v", err)
|
||||
}
|
||||
@@ -225,7 +231,7 @@ func TestGuardInsecureInstallation(t *testing.T) {
|
||||
}
|
||||
|
||||
pg, err := NewPackageManagerGuard(config, nil, nil,
|
||||
[]analyzer.PackageVersionAnalyzer{mq}, interaction)
|
||||
[]analyzer.PackageVersionAnalyzer{mq}, interaction, noopExecutor)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create pg: %v", err)
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/safedep/pmg/config"
|
||||
"github.com/safedep/pmg/guard"
|
||||
"github.com/safedep/pmg/internal/audit"
|
||||
"github.com/safedep/pmg/internal/runner"
|
||||
"github.com/safedep/pmg/internal/ui"
|
||||
"github.com/safedep/pmg/packagemanager"
|
||||
)
|
||||
@@ -77,7 +78,12 @@ func (f *commonFlow) Run(ctx context.Context, args []string, parsedCmd *packagem
|
||||
guardConfig.DryRun = cfg.DryRun
|
||||
guardConfig.InsecureInstallation = cfg.InsecureInstallation
|
||||
|
||||
guardManager, err := guard.NewPackageManagerGuard(guardConfig, f.pm, f.packageResolver, analyzers, interaction)
|
||||
pmName := f.pm.Name()
|
||||
executor := func(ctx context.Context, pc *packagemanager.ParsedCommand) error {
|
||||
return runner.Execute(ctx, pc, pmName, cfg.DryRun)
|
||||
}
|
||||
|
||||
guardManager, err := guard.NewPackageManagerGuard(guardConfig, f.pm, f.packageResolver, analyzers, interaction, executor)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create package manager guard: %s", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user