#12 Upstream pr: 226
Closed a month ago by ttomecek. Opened 3 months ago by usercont.
rpms/ usercont/colin pull-request-226-sync  into  master

@@ -0,0 +1,439 @@ 

+ diff --git a/.gitignore b/.gitignore

+ index 3236f9c..613647e 100644

+ --- a/.gitignore

+ +++ b/.gitignore

+ @@ -2,3 +2,4 @@

+  .pytest_cache/

+  noarch/

+  *.tar.gz

+ +.coverage

+ diff --git a/Dockerfile.tests b/Dockerfile.tests

+ index c799fcf..f7704bf 100644

+ --- a/Dockerfile.tests

+ +++ b/Dockerfile.tests

+ @@ -2,24 +2,23 @@ FROM registry.fedoraproject.org/fedora:29

+  

+  ENV PYTHONDONTWRITEBYTECODE=yes-please

+  

+ -# atomic in F28 can't mount: can't find the image

+ -RUN dnf install -y make python3-pytest python3-pyxattr python3-pytest-cov \

+ -    skopeo \

+ -    https://kojipkgs.fedoraproject.org/packages/podman/0.9.1/3.gitaba58d1.fc29/x86_64/podman-0.9.1-3.gitaba58d1.fc29.x86_64.rpm \

+ -    https://kojipkgs.fedoraproject.org/packages/containernetworking-plugins/0.7.3/2.fc29/x86_64/containernetworking-plugins-0.7.3-2.fc29.x86_64.rpm \

+ -    https://kojipkgs.fedoraproject.org/packages/buildah/1.4/1.dev.git0a7389c.fc29/x86_64/buildah-1.4-1.dev.git0a7389c.fc29.x86_64.rpm \

+ -    https://kojipkgs.fedoraproject.org//packages/atomic/1.22.1/27.gitb507039.fc29/x86_64/atomic-1.22.1-27.gitb507039.fc29.x86_64.rpm \

+ +RUN dnf install -y \

+ +    make python3-pytest python3-pyxattr python3-pytest-cov \

+ +    skopeo podman buildah atomic \

+ +    python3-ipdb \

+      && dnf clean all

+  

+ -# podman

+ -RUN useradd podm

+ -RUN echo "podm:231072:65536" > /etc/subuid

+ -RUN echo "podm:231072:65536" > /etc/subgid

+ -USER podm

+ +RUN sed '/^graphroot/s/.*/graphroot="\/var\/tmp\/containers"/' -i /etc/containers/storage.conf \

+ +    && printf 'checkout_path: /var/tmp/containers/atomic\n' >>/etc/atomic.conf

+ +

+ +# # podman

+ +# RUN useradd podm

+ +# RUN echo "podm:231072:65536" > /etc/subuid

+ +# RUN echo "podm:231072:65536" > /etc/subgid

+ +# USER podm

+  

+  WORKDIR /src

+  

+ -COPY ./tests /tests

+  COPY . /src

+  

+  RUN pip3 install --user .

+ diff --git a/Makefile b/Makefile

+ index 3390e80..3258437 100644

+ --- a/Makefile

+ +++ b/Makefile

+ @@ -12,17 +12,19 @@ test-in-container: build-test-image test-in-container-now

+  

+  test-in-container-now:

+  	@# use it like this: `make test-in-container TEST_TARGET=./tests/integration/test_utils.py`

+ -	docker run --rm --privileged --security-opt label=disable --cap-add SYS_ADMIN -ti -v $(CURDIR):/src $(TEST_IMAGE_NAME) make exec-test TEST_TARGET="$(TEST_TARGET)"

+ +	docker run --rm --privileged --security-opt label=disable \

+ +		--name=colin \

+ +		--cap-add SYS_ADMIN -ti \

+ +		-v /var/tmp/ \

+ +		-v $(CURDIR):/src \

+ +		$(TEST_IMAGE_NAME) \

+ +		make exec-test TEST_TARGET="$(TEST_TARGET)"

+  

+ -test-in-ci: setup-ci

+ -	PYTHONPATH=$(CURDIR) py.test --cov=colin $(TEST_TARGET)

+ +test-in-ci: test-in-container

+  

+  exec-test:

+  	PYTHONPATH=$(CURDIR) py.test-3 --cov=colin $(TEST_TARGET)

+  

+ -setup-ci:

+ -	./setup-ci.sh

+ -

+  check-code-style: check-pylint check-bandit

+  

+  check-pylint:

+ diff --git a/colin/cli/colin.py b/colin/cli/colin.py

+ index 40f57c8..e2dad2d 100644

+ --- a/colin/cli/colin.py

