Skip to content

Commit

Permalink
Merge pull request #32 from interlynk-io/fix/drymode
Browse files Browse the repository at this point in the history
fix dry mode
  • Loading branch information
viveksahu26 authored Feb 10, 2025
2 parents a707c90 + 7b4da1a commit 882d023
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 53 deletions.
28 changes: 16 additions & 12 deletions pkg/engine/transfer.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func TransferRun(ctx context.Context, cmd *cobra.Command, config mvtypes.Config)
if config.DryRun {
logger.LogDebug(transferCtx.Context, "Dry-run mode enabled: Displaying retrieved SBOMs", "values", config.DryRun)

if err := dryMode(transferCtx.Context, sbomIterator); err != nil {
if err := dryMode(transferCtx.Context, sbomIterator, ""); err != nil {
return fmt.Errorf("failed to execute dry-run mode: %v", err)
}
return nil
Expand All @@ -93,35 +93,39 @@ func TransferRun(ctx context.Context, cmd *cobra.Command, config mvtypes.Config)
return nil
}

func dryMode(ctx context.Context, iterator iterator.SBOMIterator) error {
logger.LogDebug(ctx, "Dry-run mode enabled. Preparing to print SBOM details.")
func dryMode(ctx context.Context, iterator iterator.SBOMIterator, outputDir string) error {
logger.LogDebug(ctx, "Dry-run mode enabled. Preparing to display SBOM details.")

processor := sbom.NewSBOMProcessor("", false)
processor := sbom.NewSBOMProcessor(outputDir, false) // No need for output directory in dry-run mode
sbomCount := 0

logger.LogDebug(ctx, "Processing SBOMs in dry-run mode")

for {
sbom, err := iterator.Next(ctx)
if err == io.EOF {
break // no more sboms
break // No more SBOMs
}

if err != nil {
logger.LogError(ctx, err, "Error retrieving SBOM from iterator")
continue
}

logger.LogDebug(ctx, "Processing SBOM file", "path", sbom.Path)
logger.LogDebug(ctx, "Processing SBOM from memory", "repo", sbom.Repo, "version", sbom.Version)

doc, err := processor.ProcessSBOM(sbom.Path)
doc, err := processor.ProcessSBOMs(sbom.Data, sbom.Repo)
if err != nil {
logger.LogError(ctx, err, "Failed to process SBOM", "path", sbom.Path)
logger.LogError(ctx, err, "Failed to process SBOM")
continue
}

// If outputDir is provided, save the SBOM file
if outputDir != "" {
if err := processor.WriteSBOM(doc, sbom.Repo); err != nil {
logger.LogError(ctx, err, "Failed to write SBOM to output directory")
}
}

sbomCount++
logger.LogDebug(ctx, "%d. File: %s | Format: %s | SpecVersion: %s\n", sbomCount, doc.Filename, doc.Format, doc.SpecVersion)
logger.LogDebug(ctx, fmt.Sprintf("%d. Repo: %s | Format: %s | SpecVersion: %s", sbomCount, sbom.Repo, doc.Format, doc.SpecVersion))
}

logger.LogDebug(ctx, "Dry-run mode completed", "total_sboms_processed", sbomCount)
Expand Down
71 changes: 30 additions & 41 deletions pkg/sbom/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@
package sbom

import (
"context"
"encoding/json"
"encoding/xml"
"errors"
"fmt"
"os"
"path/filepath"
"strings"

"github.com/interlynk-io/sbommv/pkg/logger"
)

// SBOMFormat represents supported SBOM document formats
Expand Down Expand Up @@ -60,52 +63,47 @@ func NewSBOMProcessor(outputDir string, verbose bool) *SBOMProcessor {
}
}

// ProcessSBOMs processes multiple SBOM files
func (p *SBOMProcessor) ProcessSBOMs(filenames []string) ([]SBOMDocument, error) {
var documents []SBOMDocument
var errs []error
// ProcessSBOMFromBytes processes an SBOM directly from memory
func (p *SBOMProcessor) ProcessSBOMs(content []byte, repoName string) (SBOMDocument, error) {
if len(content) == 0 {
return SBOMDocument{}, errors.New("empty SBOM content")
}

for _, filename := range filenames {
doc, err := p.ProcessSBOM(filename)
if err != nil {
errs = append(errs, fmt.Errorf("processing %s: %w", filename, err))
continue
}
documents = append(documents, doc)
doc := SBOMDocument{
Filename: fmt.Sprintf("%s.sbom.json", repoName), // Use repo name as filename
Content: content,
}

if len(errs) > 0 {
return documents, fmt.Errorf("encountered %d errors: %v", len(errs), errs[0])
// Detect format and parse content
if err := p.detectAndParse(&doc); err != nil {
return doc, fmt.Errorf("detecting format: %w", err)
}

return documents, nil
return doc, nil
}

// ProcessSBOM processes a single SBOM file
func (p *SBOMProcessor) ProcessSBOM(filename string) (SBOMDocument, error) {
content, err := os.ReadFile(filename)
if err != nil {
return SBOMDocument{}, fmt.Errorf("reading file: %w", err)
// WriteSBOM writes an SBOM to the output directory
func (p *SBOMProcessor) WriteSBOM(doc SBOMDocument, repoName string) error {
if p.outputDir == "" {
return nil // No output directory specified, skip writing
}

doc := SBOMDocument{
Filename: filename,
Content: content,
}
// Construct full path: sboms/<org>/<repo>.sbom.json
outputPath := filepath.Join(p.outputDir, repoName+".sbom.json")
outputDir := filepath.Dir(outputPath) // Extract directory path

// Detect format and parse content
if err := p.detectAndParse(&doc); err != nil {
return doc, fmt.Errorf("detecting format: %w", err)
// Ensure all parent directories exist
if err := os.MkdirAll(outputDir, 0o755); err != nil {
return fmt.Errorf("creating output directory: %w", err)
}

// Write processed document if output directory is specified
if p.outputDir != "" {
if err := p.writeProcessedSBOM(doc); err != nil {
return doc, fmt.Errorf("writing output: %w", err)
}
// Write SBOM file
if err := os.WriteFile(outputPath, doc.Content, 0o644); err != nil {
return fmt.Errorf("writing SBOM file: %w", err)
}

return doc, nil
logger.LogDebug(context.Background(), "SBOM successfully written", "path", outputPath)
return nil
}

// detectAndParse detects the SBOM format and parses its content
Expand Down Expand Up @@ -136,15 +134,6 @@ func (p *SBOMProcessor) detectAndParse(doc *SBOMDocument) error {
return errors.New("unknown SBOM format")
}

func (p *SBOMProcessor) writeProcessedSBOM(doc SBOMDocument) error {
if err := os.MkdirAll(p.outputDir, 0o755); err != nil {
return fmt.Errorf("creating output directory: %w", err)
}

outPath := filepath.Join(p.outputDir, filepath.Base(doc.Filename))
return os.WriteFile(outPath, doc.Content, 0o644)
}

// Helper functions to detect formats
func isJSON(content []byte) bool {
var js json.RawMessage
Expand Down

0 comments on commit 882d023

Please sign in to comment.