#2894 sidetags: configurable naming template
Merged a year ago by tkopecek. Opened a year ago by tkopecek.
tkopecek/koji issue2893  into  master

file modified
+14 -3
@@ -130,9 +130,20 @@ 

  as one of available API calls.

  

  Plugin has also its own configuration file

- ``/etc/koji-hub/plugins/sidetag.conf`` which for now contains the only boolean

- option ``remove_empty``. If it is set, sidetag is automatically deleted when

- last package is untagged from there.

+ ``/etc/koji-hub/plugins/sidetag.conf`` which contains following options:

+ 

+ .. glossary::

+    remove_empty = off

+        If this is set, sidetag is automatically deleted when

+        last package is untagged from there.

+ 

+    allowed_suffixes =

+        List of strings delimited by commas. These suffixes are then allowed to

+        be requested via ``createSideTag``

+ 

+    name_template = {basetag}s-side-{tag_id}d

+        Python string template to be used for generation of sidetag name. It needs

+        to contain both basetag/tag_id placeholders.

  

  CLI

  ---

@@ -3,3 +3,7 @@ 

  remove_empty = off

  # potential suffixes for sidetag names

  # allowed_suffixes =

+ # template for sidetag names. It must contain basetag and tag_id parts

+ # if allowed_suffixes is not empty and suffix was requested, it will be added

+ # as {name_template}-{suffix}. (percent-signs need to be escaped)

+ # name_template = {basetag}-side-{tag_id}

file modified
+6 -2
@@ -118,7 +118,7 @@ 

      # ugly, it will waste one number in tag_id_seq, but result will match with

      # id assigned by _create_tag

      tag_id = nextval("tag_id_seq") + 1

-     sidetag_name = "%s-side-%s" % (basetag["name"], tag_id)

