Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package openSUSE-release-tools for
openSUSE:Factory checked in at 2021-08-05 20:48:07
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/openSUSE-release-tools (Old)
and /work/SRC/openSUSE:Factory/.openSUSE-release-tools.new.1899 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "openSUSE-release-tools"
Thu Aug 5 20:48:07 2021 rev:313 rq:910295 version:20210805.5b68d530
Changes:
--------
---
/work/SRC/openSUSE:Factory/openSUSE-release-tools/openSUSE-release-tools.changes
2021-07-29 21:33:06.940685973 +0200
+++
/work/SRC/openSUSE:Factory/.openSUSE-release-tools.new.1899/openSUSE-release-tools.changes
2021-08-05 20:48:40.643893365 +0200
@@ -1,0 +2,15 @@
+Thu Aug 05 10:57:53 UTC 2021 - [email protected]
+
+- Update to version 20210805.5b68d530:
+ * OBSLocal: top-level classes documentation to clarify the scope
+ * Point to osc.core to compare the APIs
+ * More improvements in the OBSLocal.py documentation
+ * In OBSLocal.StagingWorkflow.submit_package, package may not be None
+ * Some convenience extensions to OBSLocal
+ * OBSLocal: improved management of meta
+ * Tiny fix in check_source_test.py
+ * Improvements in the OBSLocal.py documentation
+ * Convert OBSLocal documentation to reStructured Text
+ * document OBSLocal.py
+
+-------------------------------------------------------------------
Old:
----
openSUSE-release-tools-20210729.455dc99c.obscpio
New:
----
openSUSE-release-tools-20210805.5b68d530.obscpio
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ openSUSE-release-tools.spec ++++++
--- /var/tmp/diff_new_pack.zGG9cL/_old 2021-08-05 20:48:41.287892642 +0200
+++ /var/tmp/diff_new_pack.zGG9cL/_new 2021-08-05 20:48:41.291892638 +0200
@@ -20,7 +20,7 @@
%define source_dir openSUSE-release-tools
%define announcer_filename factory-package-news
Name: openSUSE-release-tools
-Version: 20210729.455dc99c
+Version: 20210805.5b68d530
Release: 0
Summary: Tools to aid in staging and release work for openSUSE/SUSE
License: GPL-2.0-or-later AND MIT
++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.zGG9cL/_old 2021-08-05 20:48:41.359892562 +0200
+++ /var/tmp/diff_new_pack.zGG9cL/_new 2021-08-05 20:48:41.359892562 +0200
@@ -1,6 +1,6 @@
<servicedata>
<service name="tar_scm">
<param
name="url">https://github.com/openSUSE/openSUSE-release-tools.git</param>
- <param
name="changesrevision">c838245a377d88baed3e6e8b132d0db6a367b9b8</param>
+ <param
name="changesrevision">b188340266cdd7d9621ddd5085f600fc03186ad6</param>
</service>
</servicedata>
++++++ openSUSE-release-tools-20210729.455dc99c.obscpio ->
openSUSE-release-tools-20210805.5b68d530.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openSUSE-release-tools-20210729.455dc99c/tests/OBSLocal.py
new/openSUSE-release-tools-20210805.5b68d530/tests/OBSLocal.py
--- old/openSUSE-release-tools-20210729.455dc99c/tests/OBSLocal.py
2021-07-29 12:48:27.000000000 +0200
+++ new/openSUSE-release-tools-20210805.5b68d530/tests/OBSLocal.py
2021-08-05 12:55:11.000000000 +0200
@@ -166,9 +166,18 @@
class StagingWorkflow(object):
+ """This class is intended to setup and manipulate the environment
(projects, users, etc.) in
+ the local OBS instance used to tests the release tools. It makes easy to
setup scenarios similar
+ to the ones used during the real (open)SUSE development, with staging
projects, rings, etc.
+ """
def __init__(self, project=PROJECT):
- """
- Initialize the configuration
+ """Initializes the configuration
+
+ Note this constructor calls :func:`create_target`, which implies
several projects and users
+ are created right away.
+
+ :param project: default target project
+ :type project: str
"""
THIS_DIR = os.path.dirname(os.path.abspath(__file__))
oscrc = os.path.join(THIS_DIR, 'test.oscrc')
@@ -205,6 +214,12 @@
self.api = StagingAPI(APIURL, project)
def load_config(self, project=None):
+ """Loads the corresponding :class:`osclib.Config` object into the
attribute ``config``
+
+ :param project: target project name
+ :type project: str
+ """
+
if project is None:
project = self.project
self.config = Config(APIURL, project)
@@ -248,7 +263,15 @@
attribute_value_save(APIURL, self.project, 'Config',
'\n'.join(config_lines))
def create_group(self, name, users=[]):
+ """Creates a group and assigns users to it.
+
+ If the group already exists then it just updates it users.
+ :param name: name of group
+ :type name: str
+ :param users: list of users to be in group
+ :type users: list(str)
+ """
meta = """
<group>
<title>{}</title>
@@ -268,6 +291,17 @@
osc.core.http_PUT(url, data=meta)
def create_user(self, name):
+ """Creates a user and their home project.
+
+ Do nothing if the user already exists.
+ Password is always "opensuse".
+
+ The home project is not really created in the OBS instance, but
:func:`Project.update_meta`
+ can be used to create it.
+
+ :param name: name of the user
+ :type name: str
+ """
if name in self.users: return
meta = """
<person>
@@ -285,6 +319,17 @@
self.projects[home_project] = Project(home_project, create=False)
def create_target(self):
+ """Creates
+
+ - target project
+ - "staging-bot" user
+ - "factory-staging" group
+
+ setup staging and also ``*:Staging:A`` and ``*:Staging:B`` projects.
+
+ After the execution, the target project is indexed in the projects
dictionary twice,
+ by its name and as 'target'.
+ """
if self.projects.get('target'): return
self.create_user('staging-bot')
self.create_group('factory-staging', users=['staging-bot'])
@@ -299,11 +344,23 @@
self.projects['staging:A'] = Project(self.project + ':Staging:A',
create=False)
self.projects['staging:B'] = Project(self.project + ':Staging:B',
create=False)
- def setup_rings(self):
+ def setup_rings(self, devel_project=None):
+ """Creates a typical Factory setup with rings.
+
+ It creates three projects: 'ring0', 'ring1' and the target (see
:func:`create_target`).
+ It also creates a 'wine' package in the target project and a link from
it to ring1.
+ It sets the devel project for the package if ``devel_project`` is
given.
+
+ :param devel_project: name of devel project. It must exist and contain
a 'wine' package,
+ otherwise OBS returns an error code.
+ :type devel_project: str or None
+ """
self.create_target()
self.projects['ring0'] = Project(name=self.project +
':Rings:0-Bootstrap')
self.projects['ring1'] = Project(name=self.project +
':Rings:1-MinimalX')
- target_wine = Package(name='wine', project=self.projects['target'])
+ target_wine = Package(
+ name='wine', project=self.projects['target'],
devel_project=devel_project
+ )
target_wine.create_commit()
self.create_link(target_wine, self.projects['ring1'])
@@ -321,6 +378,13 @@
return target_package
def create_project(self, name, reviewer={}, maintainer={},
project_links=[]):
+ """Creates project if it does not already exist.
+
+ For params see the constructor of :class:`Project`
+
+ :return: the project instance representing the given project
+ :rtype: Project
+ """
if isinstance(name, Project):
return name
if name in self.projects:
@@ -330,7 +394,18 @@
project_links=project_links)
return self.projects[name]
- def submit_package(self, package=None, project=None):
+ def submit_package(self, package, project=None):
+ """Creates submit request from package to target project.
+
+ Both have to exist (Use :func:`create_submit_request` otherwise).
+
+ :param package: package to submit
+ :type package: Package
+ :param project: project where to send submit request, None means use
the default.
+ :type project: Project or str or None
+ :return: created request.
+ :rtype: Request
+ """
if not project:
project = self.project
request = Request(source_package=package, target_project=project)
@@ -345,6 +420,21 @@
return request
def create_submit_request(self, project, package, text=None):
+ """Creates submit request from package in specified project to default
project.
+
+ It creates project if not exist and also package.
+ Package is commited with optional text.
+ Note different parameters than submit_package.
+
+ :param project: project where package will live
+ :type project: Project or str
+ :param package: package name to create
+ :type package: str
+ :param text: commit message for initial package creation
+ :type text: str
+ :return: created request.
+ :rtype: Request
+ """
project = self.create_project(project)
package = Package(name=package, project=project)
package.create_commit(text=text)
@@ -404,7 +494,36 @@
self.api._invalidate_all()
class Project(object):
+ """This class represents a project in the testing environment of the
release tools. It usually
+ corresponds to a project in the local OBS instance that is used by the
tests.
+
+ The class offers methods to setup and configure such projects to simulate
the different testing
+ scenarios.
+
+ Not to be confused with the class Project in osc.core_, aimed to allow osc
to manage projects
+ from real OBS instances
+
+ .. _osc.core: https://github.com/openSUSE/osc/blob/master/osc/core.py
+
+ """
def __init__(self, name, reviewer={}, maintainer={}, project_links=[],
create=True, with_repo=False):
+ """Initializes a new Project object.
+
+ If ``create`` is False, an object is created but the project is not
registered in the OBS
+ instance. If ``create`` is True, the project is created in the OBS
instance with the given
+ meta information (by passing that information directly to
:func:`update_meta`).
+
+ TODO: a class should be introduced to represent the meta information.
See :func:`get_meta`.
+
+ :param name: project name
+ :type name: str
+ :param reviewer: see the corresponding parameter at :func:`update_meta`
+ :param maintainer: see :func:`update_meta`
+ :param project_links: see :func:`update_meta`
+ :param create: whether the project should be registed in the OBS
instance
+ :type create: bool
+ :param with_repo: see :func:`update_meta`
+ """
self.name = name
self.packages = []
@@ -414,6 +533,21 @@
self.update_meta(reviewer, maintainer, project_links,
with_repo=with_repo)
def update_meta(self, reviewer={}, maintainer={}, project_links=[],
with_repo=False):
+ """Sets the meta information for the project in the OBS instance
+
+ If the project does not exist in the OBS instance, calling this method
will register it.
+
+ TODO: a class should be introduced to represent the meta. See
:func:`get_meta`.
+
+ :param reviewer: see the ``'reviewer'`` key of the meta dictionary at
:func:`get_meta`
+ :type reviewer: dict[str, list(str)]
+ :param maintainer: see the ``'maintainer'`` key of the meta dictionary
at :func:`get_meta`
+ :type maintainer: dict[str, list(str)]
+ :param project_links: names of linked project from which it inherits
+ :type project_links: list(str)
+ :param with_repo: whether a repository should be created as part of
the meta
+ :type with_repo: bool
+ """
meta = """
<project name="{0}">
<title></title>
@@ -440,6 +574,65 @@
self.custom_meta(ET.tostring(root))
+ def get_meta(self):
+ """Data from the meta section of the project in the OBS instance
+
+ TODO: a class should be introduced to represent the meta, a set of
nested dictionaries
+ is definitely not the way to go for the long term. The structure of
the dictionary has
+ to be managed at several places and the corresponding keys pollute the
signature of the
+ ``Project`` constructor and also other methods like
:func:`update_meta`.
+
+ Currently, the meta information is represented by a dictionary with
the following keys
+ and values:
+
+ * ``'reviewer'``: contains a dictionary with two keys 'groups' and
'users', each of them
+ containing a list of strings with names of the corresponding
reviewers of the project
+ * ``'maintainer'``: same structure as 'reviewer', but with lists of
maintainer names
+ * ``'project_links'``: list of names of linked projects
+ * ``'with_repo'``: boolean indicating whether the meta includes some
repository
+
+ :return: the meta dictionary, see description above
+ :rtype: dict[str, dict or list(str) or bool]
+ """
+ meta = {
+ 'reviewer': { 'groups': [], 'users': [] },
+ 'maintainer': { 'groups': [], 'users': [] },
+ 'project_links': [],
+ 'with_repo': False
+ }
+ url = osc.core.make_meta_url('prj', self.name, APIURL)
+ data = ET.parse(osc.core.http_GET(url))
+ for child in data.getroot():
+ if child.tag == 'repository':
+ meta['with_repo'] = True
+ elif child.tag == 'link':
+ meta['project_links'].append(child.attrib['project'])
+ elif child.tag == 'group':
+ role = child.attrib['role']
+ if role not in ['reviewer', 'maintainer']:
+ continue
+ meta[role]['groups'].append(child.attrib['groupid'])
+ elif child.tag == 'person':
+ role = child.attrib['role']
+ if role not in ['reviewer', 'maintainer']:
+ continue
+ meta[role]['users'].append(child.attrib['userid'])
+
+ return meta
+
+ def add_reviewers(self, users = [], groups = []):
+ """Adds the given reviewers to the meta information of the project
+
+ :param users: usernames to add to the current list of reviewers
+ :type users: list(str)
+ :param groups: groups to add to the current list of reviewers
+ :type groups: list(str)
+ """
+ meta = self.get_meta()
+ meta['reviewer']['users'] = list(set(meta['reviewer']['users'] +
users))
+ meta['reviewer']['groups'] = list(set(meta['reviewer']['groups'] +
groups))
+ self.update_meta(**meta)
+
def add_package(self, package):
self.packages.append(package)
@@ -466,7 +659,27 @@
self.remove()
class Package(object):
+ """This class represents a package in the local OBS instance used to test
the release tools and
+ offers methods to create and modify such packages in order to simulate the
different testing
+ scenarios.
+
+ Not to be confused with the class Package in osc.core_, aimed to allow osc
to manage packages
+ from real OBS instances
+
+ .. _osc.core: https://github.com/openSUSE/osc/blob/master/osc/core.py
+ """
def __init__(self, name, project, devel_project=None):
+ """Creates a package in the OBS instance and instantiates an object to
represent it
+
+ :param name: Package name
+ :type name: str
+ :param project: project where package lives
+ :type project: Project
+ :param devel_project: name of devel project. Package has to already
exists there,
+ otherwise OBS returns 400.
+ :type devel_project: str
+ """
+
self.name = name
self.project = project
@@ -512,8 +725,29 @@
text = ''.join([random.choice(string.ascii_letters) for i in
range(40)])
osc.core.http_PUT(url, data=text)
+ def commit_files(self, path):
+ """Commits to the package the files in the given directory
+
+ Useful to load fixtures.
+
+ :param path: path to a directory containing the files that must be
added to the package
+ """
+ for filename in os.listdir(path):
+ with open(os.path.join(path, filename)) as f:
+ self.create_commit(filename=filename, text=f.read())
+
class Request(object):
+ """This class represents a request in the local OBS instance used to test
the release tools and
+ offers methods to create and modify such requests in order to simulate the
different testing
+ scenarios.
+
+ Not to be confused with the class Request in osc.core_, aimed to allow osc
to create and
+ manage requests on real OBS instances
+
+ .. _osc.core: https://github.com/openSUSE/osc/blob/master/osc/core.py
+ """
def __init__(self, source_package=None, target_project=None,
target_package=None, type='submit'):
+ """Creates a request in the OBS instance and instantiates an object to
represent it"""
self.revoked = True
if type == 'submit':
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openSUSE-release-tools-20210729.455dc99c/tests/check_source_tests.py
new/openSUSE-release-tools-20210805.5b68d530/tests/check_source_tests.py
--- old/openSUSE-release-tools-20210729.455dc99c/tests/check_source_tests.py
2021-07-29 12:48:27.000000000 +0200
+++ new/openSUSE-release-tools-20210805.5b68d530/tests/check_source_tests.py
2021-08-05 12:55:11.000000000 +0200
@@ -25,6 +25,7 @@
# Using OBSLocal.StagingWorkflow makes it easier to setup testing
scenarios
self.wf = OBSLocal.StagingWorkflow(PROJECT)
+ self.project = self.wf.projects[PROJECT]
# Set up the reviewers team
self.wf.create_group(REVIEW_TEAM)
@@ -35,9 +36,8 @@
self.bot_user = 'factory-auto'
self.wf.create_user(self.bot_user)
- self.project = self.wf.create_project(PROJECT)
# When creating a review, set the by_user to bot_user
- self.project.update_meta(reviewer={'users': [self.bot_user]})
+ self.project.add_reviewers(users = [self.bot_user])
# Ensure different test runs operate in unique namespace.
self.bot_name = '::'.join([type(self).__name__,
str(random.getrandbits(8))])
@@ -164,13 +164,7 @@
devel_project = self.wf.create_project(SRC_PROJECT,
maintainer=maintainer)
devel_package = OBSLocal.Package('blowfish', project=devel_project)
- blowfish_spec = os.path.join(FIXTURES, 'packages', 'blowfish',
'blowfish.spec')
- with open(blowfish_spec) as f:
- devel_package.create_commit(filename='blowfish.spec',
text=f.read())
-
- blowfish_changes = os.path.join(FIXTURES, 'packages', 'blowfish',
'blowfish.changes')
- with open(blowfish_changes) as f:
- devel_package.create_commit(filename='blowfish.changes',
text=f.read())
+ fixtures_path = os.path.join(FIXTURES, 'packages', 'blowfish')
+ devel_package.commit_files(fixtures_path)
- devel_package.create_file(filename='blowfish-1.tar.gz')
- target_package = OBSLocal.Package('blowfish',
self.wf.projects['target'], devel_project=SRC_PROJECT)
+ OBSLocal.Package('blowfish', self.project, devel_project=SRC_PROJECT)
++++++ openSUSE-release-tools.obsinfo ++++++
--- /var/tmp/diff_new_pack.zGG9cL/_old 2021-08-05 20:48:41.963891884 +0200
+++ /var/tmp/diff_new_pack.zGG9cL/_new 2021-08-05 20:48:41.967891880 +0200
@@ -1,5 +1,5 @@
name: openSUSE-release-tools
-version: 20210729.455dc99c
-mtime: 1627555707
-commit: 455dc99c10beb8e109a8439d52c4c500da6fc26d
+version: 20210805.5b68d530
+mtime: 1628160911
+commit: 5b68d530e89562e130939079d2314ba6e6f808fa