Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Licences are now SPDX expressions #3225

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ genrule(
# Plugin versions to pull the docs from
plugins = {
"python": "v1.7.0",
"java": "v0.4.0",
"go": "v1.20.1",
"java": "v0.4.1",
"go": "v1.21.1",
"cc": "v0.4.0",
"shell": "v0.2.0",
"go-proto": "v0.3.0",
Expand Down
78 changes: 78 additions & 0 deletions docs/lexicon.html
Original file line number Diff line number Diff line change
Expand Up @@ -951,6 +951,9 @@ <h3 class="title-3" id="add_licence">
Adds a new licence to a target. The assumption (as usual) is that if
multiple are added, they are options, so any one can be accepted.
</p>
<p>
Deprecated in favour of <code>set_licence</code>.
</p>

<div class="overflow-x-auto">
<table class="table">
Expand Down Expand Up @@ -980,6 +983,45 @@ <h3 class="title-3" id="add_licence">
</div>
</section>

<section class="mt4">
<h3 class="title-3" id="set_licence">
set_licence
</h3>

<code class="code-signature">set_licence(target, licence)</code>

<p>
Sets the target's licence to the given SPDX expression. Note that no normalisation is done on it.
</p>

<div class="overflow-x-auto">
<table class="table">
<thead>
<tr>
<th>Argument</th>
<th>Default</th>
<th>Type</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>target</td>
<td></td>
<td>str</td>
<td>Label of the target to add the licence to.</td>
</tr>
<tr>
<td>licence</td>
<td></td>
<td>str</td>
<td>SPDX expression defining licensing of the target</td>
</tr>
</tbody>
</table>
</div>
</section>

<section class="mt4">
<h3 class="title-3" id="get_licences">
get_licences
Expand All @@ -990,6 +1032,9 @@ <h3 class="title-3" id="get_licences">
<p>
Returns all the licences that are currently known to apply to a target.
</p>
<p>
Deprecated in favour of get_licence.
</p>

<div class="overflow-x-auto">
<table class="table">
Expand All @@ -1013,6 +1058,39 @@ <h3 class="title-3" id="get_licences">
</div>
</section>

<section class="mt4">
<h3 class="title-3" id="get_licence">
get_licence
</h3>

<code class="code-signature">get_licence(target)</code>

<p>
Returns the licence expression of the given target.
</p>

<div class="overflow-x-auto">
<table class="table">
<thead>
<tr>
<th>Argument</th>
<th>Default</th>
<th>Type</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>target</td>
<td></td>
<td>str</td>
<td>Label of the target to get the licence expression for.</td>
</tr>
</tbody>
</table>
</div>
</section>

<section class="mt4">
<h3 class="title-3" id="package">
package
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/chzyer/readline v1.5.1 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/github/go-spdx/v2 v2.3.1 // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
Expand All @@ -85,6 +86,7 @@ require (
github.com/mostynb/zstdpool-syncpool v0.0.13 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/pborman/uuid v1.2.1 // indirect
github.com/peterebden/go-spdx/v2 v2.4.3 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
Expand Down
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/github/go-spdx/v2 v2.3.1 h1:ffGuHTbHuHzWPt53n8f9o8clGutuLPObo3zB4JAjxU8=
github.com/github/go-spdx/v2 v2.3.1/go.mod h1:2ZxKsOhvBp+OYBDlsGnUMcchLeo2mrpEBn2L1C+U3IQ=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
Expand Down Expand Up @@ -187,6 +189,12 @@ github.com/peterebden/go-cli-init/v5 v5.2.1 h1:o+7EjS/PiYDvFUQRQVXJRjinmUzDjqcea
github.com/peterebden/go-cli-init/v5 v5.2.1/go.mod h1:0eBDoCJjj3BWyEtidFcP0TlD14cRtOtLCrTG/OVPB74=
github.com/peterebden/go-deferred-regex v1.1.0 h1:XNpUuRDU7iU59Toy+OJp9LUvsun5i3kEbe3c73oyCZg=
github.com/peterebden/go-deferred-regex v1.1.0/go.mod h1:EhIu4zsN+60671cx29rzxPSIEnDd2vOia4RFSOaYpRI=
github.com/peterebden/go-spdx/v2 v2.4.1 h1:ah4SjMgKyFXqR5qkBGwKbtevTV3UK3+17OiPNw18GVM=
github.com/peterebden/go-spdx/v2 v2.4.1/go.mod h1:6KrhEd9kpULcLYV6rGkV47Rolvt2IFcaRCyewNnLkLA=
github.com/peterebden/go-spdx/v2 v2.4.2 h1:u+lPJXPPK1cJpCtDQBlUgu/cXgOg/dYUWKHUyHxakYI=
github.com/peterebden/go-spdx/v2 v2.4.2/go.mod h1:6KrhEd9kpULcLYV6rGkV47Rolvt2IFcaRCyewNnLkLA=
github.com/peterebden/go-spdx/v2 v2.4.3 h1:iiOEYy8+qvyTA3IBqVgLGpwTl5MAmU0Ej39w+8xr5gQ=
github.com/peterebden/go-spdx/v2 v2.4.3/go.mod h1:6KrhEd9kpULcLYV6rGkV47Rolvt2IFcaRCyewNnLkLA=
github.com/peterebden/go-sri v1.1.1 h1:KK8yZ5/NX8YzWUY9QvhrP220QsvEKANLLAgvw35AkyU=
github.com/peterebden/go-sri v1.1.1/go.mod h1:KIRxtog35NfDWec5LV/iBqqfOEPcMpePZLc7EPE6goQ=
github.com/peterebden/tools v0.0.0-20190805132753-b2a0db951d2a h1:R4xz7BkSIQOS5CFmaadk2gwwOzy/u2Jvnimf1NHD2LY=
Expand Down
4 changes: 4 additions & 0 deletions rules/builtins.build_defs
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,12 @@ def add_entry_point(target:str, name:str, out:str):
def get_entry_points(target:str) -> dict:
pass
def add_licence(target:str, licence:str):
"""Deprecated in favour of set_licence"""
def set_licence(target:str, licence: str):
pass
def get_licences(target:str):
"""Deprecated in favour of get_licence"""
def get_licence(target:str):
pass
def get_command(target:str, config:str=''):
pass
Expand Down
8 changes: 2 additions & 6 deletions src/build/build_step_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,22 +290,18 @@ func TestLicenceEnforcement(t *testing.T) {

// A license (non case sensitive) that is not in the list of accepted licenses will panic.
assert.Panics(t, func() {
target.Licences = append(target.Licences, "Bsd")
target.Licence = "Bsd"
checkLicences(state, target)
}, "A target with a non-accepted licence will panic")

// Accepting bsd should resolve the panic
state.Config.Licences.Accept = append(state.Config.Licences.Accept, "BSD")
checkLicences(state, target)

// Now construct a new "bad" target.
state, target = newState("//pkg:bad")
state.Config.Licences.Reject = append(state.Config.Licences.Reject, "gpl")
state.Config.Licences.Accept = append(state.Config.Licences.Accept, "mit")

// Adding an explicitly rejected licence should panic no matter what.
target.Licences = append(target.Licences, "GPL")
assert.Panics(t, func() {
target.Licence = "GPL"
checkLicences(state, target)
}, "Trying to add GPL should panic (case insensitive)")
}
Expand Down
5 changes: 1 addition & 4 deletions src/build/incrementality.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,7 @@ func ruleHash(state *core.BuildState, target *core.BuildTarget, runtime bool) []
h.Write([]byte(out))
}
}
for _, licence := range target.Licences {
h.Write([]byte(licence))
}

h.Write([]byte(target.Licence))
for _, output := range target.OptionalOutputs {
h.Write([]byte(output))
}
Expand Down
2 changes: 1 addition & 1 deletion src/build/incrementality_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ var KnownFields = map[string]bool{
"PostBuildHash": true,
"outputs": true,
"namedOutputs": true,
"Licences": true,
"Licence": true,
"Sandbox": true,
"Tools": true,
"namedTools": true,
Expand Down
1 change: 1 addition & 0 deletions src/core/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ go_library(
"///third_party/go/github.com_coreos_go-semver//semver",
"///third_party/go/github.com_google_shlex//:shlex",
"///third_party/go/github.com_peterebden_go-deferred-regex//:go-deferred-regex",
"///third_party/go/github.com_peterebden_go-spdx_v2//spdxexp",
"///third_party/go/github.com_pkg_xattr//:xattr",
"///third_party/go/github.com_please-build_gcfg//:gcfg",
"///third_party/go/github.com_please-build_gcfg//types",
Expand Down
41 changes: 11 additions & 30 deletions src/core/build_target.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"sync/atomic"
"time"

"github.com/peterebden/go-spdx/v2/spdxexp"
"golang.org/x/sync/errgroup"

"github.com/thought-machine/please/src/fs"
Expand Down Expand Up @@ -152,8 +153,8 @@ type BuildTarget struct {
// Acceptable hashes of the outputs of this rule. If the output doesn't match any of these
// it's an error at build time. Can be used to validate third-party deps.
Hashes []string
// Licences that this target is subject to.
Licences []string
// SPDX licence expression that this target is subject to.
Licence string
// Any secrets that this rule requires.
// Secrets are similar to sources but are always absolute system paths and affect the hash
// differently; they are not used to determine the hash for retrieving a file from cache, but
Expand Down Expand Up @@ -1764,17 +1765,6 @@ func (target *BuildTarget) insert(sl []string, s string) []string {
return append(sl, s)
}

// AddLicence adds a licence to the target if it's not already there.
func (target *BuildTarget) AddLicence(licence string) {
licence = strings.TrimSpace(licence)
for _, l := range target.Licences {
if l == licence {
return
}
}
target.Licences = append(target.Licences, licence)
}

// AddHash adds a new acceptable hash to the target.
func (target *BuildTarget) AddHash(hash string) {
target.Hashes = append(target.Hashes, hash)
Expand Down Expand Up @@ -1898,27 +1888,18 @@ func (target *BuildTarget) PackageDir() string {
}

// CheckLicences checks the target's licences against the accepted/rejected list.
// It returns the licence that was accepted and an error if it did not match.
// It returns the licence expression that was accepted and an error if it did not match.
func (target *BuildTarget) CheckLicences(config *Configuration) (string, error) {
if len(target.Licences) == 0 {
if target.Licence == "" || (len(config.Licences.Accept) == 0 && len(config.Licences.Reject) == 0) {
return "", nil
}
for _, licence := range target.Licences {
for _, reject := range config.Licences.Reject {
if strings.EqualFold(reject, licence) {
return "", fmt.Errorf("Target %s is licensed %s, which is explicitly rejected for this repository", target.Label, licence)
}
}
for _, accept := range config.Licences.Accept {
if strings.EqualFold(accept, licence) {
return licence, nil // Note licences are assumed to be an 'or', ie. any one of them can be accepted.
}
}
}
if len(config.Licences.Accept) > 0 {
return "", fmt.Errorf("None of the licences for %s are accepted in this repository: %s", target.Label, strings.Join(target.Licences, ", "))
accepted, err := spdxexp.ExpressionSatisfies(target.Licence, config.AcceptedLicences())
if err != nil {
return "", fmt.Errorf("Target %s has invalid licence '%s': %s", target, target.Licence, err)
} else if accepted == "" {
return "", fmt.Errorf("The licences for %s are not accepted in this repository: %s", target, target.Licence)
}
return "", nil
return accepted, nil
}

// BuildTargets makes a slice of build targets sortable by their labels.
Expand Down
11 changes: 8 additions & 3 deletions src/core/build_target_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -954,19 +954,24 @@ func TestIsTool(t *testing.T) {

func TestCheckLicences(t *testing.T) {
config := DefaultConfiguration()
config.Licences.Accept = []string{"BSD"}
config.Licences.Accept = []string{"BSD", "Apache-2.0"}
config.Licences.Reject = []string{"GPL"}

target := makeTarget1("//src/core/test_data/project", "PUBLIC")
target.Licences = []string{"BSD", "GPL"}
target.Licence = "BSD OR GPL"
accepted, err := target.CheckLicences(config)
assert.NoError(t, err)
assert.Equal(t, "BSD", accepted)

target.Licences = []string{"MIT", "GPL"}
target.Licence = "MIT OR GPL"
accepted, err = target.CheckLicences(config)
assert.Error(t, err)
assert.Equal(t, "", accepted)

target.Licence = "BSD AND Apache-2.0 OR GPL"
accepted, err = target.CheckLicences(config)
assert.NoError(t, err)
assert.Equal(t, "BSD AND Apache-2.0", accepted)
}

func makeTarget1(label, visibility string, deps ...*BuildTarget) *BuildTarget {
Expand Down
Loading
Loading