draft filter opt: use bool/None instead of bit flag

This commit is contained in:
Yu Ming Zhu 2023-10-09 22:46:13 +00:00
parent 8a34f7efa0
commit 77a06c98b3
7 changed files with 65 additions and 114 deletions

View file

@ -2847,9 +2847,9 @@ def anon_handle_list_tagged(goptions, session, args):
if options.type:
opts['type'] = options.type
elif options.no_draft:
opts['draft'] = koji.FLAG_REGULAR_BUILD
opts['draft'] = False
elif options.draft_only:
opts['draft'] = koji.FLAG_DRAFT_BUILD
opts['draft'] = True
event = koji.util.eventFromOpts(session, options)
event_id = None
if event:
@ -3526,9 +3526,9 @@ def anon_handle_list_builds(goptions, session, args):
if options.no_draft and options.draft_only:
parser.error("--draft-only conflits with --no-draft")
elif options.no_draft:
opts['draft'] = koji.FLAG_REGULAR_BUILD
opts['draft'] = False
elif options.draft_only:
opts['draft'] = koji.FLAG_DRAFT_BUILD
opts['draft'] = True
if options.cg:
opts['cgID'] = options.cg
if options.package:

View file

@ -27,7 +27,6 @@ from __future__ import absolute_import, division
import base64
import datetime
import errno
import functools
import hashlib
import json
import logging
@ -300,41 +299,6 @@ DEFAULT_AUTH_TIMEOUT = 60
# draft release format
DRAFT_RELEASE_FORMAT = '{release}#draft_{id}'
FLAG_DRAFT_BUILD = 1
FLAG_REGULAR_BUILD = 2
FLAG_ALL_BUILD = FLAG_DRAFT_BUILD | FLAG_REGULAR_BUILD
if six.PY3:
from enum import IntFlag
# draft build bit FLAGs
class DRAFT_FLAG(IntFlag):
DRAFT = FLAG_DRAFT_BUILD
REGULAR = FLAG_REGULAR_BUILD
ALL = FLAG_ALL_BUILD
@classmethod
def _missing_(cls, value):
if not isinstance(value, int):
raise ValueError("%r is not a valid %s" % (value, cls.__name__))
# diable member creation and negative integer
return cls._value2member_map_.get(value)
def convert_draft_option(func=None, kw='draft'):
def wrapper(func):
@functools.wraps(func)
def convert(*args, **kwargs):
if kw in kwargs:
kwargs[kw] = DRAFT_FLAG(kwargs[kw])
return func(*args, **kwargs)
return convert
if func is None:
return wrapper
else:
return wrapper(func)
# BEGIN kojikamid dup #
# Exceptions

View file

