[gentoo-portage-dev] [PATCH v5] news: Support News-Item-Format 2.0
Validate Display-If-Installed with EAPI 0 or 5. Add support for trailing wildcard matching for Display-If-Profile. Bug: https://bugs.gentoo.org/577372 --- pym/portage/news.py | 50 ++ 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/pym/portage/news.py b/pym/portage/news.py index 177f9db..28faf83 100644 --- a/pym/portage/news.py +++ b/pym/portage/news.py @@ -197,6 +197,7 @@ _formatRE = re.compile("News-Item-Format:\s*([^\s]*)\s*$") _installedRE = re.compile("Display-If-Installed:(.*)\n") _profileRE = re.compile("Display-If-Profile:(.*)\n") _keywordRE = re.compile("Display-If-Keyword:(.*)\n") +_valid_profile_RE = re.compile(r'^[^*]+(/\*)?$') class NewsItem(object): """ @@ -266,14 +267,24 @@ class NewsItem(object): f.close() self.restrictions = {} invalids = [] + news_format = None + + # Look for News-Item-Format for i, line in enumerate(lines): - # Optimization to ignore regex matchines on lines that - # will never match format_match = _formatRE.match(line) - if (format_match is not None and - not fnmatch.fnmatch(format_match.group(1), '1.*')): + if format_match is not None: + news_format = format_match.group(1) + if fnmatch.fnmatch(news_format, '[12].*'): + break invalids.append((i + 1, line.rstrip('\n'))) - break + + if news_format is None: + invalids.append((0, 'News-Item-Format unspecified')) + + # Parse the rest + for i, line in enumerate(lines): + # Optimization to ignore regex matches on lines that + # will never match if not line.startswith('D'): continue restricts = { _installedRE : DisplayInstalledRestriction, @@ -282,13 +293,14 @@ class NewsItem(object): for regex, restriction in restricts.items(): match = regex.match(line) if match: - restrict = restriction(match.groups()[0].strip()) + restrict = restriction(match.groups()[0].strip(), news_format) if not restrict.isValid(): invalids.append((i + 1, line.rstrip("\n"))) else: self.restrictions.setdefault( id(restriction), []).append(restrict) continue + if invalids: self._valid = False msg = [] @@ -321,13 +333,21 @@ class DisplayProfileRestriction(DisplayRestriction): if the user is running a specific profile. """ - def __init__(self, profile): + def __init__(self, profile, news_format): self.profile = profile + self.format = news_format + + def isValid(self): + if fnmatch.fnmatch(self.format, '1.*') and '*' in self.profile: + return False + if fnmatch.fnmatch(self.format, '2.*') and not _valid_profile_RE.match(self.profile): + return False + return True def checkRestriction(self, **kwargs): - if self.profile == kwargs['profile']: - return True - return False + if fnmatch.fnmatch(self.format, '2.*') and self.profile.endswith('/*'): + return (kwargs['profile'].startswith(self.profile[:-1])) + return (kwargs['profile'] == self.profile) class DisplayKeywordRestriction(DisplayRestriction): """ @@ -335,8 +355,9 @@ class DisplayKeywordRestriction(DisplayRestriction): if the user is running a specific keyword. """ - def __init__(self, keyword): + def __init__(self, keyword, news_format): self.keyword = keyword + self.format = news_format def checkRestriction(self, **kwargs): if kwargs['config'].get('ARCH', '') == self.keyword: @@ -349,10 +370,15 @@ class DisplayInstalledRestriction(DisplayRestriction): if the user has that item installed. """ - def __init__(self, atom): + def __init__(self, atom, news_format): self.atom = atom + self.format = news_format def isValid(self): +
Re: [gentoo-portage-dev] [PATCH v4] news: Support News-Item-Format 2.0
On 09/07/2016 02:03 PM, Mike Gilbert wrote: > Validate Display-If-Installed with EAPI 0 or 5. > Add support for trailing wildcard matching for Display-If-Profile. > > Bug: https://bugs.gentoo.org/577372 > --- > pym/portage/news.py | 50 ++ > 1 file changed, 38 insertions(+), 12 deletions(-) > > diff --git a/pym/portage/news.py b/pym/portage/news.py > index 177f9db..e53e905 100644 > --- a/pym/portage/news.py > +++ b/pym/portage/news.py > @@ -197,6 +197,7 @@ _formatRE = re.compile("News-Item-Format:\s*([^\s]*)\s*$") > _installedRE = re.compile("Display-If-Installed:(.*)\n") > _profileRE = re.compile("Display-If-Profile:(.*)\n") > _keywordRE = re.compile("Display-If-Keyword:(.*)\n") > +_bad_wc_RE = re.compile(r'.*([^/]\*|\*.)') Maybe it's better if we use a regex that defines a valid profile string: _valid_profile_RE = re.compile(r'^[^*]+(/\*)?$') -- Thanks, Zac
Re: [gentoo-portage-dev] [PATCH v3] news: Support News-Item-Format 2.0
On Wed, Sep 7, 2016 at 3:26 AM, Zac Medico wrote: > On 09/04/2016 10:04 AM, Mike Gilbert wrote: >> def isValid(self): >> + if fnmatch.fnmatch(self.format, '1.*'): >> + return isvalidatom(self.atom, eapi='0') > > We might want to check the existing news items to make sure that they > are all conformant here. > Good idea. I cleared out /var/lib/gentoo/news, and did not hit any errors when emerge re-evaluated them.
[gentoo-portage-dev] [PATCH v4] news: Support News-Item-Format 2.0
Validate Display-If-Installed with EAPI 0 or 5. Add support for trailing wildcard matching for Display-If-Profile. Bug: https://bugs.gentoo.org/577372 --- pym/portage/news.py | 50 ++ 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/pym/portage/news.py b/pym/portage/news.py index 177f9db..e53e905 100644 --- a/pym/portage/news.py +++ b/pym/portage/news.py @@ -197,6 +197,7 @@ _formatRE = re.compile("News-Item-Format:\s*([^\s]*)\s*$") _installedRE = re.compile("Display-If-Installed:(.*)\n") _profileRE = re.compile("Display-If-Profile:(.*)\n") _keywordRE = re.compile("Display-If-Keyword:(.*)\n") +_bad_wc_RE = re.compile(r'.*([^/]\*|\*.)') class NewsItem(object): """ @@ -266,14 +267,24 @@ class NewsItem(object): f.close() self.restrictions = {} invalids = [] + news_format = None + + # Look for News-Item-Format for i, line in enumerate(lines): - # Optimization to ignore regex matchines on lines that - # will never match format_match = _formatRE.match(line) - if (format_match is not None and - not fnmatch.fnmatch(format_match.group(1), '1.*')): + if format_match is not None: + news_format = format_match.group(1) + if fnmatch.fnmatch(news_format, '[12].*'): + break invalids.append((i + 1, line.rstrip('\n'))) - break + + if news_format is None: + invalids.append((0, 'News-Item-Format unspecified')) + + # Parse the rest + for i, line in enumerate(lines): + # Optimization to ignore regex matches on lines that + # will never match if not line.startswith('D'): continue restricts = { _installedRE : DisplayInstalledRestriction, @@ -282,13 +293,14 @@ class NewsItem(object): for regex, restriction in restricts.items(): match = regex.match(line) if match: - restrict = restriction(match.groups()[0].strip()) + restrict = restriction(match.groups()[0].strip(), news_format) if not restrict.isValid(): invalids.append((i + 1, line.rstrip("\n"))) else: self.restrictions.setdefault( id(restriction), []).append(restrict) continue + if invalids: self._valid = False msg = [] @@ -321,13 +333,21 @@ class DisplayProfileRestriction(DisplayRestriction): if the user is running a specific profile. """ - def __init__(self, profile): + def __init__(self, profile, news_format): self.profile = profile + self.format = news_format + + def isValid(self): + if fnmatch.fnmatch(self.format, '1.*') and '*' in self.profile: + return False + if fnmatch.fnmatch(self.format, '2.*') and _bad_wc_RE.match(self.profile): + return False + return True def checkRestriction(self, **kwargs): - if self.profile == kwargs['profile']: - return True - return False + if fnmatch.fnmatch(self.format, '2.*') and self.profile.endswith('/*'): + return (kwargs['profile'].startswith(self.profile[:-1])) + return (kwargs['profile'] == self.profile) class DisplayKeywordRestriction(DisplayRestriction): """ @@ -335,8 +355,9 @@ class DisplayKeywordRestriction(DisplayRestriction): if the user is running a specific keyword. """ - def __init__(self, keyword): + def __init__(self, keyword, news_format): self.keyword = keyword + self.format = news_format def checkRestriction(self, **kwargs): if kwargs['config'].get('ARCH', '') == self.keyword: @@ -349,10 +370,15 @@ class DisplayInstalledRestriction(DisplayRestriction): if the user has that item installed. """ - def __init__(self, atom): + def __init__(self, atom, news_format): self.atom = atom + self.format = news_format def isValid(self): + if fnma
Re: [gentoo-portage-dev] [PATCH v3] news: Support News-Item-Format 2.0
On 09/04/2016 10:04 AM, Mike Gilbert wrote: > Validate Display-If-Installed with EAPI 0 or 5. > Add support for trailing wildcard matching for Display-If-Profile. > > Bug: https://bugs.gentoo.org/577372 > --- > pym/portage/news.py | 42 ++ > 1 file changed, 30 insertions(+), 12 deletions(-) > > diff --git a/pym/portage/news.py b/pym/portage/news.py > index 177f9db..fa6fb00 100644 > --- a/pym/portage/news.py > +++ b/pym/portage/news.py > @@ -266,14 +266,24 @@ class NewsItem(object): > f.close() > self.restrictions = {} > invalids = [] > + news_format = None > + > + # Look for News-Item-Format > for i, line in enumerate(lines): > - # Optimization to ignore regex matchines on lines that > - # will never match > format_match = _formatRE.match(line) > - if (format_match is not None and > - not > fnmatch.fnmatch(format_match.group(1), '1.*')): > + if format_match is not None: > + news_format = format_match.group(1) > + if fnmatch.fnmatch(news_format, '[12].*'): > + break > invalids.append((i + 1, line.rstrip('\n'))) > - break > + > + if news_format is None: > + invalids.append((0, 'News-Item-Format unspecified')) > + > + # Parse the rest > + for i, line in enumerate(lines): > + # Optimization to ignore regex matchines on lines that s/matchines/matches/ > + # will never match > if not line.startswith('D'): > continue > restricts = { _installedRE : > DisplayInstalledRestriction, > @@ -282,13 +292,14 @@ class NewsItem(object): > for regex, restriction in restricts.items(): > match = regex.match(line) > if match: > - restrict = > restriction(match.groups()[0].strip()) > + restrict = > restriction(match.groups()[0].strip(), news_format) > if not restrict.isValid(): > invalids.append((i + 1, > line.rstrip("\n"))) > else: > self.restrictions.setdefault( > id(restriction), > []).append(restrict) > continue > + > if invalids: > self._valid = False > msg = [] > @@ -321,13 +332,14 @@ class DisplayProfileRestriction(DisplayRestriction): > if the user is running a specific profile. > """ > > - def __init__(self, profile): > + def __init__(self, profile, news_format): > self.profile = profile > + self.format = news_format > > def checkRestriction(self, **kwargs): > - if self.profile == kwargs['profile']: > - return True > - return False > + if fnmatch.fnmatch(self.format, '2.*') and > self.profile.endswith('/*'): > + return (kwargs['profile'].startswith(self.profile[:-1])) Maybe we should raise an exception if a wildcard is used but the format doesn't allow it? We could also raise an exception for any unsupported wildcards that do not occur at the end of the string. > + return (kwargs['profile'] == self.profile) > > class DisplayKeywordRestriction(DisplayRestriction): > """ > @@ -335,8 +347,9 @@ class DisplayKeywordRestriction(DisplayRestriction): > if the user is running a specific keyword. > """ > > - def __init__(self, keyword): > + def __init__(self, keyword, news_format): > self.keyword = keyword > + self.format = news_format > > def checkRestriction(self, **kwargs): > if kwargs['config'].get('ARCH', '') == self.keyword: > @@ -349,10 +362,15 @@ class DisplayInstalledRestriction(DisplayRestriction): > if the user has that item installed. > """ > > - def __init__(self, atom): > + def __init__(self, atom, news_format): > self.atom = atom > + self.format = news_format > > def isValid(self): > + if fnmatch.fnmatch(self.format, '1.*'): > + return isvalidatom(self.atom, eapi='0') We might want to check the existing news items to make sure that they are all conformant here. > + if fnmatch.fnmatch(self.format, '2.*'): > + return isvalidatom(self.a