mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
fix: Show error messages on fatal failures #32
This commit is contained in:
@@ -39,7 +39,7 @@ var _ Analyzer = &malysisActiveScanAnalyzer{}
|
||||
|
||||
func NewMalysisActiveScanAnalyzer(config MalysisActiveScanAnalyzerConfig) (*malysisActiveScanAnalyzer, error) {
|
||||
if config.TenantId == "" || config.ApiKey == "" {
|
||||
return nil, fmt.Errorf("active scanning requires SafeDep Cloud authentication credentials")
|
||||
return nil, fmt.Errorf("active scanning requires SafeDep Cloud credentials (https://docs.safedep.io/cloud/malware-analysis)")
|
||||
}
|
||||
|
||||
headers := http.Header{}
|
||||
|
||||
+13
-7
@@ -1,11 +1,13 @@
|
||||
package npm
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
|
||||
"github.com/safedep/dry/log"
|
||||
"github.com/safedep/pmg/config"
|
||||
"github.com/safedep/pmg/internal/flows"
|
||||
"github.com/safedep/pmg/internal/ui"
|
||||
"github.com/safedep/pmg/packagemanager"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -15,12 +17,7 @@ func NewNpmCommand() *cobra.Command {
|
||||
Short: "Guard npm package manager",
|
||||
DisableFlagParsing: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
config, err := config.FromContext(cmd.Context())
|
||||
if err != nil {
|
||||
ui.Fatalf("Failed to get config: %s", err)
|
||||
}
|
||||
|
||||
err = executeNpmFlow(cmd.Context(), config, args)
|
||||
err := executeNpmFlow(cmd.Context(), args)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to execute npm flow: %s", err)
|
||||
}
|
||||
@@ -29,3 +26,12 @@ func NewNpmCommand() *cobra.Command {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func executeNpmFlow(ctx context.Context, args []string) error {
|
||||
packageManager, err := packagemanager.NewNpmPackageManager(packagemanager.DefaultNpmPackageManagerConfig())
|
||||
if err != nil {
|
||||
ui.Fatalf("Failed to create npm package manager proxy: %s", err)
|
||||
}
|
||||
|
||||
return flows.Common(packageManager).Run(ctx, args)
|
||||
}
|
||||
|
||||
+13
-7
@@ -1,11 +1,13 @@
|
||||
package npm
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
|
||||
"github.com/safedep/dry/log"
|
||||
"github.com/safedep/pmg/config"
|
||||
"github.com/safedep/pmg/internal/flows"
|
||||
"github.com/safedep/pmg/internal/ui"
|
||||
"github.com/safedep/pmg/packagemanager"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -15,12 +17,7 @@ func NewPnpmCommand() *cobra.Command {
|
||||
Short: "Guard pnpm package manager",
|
||||
DisableFlagParsing: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
config, err := config.FromContext(cmd.Context())
|
||||
if err != nil {
|
||||
ui.Fatalf("Failed to get config: %s", err)
|
||||
}
|
||||
|
||||
err = executePnpmFlow(cmd.Context(), config, args)
|
||||
err := executePnpmFlow(cmd.Context(), args)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to execute pnpm flow: %s", err)
|
||||
}
|
||||
@@ -29,3 +26,12 @@ func NewPnpmCommand() *cobra.Command {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func executePnpmFlow(ctx context.Context, args []string) error {
|
||||
packageManager, err := packagemanager.NewNpmPackageManager(packagemanager.DefaultPnpmPackageManagerConfig())
|
||||
if err != nil {
|
||||
ui.Fatalf("Failed to create pnpm package manager proxy: %s", err)
|
||||
}
|
||||
|
||||
return flows.Common(packageManager).Run(ctx, args)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# Development
|
||||
|
||||
- [User Interface](./ui.md)
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
# User Interface
|
||||
|
||||
PMG is an interactive tool. We support multiple interactivity modes such as `silent`, `verbose` etc. to meet different developer experience needs. As such, we need to standardize the UI, UX and interactive messaging guidance for developers.
|
||||
|
||||
## Messaging
|
||||
|
||||
Two types of messages to users are supported:
|
||||
|
||||
1. UI messages
|
||||
2. Logs
|
||||
|
||||
### UI messages
|
||||
|
||||
UI messages are displayed in the user interface, currently in the terminal. Following types of messages are supported:
|
||||
|
||||
1. **Status updates** - Meant for showing the stage or status of the workflow.
|
||||
2. **Error messages** - Meant for showing fatal error messages
|
||||
|
||||
| Type | Mode | Show? |
|
||||
| ------ | ------- | ----- |
|
||||
| Status | Silent | No |
|
||||
| Status | Verbose | Yes |
|
||||
| Error | Silent | Yes |
|
||||
| Error | Verbose | Yes |
|
||||
|
||||
### Logs
|
||||
|
||||
Logs are by default for inspection and debugging purposes. They are not shown by default but can be configured through verbosity levels or logging to files. Consider logs as something meant for use only when there is an unexpected behavior.
|
||||
|
||||
@@ -172,6 +172,8 @@ func (g *packageManagerGuard) continueExecution(ctx context.Context, pc *package
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
// We will fail based on executed command's exit code. This is important
|
||||
// because other tools (scripts, CI etc.) may depend on this exit code.
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package npm
|
||||
package flows
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/safedep/pmg/analyzer"
|
||||
"github.com/safedep/pmg/config"
|
||||
@@ -11,7 +10,25 @@ import (
|
||||
"github.com/safedep/pmg/packagemanager"
|
||||
)
|
||||
|
||||
func executeCommonFlow(ctx context.Context, config config.Config, pm packagemanager.PackageManager, args []string) error {
|
||||
type commonFlow struct {
|
||||
pm packagemanager.PackageManager
|
||||
}
|
||||
|
||||
// Creates a common flow of execution for all package managers. This should work for most
|
||||
// of the cases unless a package manager has its own unique requirements. Configuration
|
||||
// should be passed through the context (Global Config)
|
||||
func Common(pm packagemanager.PackageManager) *commonFlow {
|
||||
return &commonFlow{
|
||||
pm: pm,
|
||||
}
|
||||
}
|
||||
|
||||
func (f *commonFlow) Run(ctx context.Context, args []string) error {
|
||||
config, err := config.FromContext(ctx)
|
||||
if err != nil {
|
||||
ui.Fatalf("Failed to get config: %s", err)
|
||||
}
|
||||
|
||||
packageResolverConfig := packagemanager.NewDefaultNpmDependencyResolverConfig()
|
||||
packageResolverConfig.IncludeTransitiveDependencies = config.Transitive
|
||||
packageResolverConfig.TransitiveDepth = config.TransitiveDepth
|
||||
@@ -19,7 +36,7 @@ func executeCommonFlow(ctx context.Context, config config.Config, pm packagemana
|
||||
|
||||
packageResolver, err := packagemanager.NewNpmDependencyResolver(packageResolverConfig)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create npm dependency resolver: %w", err)
|
||||
ui.Fatalf("Failed to create dependency resolver: %s", err)
|
||||
}
|
||||
|
||||
var analyzers []analyzer.PackageVersionAnalyzer
|
||||
@@ -27,14 +44,14 @@ func executeCommonFlow(ctx context.Context, config config.Config, pm packagemana
|
||||
if config.Paranoid {
|
||||
malysisActiveScanAnalyzer, err := analyzer.NewMalysisActiveScanAnalyzer(analyzer.DefaultMalysisActiveScanAnalyzerConfig())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create malysis active scan analyzer: %w", err)
|
||||
ui.Fatalf("Failed to create malware analyzer: %s", err)
|
||||
}
|
||||
|
||||
analyzers = append(analyzers, malysisActiveScanAnalyzer)
|
||||
} else {
|
||||
malysisQueryAnalyzer, err := analyzer.NewMalysisQueryAnalyzer(analyzer.MalysisQueryAnalyzerConfig{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create malysis query analyzer: %w", err)
|
||||
ui.Fatalf("Failed to create malware analyzer: %s", err)
|
||||
}
|
||||
|
||||
analyzers = append(analyzers, malysisQueryAnalyzer)
|
||||
@@ -50,28 +67,10 @@ func executeCommonFlow(ctx context.Context, config config.Config, pm packagemana
|
||||
guardConfig := guard.DefaultPackageManagerGuardConfig()
|
||||
guardConfig.DryRun = config.DryRun
|
||||
|
||||
proxy, err := guard.NewPackageManagerGuard(guardConfig, pm, packageResolver, analyzers, interaction)
|
||||
proxy, err := guard.NewPackageManagerGuard(guardConfig, f.pm, packageResolver, analyzers, interaction)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create package manager guard: %w", err)
|
||||
ui.Fatalf("Failed to create package manager guard: %s", err)
|
||||
}
|
||||
|
||||
return proxy.Run(ctx, args)
|
||||
}
|
||||
|
||||
func executeNpmFlow(ctx context.Context, config config.Config, args []string) error {
|
||||
packageManager, err := packagemanager.NewNpmPackageManager(packagemanager.DefaultNpmPackageManagerConfig())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create npm package manager: %w", err)
|
||||
}
|
||||
|
||||
return executeCommonFlow(ctx, config, packageManager, args)
|
||||
}
|
||||
|
||||
func executePnpmFlow(ctx context.Context, config config.Config, args []string) error {
|
||||
packageManager, err := packagemanager.NewNpmPackageManager(packagemanager.DefaultPnpmPackageManagerConfig())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create pnpm package manager: %w", err)
|
||||
}
|
||||
|
||||
return executeCommonFlow(ctx, config, packageManager, args)
|
||||
}
|
||||
Reference in New Issue
Block a user