spdx

package
v0.5.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 7, 2026 License: Apache-2.0 Imports: 4 Imported by: 0

Documentation

Overview

Package spdx validates and canonicalizes SPDX license expressions for the grc.store publication-license field (ADR-0036).

(The package lives at spdx/ rather than license/ because the module's case-insensitive checkout cannot hold both a license/ directory and the top-level LICENSE file.)

A publisher declares a publication license at publish time; grcli stamps it as the OCI manifest annotation org.opencontainers.image.licenses and the hub reads it back. Both ends must agree on what a valid license is and on its canonical spelling, or the index fragments (Apache-2.0 vs apache-2.0 vs ASL2 as three "licenses"). This package is that one shared definition.

The two ends use it differently, by design (ADR-0036 decision 4):

  • grcli is the STRICT gate. It calls Canonicalize and hard-fails the publish before any network call on a malformed expression OR an unknown leaf id — so typos never reach the registry.
  • The hub is LENIENT. It calls Parse (syntax only) and stores Expression.String() — the structurally-canonicalized form, with known ids re-cased but unknown-but-well-formed ids passed through unchanged. It never rejects a sync over the license field: a publisher on a newer SPDX list than the hub must not have their already-pushed bytes orphaned. A malformed annotation parses with an error and the hub stores NULL.

Canonicalization (String) is what protects the index, not rejection: it collapses divergent spellings of the SAME license regardless of which path ran.

SPDX grammar supported: simple ids, the "or-later" "+" suffix, "WITH" exception, "AND"/"OR" (OR binds loosest), parentheses, and LicenseRef-/DocumentRef- custom identifiers. Operators are case-sensitive uppercase per the SPDX spec.

STABILITY: the canonical OUTPUT of String for a given input is contract — two importers on the same SPDXListVersion must produce byte-identical output. Bumping SPDXListVersion is additive (it can only make a previously-unknown id known, never change a known id's canonical casing), so it is a minor release; any change that alters String's output for an already-known id is BREAKING.

Index

Constants

View Source
const SPDXListVersion = "3.28.0"

SPDXListVersion is the SPDX license-list-data release the bundled id tables below were generated from.

Variables

View Source
var ErrSyntax = errors.New("malformed SPDX license expression")

ErrSyntax means the string is not a well-formed SPDX license expression (the grammar is violated). The hub treats this as "no license" (store NULL).

View Source
var ErrUnknownID = errors.New("unknown SPDX license or exception id")

ErrUnknownID means the expression is well-formed but contains a license or exception id not in SPDXListVersion's list (excluding LicenseRef-/DocumentRef-, which are custom by definition). grcli treats this as fatal; the hub does not.

Functions

func Canonicalize

func Canonicalize(expr string) (string, error)

Canonicalize is the strict entry point (grcli's gate). It returns the canonical form of a well-formed expression whose every leaf id is known to SPDXListVersion, or an error wrapping ErrSyntax / ErrUnknownID otherwise.

Types

type Expression

type Expression struct {
	// contains filtered or unexported fields
}

Expression is a parsed SPDX license expression. Its zero value is not usable; obtain one from Parse.

func Parse

func Parse(expr string) (*Expression, error)

Parse validates SPDX expression GRAMMAR only and returns the parsed expression. It does NOT fail on unrecognized (but well-formed) ids — call UnknownIDs to check those. This is the hub's lenient entry point: on success store String(); on error store NULL.

func (*Expression) String

func (e *Expression) String() string

String returns the canonical form: operators uppercased and single-spaced, known ids re-cased to their official SPDX spelling, "+" preserved, LicenseRef-/DocumentRef- preserved verbatim (those are case-sensitive), and the minimum parentheses needed to preserve OR/AND precedence.

func (*Expression) UnknownIDs

func (e *Expression) UnknownIDs() []string

UnknownIDs returns the sorted, de-duplicated set of leaf license and exception ids in the expression that are NOT in SPDXListVersion's list. LicenseRef- and DocumentRef- identifiers are never reported (they are custom by definition). Empty means every id is recognized.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL