github.com/devseccon/trivy@v0.47.1-0.20231123133102-bd902a0bd996/pkg/licensing/expression/types.go (about)

     1  package expression
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"golang.org/x/exp/slices"
     7  
     8  	"github.com/devseccon/trivy/pkg/licensing"
     9  )
    10  
    11  var versioned = []string{
    12  	licensing.AGPL10,
    13  	licensing.AGPL30,
    14  	licensing.GFDL11WithInvariants,
    15  	licensing.GFDL11NoInvariants,
    16  	licensing.GFDL11,
    17  	licensing.GFDL12WithInvariants,
    18  	licensing.GFDL12NoInvariants,
    19  	licensing.GFDL12,
    20  	licensing.GFDL13WithInvariants,
    21  	licensing.GFDL13NoInvariants,
    22  	licensing.GFDL13,
    23  	licensing.GPL10,
    24  	licensing.GPL20,
    25  	licensing.GPL30,
    26  	licensing.LGPL20,
    27  	licensing.LGPL21,
    28  	licensing.LGPL30,
    29  }
    30  
    31  type Expression interface {
    32  	String() string
    33  }
    34  
    35  type Token struct {
    36  	token   int
    37  	literal string
    38  }
    39  
    40  type SimpleExpr struct {
    41  	license string
    42  	hasPlus bool
    43  }
    44  
    45  func (s SimpleExpr) String() string {
    46  	if slices.Contains(versioned, s.license) {
    47  		if s.hasPlus {
    48  			// e.g. AGPL-1.0-or-later
    49  			return s.license + "-or-later"
    50  		}
    51  		// e.g. GPL-1.0-only
    52  		return s.license + "-only"
    53  	}
    54  
    55  	if s.hasPlus {
    56  		return s.license + "+"
    57  	}
    58  	return s.license
    59  }
    60  
    61  type CompoundExpr struct {
    62  	left        Expression
    63  	conjunction Token
    64  	right       Expression
    65  }
    66  
    67  func (c CompoundExpr) String() string {
    68  	left := c.left.String()
    69  	if l, ok := c.left.(CompoundExpr); ok {
    70  		// e.g. (A OR B) AND C
    71  		if c.conjunction.token > l.conjunction.token {
    72  			left = fmt.Sprintf("(%s)", left)
    73  		}
    74  	}
    75  	right := c.right.String()
    76  	if r, ok := c.right.(CompoundExpr); ok {
    77  		// e.g. A AND (B OR C)
    78  		if c.conjunction.token > r.conjunction.token {
    79  			right = fmt.Sprintf("(%s)", right)
    80  		}
    81  	}
    82  	return fmt.Sprintf("%s %s %s", left, c.conjunction.literal, right)
    83  }