repoman: Fix unsafe string interpolation.

"on line: %d" etc. is no longer included in messages returned from individual checks.
"line %d: " is now consistently added by controller directly after ebuild path
and precedes specific message.

Example:
   app-misc/test/test-0.ebuild: line 5: please migrate from 'games' (no replacement)
   app-misc/test/test-0.ebuild: line 5: please migrate from 'versionator' to 'eapi7-ver (built-in since EAPI 7)'
   app-misc/test/test-0.ebuild: line 10: Useless blank line
   app-misc/test/test-0.ebuild: line 20: 'econf' call should be moved to src_configure

Bug: https://bugs.gentoo.org/699508
Signed-off-by: Arfrever Frehtes Taifersar Arahesis <Arfrever@Apache.Org>
Signed-off-by: Zac Medico <zmedico@gentoo.org>
diff --git a/repoman/cnf/linechecks/linechecks.yaml b/repoman/cnf/linechecks/linechecks.yaml
index c452af0..410bcd9 100644
--- a/repoman/cnf/linechecks/linechecks.yaml
+++ b/repoman/cnf/linechecks/linechecks.yaml
@@ -9,27 +9,27 @@
 # configuration file for the LineCheck plugins run via the multicheck
 # scan module
 errors:
-    COPYRIGHT_ERROR: 'Invalid Copyright on line: %d'
-    LICENSE_ERROR: 'Invalid Gentoo/GPL License on line: %d'
-    ID_HEADER_ERROR: 'Stale CVS header on line: %d'
-    NO_BLANK_LINE_ERROR: 'Non-blank line after header on line: %d'
-    LEADING_SPACES_ERROR: 'Ebuild contains leading spaces on line: %d'
-    TRAILING_WHITESPACE_ERROR: 'Trailing whitespace error on line: %d'
-    READONLY_ASSIGNMENT_ERROR: 'Ebuild contains assignment to read-only variable on line: %d'
-    MISSING_QUOTES_ERROR: 'Unquoted Variable on line: %d'
-    NESTED_DIE_ERROR: 'Ebuild calls die in a subshell on line: %d'
-    PATCHES_ERROR: 'PATCHES is not a bash array on line: %d'
-    REDUNDANT_CD_S_ERROR: 'Ebuild has redundant cd ${S} statement on line: %d'
-    EMAKE_PARALLEL_DISABLED: 'Upstream parallel compilation bug (ebuild calls emake -j1 on line: %d)'
-    EMAKE_PARALLEL_DISABLED_VIA_MAKEOPTS: 'Upstream parallel compilation bug (MAKEOPTS=-j1 on line: %d)'
-    DEPRECATED_BINDNOW_FLAGS: 'Deprecated bindnow-flags call on line: %d'
-    EAPI_DEFINED_AFTER_INHERIT: 'EAPI defined after inherit on line: %d'
-    NO_AS_NEEDED: 'Upstream asneeded linking bug (no-as-needed on line: %d)'
-    PRESERVE_OLD_LIB: 'Ebuild calls deprecated preserve_old_lib on line: %d'
-    BUILT_WITH_USE: 'built_with_use on line: %d'
-    NO_OFFSET_WITH_HELPERS: 'Helper function is used with D, ROOT, ED, EROOT or EPREFIX on line: %d'
-    SANDBOX_ADDPREDICT: 'Ebuild calls addpredict on line: %d'
-    USEQ_ERROR: 'Ebuild calls deprecated useq function on line: %d'
-    HASQ_ERROR: 'Ebuild calls deprecated hasq function on line: %d'
-    URI_HTTPS: 'Ebuild uses http:// but should use https:// on line: %d'
+    COPYRIGHT_ERROR: 'Invalid Copyright'
+    LICENSE_ERROR: 'Invalid Gentoo/GPL License'
+    ID_HEADER_ERROR: 'Stale CVS header'
+    NO_BLANK_LINE_ERROR: 'Non-blank line after header'
+    LEADING_SPACES_ERROR: 'Ebuild contains leading spaces'
+    TRAILING_WHITESPACE_ERROR: 'Trailing whitespace error'
+    READONLY_ASSIGNMENT_ERROR: 'Ebuild contains assignment to read-only variable'
+    MISSING_QUOTES_ERROR: 'Unquoted Variable'
+    NESTED_DIE_ERROR: 'Ebuild calls die in a subshell'
+    PATCHES_ERROR: 'PATCHES is not a bash array'
+    REDUNDANT_CD_S_ERROR: 'Ebuild has redundant cd ${S} statement'
+    EMAKE_PARALLEL_DISABLED: 'Upstream parallel compilation bug (ebuild calls emake -j1)'
+    EMAKE_PARALLEL_DISABLED_VIA_MAKEOPTS: 'Upstream parallel compilation bug (MAKEOPTS=-j1)'
+    DEPRECATED_BINDNOW_FLAGS: 'Deprecated bindnow-flags call'
+    EAPI_DEFINED_AFTER_INHERIT: 'EAPI defined after inherit'
+    NO_AS_NEEDED: 'Upstream asneeded linking bug (no-as-needed)'
+    PRESERVE_OLD_LIB: 'Ebuild calls deprecated preserve_old_lib'
+    BUILT_WITH_USE: 'built_with_use'
+    NO_OFFSET_WITH_HELPERS: 'Helper function is used with D, ROOT, ED, EROOT or EPREFIX'
+    SANDBOX_ADDPREDICT: 'Ebuild calls addpredict'
+    USEQ_ERROR: 'Ebuild calls deprecated useq function'
+    HASQ_ERROR: 'Ebuild calls deprecated hasq function'
+    URI_HTTPS: 'Ebuild uses http:// but should use https://'
 
diff --git a/repoman/lib/repoman/modules/linechecks/base.py b/repoman/lib/repoman/modules/linechecks/base.py
index 4e3d6f0..39d7ebd 100644
--- a/repoman/lib/repoman/modules/linechecks/base.py
+++ b/repoman/lib/repoman/modules/linechecks/base.py
@@ -88,9 +88,8 @@
 				if eapi_func is None or not eapi_func(self._eapi):
 					self._func_call = True
 					return (
-						'%s.eclass is not inherited, '
-						'but "%s" found at line: %s' %
-						(self._eclass, func_name, '%d'))
+						'%s.eclass not inherited, but "%s" called' %
+						(self._eclass, func_name))
 		elif not self._func_call:
 			self._func_call = self._func_re.search(line)
 
diff --git a/repoman/lib/repoman/modules/linechecks/controller.py b/repoman/lib/repoman/modules/linechecks/controller.py
index 7082a5d..a3dfd9b 100644
--- a/repoman/lib/repoman/modules/linechecks/controller.py
+++ b/repoman/lib/repoman/modules/linechecks/controller.py
@@ -74,7 +74,7 @@
 	def run_checks(self, contents, pkg):
 		'''Run the configured linechecks
 
-		@param contents: the ebjuild contents to check
+		@param contents: the ebuild contents to check
 		@param pkg: the package being checked
 		'''
 		if self._constant_checks is None:
@@ -134,9 +134,13 @@
 					if lc.check_eapi(pkg.eapi):
 						ignore = lc.ignore_line
 						if not ignore or not ignore.match(line):
-							e = lc.check(num, line)
-							if e:
-								yield lc.repoman_check_name, e % (num + 1)
+							errors = lc.check(num, line)
+							if errors:
+								if isinstance(errors, (tuple, list)):
+									for error in errors:
+										yield lc.repoman_check_name, "line %d: %s" % (num + 1, error)
+								else:
+									yield lc.repoman_check_name, "line %d: %s" % (num + 1, errors)
 
 		for lc in checks:
 			i = lc.end()
diff --git a/repoman/lib/repoman/modules/linechecks/deprecated/inherit.py b/repoman/lib/repoman/modules/linechecks/deprecated/inherit.py
index 361da09..9cef086 100644
--- a/repoman/lib/repoman/modules/linechecks/deprecated/inherit.py
+++ b/repoman/lib/repoman/modules/linechecks/deprecated/inherit.py
@@ -37,9 +37,6 @@
 
 	_inherit_re = re.compile(r'^\s*inherit\s(.*)$')
 
