github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/internal/runners/manifest/requirements.go (about)

     1  package manifest
     2  
     3  import (
     4  	"github.com/ActiveState/cli/internal/locale"
     5  	"github.com/ActiveState/cli/internal/output"
     6  	"github.com/ActiveState/cli/pkg/buildplan"
     7  	"github.com/ActiveState/cli/pkg/platform/api/buildplanner/types"
     8  	platformModel "github.com/ActiveState/cli/pkg/platform/model"
     9  )
    10  
    11  type requirement struct {
    12  	Name            string                      `json:"name"`
    13  	Namespace       string                      `json:"namespace,omitempty"`
    14  	ResolvedVersion *resolvedVersion            `json:"version"`
    15  	Vulnerabilities *requirementVulnerabilities `json:"vulnerabilities,omitempty"`
    16  }
    17  
    18  type requirements struct {
    19  	Requirements []*requirement `json:"requirements"`
    20  }
    21  
    22  func newRequirements(reqs []types.Requirement, bpReqs buildplan.Ingredients, vulns vulnerabilities) requirements {
    23  	var result []*requirement
    24  	for _, req := range reqs {
    25  		result = append(result, &requirement{
    26  			Name:            req.Name,
    27  			Namespace:       processNamespace(req.Namespace),
    28  			ResolvedVersion: resolveVersion(req, bpReqs),
    29  			Vulnerabilities: vulns.getVulnerability(req.Name, req.Namespace),
    30  		})
    31  	}
    32  
    33  	return requirements{Requirements: result}
    34  }
    35  
    36  func (o requirements) MarshalOutput(_ output.Format) interface{} {
    37  	type requirementOutput struct {
    38  		Name            string `locale:"manifest_name,Name"`
    39  		Version         string `locale:"manifest_version,Version"`
    40  		Vulnerabilities string `locale:"manifest_vulnerabilities,Vulnerabilities (CVEs)" opts:"omitEmpty"`
    41  		// Must be last of the output fields in order for our table renderer to include all the fields before it
    42  		Namespace string `locale:"manifest_namespace,Namespace" opts:"omitEmpty,separateLine"`
    43  	}
    44  
    45  	var requirementsOutput []*requirementOutput
    46  	for _, req := range o.Requirements {
    47  		requirementOutput := &requirementOutput{
    48  			Name:            locale.Tl("manifest_name", "[ACTIONABLE]{{.V0}}[/RESET]", req.Name),
    49  			Version:         req.ResolvedVersion.String(),
    50  			Vulnerabilities: req.Vulnerabilities.String(),
    51  		}
    52  
    53  		if req.Namespace != "" {
    54  			requirementOutput.Namespace = locale.Tl("manifest_namespace", " └─ [DISABLED]namespace:[/RESET] [CYAN]{{.V0}}[/RESET]", req.Namespace)
    55  		}
    56  
    57  		requirementsOutput = append(requirementsOutput, requirementOutput)
    58  	}
    59  
    60  	return struct {
    61  		Requirements []*requirementOutput `locale:"," opts:"hideDash"`
    62  	}{
    63  		Requirements: requirementsOutput,
    64  	}
    65  }
    66  
    67  func (o requirements) MarshalStructured(f output.Format) interface{} {
    68  	for _, req := range o.Requirements {
    69  		req.ResolvedVersion.MarshalStructured(f)
    70  
    71  		if req.Vulnerabilities != nil && !req.Vulnerabilities.authenticated {
    72  			req.Vulnerabilities = nil
    73  		}
    74  	}
    75  
    76  	return o
    77  }
    78  
    79  func processNamespace(namespace string) string {
    80  	if !isCustomNamespace(namespace) {
    81  		return ""
    82  	}
    83  
    84  	return namespace
    85  }
    86  
    87  func isCustomNamespace(ns string) bool {
    88  	supportedNamespaces := []platformModel.NamespaceType{
    89  		platformModel.NamespacePackage,
    90  		platformModel.NamespaceBundle,
    91  		platformModel.NamespaceLanguage,
    92  	}
    93  
    94  	for _, n := range supportedNamespaces {
    95  		if platformModel.NamespaceMatch(ns, n.Matchable()) {
    96  			return false
    97  		}
    98  	}
    99  
   100  	return true
   101  }