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
|
# -*- coding:utf-8 -*-
# repoman: Checks
# Copyright 2007-2017 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
"""This module contains functions used in Repoman to ascertain the quality
and correctness of an ebuild."""
from __future__ import unicode_literals
import collections
import logging
import os
from copy import deepcopy
from repoman._portage import portage
from repoman.config import load_config
# Avoid a circular import issue in py2.7
portage.proxy.lazyimport.lazyimport(globals(),
'portage.util:stack_lists',
)
def merge(dict1, dict2):
''' Return a new dictionary by merging two dictionaries recursively. '''
result = deepcopy(dict1)
for key, value in dict2.items():
if isinstance(value, collections.Mapping):
result[key] = merge(result.get(key, {}), value)
else:
result[key] = deepcopy(dict2[key])
return result
class LineChecksConfig(object):
'''Holds our LineChecks configuration data and operation functions'''
def __init__(self, repo_settings):
'''Class init
@param repo_settings: RepoSettings instance
@param configpaths: ordered list of filepaths to load
'''
self.repo_settings = repo_settings
self.infopaths = [os.path.join(path, 'linechecks.yaml') for path in self.repo_settings.masters_list]
logging.debug("LineChecksConfig; configpaths: %s", self.infopaths)
self.info_config = None
self._config = None
self.usex_supported_eapis = None
self.in_iuse_supported_eapis = None
self.get_libdir_supported_eapis = None
self.eclass_eapi_functions = {}
self.eclass_export_functions = None
self.eclass_info = {}
self.eclass_info_experimental_inherit = {}
self.errors = {}
self.load_checks_info()
def load_checks_info(self, infopaths=None):
'''load the config files in order
@param infopaths: ordered list of filepaths to load
'''
if infopaths:
self.infopaths = infopaths
elif not self.infopaths:
logging.error("LineChecksConfig; Error: No linechecks.yaml files defined")
configs = load_config(self.infopaths, 'yaml')
if configs == {}:
logging.error("LineChecksConfig: Failed to load a valid 'linechecks.yaml' file at paths: %s", self.infopaths)
return False
logging.debug("LineChecksConfig: linechecks.yaml configs: %s", configs)
self.info_config = configs
self.errors = self.info_config['errors']
self.usex_supported_eapis = self.info_config.get('usex_supported_eapis', [])
self.in_iuse_supported_eapis = self.info_config.get('in_iuse_supported_eapis', [])
self.eclass_info_experimental_inherit = self.info_config.get('eclass_info_experimental_inherit', [])
self.get_libdir_supported_eapis = self.in_iuse_supported_eapis
self.eclass_eapi_functions = {
"usex": lambda eapi: eapi not in self.usex_supported_eapis,
"in_iuse": lambda eapi: eapi not in self.in_iuse_supported_eapis,
"get_libdir": lambda eapi: eapi not in self.get_libdir_supported_eapis,
}
# eclasses that export ${ECLASS}_src_(compile|configure|install)
self.eclass_export_functions = self.info_config.get('eclass_export_functions', [])
self.eclass_info_experimental_inherit = self.info_config.get('eclass_info_experimental_inherit', {})
# These are "eclasses are the whole ebuild" type thing.
try:
self.eclass_info_experimental_inherit['eutils']['exempt_eclasses'] = self.eclass_export_functions
except KeyError:
pass
try:
self.eclass_info_experimental_inherit['multilib']['exempt_eclasses'] = self.eclass_export_functions + [
'autotools', 'libtool', 'multilib-minimal']
except KeyError:
pass
|