diff --git a/.github/labels.yml b/.github/labels.yml deleted file mode 100644 index d142b4d..0000000 --- a/.github/labels.yml +++ /dev/null @@ -1,41 +0,0 @@ -# Format and labels used aim to match those used by Ansible project -# https://github.com/marketplace/actions/github-labeler -- name: bug - color: "fbca04" - description: "This issue/PR relates to a bug." -- name: deprecated - color: "fef2c0" - description: "This issue/PR relates to a deprecated module." -- name: docs - color: "4071a5" - description: "This issue/PR relates to or includes documentation." -- name: enhancement - color: "ededed" - description: "This issue/PR relates to a feature request." -- name: feature - color: "006b75" - description: "This issue/PR relates to a feature request." -- name: major - color: "c6476b" - description: "Marks an important and likely breaking change." -- name: packaging - color: "4071a5" - description: "Packaging category" -- name: performance - color: "555555" - description: "Relates to product or testing performance." -- name: skip-changelog - color: "eeeeee" - description: "Can be missed from the changelog." -- name: stale - color: "eeeeee" - description: "Not updated in long time, will be closed soon." -- name: wontfix - color: "eeeeee" - description: "This will not be worked on" -- name: test - color: "0e8a16" - description: "This PR relates to tests, QA, CI." -- name: gate - color: "41b6e6" - description: "Gate PR in Zuul CI" diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml deleted file mode 100644 index d51dcc6..0000000 --- a/.github/release-drafter.yml +++ /dev/null @@ -1,28 +0,0 @@ -# Format and labels used aim to match those used by Ansible project -categories: - - title: 'Major Changes' - labels: - - 'major' # c6476b - - title: 'Minor Changes' - labels: - - 'feature' # 006b75 - - 'enhancement' # ededed - - 'performance' # 555555 - - 'test' - - title: 'Bugfixes' - labels: - - 'fix' - - 'bugfix' - - 'bug' # fbca04 - - 'docs' # 4071a5 - - 'packaging' # 4071a5 - - 'test' # #0e8a16 - - title: 'Deprecations' - labels: - - 'deprecated' # fef2c0 -exclude-labels: - - 'skip-changelog' -template: | - ## Changes - - $CHANGES diff --git a/README.md b/README.md index 59e4c0d..35ff925 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,21 @@ Example of activities performed: ![screenshot](https://sbarnea.com/ss/Screen-Shot-2020-08-16-21-23-29.23.png) +## Configuration + +By default the file tries to load the configuration files from local reposity +and falls back to "meta" repository from the same organization. If these are +also missing it will load them from [pycontribs/meta](https://github.com/pycontribs/meta/tree/master/.github) +repository. + +Recognized config files: + +- [`.github/lables.yml`](https://github.com/pycontribs/meta/blob/master/.github/labels.yml) +- [`.release-drafter.yml`](https://github.com/pycontribs/meta/blob/master/.github/release-drafter.yml) + +The file format is the same as the original tools, as tender is seen as a +drop-in replacements for these. + ## Background The project was inspired by existing tools like: diff --git a/tender/__main__.py b/tender/__main__.py index 556bd63..0c386f4 100755 --- a/tender/__main__.py +++ b/tender/__main__.py @@ -4,7 +4,9 @@ import json import logging import os +import re import sys +import urllib from copy import deepcopy from types import SimpleNamespace from typing import Dict, List, Optional, Set @@ -55,7 +57,19 @@ class Config(SimpleNamespace): """Config.""" def __init__(self, **kwargs): + self.org = None + self.repo = None + self.__dict__.update(kwargs) + + if not self.org or not self.repo: + url = git.repo.base.Repo().remotes.origin.url + gitrepo = giturlparse.parse(url) + self.org = gitrepo.owner + self.repo = gitrepo.name + # it.repo.fun.is_git_dir(".") + _logger.info("Detected %s/%s from context %s", self.org, self.repo, url) + self.labels = {} for label in self.load_config(".github/labels.yml"): self.labels[label["name"]] = SimpleNamespace( @@ -63,21 +77,39 @@ def __init__(self, **kwargs): ) self.release_drafter = self.load_config(".github/release-drafter.yml") - @classmethod - def load_config(cls, config_file): - config_file = os.path.expanduser(config_file) - try: - with open(config_file, "r") as stream: + def load_config(self, config_file): + def unique(sequence): + seen = set() + return [x for x in sequence if not (x in seen or seen.add(x))] + + result = None + for location in unique( + [ + os.path.expanduser(config_file), + f"https://raw.githubusercontent.com/{self.org}/meta/master/{config_file}", + f"https://raw.githubusercontent.com/pycontribs/meta/master/{config_file}", + ] + ): + + try: + if re.match(r"https?://", location): + stream = urllib.request.urlopen(location) + else: + stream = open(location, "r") try: - return yaml.safe_load(stream) + result = yaml.safe_load(stream) except yaml.YAMLError as exc: _logger.error(exc) sys.exit(2) - except FileNotFoundError: - _logger.warning( - "Config file %s not found, defaulting to empty.", config_file - ) - return {} + except urllib.error.HTTPError as error: + _logger.info("Config file %s not loaded due to %s", location, error) + continue + except FileNotFoundError: + _logger.info("Config file %s not found", location) + continue + _logger.info("Loaded %s", location) + return result + raise NotImplementedError("Unable to load any configuration file") class Tender: @@ -92,15 +124,6 @@ def __init__(self, cfg: Config): self.required_labels: Set[str] = set() self.errors: List[str] = [] - if not self.cfg.org or not self.cfg.repo: - url = git.repo.base.Repo().remotes.origin.url - gitrepo = giturlparse.parse(url) - self.cfg.org = gitrepo.owner - self.cfg.repo = gitrepo.name - # it.repo.fun.is_git_dir(".") - _logger.info( - "Detected %s/%s from context %s", self.cfg.org, self.cfg.repo, url - ) self.repo = self.github.get_repo(f"{self.cfg.org}/{self.cfg.repo}") self.pulls = self.repo.get_pulls(state="all")