[BACK]Return to mkvarusechecker.go CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / pkgsrc / pkgtools / pkglint / files

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /pkgsrc/pkgtools/pkglint/files/Attic/mkvarusechecker.go between version 1.2 and 1.8

version 1.2, 2019/12/08 22:03:38 version 1.8, 2020/03/15 11:31:24
Line 25  func (ck *MkVarUseChecker) Check(vuc *Va
Line 25  func (ck *MkVarUseChecker) Check(vuc *Va
         ck.checkUndefined()          ck.checkUndefined()
         ck.checkPermissions(vuc)          ck.checkPermissions(vuc)
   
         ck.checkVarname()          ck.checkVarname(vuc.time)
         ck.checkModifiers()          ck.checkModifiers()
           ck.checkAssignable(vuc)
         ck.checkQuoting(vuc)          ck.checkQuoting(vuc)
   
           ck.checkToolsPlatform()
         ck.checkBuildDefs()          ck.checkBuildDefs()
         ck.checkDeprecated()          ck.checkDeprecated()
           ck.checkPkgBuildOptions()
   
         NewMkLineChecker(ck.MkLines, ck.MkLine).          NewMkLineChecker(ck.MkLines, ck.MkLine).
                 checkTextVarUse(ck.use.varname, ck.vartype, vuc.time)                  checkTextVarUse(ck.use.varname, ck.vartype, vuc.time)
Line 42  func (ck *MkVarUseChecker) checkUndefine
Line 45  func (ck *MkVarUseChecker) checkUndefine
         varname := varuse.varname          varname := varuse.varname
   
         switch {          switch {
         case !G.Opts.WarnExtra,          case !G.WarnExtra,
                 // Well-known variables are probably defined by the infrastructure.                  // Well-known variables are probably defined by the infrastructure.
                 vartype != nil && !vartype.IsGuessed(),                  vartype != nil && !vartype.IsGuessed(),
                 // TODO: At load time, check ck.MkLines.loadVars instead of allVars.                  // TODO: At load time, check ck.MkLines.loadVars instead of allVars.
                 ck.MkLines.allVars.IsDefinedSimilar(varname),                  ck.MkLines.allVars.IsDefinedSimilar(varname),
                 ck.MkLines.forVars[varname],                  ck.MkLines.checkAllData.forVars[varname],
                 ck.MkLines.allVars.Mentioned(varname) != nil,                  ck.MkLines.allVars.Mentioned(varname) != nil,
                 G.Pkg != nil && G.Pkg.vars.IsDefinedSimilar(varname),                  ck.MkLines.pkg != nil && ck.MkLines.pkg.vars.IsDefinedSimilar(varname),
                 containsVarRef(varname),                  containsVarUse(varname),
                 G.Pkgsrc.vartypes.IsDefinedCanon(varname),                  G.Pkgsrc.vartypes.IsDefinedCanon(varname),
                 varname == "":                  varname == "":
                 return                  return
Line 130  func (ck *MkVarUseChecker) checkModifier
Line 133  func (ck *MkVarUseChecker) checkModifier
         fix.Apply()          fix.Apply()
 }  }
   
 func (ck *MkVarUseChecker) checkVarname() {  func (ck *MkVarUseChecker) checkVarname(time VucTime) {
         varname := ck.use.varname          varname := ck.use.varname
         if varname == "@" {          if varname == "@" {
                 ck.MkLine.Warnf("Please use %q instead of %q.", "${.TARGET}", "$@")                  ck.MkLine.Warnf("Please use %q instead of %q.", "${.TARGET}", "$@")
Line 139  func (ck *MkVarUseChecker) checkVarname(
Line 142  func (ck *MkVarUseChecker) checkVarname(
                         "of the same name.")                          "of the same name.")
         }          }
   
         if varname == "LOCALBASE" && !G.Infrastructure {          if varname == "LOCALBASE" && !G.Infrastructure && time == VucRunTime {
                 fix := ck.MkLine.Autofix()                  fix := ck.MkLine.Autofix()
                 fix.Warnf("Please use PREFIX instead of LOCALBASE.")                  fix.Warnf("Please use PREFIX instead of LOCALBASE.")
                 fix.ReplaceRegex(`\$\{LOCALBASE\b`, "${PREFIX", 1)                  fix.ReplaceAfter("${", "LOCALBASE", "PREFIX")
                 fix.Apply()                  fix.Apply()
         }          }
 }  }
Line 153  func (ck *MkVarUseChecker) checkVarname(
Line 156  func (ck *MkVarUseChecker) checkVarname(
 //  //
 // See checkVarassignLeftPermissions.  // See checkVarassignLeftPermissions.
 func (ck *MkVarUseChecker) checkPermissions(vuc *VarUseContext) {  func (ck *MkVarUseChecker) checkPermissions(vuc *VarUseContext) {
         if !G.Opts.WarnPerm {          if !G.WarnPerm {
                 return                  return
         }          }
         if G.Infrastructure {          if G.Infrastructure {
Line 200  func (ck *MkVarUseChecker) checkPermissi
Line 203  func (ck *MkVarUseChecker) checkPermissi
   
         effPerms := vartype.EffectivePermissions(basename)          effPerms := vartype.EffectivePermissions(basename)
         if effPerms.Contains(aclpUseLoadtime) {          if effPerms.Contains(aclpUseLoadtime) {
                 ck.checkUseAtLoadTime(vuc.time)                  if vuc.time == VucLoadTime {
                           ck.checkUseAtLoadTime()
                   }
   
                 // Since the variable may be used at load time, it probably                  // Since the variable may be used at load time, it probably
                 // may be used at run time as well. If it weren't, that would                  // may be used at run time as well. If it weren't, that would
Line 285  func (ck *MkVarUseChecker) warnPermissio
Line 290  func (ck *MkVarUseChecker) warnPermissio
         }          }
         alternativeFiles := vartype.AlternativeFiles(needed)          alternativeFiles := vartype.AlternativeFiles(needed)
   
         loadTimeExplanation := func() []string {          loadTimeExplanation := []string{
                 return []string{                  "Many variables, especially lists of something, get their values incrementally.",
                         "Many variables, especially lists of something, get their values incrementally.",                  "Therefore it is generally unsafe to rely on their",
                         "Therefore it is generally unsafe to rely on their",                  "value until it is clear that it will never change again.",
                         "value until it is clear that it will never change again.",                  "This point is reached when the whole package Makefile is loaded and",
                         "This point is reached when the whole package Makefile is loaded and",                  "execution of the shell commands starts; in some cases earlier.",
                         "execution of the shell commands starts; in some cases earlier.",                  "",
                         "",                  "Additionally, when using the \":=\" operator, each $$ is replaced",
                         "Additionally, when using the \":=\" operator, each $$ is replaced",                  "with a single $, so variables that have references to shell",
                         "with a single $, so variables that have references to shell",                  "variables or regular expressions are modified in a subtle way."}
                         "variables or regular expressions are modified in a subtle way."}  
         }  
   
         switch {          switch {
         case alternativeFiles == "" && directly:          case alternativeFiles == "" && directly:
                 mkline.Warnf("%s should not be used at load time in any file.", varname)                  mkline.Warnf("%s should not be used at load time in any file.", varname)
                 ck.explainPermissions(varname, vartype, loadTimeExplanation()...)                  ck.explainPermissions(varname, vartype, loadTimeExplanation...)
   
         case alternativeFiles == "":          case alternativeFiles == "":
                 mkline.Warnf("%s should not be used in any file.", varname)                  mkline.Warnf("%s should not be used in any file.", varname)
                 ck.explainPermissions(varname, vartype, loadTimeExplanation()...)                  ck.explainPermissions(varname, vartype, loadTimeExplanation...)
   
         case directly:          case directly:
                 mkline.Warnf(                  mkline.Warnf(
                         "%s should not be used at load time in this file; "+                          "%s should not be used at load time in this file; "+
                                 "it would be ok in %s.",                                  "it would be ok in %s.",
                         varname, alternativeFiles)                          varname, alternativeFiles)
                 ck.explainPermissions(varname, vartype, loadTimeExplanation()...)                  ck.explainPermissions(varname, vartype, loadTimeExplanation...)
   
         default:          default:
                 mkline.Warnf(                  mkline.Warnf(
Line 364  func (ck *MkVarUseChecker) explainPermis
Line 367  func (ck *MkVarUseChecker) explainPermis
         ck.MkLine.Explain(expl...)          ck.MkLine.Explain(expl...)
 }  }
   
 func (ck *MkVarUseChecker) checkUseAtLoadTime(time VucTime) {  func (ck *MkVarUseChecker) checkUseAtLoadTime() {
         if time != VucLoadTime {  
                 return  
         }  
         if ck.vartype.IsAlwaysInScope() || ck.MkLines.Tools.SeenPrefs {          if ck.vartype.IsAlwaysInScope() || ck.MkLines.Tools.SeenPrefs {
                 return                  return
         }          }
         if G.Pkg != nil && G.Pkg.seenPrefs {          if ck.MkLines.pkg != nil && ck.MkLines.pkg.seenPrefs {
                 return                  return
         }          }
         mkline := ck.MkLine          mkline := ck.MkLine
Line 380  func (ck *MkVarUseChecker) checkUseAtLoa
Line 380  func (ck *MkVarUseChecker) checkUseAtLoa
                 return                  return
         }          }
   
         if ck.vartype.IsPackageSettable() &&          if ck.vartype.IsPackageSettable() {
                 basename != "Makefile" && basename != "options.mk" {                  // For package-settable variables, the explanation below
                   // doesn't make sense since including bsd.prefs.mk won't
                 // For package-settable variables, the explanation doesn't                  // define any package-settable variables.
                 // make sense since it talks about completely different  
                 // types of variables.  
                 return                  return
         }          }
   
Line 419  func (ck *MkVarUseChecker) warnToolLoadT
Line 417  func (ck *MkVarUseChecker) warnToolLoadT
         //  to skip the shell and execute the commands via execve, which          //  to skip the shell and execute the commands via execve, which
         //  means that even echo is not a shell-builtin anymore.          //  means that even echo is not a shell-builtin anymore.
   
         // TODO: Replace "parse time" with "load time" everywhere.  
   
         if tool.Validity == AfterPrefsMk {          if tool.Validity == AfterPrefsMk {
                 ck.MkLine.Warnf("To use the tool ${%s} at load time, bsd.prefs.mk has to be included before.", varname)                  ck.MkLine.Warnf("To use the tool ${%s} at load time, bsd.prefs.mk has to be included before.", varname)
                 return                  return
Line 452  func (ck *MkVarUseChecker) warnToolLoadT
Line 448  func (ck *MkVarUseChecker) warnToolLoadT
                 "except in the package Makefile itself.")                  "except in the package Makefile itself.")
 }  }
   
   func (ck *MkVarUseChecker) checkAssignable(vuc *VarUseContext) {
           leftType := vuc.vartype
           if leftType == nil || leftType.basicType != BtPathname {
                   return
           }
           rightType := G.Pkgsrc.VariableType(ck.MkLines, ck.use.varname)
           if rightType == nil || rightType.basicType != BtShellCommand {
                   return
           }
   
           mkline := ck.MkLine
           if mkline.Varcanon() == "PKG_SHELL.*" {
                   switch ck.use.varname {
                   case "SH", "BASH", "TOOLS_PLATFORM.sh":
                           return
                   }
           }
   
           mkline.Warnf(
                   "Incompatible types: %s (type %q) cannot be assigned to type %q.",
                   ck.use.varname, rightType.basicType.name, leftType.basicType.name)
           mkline.Explain(
                   "Shell commands often start with a pathname.",
                   "They could also start with a list of environment variable",
                   "definitions, since that is accepted by the shell.",
                   "They can also contain addition command line arguments",
                   "that are not filenames at all.")
   }
   
 // checkVarUseWords checks whether a variable use of the form ${VAR}  // checkVarUseWords checks whether a variable use of the form ${VAR}
 // or ${VAR:modifiers} is allowed in a certain context.  // or ${VAR:modifiers} is allowed in a certain context.
 func (ck *MkVarUseChecker) checkQuoting(vuc *VarUseContext) {  func (ck *MkVarUseChecker) checkQuoting(vuc *VarUseContext) {
         if !G.Opts.WarnQuoting || vuc.quoting == VucQuotUnknown {          if !G.WarnQuoting || vuc.quoting == VucQuotUnknown {
                 return                  return
         }          }
   
Line 475  func (ck *MkVarUseChecker) checkQuoting(
Line 500  func (ck *MkVarUseChecker) checkQuoting(
         // since the GNU configure scripts cannot handle these space characters.          // since the GNU configure scripts cannot handle these space characters.
         //          //
         // When doing checks outside a package, the :M* modifier is needed for safety.          // When doing checks outside a package, the :M* modifier is needed for safety.
         needMstar := (G.Pkg == nil || G.Pkg.vars.IsDefined("GNU_CONFIGURE")) &&          needMstar := (ck.MkLines.pkg == nil || ck.MkLines.pkg.vars.IsDefined("GNU_CONFIGURE")) &&
                 matches(varUse.varname, `^(?:.*_)?(?:CFLAGS|CPPFLAGS|CXXFLAGS|FFLAGS|LDFLAGS|LIBS)$`)                  matches(varUse.varname, `^(?:.*_)?(?:CFLAGS|CPPFLAGS|CXXFLAGS|FFLAGS|LDFLAGS|LIBS)$`)
   
         mkline := ck.MkLine          mkline := ck.MkLine
Line 504  func (ck *MkVarUseChecker) checkQuotingQ
Line 529  func (ck *MkVarUseChecker) checkQuotingQ
         if correctMod == mod+":Q" && vuc.IsWordPart && !vartype.IsShell() {          if correctMod == mod+":Q" && vuc.IsWordPart && !vartype.IsShell() {
   
                 isSingleWordConstant := func() bool {                  isSingleWordConstant := func() bool {
                         if G.Pkg == nil {                          if ck.MkLines.pkg == nil {
                                 return false                                  return false
                         }                          }
   
                         varinfo := G.Pkg.redundant.vars[varname]                          varinfo := ck.MkLines.pkg.redundant.vars[varname]
                         if varinfo == nil || !varinfo.vari.IsConstant() {                          if varinfo == nil || !varinfo.vari.IsConstant() {
                                 return false                                  return false
                         }                          }
Line 645  func (ck *MkVarUseChecker) warnRedundant
Line 670  func (ck *MkVarUseChecker) warnRedundant
         fix.Apply()          fix.Apply()
 }  }
   
   func (ck *MkVarUseChecker) checkToolsPlatform() {
           if ck.MkLine.IsDirective() {
                   return
           }
   
           varname := ck.use.varname
           if varnameCanon(varname) != "TOOLS_PLATFORM.*" {
                   return
           }
   
           indentation := ck.MkLines.indentation
           switch {
           case indentation.DependsOn("OPSYS"),
                   indentation.DependsOn("MACHINE_PLATFORM"),
                   indentation.DependsOn(varname):
                   // TODO: Only return if the conditional is on the correct OPSYS.
                   return
           }
   
           toolName := varnameParam(varname)
           tool := G.Pkgsrc.Tools.ByName(toolName)
           if tool == nil {
                   return
           }
   
           if len(tool.undefinedOn) > 0 {
                   ck.MkLine.Warnf("%s is undefined on %s.",
                           varname, joinCambridge("and", tool.undefinedOn...))
           } else if len(tool.conditionalOn) > 0 {
                   ck.MkLine.Warnf("%s may be undefined on %s.",
                           varname, joinCambridge("and", tool.conditionalOn...))
           }
   }
   
 func (ck *MkVarUseChecker) checkBuildDefs() {  func (ck *MkVarUseChecker) checkBuildDefs() {
         varname := ck.use.varname          varname := ck.use.varname
   
Line 680  func (ck *MkVarUseChecker) checkDeprecat
Line 739  func (ck *MkVarUseChecker) checkDeprecat
   
         ck.MkLine.Warnf("Use of %q is deprecated. %s", varname, instead)          ck.MkLine.Warnf("Use of %q is deprecated. %s", varname, instead)
 }  }
   
   func (ck *MkVarUseChecker) checkPkgBuildOptions() {
           pkg := ck.MkLines.pkg
           if pkg == nil {
                   return
           }
           varname := ck.use.varname
           if !hasPrefix(varname, "PKG_BUILD_OPTIONS.") {
                   return
           }
           param := varnameParam(varname)
           if pkg.seenPkgbase.Seen(param) {
                   return
           }
   
           ck.MkLine.Warnf("The PKG_BUILD_OPTIONS for %q are not available to this package.",
                   param)
           ck.MkLine.Explain(
                   "The variable parameter for PKG_BUILD_OPTIONS must correspond",
                   "to the value of \"pkgbase\" above.",
                   "",
                   "For more information, see mk/pkg-build-options.mk.")
   }

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.8

CVSweb <webmaster@jp.NetBSD.org>