-	def new(self, pkg):
-		self._errors = []
-
 	def check(self, num, line):
 		direct_inherits = None
 		m = self._inherit_re.match(line)
@@ -51,20 +48,17 @@
 		if not direct_inherits:
 			return
 
+		errors = []
 		for eclass in direct_inherits:
 			replacement = self.deprecated_eclasses.get(eclass)
 			if replacement is None:
 				pass
 			elif replacement is False:
-				self._errors.append(
+				errors.append(
 					"please migrate from "
-					"'%s' (no replacement) on line: %d" % (eclass, num + 1))
+					"'%s' (no replacement)" % eclass)
 			else:
-				self._errors.append(
+				errors.append(
 					"please migrate from "
-					"'%s' to '%s' on line: %d" % (eclass, replacement, num + 1))
-
-	def end(self):
-		for error in self._errors:
-			yield error
-		del self._errors
+					"'%s' to '%s'" % (eclass, replacement))
+		return errors
diff --git a/repoman/lib/repoman/modules/linechecks/do/dosym.py b/repoman/lib/repoman/modules/linechecks/do/dosym.py
index c342d35..d1aed74 100644
--- a/repoman/lib/repoman/modules/linechecks/do/dosym.py
+++ b/repoman/lib/repoman/modules/linechecks/do/dosym.py
@@ -15,4 +15,4 @@
 	def check(self, num, line):
 		match = self.regex.match(line)
 		if match:
-			return "dosym '%s'... could use relative path" % (match.group(1), ) + " on line: %d"
+			return "dosym '%s'... could use relative path" % match.group(1)
diff --git a/repoman/lib/repoman/modules/linechecks/eapi/checks.py b/repoman/lib/repoman/modules/linechecks/eapi/checks.py
index de899c0..c53ca38 100644
--- a/repoman/lib/repoman/modules/linechecks/eapi/checks.py
+++ b/repoman/lib/repoman/modules/linechecks/eapi/checks.py
@@ -19,7 +19,7 @@
 		m = self.src_configprepare_re.match(line)
 		if m is not None:
 			return ("'%s'" % m.group(1)) + \
-				" phase is not defined in EAPI < 2 on line: %d"
+				" phase is not defined in EAPI < 2"
 
 
 # EAPI-3 checks
@@ -34,7 +34,7 @@
 		m = self.deprecated_commands_re.match(line)
 		if m is not None:
 			return ("'%s'" % m.group(1)) + \
-				" has been deprecated in EAPI=3 on line: %d"
+				" has been deprecated in EAPI=3"
 
 
 # EAPI <4 checks
@@ -49,7 +49,7 @@
 		m = self.pkg_pretend_re.match(line)
 		if m is not None:
 			return ("'%s'" % m.group(1)) + \
-				" phase is not defined in EAPI < 4 on line: %d"
+				" phase is not defined in EAPI < 4"
 
 
 # EAPI-4 checks
@@ -64,7 +64,7 @@
 		m = self.banned_commands_re.match(line)
 		if m is not None:
 			return ("'%s'" % m.group(1)) + \
-				" has been banned in EAPI=4 on line: %d"
+				" has been banned in EAPI=4"
 
 
 class Eapi4GoneVars(LineCheck):
@@ -80,4 +80,4 @@
 		m = self.undefined_vars_re.match(line)
 		if m is not None:
 			return ("variable '$%s'" % m.group(1)) + \
-				" is gone in EAPI=4 on line: %d"
+				" is gone in EAPI=4"
diff --git a/repoman/lib/repoman/modules/linechecks/emake/emake.py b/repoman/lib/repoman/modules/linechecks/emake/emake.py
index e1e3e63..e618872 100644
--- a/repoman/lib/repoman/modules/linechecks/emake/emake.py
+++ b/repoman/lib/repoman/modules/linechecks/emake/emake.py
@@ -20,4 +20,4 @@
 		m = self._re.match(line)
 		if m is not None:
 			return 'WANT_AUTO' + m.group(1) + \
