aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan200101 <sentrycraft123@gmail.com>2022-09-07 09:52:37 +0200
committerJan200101 <sentrycraft123@gmail.com>2022-09-07 09:52:37 +0200
commit256aeeee6077da0a28bcc2fb19ab7923e472d26a (patch)
treedec941fb85041945e186d007b5150459b7f13223
parentec850ccb99d3ebfb8a69483de868097ed8288f7f (diff)
downloadlab-bot-256aeeee6077da0a28bcc2fb19ab7923e472d26a.tar.gz
lab-bot-256aeeee6077da0a28bcc2fb19ab7923e472d26a.zip
add per repository settings
-rw-r--r--labbot/__main__.py11
-rw-r--r--labbot/addons/approve-merge.py12
-rw-r--r--labbot/addons/merge-label.py54
-rw-r--r--labbot/addons/merge-stable.py26
-rw-r--r--labbot/bot.py7
-rw-r--r--labbot/config.py87
6 files changed, 157 insertions, 40 deletions
diff --git a/labbot/__main__.py b/labbot/__main__.py
index fdd2537..39d8842 100644
--- a/labbot/__main__.py
+++ b/labbot/__main__.py
@@ -3,6 +3,7 @@ import logging
from typing import List
from importlib import import_module
import json
+import shutil
import labbot.bot
import labbot.config
@@ -98,5 +99,15 @@ def list_instances():
for ins in labbot.config.list_instances():
print(f"- {ins}")
+@main.command(name="remove", help="Remove an instance")
+@click.argument('name')
+@click.option('--yes', is_flag=True, expose_value=False,
+ prompt='Are you sure you want to remove the instance?')
+def remove_instance(name):
+ try:
+ shutil.rmtree(labbot.config.instance_config_dir(name))
+ except FileNotFoundError:
+ print("Instance not found")
+
if __name__ == "__main__":
main() \ No newline at end of file
diff --git a/labbot/addons/approve-merge.py b/labbot/addons/approve-merge.py
index 9b10ef6..9c6eceb 100644
--- a/labbot/addons/approve-merge.py
+++ b/labbot/addons/approve-merge.py
@@ -4,10 +4,16 @@ is reached.
"""
import logging
+from labbot.config import Config
+
log = logging.getLogger(__name__)
-required_approval_count = 2
+config = Config(__name__)
+config.set_global_data(
+ required_approval_count = 2
+)
+@config.config_decorator()
async def merge_label_hook(event, gl, *args, **kwargs):
title = event.object_attributes["title"]
state = event.object_attributes["state"]
@@ -24,12 +30,12 @@ async def merge_label_hook(event, gl, *args, **kwargs):
approval_count = len(data["approved_by"])
- if approval_count >= required_approval_count:
+ if approval_count >= config["required_approval_count"]:
if merge_status == "can_be_merged":
await gl.put(merge_url)
else:
log.debug(f"Cannot merge !{iid} because of its merge_status `{merge_status}`")
def setup(bot):
+ config.setup(__name__, bot.name)
bot.register_merge_hook(merge_label_hook)
- pass \ No newline at end of file
diff --git a/labbot/addons/merge-label.py b/labbot/addons/merge-label.py
index a978388..746e236 100644
--- a/labbot/addons/merge-label.py
+++ b/labbot/addons/merge-label.py
@@ -7,29 +7,34 @@ import os
import re
import logging
-log = logging.getLogger(__name__)
-
-
-title_regex = r"^(?:#|)(\d+)\s*"
-word_regex = r"^#(\d+)$"
-relation_keywords = [
- "related"
-]
-relation_distance = 2
+from labbot.config import Config
-state_label = {
- "closed": "In Progress",
- "opened": "Code-Review",
- "merged": "C-R Bestanden",
-}
-
-# Extra labels that the bot will check for before acting
-act_labels = [
- "Sprint",
- "Testing",
- "TestingFailed",
-]
+log = logging.getLogger(__name__)
+config = Config(__name__)
+config.set_global_data(
+ title_regex = r"^(?:#|)(\d+)\s*",
+ word_regex = r"^#(\d+)$",
+
+ relation_keywords = [
+ "related"
+ ],
+ relation_distance = 2,
+
+ state_label = {
+ "closed": "In Progress",
+ "opened": "Code-Review",
+ "merged": "C-R Bestanden",
+ },
+
+ act_labels = [
+ "Sprint",
+ "Testing",
+ "TestingFailed",
+ ]
+)
+
+@config.config_decorator()
async def merge_label_hook(event, gl, *args, **kwargs):
title = event.object_attributes["title"]
description = event.object_attributes["description"]
@@ -75,7 +80,7 @@ async def merge_label_hook(event, gl, *args, **kwargs):
has_label = False
issue_data = await gl.getitem(base_url)
for label in issue_data["labels"]:
- if label in act_labels or label in state_label.values():
+ if label in act_labels or label in config["state_label"].values():
has_label = True
break
@@ -83,10 +88,10 @@ async def merge_label_hook(event, gl, *args, **kwargs):
log.debug(f"Issue #{issue} does not have a relevant label")
continue
- delete_labels = act_labels + list(state_label.values())
+ delete_labels = act_labels + list(config["state_label"].values())
try:
- label = state_label[state]
+ label = config["state_label"][state]
if label in delete_labels:
delete_labels.remove(label)
@@ -103,4 +108,5 @@ async def merge_label_hook(event, gl, *args, **kwargs):
log.exception("Unknown state")
def setup(bot) -> None:
+ config.setup(__name__, bot.name)
bot.register_merge_hook(merge_label_hook)
diff --git a/labbot/addons/merge-stable.py b/labbot/addons/merge-stable.py
index d395160..f8e0ced 100644
--- a/labbot/addons/merge-stable.py
+++ b/labbot/addons/merge-stable.py
@@ -6,13 +6,18 @@ branch relation is figured out by looking at related merge requests
import logging
-log = logging.getLogger(__name__)
+from labbot.config import Config
+log = logging.getLogger(__name__)
-stable_branch = "main"
-staging_branch = "staging"
-merge_label = "Release"
+config = Config()
+config.set_global_data(
+ stable_branch = "main",
+ staging_branch = "staging",
+ merge_label = "Release",
+)
+@config.config_decorator()
async def issue_update_hook(event, gl, *args, **kwargs):
issue_id = event.object_attributes["iid"]
issue_url = f"/projects/{event.project_id}/issues/{issue_id}"
@@ -20,14 +25,14 @@ async def issue_update_hook(event, gl, *args, **kwargs):
branches = {}
- if merge_label in issue_data["labels"]:
+ if config["merge_label"] in issue_data["labels"]:
async for merge_data in gl.getiter(f"{issue_url}/related_merge_requests"):
source_branch = merge_data["source_branch"]
target_branch = merge_data["target_branch"]
merge_id = merge_data["iid"]
# we only want staging merges
- if target_branch != staging_branch:
+ if target_branch != config["staging_branch"]:
continue
if not source_branch in branches:
@@ -44,7 +49,7 @@ async def issue_update_hook(event, gl, *args, **kwargs):
async for merge_data in gl.getiter(merge_url, params={
"source_branch": branch,
- "target_branch": stable_branch
+ "target_branch": config["stable_branch"]
}):
if merge_data["state"] == "opened":
merge_exists = True
@@ -55,11 +60,12 @@ async def issue_update_hook(event, gl, *args, **kwargs):
merge_string = ", ".join(merge)
await gl.post(merge_url, data={
"source_branch": branch,
- "target_branch": stable_branch,
- "title": f"[stable] Merge `{branch}` into `{stable_branch}`",
+ "target_branch": config["stable_branch"],
+ "title": f"[stable] Merge `{branch}` into `{config['stable_branch']}`",
"description": f"Related to #{issue_id} \n \nStaging Merges: \n{merge_string}"
})
def setup(bot) -> None:
- bot.register_issue_hook(issue_update_hook) \ No newline at end of file
+ config.setup(__name__, bot.name)
+ bot.register_issue_hook(issue_update_hook)
diff --git a/labbot/bot.py b/labbot/bot.py
index 6781196..ef13978 100644
--- a/labbot/bot.py
+++ b/labbot/bot.py
@@ -79,6 +79,7 @@ class Bot:
self.register(func, "Deployment Hook", *args, **kwargs)
- def run(self, *args, **kwargs) -> None:
- log.info(f"Started {self.name}")
- self.instance.run(*args, print=False, **kwargs) \ No newline at end of file
+ def run(self, **kwargs) -> None:
+ kwargs["print"] = False
+ log.info(f"Started {self.name} under :{kwargs['port']}")
+ self.instance.run(**kwargs)
diff --git a/labbot/config.py b/labbot/config.py
index f3da425..07c4d48 100644
--- a/labbot/config.py
+++ b/labbot/config.py
@@ -2,9 +2,96 @@ import os
import json
from typing import List, Dict, Any
from appdirs import user_config_dir # type: ignore
+from functools import wraps
CONFIG_FILE = "config.json"
+class Config:
+ def __init__(self, conf_name=None, name=None):
+ self.conf_name = conf_name
+ self.name = name
+
+ self.settings = {
+ "GLOBAL": {},
+ "GROUP": {},
+ "PROJECT": {},
+ }
+ self.group_id = None
+ self.project_id = None
+
+ if self.conf_name and self.name:
+ self.setup(self.conf_name, self.name)
+
+ def setup(self, conf_name, name):
+ instance_path = instance_config_dir(name)
+ if conf_name.endswith(".json"):
+ conf_name = conf_name[:-5]
+
+ if conf_name == "config":
+ raise ValueError("Config cannot be named config")
+
+ self.conf_name = conf_name
+ self.name = name
+
+ try:
+ global_data = self.settings.get("GLOBAL", {})
+
+ self.settings = json.load(
+ open(os.path.join(instance_path, f"{conf_name}.json")))
+
+ # write the hardcoded config data ontop of the loaded data
+ self.settings["GLOBAL"].update(global_data)
+ except (IOError, ValueError):
+ pass
+
+ def __getitem__(self, key):
+ try:
+ return self.settings["PROJECT"][str(self.project_id)][key]
+ except KeyError:
+ try:
+ return self.settings["GROUP"][str(self.group_id)][key]
+ except KeyError:
+ return self.settings["GLOBAL"][key]
+
+ def save(self):
+ instance_path = instance_config_dir(self.name)
+ conf_path = os.path.join(instance_path, f"{self.conf_name}.json")
+
+ with open(conf_path, "w") as f:
+ json.dump(self.settings, f)
+
+ def config_decorator(self, **dkwargs):
+ def decorator(func):
+ @wraps(func)
+ async def wrapper(*args, **kwargs):
+
+ full_kwargs = kwargs.copy()
+ full_kwargs.update(zip(func.__code__.co_varnames, args))
+ try:
+ event = full_kwargs["event"]
+ self.project_id = event.project_id
+ except KeyError:
+ pass
+
+ try:
+ return await func(*args, **kwargs)
+ finally:
+ self.group_id = None
+ self.project_id = None
+ self.save()
+
+ return wrapper
+ return decorator
+
+ def set_global_data(self, **kwargs):
+ self.settings["GLOBAL"] = kwargs
+
+ def set_group_data(self, group_id, **kwargs):
+ self.settings["GROUP"][group_id] = kwargs
+
+ def set_project_data(self, project_id, **kwargs):
+ self.settings["PROJECT"][project_id] = kwargs
+
def list_instances() -> List[str]:
instances = []
with os.scandir(config_dir()) as it: