Skip to content

Commit

Permalink
addons: ProfileAddon: move profile initialization to arg checking phase
Browse files Browse the repository at this point in the history
That way we can throw better errors when invalid profiles are input by
the user.
  • Loading branch information
radhermit committed May 28, 2016
1 parent b5973c4 commit fa07a5b
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 54 deletions.
36 changes: 19 additions & 17 deletions pkgcheck/addons.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,17 +173,14 @@ def check_args(parser, namespace):
"profile-base location %r doesn't exist/isn't a dir" % (
profiles_dir,))

namespace.profiles_dir = profiles_dir
if namespace.profiles is None:
namespace.profiles = ((), ())
selected_profiles = namespace.profiles
if selected_profiles is None:
selected_profiles = ((), ())

def __init__(self, options, *args):
base.Addon.__init__(self, options)

if options.profiles_dir:
profiles_obj = repo_objs.BundledProfiles(options.profiles_dir)
if profiles_dir:
profiles_obj = repo_objs.BundledProfiles(profiles_dir)
else:
profiles_obj = options.target_repo.config.profiles
profiles_obj = namespace.target_repo.config.profiles

def norm_name(s):
"""Expand status keywords and format paths."""
Expand All @@ -193,7 +190,7 @@ def norm_name(s):
else:
yield '/'.join(filter(None, s.split('/')))

disabled, enabled = options.profiles
disabled, enabled = selected_profiles
disabled = set(disabled)
enabled = set(enabled)
# remove profiles that are both enabled and disabled
Expand All @@ -219,15 +216,17 @@ def norm_name(s):
# temporarily.
cached_profiles = []

ignore_deprecated = self.options.profiles_ignore_deprecated
arch_profiles = defaultdict(list)
for profile_path in profile_paths:
try:
p = profiles_obj.create_profile(profile_path)
except profiles.ProfileError:
# caught via a later report
except profiles.ProfileError as e:
# Only throw errors if the profile was selected by the user, bad
# repo profiles will be caught during repo metadata scans.
if namespace.profiles is not None:
parser.error('invalid profile: %r: %s' % (e.path, e.error))
continue
if ignore_deprecated and p.deprecated:
if namespace.profiles_ignore_deprecated and p.deprecated:
continue
cached_profiles.append(p)
if p.arch is None:
Expand All @@ -236,8 +235,12 @@ def norm_name(s):
"profile %s lacks arch settings, unable to use it" % profile_path)
arch_profiles[p.arch].append((profile_path, p))

self.official_arches = options.target_repo.config.known_arches
namespace.arch_profiles = arch_profiles

def __init__(self, options, *args):
base.Addon.__init__(self, options)

self.official_arches = options.target_repo.config.known_arches
self.desired_arches = getattr(self.options, 'arches', None)
if self.desired_arches is None or self.options.selected_arches is None:
# copy it to be safe
Expand All @@ -264,7 +267,7 @@ def norm_name(s):

profile_filters.update({stable_key: [], unstable_key: []})

for profile_name, profile in arch_profiles.get(k, []):
for profile_name, profile in options.arch_profiles.get(k, []):
vfilter = domain.generate_filter(profile.masks, profile.unmasks)

immutable_flags = profile.masked_use.clone(unfreeze=True)
Expand Down Expand Up @@ -336,7 +339,6 @@ def norm_name(s):
similar.append([profile])

self.profile_evaluate_dict = profile_evaluate_dict
self.arch_profiles = arch_profiles
self.keywords_filter = OrderedDict(
(k, self.keywords_filter[k])
for k in sorted(self.keywords_filter))
Expand Down
80 changes: 43 additions & 37 deletions pkgcheck/test/test_addons.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Copyright: 2007 Brian Harring <ferringb@gmail.com>
# License: BSD/GPL2

import argparse
import itertools
import os
import shutil
Expand All @@ -22,11 +23,11 @@ class base_test(TestCase):

addon_kls = None

def process_check(self, args, silence=False, preset_values={}, **settings):
def process_check(self, args, silence=False, preset_values={}, namespace=None, **settings):
p = commandline.ArgumentParser(domain=False, color=False)
p.plugin = p.add_argument_group('plugin options')
self.addon_kls.mangle_argparser(p)
args, unknown_args = p.parse_known_args(args)
args, unknown_args = p.parse_known_args(args, namespace)
self.assertEqual(unknown_args, [])
orig_out, orig_err = None, None
for attr, val in preset_values.iteritems():
Expand Down Expand Up @@ -161,20 +162,11 @@ def setUp(self):
mixins.TempDirMixin.setUp(self)
base_test.setUp(self)

def process_check(self, profiles_base, *args, **kwds):
options = base_test.process_check(self, *args, **kwds)
options.search_repo = Options()
if profiles_base is None:
repo = QuietRepoConfig(self.dir)
else:
repo = QuietRepoConfig(profiles_base, profiles_base='.')
options.target_repo = Options(config=repo)
return options


class TestProfileAddon(profile_mixin):
def mk_profiles(self, profiles, base='profiles', arches=None):
os.mkdir(pjoin(self.dir, 'metadata'))
# write masters= to suppress logging complaints.
write_file(pjoin(self.dir, 'metadata', 'layout.conf'), 'w', 'masters=')

def mk_profiles(self, profiles, base='default', arches=None):
loc = pjoin(self.dir, base)
os.mkdir(loc)
for profile in profiles:
Expand All @@ -184,6 +176,7 @@ def mk_profiles(self, profiles, base='default', arches=None):
arches = set(val[0] for val in profiles.itervalues())
write_file(pjoin(loc, 'arch.list'), 'w', "\n".join(arches))
write_file(pjoin(loc, 'repo_name'), 'w', 'testing')
write_file(pjoin(loc, 'eapi'), 'w', '5')
with open(pjoin(loc, 'profiles.desc'), 'w') as fd:
for profile, vals in profiles.iteritems():
l = len(vals)
Expand All @@ -199,6 +192,20 @@ def mk_profiles(self, profiles, base='default', arches=None):
with open(pjoin(loc, profile, 'eapi'), 'w') as f:
f.write('5')

def process_check(self, profiles_base, *args, **kwds):
namespace = argparse.Namespace()
if profiles_base is None:
repo = QuietRepoConfig(self.dir)
else:
repo = QuietRepoConfig(profiles_base, profiles_base='.')
namespace.target_repo = Options(config=repo)
namespace.search_repo = Options()
options = base_test.process_check(self, namespace=namespace, *args, **kwds)
return options


class TestProfileAddon(profile_mixin):

def assertProfiles(self, check, key, *profile_names):
self.assertEqual(
sorted(x.name for y in check.profile_evaluate_dict[key] for x in y),
Expand All @@ -209,11 +216,8 @@ def test_defaults(self):
"profile1": ["x86"],
"profile1/2": ["x86"]},
base='profiles')
os.mkdir(pjoin(self.dir, 'metadata'))
# write masters= to suppress logging complaints.
write_file(pjoin(self.dir, 'metadata', 'layout.conf'), 'w', 'masters=')
options = self.process_check(
None, [], profiles=((), ()),
None, [], profiles=None,
profiles_ignore_deprecated=False)
# override the default
check = self.addon_kls(options)
Expand Down Expand Up @@ -245,7 +249,8 @@ def test_disable_deprecated(self):
"default-linux": ["x86", False, True],
"default-linux/x86": ["x86"]},
base='foo')
options = self.process_check(pjoin(self.dir, 'foo'), ['--profiles-disable-deprecated'],
options = self.process_check(
pjoin(self.dir, 'foo'), ['--profiles-disable-deprecated'],
profiles_ignore_deprecated=True)
check = self.addon_kls(options)
self.assertProfiles(check, 'x86', 'default-linux/x86')
Expand Down Expand Up @@ -285,6 +290,7 @@ def test_identify_profiles(self):
base='foo')

counter = itertools.count()

def run_check(*args):
# create a fresh tree for the profile work everytime.
# do this, so that it's always a unique pathway- this sidesteps
Expand Down Expand Up @@ -365,33 +371,33 @@ def get_check(self, *profiles):
# since evaluate relies on it.
self.addon_kls = addons.ProfileAddon
profile_options = profile_mixin.process_check(
self, self.dir,
['--profiles=%s' % ','.join(x.name for x in profiles)])
self, None, ['--profiles=%s' % ','.join(profiles)])
self.addon_kls = self.orig_addon_kls
profiles = dict((x.name, x) for x in profiles)
profiles_obj = Options(create_profile=lambda x: profiles[x])
# XXX: Cheat.
object.__setattr__(profile_options.target_repo.config, '_profiles',
profiles_obj)
profile_check = addons.ProfileAddon(profile_options)

# now we're good to go.
return self.addon_kls(profile_options, profile_check)

def test_it(self):
check = self.get_check(
FakeProfile(stable_masked_use={"dev-util/diffball": ['foo']},
arch='x86', name='1'),
FakeProfile(stable_forced_use={"=dev-util/diffball-0.1": ['bar', 'foo']},
arch='x86', name='2'),
FakeProfile(stable_forced_use={"dev-util/diffball": ['bar', 'foo']},
arch='ppc', name='3')
)
self.mk_profiles({
"1": ["x86"],
"2": ["x86"],
"3": ["ppc"]},
base='profiles')

with open(pjoin(self.dir, 'profiles', '1', 'package.use.stable.mask'), 'w') as f:
f.write('dev-util/diffball foo')
with open(pjoin(self.dir, 'profiles', '2', 'package.use.stable.force'), 'w') as f:
f.write('=dev-util/diffball-0.1 bar foo')
with open(pjoin(self.dir, 'profiles', '3', 'package.use.stable.force'), 'w') as f:
f.write('dev-util/diffball bar foo')

check = self.get_check('1', '2', '3')

def get_rets(ver, attr, KEYWORDS="x86", **data):
data["KEYWORDS"] = KEYWORDS
pkg = FakePkg("dev-util/diffball-%s" % ver, data=data)
return check.collapse_evaluate_depset(pkg, attr,
getattr(pkg, attr))
return check.collapse_evaluate_depset(pkg, attr, getattr(pkg, attr))

# few notes... for ensuring proper profiles came through, use
# sorted(x.name for x in blah); reasoning is that it will catch
Expand Down

0 comments on commit fa07a5b

Please sign in to comment.