-				' redundantly set to default value "latest" on line: %d'
+				' redundantly set to default value "latest"'
diff --git a/repoman/lib/repoman/modules/linechecks/phases/phase.py b/repoman/lib/repoman/modules/linechecks/phases/phase.py
index acc3a1e..74cf460 100644
--- a/repoman/lib/repoman/modules/linechecks/phases/phase.py
+++ b/repoman/lib/repoman/modules/linechecks/phases/phase.py
@@ -53,7 +53,7 @@
 			m = self.configure_re.match(line)
 			if m is not None:
 				return ("'%s'" % m.group(1)) + \
-					" call should be moved to src_configure from line: %d"
+					" call should be moved to src_configure"
 
 
 class SrcUnpackPatches(PhaseCheck):
@@ -68,4 +68,4 @@
 			m = self.src_prepare_tools_re.search(line)
 			if m is not None:
 				return ("'%s'" % m.group(1)) + \
-					" call should be moved to src_prepare from line: %d"
+					" call should be moved to src_prepare"
diff --git a/repoman/lib/repoman/modules/linechecks/portage/internal.py b/repoman/lib/repoman/modules/linechecks/portage/internal.py
index 8693372..bc05646 100644
--- a/repoman/lib/repoman/modules/linechecks/portage/internal.py
+++ b/repoman/lib/repoman/modules/linechecks/portage/internal.py
@@ -20,7 +20,7 @@
 		"""Run the check on line and return error if there is one"""
 		m = self.re.match(line)
 		if m is not None:
-			return ("'%s'" % m.group(2)) + " called on line: %d"
+			return "'%s' called" % m.group(2)
 
 
 class PortageInternalVariableAssignment(LineCheck):
@@ -30,8 +30,5 @@
 
 	def check(self, num, line):
 		match = self.internal_assignment.match(line)
-		e = None
 		if match is not None:
-			e = 'Assignment to variable %s' % match.group(2)
-			e += ' on line: %d'
-		return e
+			return 'Assignment to variable %s' % match.group(2)
diff --git a/repoman/lib/repoman/modules/linechecks/quotes/quoteda.py b/repoman/lib/repoman/modules/linechecks/quotes/quoteda.py
index 7fd9ba7..5b68f30 100644
--- a/repoman/lib/repoman/modules/linechecks/quotes/quoteda.py
+++ b/repoman/lib/repoman/modules/linechecks/quotes/quoteda.py
@@ -13,4 +13,4 @@
 	def check(self, num, line):
 		match = self.a_quoted.match(line)
 		if match:
-			return "Quoted \"${A}\" on line: %d"
+			return "Quoted \"${A}\""
diff --git a/repoman/lib/repoman/modules/linechecks/useless/dodoc.py b/repoman/lib/repoman/modules/linechecks/useless/dodoc.py
index 502bfbe..3270af1 100644
--- a/repoman/lib/repoman/modules/linechecks/useless/dodoc.py
+++ b/repoman/lib/repoman/modules/linechecks/useless/dodoc.py
@@ -13,4 +13,4 @@
 	def check(self, num, line):
 		match = self.uselessdodoc_re.match(line)
 		if match:
-			return "Useless dodoc '%s'" % (match.group(2), ) + " on line: %d"
+			return "Useless dodoc '%s'" % match.group(2)
diff --git a/repoman/lib/repoman/modules/linechecks/whitespace/blank.py b/repoman/lib/repoman/modules/linechecks/whitespace/blank.py
index 2ab4097..1fa3eb2 100644
--- a/repoman/lib/repoman/modules/linechecks/whitespace/blank.py
+++ b/repoman/lib/repoman/modules/linechecks/whitespace/blank.py
@@ -14,7 +14,7 @@
 
 	def check(self, num, line):
 		if self.line_is_blank and self.blank_line.match(line):
-			return 'Useless blank line on line: %d'
+			return 'Useless blank line'
 		if self.blank_line.match(line):
 			self.line_is_blank = True
 		else: