summaryrefslogtreecommitdiff
path: root/pkgtools/pkglint/files/alternatives.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkgtools/pkglint/files/alternatives.go')
-rw-r--r--pkgtools/pkglint/files/alternatives.go84
1 files changed, 58 insertions, 26 deletions
diff --git a/pkgtools/pkglint/files/alternatives.go b/pkgtools/pkglint/files/alternatives.go
index 3fd6397a7ec..d7485f4d13e 100644
--- a/pkgtools/pkglint/files/alternatives.go
+++ b/pkgtools/pkglint/files/alternatives.go
@@ -1,8 +1,11 @@
package pkglint
-import "strings"
+import (
+ "netbsd.org/pkglint/textproc"
+ "strings"
+)
-func CheckfileAlternatives(filename string) {
+func CheckFileAlternatives(filename string) {
lines := Load(filename, NotEmpty|LogErrors)
if lines == nil {
return
@@ -13,35 +16,64 @@ func CheckfileAlternatives(filename string) {
plist = G.Pkg.Plist
}
+ checkPlistWrapper := func(line Line, wrapper string) {
+ if plist.Files[wrapper] {
+ line.Errorf("Alternative wrapper %q must not appear in the PLIST.", wrapper)
+ }
+ }
+
+ checkPlistAlternative := func(line Line, alternative string) {
+ relImplementation := strings.Replace(alternative, "@PREFIX@/", "", 1)
+ plistName := replaceAll(relImplementation, `@(\w+)@`, "${$1}")
+ if plist.Files[plistName] || G.Pkg.vars.Defined("ALTERNATIVES_SRC") {
+ return
+ }
+
+ switch {
+
+ case hasPrefix(alternative, "/"):
+ // It's possible but unusual to refer to a fixed absolute path.
+ // These cannot be mentioned in the PLIST since they are not part of the package.
+ break
+
+ case plistName == alternative:
+ line.Errorf("Alternative implementation %q must appear in the PLIST.", alternative)
+
+ default:
+ line.Errorf("Alternative implementation %q must appear in the PLIST as %q.", alternative, plistName)
+ }
+ }
+
for _, line := range lines.Lines {
- if m, wrapper, space, alternative := match3(line.Text, `^([^\t ]+)([ \t]+)([^\t ]+)`); m {
- if plist.Files != nil {
- if plist.Files[wrapper] {
- line.Errorf("Alternative wrapper %q must not appear in the PLIST.", wrapper)
- }
-
- relImplementation := strings.Replace(alternative, "@PREFIX@/", "", 1)
- plistName := replaceAll(relImplementation, `@(\w+)@`, "${$1}")
- if !plist.Files[plistName] && !G.Pkg.vars.Defined("ALTERNATIVES_SRC") {
- if plistName != alternative {
- line.Errorf("Alternative implementation %q must appear in the PLIST as %q.", alternative, plistName)
- } else {
- line.Errorf("Alternative implementation %q must appear in the PLIST.", alternative)
- }
- }
- }
+ m, wrapper, space, alternative := match3(line.Text, `^([^\t ]+)([ \t]+)([^\t ]+)$`)
+ if !m {
+ line.Errorf("Invalid line %q.", line.Text)
+ G.Explain(
+ sprintf("Run %q for more information.", makeHelp("alternatives")))
+ continue
+ }
+
+ if plist.Files != nil {
+ checkPlistWrapper(line, wrapper)
+ checkPlistAlternative(line, alternative)
+ }
+
+ switch {
+ case hasPrefix(alternative, "/"), hasPrefix(alternative, "@"):
+ break
+ case textproc.NewLexer(alternative).NextByteSet(textproc.Alnum) != -1:
fix := line.Autofix()
- fix.Notef("@PREFIX@/ can be omitted from the filename.")
+ fix.Errorf("Alternative implementation %q must be an absolute path.", alternative)
fix.Explain(
- "The alternative implementation is always interpreted relative to",
- "${PREFIX}.")
- fix.ReplaceAfter(space, "@PREFIX@/", "")
+ "It usually starts with @PREFIX@/... to refer to a path inside the installation prefix.")
+ fix.ReplaceAfter(space, alternative, "@PREFIX@/"+alternative)
fix.Apply()
- } else {
- line.Errorf("Invalid ALTERNATIVES line %q.", line.Text)
- G.Explain(
- sprintf("Run %q for more information.", makeHelp("alternatives")))
+
+ default:
+ line.Errorf("Alternative implementation %q must be an absolute path.", alternative)
+ line.Explain(
+ "It usually starts with @PREFIX@/... to refer to a path inside the installation prefix.")
}
}
}