Repository: packit-service/packit
Pull request #839 (2020-05-25 15:35:05)

Implement aliases for koji targets
- Implement aliases for koji-targets and add `get_all_koji_targets` function.
- Return empty set in the aliase-expansion methods when `default=None` to be able to not expand defaults when not needed.
- We can use that for CLI. (Follow-up.)


Patch:
diff --git a/packit/config/aliases.py b/packit/config/aliases.py
index 95d35b67..14b83cc3 100644
--- a/packit/config/aliases.py
+++ b/packit/config/aliases.py
@@ -22,6 +22,7 @@
 from typing import Dict, List, Set
 
 from packit.exceptions import PackitException
+from packit.utils import run_command
 
 ALIASES: Dict[str, List[str]] = {
     "fedora-development": ["fedora-rawhide"],
@@ -48,6 +49,9 @@ def get_versions(*name: str, default=DEFAULT_VERSION) -> Set[str]:
     :param default: used if no positional argument was given
     :return: set of string containing system name and version
     """
+    if not default and not name:
+        return set()
+
     names = list(name) or [default]
     versions: Set[str] = set()
     for one_name in names:
@@ -64,6 +68,9 @@ def get_build_targets(*name: str, default=DEFAULT_VERSION) -> Set[str]:
     :param default: used if no positional argument was given
     :return: set of build targets
     """
+    if not default and not name:
+        return set()
+
     names = list(name) or [default]
     possible_sys_and_versions: Set[str] = set([])
     for one_name in names:
@@ -114,6 +121,9 @@ def get_branches(*name: str, default=DEFAULT_VERSION) -> Set[str]:
     :param default: used if no positional argument was given
     :return: set of dist-git branch names
     """
+    if not default and not name:
+        return set()
+
     names = list(name) or [default]
     branches = set()
 
@@ -138,3 +148,37 @@ def get_branches(*name: str, default=DEFAULT_VERSION) -> Set[str]:
             branches.add(sys_and_version)
 
     return branches
+
+
+def get_koji_targets(*name: str, default=DEFAULT_VERSION) -> Set[str]:
+    if not default and not name:
+        return set()
+
+    names = list(name) or [default]
+    targets = set()
+
+    for sys_and_version in get_versions(*names):
+        if sys_and_version == "fedora-rawhide":
+            targets.add("rawhide")
+        elif sys_and_version.startswith("fedora"):
+            sys, version = sys_and_version.rsplit("-", maxsplit=1)
+            targets.add(f"f{version}")
+        elif sys_and_version.startswith("el") and sys_and_version[2:].isnumeric():
+            targets.add(f"epel{sys_and_version[2:]}")
+        elif sys_and_version.startswith("epel"):
+            split = sys_and_version.rsplit("-", maxsplit=1)
+            if len(split) == 2:
+                sys, version = split
+                if version.isnumeric():
+                    targets.add(f"epel{version}")
+                    continue
+            targets.add(sys_and_version)
+        else:
+            # We don't know, let's leave the original name.
+            targets.add(sys_and_version)
+
+    return targets
+
+
+def get_all_koji_targets() -> List[str]:
+    return run_command(["koji", "list-targets", "--quiet"], output=True).split()


Test patch:
diff --git a/tests/spellbook.py b/tests/spellbook.py
index 6bafdcde..025a0f43 100644
--- a/tests/spellbook.py
+++ b/tests/spellbook.py
@@ -215,3 +215,373 @@ def can_a_module_be_imported(module_name):
         return True
     except ImportError:
         return False
+
+
+ALL_KOJI_TARGETS_SNAPSHOT = [
+    "dist-6E-epel",
+    "dist-6E-epel-build",
+    "dist-6E-epel-testing-candidate",
+    "dist-6E-epel-testing-candidate",
+    "dist-6E-epel-build",
+    "dist-6E-epel-testing-candidate",
+    "el6-candidate",
+    "dist-6E-epel-build",
+    "dist-6E-epel-testing-candidate",
+    "eln",
+    "eln-build",
+    "eln-updates-candidate",
+    "eln-candidate",
+    "eln-build",
+    "eln-updates-candidate",
+    "eln-rebuild",
+    "eln-build",
+    "eln-rebuild",
+    "epel6-infra",
+    "epel6-infra",
+    "epel6-infra-candidate",
+    "epel7",
+    "epel7-build",
+    "epel7-testing-candidate",
+    "epel7-candidate",
+    "epel7-build",
+    "epel7-testing-candidate",
+    "epel7-infra",
+    "epel7-infra-build",
+    "epel7-infra-candidate",
+    "epel7-infra-mailman",
+    "epel7-infra-mailman",
+    "epel7-infra-mailman-candidate",
+    "epel8",
+    "epel8-build",
+    "epel8-testing-candidate",
+    "epel8-candidate",
+    "epel8-build",
+    "epel8-testing-candidate",
+    "epel8-infra",
+    "epel8-infra-build",
+    "epel8-infra-candidate",
+    "epel8-playground",
+    "epel8-playground-build",
+    "epel8-playground-pending",
+    "epel8-playground-candidate",
+    "epel8-playground-build",
+    "epel8-playground-pending",
+    "f30",
+    "f30-build",
+    "f30-updates-candidate",
+    "f30-candidate",
+    "f30-build",
+    "f30-updates-candidate",
+    "f30-container-candidate",
+    "f30-container-build",
+    "f30-container-updates-candidate",
+    "f30-coreos-continuous",
+    "f30-build",
+    "f30-coreos-continuous",
+    "f30-flatpak-candidate",
+    "f30-build",
+    "f30-flatpak-updates-candidate",
+    "f30-infra",
+    "f30-infra-build",
+    "f30-infra-candidate",
+    "f30-kde",
+    "f30-kde",
+    "f30-kde",
+    "f30-rebuild",
+    "f30-build",
+    "f30-rebuild",
+    "f31",
+    "f31-build",
+    "f31-updates-candidate",
+    "f31-build-side-18630",
+    "f31-build-side-18630",
+    "f31-build-side-18630",
+    "f31-build-side-23208",
+    "f31-build-side-23208",
+    "f31-build-side-23208",
+    "f31-build-side-23528",
+    "f31-build-side-23528",
+    "f31-build-side-23528",
+    "f31-build-side-23731",
+    "f31-build-side-23731",
+    "f31-build-side-23731",
+    "f31-build-side-23745",
+    "f31-build-side-23745",
+    "f31-build-side-23745",
+    "f31-candidate",
+    "f31-build",
+    "f31-updates-candidate",
+    "f31-container-candidate",
+    "f31-container-build",
+    "f31-container-updates-candidate",
+    "f31-coreos-continuous",
+    "f31-build",
+    "f31-coreos-continuous",
+    "f31-flatpak-candidate",
+    "f31-build",
+    "f31-flatpak-updates-candidate",
+    "f31-infra",
+    "f31-infra-build",
+    "f31-infra-candidate",
+    "f31-kde",
+    "f31-kde",
+    "f31-kde",
+    "f31-rebuild",
+    "f31-build",
+    "f31-rebuild",
+    "f32",
+    "f32-build",
+    "f32-updates-candidate",
+    "f32-build-side-14233",
+    "f32-build-side-14233",
+    "f32-build-side-14233",
+    "f32-build-side-18049",
+    "f32-build-side-18049",
+    "f32-build-side-18049",
+    "f32-build-side-18314",
+    "f32-build-side-18314",
+    "f32-build-side-18314",
+    "f32-build-side-19863",
+    "f32-build-side-19863",
+    "f32-build-side-19863",
+    "f32-build-side-19894",
+    "f32-build-side-19894",
+    "f32-build-side-19894",
+    "f32-build-side-20363",
+    "f32-build-side-20363",
+    "f32-build-side-20363",
+    "f32-build-side-23072",
+    "f32-build-side-23072",
+    "f32-build-side-23072",
+    "f32-build-side-23076",
+    "f32-build-side-23076",
+    "f32-build-side-23076",
+    "f32-build-side-23196",
+    "f32-build-side-23196",
+    "f32-build-side-23196",
+    "f32-build-side-23526",
+    "f32-build-side-23526",
+    "f32-build-side-23526",
+    "f32-build-side-23640",
+    "f32-build-side-23640",
+    "f32-build-side-23640",
+    "f32-build-side-23729",
+    "f32-build-side-23729",
+    "f32-build-side-23729",
+    "f32-build-side-23739",
+    "f32-build-side-23739",
+    "f32-build-side-23739",
+    "f32-build-side-23743",
+    "f32-build-side-23743",
+    "f32-build-side-23743",
+    "f32-build-side-23781",
+    "f32-build-side-23781",
+    "f32-build-side-23781",
+    "f32-build-side-23801",
+    "f32-build-side-23801",
+    "f32-build-side-23801",
+    "f32-build-side-23867",
+    "f32-build-side-23867",
+    "f32-build-side-23867",
+    "f32-candidate",
+    "f32-build",
+    "f32-updates-candidate",
+    "f32-container-candidate",
+    "f32-container-build",
+    "f32-container-updates-candidate",
+    "f32-coreos-continuous",
+    "f32-build",
+    "f32-coreos-continuous",
+    "f32-flatpak-candidate",
+    "f32-build",
+    "f32-flatpak-updates-candidate",
+    "f32-gnome",
+    "f32-gnome",
+    "f32-gnome",
+    "f32-infra",
+    "f32-infra-build",
+    "f32-infra-candidate",
+    "f32-kde",
+    "f32-kde",
+    "f32-kde",
+    "f32-rebuild",
+    "f32-build",
+    "f32-rebuild",
+    "f33",
+    "f33-build",
+    "f33-updates-candidate",
+    "f33-build-side-21982",
+    "f33-build-side-21982",
+    "f33-build-side-21982",
+    "f33-build-side-22329",
+    "f33-build-side-22329",
+    "f33-build-side-22329",
+    "f33-build-side-22337",
+    "f33-build-side-22337",
+    "f33-build-side-22337",
+    "f33-build-side-23466",
+    "f33-build-side-23466",
+    "f33-build-side-23466",
+    "f33-build-side-23544",
+    "f33-build-side-23544",
+    "f33-build-side-23544",
+    "f33-build-side-23564",
+    "f33-build-side-23564",
+    "f33-build-side-23564",
+    "f33-build-side-23572",
+    "f33-build-side-23572",
+    "f33-build-side-23572",
+    "f33-build-side-23578",
+    "f33-build-side-23578",
+    "f33-build-side-23578",
+    "f33-build-side-23580",
+    "f33-build-side-23580",
+    "f33-build-side-23580",
+    "f33-build-side-23622",
+    "f33-build-side-23622",
+    "f33-build-side-23622",
+    "f33-build-side-23628",
+    "f33-build-side-23628",
+    "f33-build-side-23628",
+    "f33-build-side-23632",
+    "f33-build-side-23632",
+    "f33-build-side-23632",
+    "f33-build-side-23634",
+    "f33-build-side-23634",
+    "f33-build-side-23634",
+    "f33-build-side-23636",
+    "f33-build-side-23636",
+    "f33-build-side-23636",
+    "f33-build-side-23677",
+    "f33-build-side-23677",
+    "f33-build-side-23677",
+    "f33-build-side-23695",
+    "f33-build-side-23695",
+    "f33-build-side-23695",
+    "f33-build-side-23715",
+    "f33-build-side-23715",
+    "f33-build-side-23715",
+    "f33-build-side-23723",
+    "f33-build-side-23723",
+    "f33-build-side-23723",
+    "f33-build-side-23737",
+    "f33-build-side-23737",
+    "f33-build-side-23737",
+    "f33-build-side-23741",
+    "f33-build-side-23741",
+    "f33-build-side-23741",
+    "f33-build-side-23785",
+    "f33-build-side-23785",
+    "f33-build-side-23785",
+    "f33-build-side-23789",
+    "f33-build-side-23789",
+    "f33-build-side-23789",
+    "f33-build-side-23793",
+    "f33-build-side-23793",
+    "f33-build-side-23793",
+    "f33-build-side-23807",
+    "f33-build-side-23807",
+    "f33-build-side-23807",
+    "f33-build-side-23821",
+    "f33-build-side-23821",
+    "f33-build-side-23821",
+    "f33-build-side-23827",
+    "f33-build-side-23827",
+    "f33-build-side-23827",
+    "f33-build-side-23829",
+    "f33-build-side-23829",
+    "f33-build-side-23829",
+    "f33-build-side-23839",
+    "f33-build-side-23839",
+    "f33-build-side-23839",
+    "f33-build-side-23847",
+    "f33-build-side-23847",
+    "f33-build-side-23847",
+    "f33-build-side-23853",
+    "f33-build-side-23853",
+    "f33-build-side-23853",
+    "f33-build-side-23863",
+    "f33-build-side-23863",
+    "f33-build-side-23863",
+    "f33-build-side-23865",
+    "f33-build-side-23865",
+    "f33-build-side-23865",
+    "f33-build-side-23869",
+    "f33-build-side-23869",
+    "f33-build-side-23869",
+    "f33-build-side-23871",
+    "f33-build-side-23871",
+    "f33-build-side-23871",
+    "f33-candidate",
+    "f33-build",
+    "f33-updates-candidate",
+    "f33-container-candidate",
+    "f33-container-build",
+    "f33-container-updates-candidate",
+    "f33-coreos-continuous",
+    "f33-build",
+    "f33-coreos-continuous",
+    "f33-infra",
+    "f33-infra-build",
+    "f33-infra-candidate",
+    "f33-nodejs14",
+    "f33-nodejs14",
+    "f33-nodejs14",
+    "f33-python",
+    "f33-python",
+    "f33-python",
+    "module-3a383ba0732c1055",
+    "module-3a383ba0732c1055-build",
+    "module-3a383ba0732c1055",
+    "module-4e782003431f6e88",
+    "module-4e782003431f6e88-build",
+    "module-4e782003431f6e88",
+    "module-512311f662441d1a",
+    "module-512311f662441d1a-build",
+    "module-512311f662441d1a",
+    "module-5be2d05f123faa41",
+    "module-5be2d05f123faa41-build",
+    "module-5be2d05f123faa41",
+    "module-5cd8370d3c6532d6",
+    "module-5cd8370d3c6532d6-build",
+    "module-5cd8370d3c6532d6",
+    "module-8b08096c2be105f5",
+    "module-8b08096c2be105f5-build",
+    "module-8b08096c2be105f5",
+    "module-8ca335b34e88ba66",
+    "module-8ca335b34e88ba66-build",
+    "module-8ca335b34e88ba66",
+    "module-9721006f9645a474",
+    "module-9721006f9645a474-build",
+    "module-9721006f9645a474",
+    "module-9cc85b1dc751823c",
+    "module-9cc85b1dc751823c-build",
+    "module-9cc85b1dc751823c",
+    "module-b787c9c6bbefc539",
+    "module-b787c9c6bbefc539-build",
+    "module-b787c9c6bbefc539",
+    "module-d11cd1edd3bcbf27",
+    "module-d11cd1edd3bcbf27-build",
+    "module-d11cd1edd3bcbf27",
+    "module-d734ed3acfa7f713",
+    "module-d734ed3acfa7f713-build",
+    "module-d734ed3acfa7f713",
+    "module-eclipse-latest-3020200402152434-d2c1e272",
+    "module-eclipse-latest-3020200402152434-d2c1e272-build",
+    "module-eclipse-latest-3020200402152434-d2c1e272",
+    "module-nodejs-10-20180816111713-a5b0195c",
+    "module-nodejs-10-20180816111713-a5b0195c-build",
+    "module-nodejs-10-20180816111713-a5b0195c",
+    "module-nodejs-8-20180816123422-a5b0195c",
+    "module-nodejs-8-20180816123422-a5b0195c-build",
+    "module-nodejs-8-20180816123422-a5b0195c",
+    "module-postgresql-12-3120191125133933-f636be4b",
+    "module-postgresql-12-3120191125133933-f636be4b-build",
+    "module-postgresql-12-3120191125133933-f636be4b",
+    "rawhide",
+    "f33-build",
+    "f33-updates-candidate",
+    "rawhide-container-candidate",
+    "f33-container-build",
+    "f33-container-updates-candidate",
+]
diff --git a/tests/unit/test_config_aliases.py b/tests/unit/test_config_aliases.py
index 31a21d6f..05137077 100644
--- a/tests/unit/test_config_aliases.py
+++ b/tests/unit/test_config_aliases.py
@@ -1,7 +1,15 @@
 import pytest
 
-from packit.config.aliases import get_versions, get_build_targets, get_branches, ALIASES
+from packit.config.aliases import (
+    get_versions,
+    get_build_targets,
+    get_branches,
+    ALIASES,
+    get_koji_targets,
+    get_all_koji_targets,
+)
 from packit.exceptions import PackitException
+from tests.spellbook import ALL_KOJI_TARGETS_SNAPSHOT
 
 
 @pytest.mark.parametrize(
@@ -27,12 +35,17 @@ def test_get_versions(name, versions):
     [
         (["fedora-30", "fedora-stable"], {"fedora-30", "fedora-31", "fedora-32"},),
         (["fedora-31", "fedora-stable"], {"fedora-31", "fedora-32"}),
+        ([], {"fedora-31", "fedora-32"}),
     ],
 )
 def test_get_versions_from_multiple_values(names, versions):
     assert get_versions(*names) == versions
 
 
+def test_get_versions_empty_without_default():
+    assert get_versions(default=None) == set()
+
+
 @pytest.mark.parametrize(
     "name,targets",
     [
@@ -72,6 +85,10 @@ def test_get_build_targets_invalid_input():
     assert str(ex.value) == err_msg
 
 
+def test_get_build_targets_without_default():
+    assert get_build_targets(default=None) == set()
+
+
 @pytest.mark.parametrize(
     "names,versions",
     [
@@ -116,3 +133,53 @@ def test_get_branches(name, branches):
 )
 def test_get_branches_from_multiple_values(names, versions):
     assert get_branches(*names) == versions
+
+
+def test_get_branches_without_default():
+    assert get_branches(default=None) == set()
+
+
+@pytest.mark.parametrize("target", ALL_KOJI_TARGETS_SNAPSHOT)
+def test_preserve_koji_targets_single(target):
+    assert {target} == get_koji_targets(target)
+
+
+def test_preserve_all_koji_targets_together():
+    assert set(ALL_KOJI_TARGETS_SNAPSHOT) == get_koji_targets(
+        *ALL_KOJI_TARGETS_SNAPSHOT
+    )
+
+
+@pytest.mark.parametrize(
+    "name,targets",
+    [
+        ("fedora-29", {"f29"}),
+        ("fedora-rawhide", {"rawhide"}),
+        ("rawhide", {"rawhide"}),
+        ("master", {"master"}),
+        ("f30", {"f30"}),
+        ("fedora-development", {"rawhide"}),
+        ("fedora-stable", {"f31", "f32"}),
+        ("epel-7", {"epel7"}),
+        ("epel7", {"epel7"}),
+        ("el6", {"epel6"}),
+        ("epel-6", {"epel6"}),
+        ("fedora-all", {"rawhide", "f31", "f32"}),
+        ("epel-all", {"epel6", "epel7", "epel8"}),
+    ],
+)
+def test_get_koji_targets(name, targets):
+    assert get_koji_targets(name) == targets
+
+
+def test_get_koji_targets_without_default():
+    assert get_koji_targets(default=None) == set()
+
+
+def test_get_all_koji_targets():
+    targets = get_all_koji_targets()
+    assert targets
+    assert "Name" not in targets
+    assert "rawhide" in targets
+    assert "epel8" in targets
+    assert all(isinstance(target, str) for target in targets)