diff options
Diffstat (limited to 'pkgtools/pkglint/files/alternatives.go')
-rw-r--r-- | pkgtools/pkglint/files/alternatives.go | 84 |
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.") } } } |