+ +++ b/colin/cli/colin.py

+ @@ -47,7 +47,7 @@ def cli():

+  

+  @click.command(name="check",

+                 context_settings=CONTEXT_SETTINGS)

+ -@click.argument('target', type=click.STRING)

+ +@click.argument('TARGET', type=click.STRING)

+  @click.option('--ruleset', '-r', type=click.STRING, envvar='COLIN_RULESET',

+                help="Select a predefined ruleset (e.g. fedora).")

+  @click.option('--ruleset-file', '-f', type=click.File(mode='r'),

+ diff --git a/colin/core/loader.py b/colin/core/loader.py

+ index a8a4566..3d7d1db 100644

+ --- a/colin/core/loader.py

+ +++ b/colin/core/loader.py

+ @@ -21,9 +21,9 @@ loads AbstractCheck classes from it.

+  import inspect

+  import logging

+  import os

+ -import warnings

+ -

+ -import six

+ +from importlib import import_module

+ +from importlib.util import module_from_spec

+ +from importlib.util import spec_from_file_location

+  

+  from ..core.checks.fmf_check import receive_fmf_metadata, FMFAbstractCheck

+  

+ @@ -44,22 +44,11 @@ def path_to_module(path):

+  def _load_module(path):

+      module_name = path_to_module(path)

+      logger.debug("Will try to load selected file as module '%s'.", module_name)

+ -    if six.PY3:

+ -        from importlib.util import module_from_spec

+ -        from importlib.util import spec_from_file_location

+ -

+ -        s = spec_from_file_location(module_name, path)

+ -        m = module_from_spec(s)

+ -        s.loader.exec_module(m)

+ -        return m

+  

+ -    elif six.PY2:

+ -        import imp

+ -

+ -        with warnings.catch_warnings():

+ -            warnings.simplefilter("ignore")  # FIXME: let's at least debug log other warnings

+ -            m = imp.load_source(module_name, path)

+ -        return m

+ +    s = spec_from_file_location(module_name, path)

+ +    m = module_from_spec(s)

+ +    s.loader.exec_module(m)

+ +    return m

+  

+  

+  def should_we_load(kls):

+ @@ -124,6 +113,20 @@ class CheckLoader(object):

+                          load_check_classes_from_file(path)))

+          return list(check_classes)

+  

+ +    def import_class(self, import_name):

+ +        """

+ +        import selected class

+ +

+ +        :param import_name, str, e.g. some.module.MyClass

+ +        :return the class

+ +        """

+ +        module_name, class_name = import_name.rsplit(".", 1)

+ +        mod = import_module(module_name)

+ +        check_class = getattr(mod, class_name)

+ +        self.mapping[check_class.name] = check_class

+ +        logger.info("successfully loaded class %s", check_class)

+ +        return check_class

+ +

+      @property

+      def check_classes(self):

+          if self._check_classes is None:

+ diff --git a/colin/core/ruleset/loader.py b/colin/core/ruleset/loader.py

+ index fb7d925..476f0d9 100644

+ --- a/colin/core/ruleset/loader.py

+ +++ b/colin/core/ruleset/loader.py

+ @@ -93,6 +93,11 @@ class CheckStruct(object):

+      def __str__(self):

+          return "%s" % self.name

+  

+ +    @property

+ +    def import_name(self):

+ +        """ module name + class, e.g. our.colin.checks.CustomCheck """

+ +        return self._get(False, "import_name")

+ +

+      @property

+      def name(self):

+          return self._get(True, "name")

+ diff --git a/colin/core/ruleset/ruleset.py b/colin/core/ruleset/ruleset.py

+ index 37bf90d..fd17671 100644

+ --- a/colin/core/ruleset/ruleset.py

+ +++ b/colin/core/ruleset/ruleset.py

+ @@ -76,19 +76,16 @@ class Ruleset(object):

+                  logger.info("Skipping... Target type does not match.")

+                  continue

+  

+ -            try:

+ -                check_class = self.check_loader.mapping[check_struct.name]

+ -                check_instance = check_class()

+ -            except KeyError as ke:

+ -                check_instance = NotLoadedCheck(check_name=check_struct.name,

+ -                                                reason="not found")

+ -                logger.debug("Cannot find a code for the check {}. ({})".format(check_struct.name,

+ -                                                                                ke))

+ -            except Exception as ex:

+ -                check_instance = NotLoadedCheck(check_name=check_struct.name,

+ -                                                reason="not instantiated")

+ -                logger.debug("Cannot instantiate the check {}. ({})".format(check_struct.name,

+ -                                                                            ex))

