aboutsummaryrefslogtreecommitdiff
blob: 4e1d216e1d15f19e7c1e19007114eeff3aac0564 (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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# -*- coding:utf-8 -*-


from _emerge.Package import Package

from repoman.check_missingslot import check_missingslot
# import our initialized portage instance
from repoman._portage import portage
from repoman.qa_data import suspect_virtual, suspect_rdepend


def _depend_checks(ebuild, pkg, portdb, qatracker, repo_metadata):
	'''Checks the ebuild dependencies for errors

	@param pkg: Package in which we check (object).
	@param ebuild: Ebuild which we check (object).
	@param portdb: portdb instance
	@param qatracker: QATracker instance
	@param repo_metadata: dictionary of various repository items.
	@returns: (unknown_pkgs, badlicsyntax)
	'''

	unknown_pkgs = set()

	inherited_java_eclass = "java-pkg-2" in ebuild.inherited or \
		"java-pkg-opt-2" in ebuild.inherited,
	inherited_wxwidgets_eclass = "wxwidgets" in ebuild.inherited
	# operator_tokens = set(["||", "(", ")"])
	type_list, badsyntax = [], []
	for mytype in Package._dep_keys + ("LICENSE", "PROPERTIES", "PROVIDE"):
		mydepstr = ebuild.metadata[mytype]

		buildtime = mytype in Package._buildtime_keys
		runtime = mytype in Package._runtime_keys
		token_class = None
		if mytype.endswith("DEPEND"):
			token_class = portage.dep.Atom

		try:
			atoms = portage.dep.use_reduce(
				mydepstr, matchall=1, flat=True,
				is_valid_flag=pkg.iuse.is_valid_flag, token_class=token_class)
		except portage.exception.InvalidDependString as e:
			atoms = None
			badsyntax.append(str(e))

		if atoms and mytype.endswith("DEPEND"):
			if runtime and \
				"test?" in mydepstr.split():
				qatracker.add_error(
					mytype + '.suspect',
					"%s: 'test?' USE conditional in %s" %
					(ebuild.relative_path, mytype))

			for atom in atoms:
				if atom == "||":
					continue

				is_blocker = atom.blocker

				# Skip dependency.unknown for blockers, so that we
				# don't encourage people to remove necessary blockers,
				# as discussed in bug 382407. We use atom.without_use
				# due to bug 525376.
				if not is_blocker and \
					not portdb.xmatch("match-all", atom.without_use) and \
					not atom.cp.startswith("virtual/"):
					unknown_pkgs.add((mytype, atom.unevaluated_atom))

				if pkg.category != "virtual":
					if not is_blocker and \
						atom.cp in suspect_virtual:
						qatracker.add_error(
							'virtual.suspect', ebuild.relative_path +
							": %s: consider using '%s' instead of '%s'" %
							(mytype, suspect_virtual[atom.cp], atom))
					if not is_blocker and \
						atom.cp.startswith("perl-core/"):
						qatracker.add_error('dependency.perlcore',
							ebuild.relative_path +
							": %s: please use '%s' instead of '%s'" %
							(mytype,
							atom.replace("perl-core/","virtual/perl-"),
							atom))

				if buildtime and \
					not is_blocker and \
					not inherited_java_eclass and \
					atom.cp == "virtual/jdk":
					qatracker.add_error(
						'java.eclassesnotused', ebuild.relative_path)
				elif buildtime and \
					not is_blocker and \
					not inherited_wxwidgets_eclass and \
					atom.cp == "x11-libs/wxGTK":
					qatracker.add_error(
						'wxwidgets.eclassnotused',
						"%s: %ss on x11-libs/wxGTK without inheriting"
						" wxwidgets.eclass" % (ebuild.relative_path, mytype))
				elif runtime:
					if not is_blocker and \
						atom.cp in suspect_rdepend:
						qatracker.add_error(
							mytype + '.suspect',
							ebuild.relative_path + ": '%s'" % atom)

				if atom.operator == "~" and \
					portage.versions.catpkgsplit(atom.cpv)[3] != "r0":
					qacat = 'dependency.badtilde'
					qatracker.add_error(
						qacat, "%s: %s uses the ~ operator"
						" with a non-zero revision: '%s'" %
						(ebuild.relative_path, mytype, atom))

				check_missingslot(atom, mytype, ebuild.eapi, portdb, qatracker,
					ebuild.relative_path, ebuild.metadata)

		type_list.extend([mytype] * (len(badsyntax) - len(type_list)))

	for m, b in zip(type_list, badsyntax):
		if m.endswith("DEPEND"):
			qacat = "dependency.syntax"
		else:
			qacat = m + ".syntax"
		qatracker.add_error(
			qacat, "%s: %s: %s" % (ebuild.relative_path, m, b))

	# data required for some other tests
	badlicsyntax = len([z for z in type_list if z == "LICENSE"])
	badprovsyntax = len([z for z in type_list if z == "PROVIDE"])
	baddepsyntax = len(type_list) != badlicsyntax + badprovsyntax
	badlicsyntax = badlicsyntax > 0
	#badprovsyntax = badprovsyntax > 0

	# Parse the LICENSE variable, remove USE conditions and flatten it.
	licenses = portage.dep.use_reduce(
		ebuild.metadata["LICENSE"], matchall=1, flat=True)

	# Check each entry to ensure that it exists in ${PORTDIR}/licenses/.
	for lic in licenses:
		# Need to check for "||" manually as no portage
		# function will remove it without removing values.
		if lic not in repo_metadata['liclist'] and lic != "||":
			qatracker.add_error("LICENSE.invalid",
				"%s: %s" % (ebuild.relative_path, lic))
		elif lic in repo_metadata['lic_deprecated']:
			qatracker.add_error("LICENSE.deprecated",
				"%s: %s" % (ebuild.relative_path, lic))

	return unknown_pkgs, baddepsyntax