+     sidetag_name = NAME_TEMPLATE.format(basetag=basetag["name"], tag_id=tag_id)

      if suffix:

          sidetag_name += '-%s' % suffix

      extra = {
@@ -313,10 +313,14 @@ 

  

  # read config and register

  if not CONFIG:

-     CONFIG = koji.read_config_files(CONFIG_FILE)

+     CONFIG = koji.read_config_files(CONFIG_FILE, raw=True)

      if CONFIG.has_option("sidetag", "remove_empty") and CONFIG.getboolean(

          "sidetag", "remove_empty"

      ):

          handle_sidetag_untag = callback("postUntag")(handle_sidetag_untag)

      if CONFIG.has_option("sidetag", "allowed_suffixes"):

          ALLOWED_SUFFIXES = CONFIG.get("sidetag", "allowed_suffixes").split(',')

+     if CONFIG.has_option("sidetag", "name_template"):

+         NAME_TEMPLATE = CONFIG.get("sidetag", "name_template")

+     else:

+         NAME_TEMPLATE = '{basetag}-side-{tag_id}'

@@ -0,0 +1,102 @@ 

+ from __future__ import absolute_import

+ import mock

+ import unittest

+ 

+ import koji

+ import kojihub

+ import sidetag_hub

+ 

+ 

+ class TestSideTagHub(unittest.TestCase):

+     def setUp(self):

+         self.QueryProcessor = mock.patch('sidetag_hub.QueryProcessor',

+                 side_effect=self.getQuery).start()

+         self.queries = []

+ 

+     def getQuery(self, *args, **kwargs):

+         query = kojihub.QueryProcessor(*args, **kwargs)

+         query.execute = mock.MagicMock()

+         query.executeOne = mock.MagicMock()

+         query.executeOne.return_value = {'user_tags': 0}

+         self.queries.append(query)

+         return query

+ 

+     @mock.patch('sidetag_hub.nextval')

+     @mock.patch('sidetag_hub._create_build_target')

+     @mock.patch('sidetag_hub._create_tag')

+     @mock.patch('sidetag_hub.assert_policy')

+     @mock.patch('sidetag_hub.get_tag')

+     @mock.patch('sidetag_hub.get_user')

+     @mock.patch('sidetag_hub.context')

+     def test_createsidetag_basic(self, context, get_user, get_tag, assert_policy,

+                                  _create_tag, _create_build_target, nextval):

+         basetag = {

+             'id': 32,

+             'name': 'base_tag',

+             'arches': ['x86_64', 'i686']

+         }

+         user = {

+             'id': 23,

+             'name': 'username',

+         }

+         sidetag_name = 'base_tag-side-12346'

+         context.session.assertLogin = mock.MagicMock()

+         context.session.user_id = 123

+         get_user.return_value = user

+         get_tag.return_value = basetag

+         nextval.return_value = 12345

+         _create_tag.return_value = 12346

+ 

+         ret = sidetag_hub.createSideTag('base_tag')

+         self.assertEqual(ret, {'name': sidetag_name, 'id': 12346})

+ 

+         get_user.assert_called_once_with(123, strict=True)

+         get_tag.assert_called_once_with(basetag['name'], strict=True)

+         assert_policy.assert_called_once_with(

+             "sidetag", {"tag": basetag["id"], "number_of_tags": 0}

+         )

+         nextval.assert_called_once_with('tag_id_seq')

+         _create_tag.assert_called_once_with(

+                 sidetag_name,

+                 parent=basetag['id'],

+                 arches=basetag['arches'],

+                 extra={

+                     "sidetag": True,

+                     "sidetag_user": user["name"],

+                     "sidetag_user_id": user["id"],

+                 })

+         _create_build_target.assert_called_once_with(sidetag_name, 12346, 12346)

+ 

+     @mock.patch('sidetag_hub.nextval')

+     @mock.patch('sidetag_hub._create_build_target')

+     @mock.patch('sidetag_hub._create_tag')

+     @mock.patch('sidetag_hub.assert_policy')

+     @mock.patch('sidetag_hub.get_tag')

+     @mock.patch('sidetag_hub.get_user')

+     @mock.patch('sidetag_hub.context')

+     def test_createsidetag_template(self, context, get_user, get_tag, assert_policy,

+                                     _create_tag, _create_build_target, nextval):

+         basetag = {

+             'id': 32,

+             'name': 'base_tag',

+             'arches': ['x86_64', 'i686']

+         }

+         user = {

+             'id': 23,

+             'name': 'username',

+         }

+         sidetag_name = 'base_tag-sidetag-12346-suffix'

+         context.session.assertLogin = mock.MagicMock()

+         context.session.user_id = 123

+         get_user.return_value = user

+         get_tag.return_value = basetag

+         nextval.return_value = 12345

+         _create_tag.return_value = 12346

+         sidetag_hub.ALLOWED_SUFFIXES = ['suffix', 'another']

+         sidetag_hub.NAME_TEMPLATE = '{basetag}-sidetag-{tag_id}'

+ 

+         ret = sidetag_hub.createSideTag('base_tag', suffix='suffix')

+         self.assertEqual(ret, {'name': sidetag_name, 'id': 12346})

+ 

+         with self.assertRaises(koji.GenericError):

+             ret = sidetag_hub.createSideTag('base_tag', suffix='forbidden_suffix')

Having to use the escaped percent in the config (%%) is awkward and error -prone. Is there any barrier to passing raw=True to koji.read_config_files() as we do for the hub?

If we do need to keep that, then it should be documented.

Alternately, might it make sense to use .format() instead?

Need to update docs/source/plugins.rst

This appears to be debug code

+ print(open(CONFIG_FILE).read())

Looks like we have no unit tests for this plugin. That doesn't have to be solved in this PR, but....

4 new commits added

  • basic test
  • remove debug
  • use format for name_template
  • update docs
a year ago

updated with at least some basic test for creating tag

Commit b345b62 fixes this pull-request

Pull-Request has been merged by tkopecek

a year ago

Metadata Update from @tkopecek:
- Pull-request tagged with: testing-ready

a year ago