summaryrefslogtreecommitdiff
path: root/pkgtools/pkglint/files/licenses.go
blob: 56f1590792106eb8622d07b797922b2f9d811cb4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package pkglint

import "netbsd.org/pkglint/licenses"

type LicenseChecker struct {
	MkLines *MkLines
	MkLine  *MkLine
}

func (lc *LicenseChecker) Check(value string, op MkOperator) {
	expanded := resolveVariableRefs(lc.MkLines, value) // For ${PERL5_LICENSE}
	cond := licenses.Parse(condStr(op == opAssignAppend, "append-placeholder ", "") + expanded)

	if cond == nil {
		if op == opAssign {
			lc.MkLine.Errorf("Parse error for license condition %q.", value)
		} else {
			lc.MkLine.Errorf("Parse error for appended license condition %q.", value)
		}
		return
	}

	cond.Walk(lc.checkNode)
}

func (lc *LicenseChecker) checkName(license string) {
	licenseFile := NewPath("")
	if G.Pkg != nil {
		if mkline := G.Pkg.vars.FirstDefinition("LICENSE_FILE"); mkline != nil {
			licenseFile = G.Pkg.File(mkline.ResolveVarsInRelativePath(NewPath(mkline.Value())))
		}
	}
	if licenseFile == "" {
		licenseFile = G.Pkgsrc.File("licenses").JoinNoClean(NewPath(license))
		G.InterPackage.UseLicense(license)
	}

	if !licenseFile.IsFile() {
		lc.MkLine.Warnf("License file %s does not exist.",
			lc.MkLine.PathToFile(licenseFile))
	}

	switch license {
	case "fee-based-commercial-use",
		"no-commercial-use",
		"no-profit",
		"no-redistribution",
		"shareware":
		lc.MkLine.Errorf("License %q must not be used.", license)
		lc.MkLine.Explain(
			"Instead of using these deprecated licenses, extract the actual",
			"license from the package into the pkgsrc/licenses/ directory",
			"and define LICENSE to that filename.",
			"",
			seeGuide("Handling licenses", "handling-licenses"))
	}
}

func (lc *LicenseChecker) checkNode(cond *licenses.Condition) {
	if name := cond.Name; name != "" && name != "append-placeholder" {
		lc.checkName(name)
		return
	}

	if cond.And && cond.Or {
		lc.MkLine.Errorf("AND and OR operators in license conditions can only be combined using parentheses.")
		lc.MkLine.Explain(
			"Examples for valid license conditions are:",
			"",
			"\tlicense1 AND license2 AND (license3 OR license4)",
			"\t(((license1 OR license2) AND (license3 OR license4)))")
	}
}