@ -55,7 +55,6 @@ import rpm
from psycopg2._psycopg import IntegrityError
import koji
from koji import DRAFT_FLAG, convert_draft_option
import koji.plugin
import koji.policy
import koji.rpmdiff
@ -1395,9 +1394,8 @@ def list_tags(build=None, package=None, perms=True, queryOpts=None, pattern=None
return query.iterate()
@convert_draft_option
def readTaggedBuilds(tag, event=None, inherit=False, latest=False, package=None, owner=None,
type=None, extra=False, *, draft=DRAFT_FLAG.ALL):
type=None, extra=False, *, draft=None):
"""Returns a list of builds for specified tag
:param int tag: tag ID
@ -1409,10 +1407,10 @@ def readTaggedBuilds(tag, event=None, inherit=False, latest=False, package=None,
:param str type: restrict the list to builds of the given type. Currently the supported
types are 'maven', 'win', 'image', or any custom content generator btypes.
:param bool extra: Set to "True" to get the build extra info
:param DRAFT_FLAG draft: bit flag(enum.IntFlag) indicates
- DRAFT(1): draft only
- REGULAR(2): regular only
- ALL(3): both draft and regular builds
:param bool draft: bool or None option that indicates the filter based on draft field
- None: no filter (both draft and regular builds)
- True: draft only
- False: regular only
:returns [dict]: list of buildinfo dicts
"""
# build - id pkg_id version release epoch
@ -1522,9 +1520,8 @@ def readTaggedBuilds(tag, event=None, inherit=False, latest=False, package=None,
return builds
@convert_draft_option
def readTaggedRPMS(tag, package=None, arch=None, event=None, inherit=False, latest=True,
rpmsigs=False, owner=None, type=None, extra=True, *, draft=DRAFT_FLAG.ALL):
rpmsigs=False, owner=None, type=None, extra=True, draft=None):
"""Returns a list of rpms and builds for specified tag
:param int|str tag: The tag name or ID to search
@ -1544,10 +1541,10 @@ def readTaggedRPMS(tag, package=None, arch=None, event=None, inherit=False, late
:param str type: Filter by build type. Supported types are 'maven',
'win', and 'image'.
:param bool extra: Set to "False" to skip the rpm extra info
:param DRAFT_FLAG draft: bit flag(enum.IntFlag) indicates
- DRAFT(1): draft only
- REGULAR(2): regular only
- ALL(3): both draft and regular builds
:param bool draft: bool or None option that indicates the filter based on draft field
- None: no filter (both draft and regular builds)
- True: draft only
- False: regular only
:returns: a two-element list. The first element is the list of RPMs, and
the second element is the list of builds.
"""
@ -4708,9 +4705,8 @@ def get_rpm(rpminfo, strict=False, multi=False, build=None):
return ret
@convert_draft_option
def list_rpms(buildID=None, buildrootID=None, imageID=None, componentBuildrootID=None, hostID=None,
arches=None, queryOpts=None, *, draft=DRAFT_FLAG.ALL):
arches=None, queryOpts=None, draft=None):
"""List RPMS. If buildID, imageID and/or buildrootID are specified,
restrict the list of RPMs to only those RPMs that are part of that
build, or were built in that buildroot. If componentBuildrootID is specified,
@ -4743,11 +4739,11 @@ def list_rpms(buildID=None, buildrootID=None, imageID=None, componentBuildrootID
If no build has the given ID, or the build generated no RPMs,
an empty list is returned.
The option draft with a bit flag(enum.IntFlag) value is to filter rpm by that
rpm belongs to a draft build, a regular build or both (default).
- DRAFT(1): draft only
- REGULAR(2): regular only
- ALL(3): both draft and regular
The option draft with a bool/None value is to filter rpm by that
rpm belongs to a draft build, a regular build or both (default). It stands for:
- None: no filter (both draft and regular builds)
- True: draft only
- False: regular only
"""
fields = [('rpminfo.id', 'id'), ('rpminfo.name', 'name'), ('rpminfo.version', 'version'),
@ -8501,8 +8497,7 @@ def query_history(tables=None, **kwargs):
return ret
@convert_draft_option
def untagged_builds(name=None, queryOpts=None, *, draft=DRAFT_FLAG.ALL):
def untagged_builds(name=None, queryOpts=None, *, draft=None):
"""Returns the list of untagged builds"""
st_complete = koji.BUILD_STATES['COMPLETE']
# following can be achieved with simple query but with
@ -11884,9 +11879,8 @@ class RootExports(object):
raise koji.GenericError("Finished task's priority can't be updated")
task.setPriority(priority, recurse=recurse)
@convert_draft_option
def listTagged(self, tag, event=None, inherit=False, prefix=None, latest=False, package=None,
owner=None, type=None, strict=True, extra=False, *, draft=DRAFT_FLAG.ALL):
owner=None, type=None, strict=True, extra=False, draft=None):
"""List builds tagged with tag.
:param int|str tag: tag name or ID number
@ -11902,10 +11896,10 @@ class RootExports(object):
:param bool strict: If tag doesn't exist, an exception is raised,
unless strict is False in which case returns an empty list.
:param bool extra: Set to "True" to get the build extra info
:param DRAFT_FLAG draft: bit flag(enum.IntFlag) indicates
- DRAFT(1): draft only
- REGULAR(2): regular only
- ALL(3): both draft and regular builds
:param bool draft: bool or None option that indicates the filter based on draft field
- None: no filter (both draft and regular builds)
- True: draft only
- False: regular only
"""
# lookup tag id
tag = get_tag(tag, strict=strict, event=event)
@ -11920,10 +11914,9 @@ class RootExports(object):
if build['package_name'].lower().startswith(prefix)]
return results
@convert_draft_option
def listTaggedRPMS(self, tag, event=None, inherit=False, latest=False, package=None, arch=None,
rpmsigs=False, owner=None, type=None, strict=True, extra=True,
*, draft=DRAFT_FLAG.ALL):
draft=None):
"""List rpms and builds within tag.
:param int|str tag: tag name or ID number
@ -11942,10 +11935,10 @@ class RootExports(object):
:param bool strict: If tag doesn't exist, an exception is raised,
unless strict is False in which case returns an empty list.
:param bool extra: Set to "False" to skip the rpms extra info
:param DRAFT_FLAG draft: bit flag(enum.IntFlag) indicates
- DRAFT(1): draft only
- REGULAR(2): regular only
- ALL(3): both draft and regular
:param bool draft: bool or None option that indicates the filter based on draft field
- None: no filter (both draft and regular builds)
- True: draft only
- False: regular only
"""
# lookup tag id
tag = get_tag(tag, strict=strict, event=event)
@ -11978,11 +11971,10 @@ class RootExports(object):
return readTaggedArchives(tag['id'], event=event, inherit=inherit, latest=latest,
package=package, type=type, extra=extra)
@convert_draft_option
def listBuilds(self, packageID=None, userID=None, taskID=None, prefix=None, state=None,
volumeID=None, source=None, createdBefore=None, createdAfter=None,
completeBefore=None, completeAfter=None, type=None, typeInfo=None,
queryOpts=None, pattern=None, cgID=None, *, draft=DRAFT_FLAG.ALL):
queryOpts=None, pattern=None, cgID=None, draft=None):
"""
Return a list of builds that match the given parameters
@ -12018,10 +12010,10 @@ class RootExports(object):
fields are matched
For type=win, the provided platform fields are matched
:param DRAFT_FLAG draft: bit flag(enum.IntFlag) indicates
- DRAFT(1): draft only
- REGULAR(2): regular only
- ALL(3): both draft and regular builds
:param bool draft: bool or None option that indicates the filter based on draft field
- None: no filter (both draft and regular builds)
- True: draft only
- False: regular only
:returns: Returns a list of maps. Each map contains the following keys:
@ -12182,8 +12174,7 @@ class RootExports(object):
return query.iterate()
@convert_draft_option
def getLatestBuilds(self, tag, event=None, package=None, type=None, *, draft=DRAFT_FLAG.ALL):
def getLatestBuilds(self, tag, event=None, package=None, type=None, draft=None):
"""List latest builds for tag (inheritance enabled, wrapper of readTaggedBuilds)
:param int tag: tag ID
@ -12191,10 +12182,10 @@ class RootExports(object):
:param int package: filter on package name
:param str type: restrict the list to builds of the given type. Currently the supported
types are 'maven', 'win', 'image', or any custom content generator btypes.
:param DRAFT_FLAG draft: bit flag(enum.IntFlag) indicates
- DRAFT(1): draft only
- REGULAR(2): regular only
- ALL(3): both draft and regular builds
:param bool draft: bool or None option that indicates the filter based on draft field
- None: no filter (both draft and regular builds)
- True: draft only
- False: regular only
:returns [dict]: list of buildinfo dicts
"""
@ -12204,9 +12195,8 @@ class RootExports(object):
return readTaggedBuilds(tag, event, inherit=True, latest=True, package=package, type=type,
draft=draft)
@convert_draft_option
def getLatestRPMS(self, tag, package=None, arch=None, event=None, rpmsigs=False, type=None,
*, draft=DRAFT_FLAG.ALL):
draft=None):
"""List latest RPMS for tag (inheritance enabled, wrapper of readTaggedBuilds)
:param int|str tag: The tag name or ID to search
@ -12219,10 +12209,10 @@ class RootExports(object):
:param bool rpmsigs: query will return one record per rpm/signature combination
:param str type: Filter by build type. Supported types are 'maven',
'win', and 'image'.
:param DRAFT_FLAG draft: bit flag(enum.IntFlag) indicates
- DRAFT(1): draft only
- REGULAR(2): regular only
- ALL(3): both draft and regular
:param bool draft: bool or None option that indicates the filter based on draft field
- None: no filter (both draft and regular builds)
- True: draft only
- False: regular only
:returns: a two-element list. The first element is the list of RPMs, and
the second element is the list of builds.
"""
@ -16027,27 +16017,24 @@ def reject_draft(buildinfo, error=None):
def append_draft_clause(draft, clauses, table=None):
"""append proper clause in build/rpm query for draft flags
"""append proper clause in build/rpm query for draft option
DRAFT=1: append "draft IS True"
REGULAR=2: append "draft IS NOT True"
ALL(DRAFT|REGULAR)=3: do nothing
:param DRAFT_FLAGS draft: draft bit flag(s)
:param bool draft: draft option:
True: append "draft IS True"
False: append "draft IS NOT True"
None: do nothing
:param list clauses: clauses list to construct query by QueryProcessor, which the draft clause
to append
"""
if not isinstance(draft, (DRAFT_FLAG)):
raise koji.ParameterError(f'draft must be a DRAFT_FLAG, but got {draft}')
if not table:
table = ''
else:
table += '.'
if DRAFT_FLAG.ALL in draft:
if draft is None:
return
if DRAFT_FLAG.DRAFT in draft:
if draft:
clauses.append(f'{table}draft IS TRUE')
if DRAFT_FLAG.REGULAR in draft:
else:
# null is included
clauses.append(f'{table}draft IS NOT TRUE')

View file

@ -103,7 +103,7 @@ n-v-r tag owner
self.session.getTag.assert_called_once_with(self.tag, event=self.event_id)
self.session.listTagged.assert_called_once_with(
self.tag, event=self.event_id, inherit=True, latest=True, package=self.pkg,
draft=2)
draft=False)
self.session.listTaggedRPMS.assert_not_called()
self.assert_console_message(stdout, expected)
@ -121,7 +121,7 @@ n-v-r tag owner
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_called_once_with(self.tag, event=None)
self.session.listTagged.assert_called_once_with(
self.tag, inherit=True, latest=True, package=self.pkg, draft=1)
self.tag, inherit=True, latest=True, package=self.pkg, draft=True)
self.session.listTaggedRPMS.assert_not_called()
@mock.patch('sys.stdout', new_callable=six.StringIO)

View file

@ -101,7 +101,7 @@ class TestListBuilds(unittest.TestCase):
package_id = 1
self.get_package_id.return_value = package_id
self.query_executeOne.return_value = None
self.exports.listBuilds(packageID=package, draft=1)
self.exports.listBuilds(packageID=package, draft=True)
self.assertEqual(len(self.queries), 1)
args, kwargs = self.QueryProcessor.call_args
qp = QP(**kwargs)

View file

@ -84,7 +84,7 @@ class TestReadTaggedBuilds(unittest.TestCase):
'package': None, 'packages': self.package_list,
'queryOpts': {'order': '-create_event'}, 'st_complete': 1, 'tables': self.tables,
'tag': self.tag_name, 'tagid': self.tag_name, 'taglist': [self.tag_name],
'type': None, 'draft': 3
'type': None, 'draft': None
}
self.assertEqual(query.tables, self.tables)
self.assertEqual(query.joins, self.joins)
@ -120,7 +120,7 @@ class TestReadTaggedBuilds(unittest.TestCase):
'package': self.pkg_name, 'packages': self.package_list,
'queryOpts': {'order': '-create_event'}, 'st_complete': 1, 'tables': self.tables,
'tag': self.tag_name, 'tagid': self.tag_name, 'taglist': [self.tag_name],
'type': 'maven', 'draft': 3}
'type': 'maven', 'draft': None}
self.assertEqual(query.tables, self.tables)
self.assertEqual(query.joins, joins)
self.assertEqual(set(query.columns), set(columns))
@ -149,7 +149,7 @@ class TestReadTaggedBuilds(unittest.TestCase):
'package': None, 'packages': self.package_list,
'queryOpts': {'order': '-create_event'}, 'st_complete': 1, 'tables': self.tables,
'tag': self.tag_name, 'tagid': self.tag_name, 'taglist': [self.tag_name],
'type': 'win', 'draft': 3}
'type': 'win', 'draft': None}
self.assertEqual(query.tables, self.tables)
self.assertEqual(query.joins, joins)
self.assertEqual(set(query.columns), set(columns))
@ -178,7 +178,7 @@ class TestReadTaggedBuilds(unittest.TestCase):
'package': None, 'packages': self.package_list,
'queryOpts': {'order': '-create_event'}, 'st_complete': 1, 'tables': self.tables,
'tag': self.tag_name, 'tagid': self.tag_name, 'taglist': [self.tag_name],
'type': 'image', 'draft': 3}
'type': 'image', 'draft': None}
self.assertEqual(query.tables, self.tables)
self.assertEqual(query.joins, joins)
self.assertEqual(set(query.columns), set(columns))
@ -213,7 +213,7 @@ class TestReadTaggedBuilds(unittest.TestCase):
'package': None, 'packages': self.package_list,
'queryOpts': {'order': '-create_event'}, 'st_complete': 1, 'tables': self.tables,
'tag': self.tag_name, 'tagid': self.tag_name, 'taglist': [self.tag_name],
'type': type, 'draft': 3}
'type': type, 'draft': None}
self.assertEqual(query.tables, self.tables)
self.assertEqual(query.joins, joins)
self.assertEqual(set(query.columns), set(self.columns))
@ -223,7 +223,7 @@ class TestReadTaggedBuilds(unittest.TestCase):
def test_get_tagged_builds_draft(self):
self.readPackageList.return_value = self.package_list
kojihub.readTaggedBuilds(self.tag_name, draft=koji.DRAFT_FLAG.DRAFT)
kojihub.readTaggedBuilds(self.tag_name, draft=True)
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
@ -236,7 +236,7 @@ class TestReadTaggedBuilds(unittest.TestCase):
'package': None, 'packages': self.package_list,
'queryOpts': {'order': '-create_event'}, 'st_complete': 1, 'tables': self.tables,
'tag': self.tag_name, 'tagid': self.tag_name, 'taglist': [self.tag_name],
'type': None, 'draft': koji.DRAFT_FLAG.DRAFT
'type': None, 'draft': True
}
self.assertEqual(query.tables, self.tables)

View file

@ -105,7 +105,7 @@ class TestReadTaggedRPMS(unittest.TestCase):
def test_get_tagged_rpms_draft(self):
self.readTaggedBuilds.return_value = self.build_list
kojihub.readTaggedRPMS(self.tag_name, draft=2, extra=False)
kojihub.readTaggedRPMS(self.tag_name, draft=False, extra=False)
self.assertEqual(len(self.queries), 1)
query = self.queries[0]