+ +            if check_struct.import_name:

+ +                check_class = self.check_loader.import_class(check_struct.import_name)

+ +            else:

+ +                try:

+ +                    check_class = self.check_loader.mapping[check_struct.name]

+ +                except KeyError:

+ +                    logger.error("Check %s was not found -- it can't be loaded", check_struct.name)

+ +                    raise ColinRulesetException(

+ +                        "Check {} can't be loaded, we couldn't find it.".format(check_struct.name))

+ +            check_instance = check_class()

+  

+              if check_struct.tags:

+                  logger.info("Overriding check's tags %s with the one defined in ruleset: %s",

+ @@ -131,10 +128,11 @@ def get_checks_paths(checks_paths=None):

+      :param checks_paths: list of str, directories where the checks are present

+      :return: list of str (absolute path of directory with checks)

+      """

+ -    if checks_paths:

+ -        return [os.path.abspath(x) for x in checks_paths]

+      p = os.path.join(__file__, os.pardir, os.pardir, os.pardir, "checks")

+      p = os.path.abspath(p)

+ +    # let's utilize the default upstream checks always

+ +    if checks_paths:

+ +        p += [os.path.abspath(x) for x in checks_paths]

+      return [p]

+  

+  

+ diff --git a/colin/core/target.py b/colin/core/target.py

+ index 923fbea..ac083de 100644

+ --- a/colin/core/target.py

+ +++ b/colin/core/target.py

+ @@ -413,7 +413,8 @@ class OstreeTarget(AbstractImageTarget):

+              kwargs["cwd"] = wd

+          try:

+              out = subprocess.check_output(cmd, **kwargs)

+ -        except subprocess.CalledProcessError:

+ +        except subprocess.CalledProcessError as ex:

+ +            logger.error(ex.output)

+              logger.error(error_msg)

+              raise

+          logger.debug("%s", out)

+ diff --git a/setup-ci.sh b/setup-ci.sh

+ deleted file mode 100755

+ index 246c5d6..0000000

+ --- a/setup-ci.sh

+ +++ /dev/null

+ @@ -1,23 +0,0 @@

+ -#!/bin/bash

+ -

+ -echo "yum -y install yum-plugin-copr"

+ -yum -y install yum-plugin-copr

+ -

+ -echo "yum copr enable -y shosca/python"

+ -yum copr enable -y shosca/python

+ -

+ -echo "yum -y install make gcc python36 python36-devel python36-setuptools python36-pip"

+ -yum -y install make gcc python36 python36-devel python36-setuptools python36-pip python36-cffi python36-pycparser

+ -

+ -echo "pip3 install pytest xattr"

+ -pip3.6 install pytest pytest-cov xattr

+ -

+ -echo "yum copr enable -y baude/Upstream_CRIO_Family"

+ -yum copr enable -y baude/Upstream_CRIO_Family

+ -

+ -echo "yum -y install skopeo podman atomic ostree"

+ -yum -y install skopeo podman atomic ostree

+ -

+ -

+ -echo "pip3.6 install ."

+ -pip3.6 install .

+ diff --git a/tests/integration/conftest.py b/tests/conftest.py

+ similarity index 84%

+ rename from tests/integration/conftest.py

+ rename to tests/conftest.py

+ index 5eecedf..ef69f52 100644

+ --- a/tests/integration/conftest.py

+ +++ b/tests/conftest.py

+ @@ -13,7 +13,7 @@ _set_logging(level=logging.DEBUG)

+  

+  BASH_IMAGE = "colin-test-bash"

+  LS_IMAGE = "colin-test-ls"

+ -BUSYBOX_IMAGE = "busybox"

+ +BUSYBOX_IMAGE = "busybox:latest"

+  LABELS_IMAGE = "colin-labels"

+  IMAGES = {

+      BASH_IMAGE: {

+ @@ -30,25 +30,21 @@ IMAGES = {

+  

+  def build_image_if_not_exists(image_name):

+      try:

+ -        subprocess.check_call(["podman", "image", "inspect", image_name],

+ -                              stdout=subprocess.PIPE)

+ +        subprocess.check_call(["podman", "image", "exists", image_name])

+      except subprocess.CalledProcessError:

+          this_dir = os.path.abspath(os.path.dirname(__file__))

+ -        data_dir = os.path.join(this_dir, os.path.pardir, "data")

+ +        data_dir = os.path.join(this_dir, "data")

+  

+          dockerfile_path = IMAGES[image_name]["dockerfile_path"]

+          cmd_create = ["podman", "build", "-t", image_name, "-f", dockerfile_path, data_dir]

+ -        output = subprocess.check_output(cmd_create)

+ -        assert output

+ +        subprocess.check_call(cmd_create)

+  

+  

+  def pull_image_if_not_exists(image_name):

+      try:

+ -        subprocess.check_call(["podman", "image", "inspect", image_name],

+ -                              stdout=subprocess.PIPE)

+ +        subprocess.check_call(["podman", "image", "exists", image_name])

+      except subprocess.CalledProcessError:

+ -        subprocess.check_call(["podman", "pull", image_name],

+ -                              stdout=subprocess.PIPE)

+ +        subprocess.check_call(["podman", "pull", image_name])

+  

+  

+  def convert_image_to_ostree(image_name):

+ @@ -88,7 +84,7 @@ def get_target(name, type):

+      elif type == "dockerfile":

+  

+          this_dir = os.path.abspath(os.path.dirname(__file__))

+ -        data_dir = os.path.join(this_dir, os.path.pardir, "data")

+ +        data_dir = os.path.join(this_dir, "data")

+          dockerfile_path = os.path.join(data_dir, IMAGES[name]["dockerfile_path"])

+  

+          yield DockerfileTarget(target=dockerfile_path)

+ @@ -98,7 +94,7 @@ def get_skopeo_path(image_name, ostree_path):

+      return "ostree:%s@%s" % (image_name, ostree_path)

+  

+  

+ -@pytest.fixture(scope="session")

+ +@pytest.fixture(scope="session", autouse=True)

+  def label_image():

+      build_image_if_not_exists(LABELS_IMAGE)

+  

+ @@ -119,7 +115,7 @@ def target_label_image_and_dockerfile(request, label_image):

+          yield t

+  

+  

+ -@pytest.fixture(scope="session")

+ +@pytest.fixture(scope="session", autouse=True)

+  def target_bash_image():

+      build_image_if_not_exists(BASH_IMAGE)

+  

+ @@ -132,7 +128,7 @@ def target_bash(request, target_bash_image):

+          yield t

+  

+  

+ -@pytest.fixture(scope="session")

+ +@pytest.fixture(scope="session", autouse=True)

+  def target_ls_image():

+      build_image_if_not_exists(LS_IMAGE)

+  

+ @@ -154,7 +150,7 @@ def target_help_file(request, target_ls, target_bash):

+          return target_bash, True

+  

+  

+ -@pytest.fixture(scope="session")

+ +@pytest.fixture(scope="session", autouse=True)

+  def target_busybox_image():

+      pull_image_if_not_exists(image_name=BUSYBOX_IMAGE)

+  

+ diff --git a/tests/integration/test_ruleset_file.py b/tests/integration/test_ruleset_file.py

+ index 2e7d5aa..3f47ec3 100644

+ --- a/tests/integration/test_ruleset_file.py

+ +++ b/tests/integration/test_ruleset_file.py

+ @@ -18,6 +18,7 @@ import tempfile

+  

+  import pytest

+  import yaml

+ +from colin.core.exceptions import ColinRulesetException

+  

+  import colin

+  from colin.core.checks.check_utils import NotLoadedCheck

+ @@ -140,16 +141,9 @@ def test_coupled_ruleset(ruleset_coupled):

+  

+  

+  def test_unknown_check(ruleset_unknown_check):

+ -    checks = colin.get_checks(ruleset=ruleset_unknown_check)

+ -    assert checks

+ -    assert len(checks) == 2

+ -    for check in checks:

+ -        if check.name == 'i_forgot_the_name':

+ -            assert isinstance(check, NotLoadedCheck)

+ -        elif check.name == 'maintainer_label':

+ -            assert isinstance(check, LabelAbstractCheck)

+ -        else:

+ -            assert False

+ +    with pytest.raises(ColinRulesetException) as ex:

+ +        colin.get_checks(ruleset=ruleset_unknown_check)

+ +    assert str(ex.value) == "Check i_forgot_the_name can't be loaded, we couldn't find it."

+  

+  

+  def test_skip(ruleset):

+ diff --git a/tests/integration/test_targets.py b/tests/integration/test_targets.py

+ index 65b1066..5b1b52f 100644

+ --- a/tests/integration/test_targets.py

+ +++ b/tests/integration/test_targets.py

+ @@ -5,7 +5,7 @@ Test different target types.

+  import pytest

+  

+  import colin

+ -from tests.integration.conftest import LABELS_IMAGE, convert_image_to_ostree, get_skopeo_path

+ +from tests.conftest import LABELS_IMAGE, convert_image_to_ostree, get_skopeo_path

+  

+  

+  @pytest.fixture()

+ diff --git a/tests/unit/test_cli.py b/tests/unit/test_cli.py

+ index 2e06459..e5df11e 100644

+ --- a/tests/unit/test_cli.py

+ +++ b/tests/unit/test_cli.py

+ @@ -41,13 +41,11 @@ def _common_help_options(result):

+  

+  def test_check_command():

+      result = _call_colin(check)

+ -    expected_output = """Usage: check [OPTIONS] TARGET

+ -Try "check -h" for help.

+ -

+ -Error: Missing argument "TARGET".

+ -"""

+ +    expected_output1 = "Usage: check [OPTIONS] TARGET"

+ +    expected_output2 = 'Error: Missing argument "TARGET"'

+      assert result.exit_code == 2

+ -    assert result.output == expected_output

+ +    assert expected_output1 in result.output

+ +    assert expected_output2 in result.output

+  

+  

+  def test_check_help_command():

+ diff --git a/tests/unit/test_loader.py b/tests/unit/test_loader.py

+ index df21644..30ffbc5 100644

+ --- a/tests/unit/test_loader.py

+ +++ b/tests/unit/test_loader.py

+ @@ -73,3 +73,10 @@ def test_loading_custom_check(tmpdir):

+      assert len(l.check_classes) == 3

+      assert l.mapping["a-peter-file-check"]

+      assert l.mapping["this-is-a-funky-check"]

+ +

+ +

+ +def test_import_class():

+ +    l = CheckLoader([])

+ +    check_name = "ArchitectureLabelCheck"

+ +    c = l.import_class("colin.checks.labels.%s" % check_name)

+ +    assert c.name == "architecture_label"

@@ -0,0 +1,177 @@ 

+ diff --git a/colin/utils/cmd_tools.py b/colin/utils/cmd_tools.py

+ index 2da4118..f3f08a8 100644

+ --- a/colin/utils/cmd_tools.py

+ +++ b/colin/utils/cmd_tools.py

+ @@ -13,9 +13,11 @@

+  # You should have received a copy of the GNU General Public License

+  # along with this program.  If not, see <http://www.gnu.org/licenses/>.

+  #

+ +import functools

+  import logging

+  import subprocess

+  import threading

+ +import time

+  

+  try:

+      import thread

+ @@ -120,3 +122,30 @@ def exit_after(s):

+          return inner

+  

+      return outer

+ +

+ +

+ +def retry(retry_count=5, delay=2):

+ +    """

+ +    Use as decorator to retry functions few times with delays

+ +

+ +    Exception will be raised if last call fails

+ +

+ +    :param retry_count: int could of retries in case of failures. It must be

+ +                        a positive number

+ +    :param delay: int delay between retries

+ +    """

+ +    if retry_count <= 0:

+ +        raise ValueError("retry_count have to be positive")

+ +

+ +    def decorator(f):

+ +        @functools.wraps(f)

+ +        def wrapper(*args, **kwargs):

+ +            for i in range(retry_count, 0, -1):

+ +                try:

+ +                    return f(*args, **kwargs)

+ +                except Exception:

+ +                    if i <= 1:

+ +                        raise

+ +                time.sleep(delay)

+ +        return wrapper

+ +    return decorator

+ diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py

+ index 0d23182..4185a56 100644

+ --- a/tests/unit/test_utils.py

+ +++ b/tests/unit/test_utils.py

+ @@ -13,12 +13,13 @@

+  # You should have received a copy of the GNU General Public License

+  # along with this program.  If not, see <http://www.gnu.org/licenses/>.

+  #

+ -from time import sleep

+ +import time

+  

+  import pytest

+  

+  from colin.core.exceptions import ColinException

+  from colin.utils.cmd_tools import exit_after

+ +from colin.utils.cmd_tools import retry

+  

+  

+  @exit_after(1)

+ @@ -28,7 +29,7 @@ def fast_fce():

+  

+  @exit_after(1)

+  def slow_fce():

+ -    sleep(2)

+ +    time.sleep(2)

+  

+  

+  @exit_after(1)

+ @@ -52,4 +53,100 @@ def test_timeout_bad_fce():

+  

+  def test_timeout_dirrect():

+      with pytest.raises(TimeoutError):

+ -        exit_after(1)(sleep)(2)

+ +        exit_after(1)(time.sleep)(2)

+ +

+ +

+ +COUNTER = 0

+ +

+ +

+ +def raise_exception():

+ +    global COUNTER

+ +    COUNTER += 1

+ +

+ +    raise Exception('I am bad function')

+ +

+ +

+ +def test_no_retry_for_success():

+ +    global COUNTER

+ +    COUNTER = 0

+ +

+ +    @retry(5, 0)

+ +    def always_success():

+ +        global COUNTER

+ +        COUNTER = COUNTER + 1

+ +

+ +        return 42

+ +

+ +    assert always_success() == 42

+ +    assert COUNTER == 1

+ +

+ +

+ +def test_retry_with_exception():

+ +    global COUNTER

+ +    COUNTER = 0

+ +

+ +    @retry(5, 0)

+ +    def always_raise_exception():

+ +        raise_exception()

+ +

+ +    with pytest.raises(Exception) as ex:

+ +        always_raise_exception()

+ +

+ +    assert str(ex.value) == 'I am bad function'

+ +    assert COUNTER == 5

+ +

+ +

+ +def test_wrong_parameter():

+ +    with pytest.raises(ValueError) as ex:

+ +        retry(-1, 1)

+ +    assert str(ex.value) == 'retry_count have to be positive'

+ +

+ +    with pytest.raises(ValueError) as ex:

+ +        retry(0, 1)

+ +    assert str(ex.value) == 'retry_count have to be positive'

+ +

+ +    @retry(5, -1)

+ +    def fail_negative_sleep():

+ +        raise_exception()

+ +

+ +    with pytest.raises(ValueError) as ex:

+ +        fail_negative_sleep()

+ +    assert str(ex.value) == 'sleep length must be non-negative'

+ +

+ +

+ +def test_retry_with_sleep():

+ +    global COUNTER

+ +    COUNTER = 0

+ +

+ +    @retry(4, .5)

+ +    def fail_and_sleep():

+ +        raise_exception()

+ +

+ +    time_start = time.time()

+ +    with pytest.raises(Exception) as ex:

+ +        fail_and_sleep()

+ +    time_end = time.time()

+ +

+ +    assert str(ex.value) == 'I am bad function'

+ +    assert COUNTER == 4

+ +

+ +    # there are 3 sleeps between 4 delays

+ +    assert time_end - time_start >= 1.5

+ +    # there were not 4 sleeps

+ +    assert time_end - time_start < 4

+ +

+ +

+ +def test_recover_after_few_failures():

+ +    global COUNTER

+ +    COUNTER = 0

+ +

+ +    @retry(5, 0)

+ +    def sleep_like_a_baby():

+ +        global COUNTER

+ +        if COUNTER < 3:

+ +            COUNTER += 1

+ +            raise Exception("sleeping")

+ +        return []

+ +

+ +    assert sleep_like_a_baby() == []

+ +    assert COUNTER == 3

@@ -0,0 +1,38 @@ 

+ diff --git a/.packit.json b/.packit.json

+ new file mode 100644

+ index 0000000..d4abaa4

+ --- /dev/null

+ +++ b/.packit.json

+ @@ -0,0 +1,32 @@

+ +{

+ +  "specfile_path": "colin.spec",

+ +  "synced_files": [

+ +    ".packit.json",

+ +    "colin.spec"

+ +  ],

+ +  "jobs": [

+ +    {

+ +      "trigger": "release",

+ +      "release_to": [

+ +        "master"

+ +      ]

+ +    },

+ +    {

+ +      "trigger": "pull_request",

+ +      "release_to": [

+ +        "master"

+ +      ]

+ +    }

+ +  ],

+ +  "upstream_name": "colin",

+ +  "package_name": "colin",

+ +  "dist_git_url": "https://src.fedoraproject.org/rpms/colin.git",

+ +  "checks": [

+ +    {

+ +      "name": "simple-koji-ci"

+ +    },

+ +    {

+ +      "name": "Fedora CI"

+ +    }

+ +  ]

+ +}

@@ -0,0 +1,22 @@ 

+ diff --git a/release-conf.yaml b/release-conf.yaml

+ index 77c8101..4543ef8 100644

+ --- a/release-conf.yaml

+ +++ b/release-conf.yaml

+ @@ -1,13 +1,15 @@

+  # list of major python versions that release-bot will build separate wheels for

+  python_versions:

+    - 3

+ -  

+ +

+  # whether to release on fedora

+  fedora: true

+  # list of fedora branches bot should release on. Master is always implied

+ +

+  fedora_branches:

+ +  - f30

+    - f29

+ -  - f28

+ +

+  # whether to allow bot to make PRs based on issues

+  trigger_on_issue: true

+  

@@ -0,0 +1,47 @@ 

+ diff --git a/.travis.yml b/.travis.yml

+ deleted file mode 100644

+ index 9b58a36..0000000

+ --- a/.travis.yml

+ +++ /dev/null

+ @@ -1,17 +0,0 @@

+ -language: python

+ -sudo: required

+ -notifications:

+ -  email: false

+ -

+ -python:

+ -- '2.7'

+ -- '3.6'

+ -before_install:

+ -- sudo apt-get -y install gcc libattr1-dev

+ -script:

+ -  - make check TEST_TARGET=./tests/

+ -deploy:

+ -  provider: pypi

+ -

+ -after_deploy:

+ -- make rpm

+ diff --git a/README.md b/README.md

+ index eb18ba8..b45ce79 100644

+ --- a/README.md

+ +++ b/README.md

+ @@ -37,6 +37,7 @@ have to compile it yourself when getting it from PyPI.

+  $ pip3 install --user colin

+  ```

+  

+ +`colin` is supported on python 3.6+ only.

+  

+  ### On Fedora distribution

+  

+ diff --git a/release-conf.yaml b/release-conf.yaml

+ index 4543ef8..addb174 100644

+ --- a/release-conf.yaml

+ +++ b/release-conf.yaml

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

+ -# list of major python versions that release-bot will build separate wheels for

+ -python_versions:

+ -  - 3

+ -

+  # whether to release on fedora

+  fedora: true

+  # list of fedora branches bot should release on. Master is always implied

@@ -0,0 +1,61 @@ 

+ diff --git a/.packit.json b/.packit.json

+ deleted file mode 100644

+ index d4abaa4..0000000

+ --- a/.packit.json

+ +++ /dev/null

+ @@ -1,32 +0,0 @@

+ -{

+ -  "specfile_path": "colin.spec",

+ -  "synced_files": [

+ -    ".packit.json",

+ -    "colin.spec"

+ -  ],

+ -  "jobs": [

+ -    {

+ -      "trigger": "release",

+ -      "release_to": [

+ -        "master"

+ -      ]

+ -    },

+ -    {

+ -      "trigger": "pull_request",

+ -      "release_to": [

+ -        "master"

+ -      ]

+ -    }

+ -  ],

+ -  "upstream_name": "colin",

+ -  "package_name": "colin",

+ -  "dist_git_url": "https://src.fedoraproject.org/rpms/colin.git",

+ -  "checks": [

+ -    {

+ -      "name": "simple-koji-ci"

+ -    },

+ -    {

+ -      "name": "Fedora CI"

+ -    }

+ -  ]

+ -}

+ diff --git a/.packit.yaml b/.packit.yaml

+ new file mode 100644

+ index 0000000..df00750

+ --- /dev/null

+ +++ b/.packit.yaml

+ @@ -0,0 +1,17 @@

+ +specfile_path: colin.spec

+ +synced_files:

+ +  - .packit.yaml

+ +  - colin.spec

+ +jobs:

+ +  - trigger: release

+ +    release_to:

+ +      - master

+ +  - trigger: pull_request

+ +    release_to:

+ +      - master

+ +upstream_name: colin

+ +package_name: colin

+ +dist_git_url: https://src.fedoraproject.org/rpms/colin.git

+ +checks:

+ +  - name: simple-koji-ci

+ +  - name: Fedora CI

@@ -0,0 +1,11 @@ 

+ diff --git a/.packit.yaml b/.packit.yaml

+ index df00750..2147d22 100644

+ --- a/.packit.yaml

+ +++ b/.packit.yaml

+ @@ -1,6 +1,5 @@

+  specfile_path: colin.spec

+  synced_files:

+ -  - .packit.yaml

+    - colin.spec

+  jobs:

+    - trigger: release

@@ -0,0 +1,21 @@ 

+ diff --git a/.packit.yaml b/.packit.yaml

+ index 2147d22..f2dbf7d 100644

+ --- a/.packit.yaml

+ +++ b/.packit.yaml

+ @@ -1,16 +1,6 @@

+  specfile_path: colin.spec

+  synced_files:

+    - colin.spec

+ -jobs:

+ -  - trigger: release

+ -    release_to:

+ -      - master

+ -  - trigger: pull_request

+ -    release_to:

+ -      - master

+  upstream_name: colin

+  package_name: colin

+  dist_git_url: https://src.fedoraproject.org/rpms/colin.git

+ -checks:

+ -  - name: simple-koji-ci

+ -  - name: Fedora CI

file modified
+45 -26

@@ -9,13 +9,48 @@ 

  %endif

  

  Name:           %{pypi_name}

- Version:        0.3.1

- Release:        2%{?dist}

- Summary:        Tool to check generic rules/best-practices for containers/images/dockerfiles.

+ Version:        0.3.0

+ Release:        1%{?dist}

+ Summary:        Tool to check generic rules/best-practices for containers/images/dockerfiles

  

  License:        GPLv3+

  URL:            https://github.com/user-cont/colin

  Source0:        https://files.pythonhosted.org/packages/source/c/%{pypi_name}/%{pypi_name}-%{version}.tar.gz

+ 

+ 

+ # PATCHES FROM SOURCE GIT:

+ 

+ # Merge pull request #220 from TomasTomecek/stuff

+ # Author: lachmanfrantisek <lachmanfrantisek@gmail.com>

+ Patch0001: 0001-3fb470e5fdc8af4f85c2f38638b12e9947077f0e.patch

+ 

+ # Merge pull request #221 from lslebodn/retry_decorator

+ # Author: lachmanfrantisek <lachmanfrantisek@gmail.com>

+ Patch0002: 0002-42d432285e61d4c8e938a29562c4cfc94e472d73.patch

+ 

+ # Merge pull request #222 from lachmanfrantisek/add-packit-config

+ # Author: lachmanfrantisek <lachmanfrantisek@gmail.com>

+ Patch0003: 0003-0d6e748081df99cd69b526e2ea2c29a1021f63e5.patch

+ 

+ # Merge pull request #223 from jpopelka/release-conf-f30

+ # Author: Tomas Tomecek <nereone@gmail.com>

+ Patch0004: 0004-c4cc9aa73c6ee06e69071d599f52209a56fa5dbf.patch

+ 

+ # Merge pull request #224 from phracek/remove_python_2

+ # Author: Petr Hracek <phracek@redhat.com>

+ Patch0005: 0005-62f8587a1e5d959ec76ae4c1434ae6f9225934b6.patch

+ 

+ # Merge pull request #225 from jpopelka/packit-yaml

+ # Author: Tomas Tomecek <tomas@tomecek.net>

+ Patch0006: 0006-f95b4b295c8bffa0666bbc15a28cde81d23ea08f.patch

+ 

+ # packit: don't sync packit config

+ # Author: Tomas Tomecek <ttomecek@redhat.com>

+ Patch0007: 0007-4c1b181a89ef762a5d1d89ecf73afce6c20f5a2d.patch

+ 

+ # packit: remove things which packit can't do yet

+ # Author: Tomas Tomecek <ttomecek@redhat.com>

+ Patch0008: 0008-6c00dfd13f023985ab1441f4bdd82c0f426f958d.patch

  BuildArch:      noarch

  Requires:       python3-%{pypi_name}

  

@@ -28,8 +63,10 @@ 

  %{?python_provide:%python_provide python3-%{pypi_name}}

  BuildRequires:  python3-devel

  BuildRequires:  python3-setuptools

- Requires:       docker

- Recommends:     atomic

+ Requires:       python3-click

+ Requires:       python3-six

+ Requires:       python3-dockerfile-parse

+ Requires:       python3-PyYAML

  

  %description -n python3-%{pypi_name}

  `colin` as a tool to check generic rules/best-practices

@@ -76,29 +113,11 @@ 

  %doc html

  

  %changelog

- * Thu Jan 31 2019 Fedora Release Engineering <releng@fedoraproject.org> - 0.3.1-2

- - Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild

- 

- * Mon Jan 21 2019 Tomas Tomecek <nereone@gmail.com> 0.3.1-1

- - 0.3.1 release

- 

- * Thu Nov 15 2018 lachmanfrantisek <lachmanfrantisek@gmail.com> 0.3.0-1

+ * Wed Nov 14 2018 Frantisek Lachman <flachman@redhat.com> - 0.3.0-1

  - 0.3.0 release

  

- * Mon Oct 22 2018 lachmanfrantisek <lachmanfrantisek@gmail.com> 0.2.1-1

- - 0.2.1 release

- 

- * Wed Sep 19 2018 Jiri Popelka <jpopelka@redhat.com> 0.2.0-1

- - 0.2.0 release

- 

- * Thu Jul 12 2018 Fedora Release Engineering <releng@fedoraproject.org> - 0.1.0-3

- - Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild

- 

- * Tue Jun 19 2018 Miro HronĨok <mhroncok@redhat.com> - 0.1.0-2

- - Rebuilt for Python 3.7

- 

- * Wed May 30 2018 Jiri Popelka <jpopelka@redhat.com> 0.1.0-1

- - 0.1.0 release

+ * Mon May 28 2018 Tomas Tomecek <ttomecek@redhat.com> - 0.1.0-1

+ - new upstream release: 0.1.0

  

  * Wed May 02 2018 Petr Hracek <phracek@redhat.com> - 0.0.4-3

  - Polishing texts and remove leftovers (#1572084)