Commit e25717aa authored by Cyril Matthey-Doret's avatar Cyril Matthey-Doret
Browse files

modularize send_feedback

parent dd0f2bae
Pipeline #388193 passed with stage
in 3 minutes and 45 seconds
......@@ -10,11 +10,13 @@
import sys
import json
from string import Formatter
from typing import Dict
from typing import Dict, Optional
import requests
from pathlib import Path
import click
import pandas as pd
from teach_utils.common_requests import parse_repo_url
from teach_utils.utils import ingest_token
FEEDBACK_TEMPLATE = """
......@@ -58,10 +60,39 @@ def fill_template(content: Dict[str, str], template: str) -> str:
raise ValueError(f"Fields missing from content: {missing_flds}") from None
def gather_fill_data(fork: Dict, feedback_csv: Optional[Path] = None) -> Dict:
"""Gather metadata and feedback for a single fork into a dictionary
to use for filling the template. The resulting dictionary contains
fields: project, group, members, url, commit and visibility from the fork
metadata, as well as all columns present in the feedback csv file.
"""
# Get basic fields in fork metadata
_, group, repo = parse_repo_url(fork["url"])
members = "\n".join([f"* {member['name']}" for member in fork["members"]])
fill_data = {
"project": repo.removesuffix(".git"),
"group": group,
"members": members,
}
# add commit, url and visibility fields from fork data
fill_data |= {key: fork.get(key) for key in ["url", "commit", "visibility"]}
# If a CSV file with feedback is provided, read the fields
# of the current fork (row) to the fill data.
if feedback_csv:
fill_data |= (
pd.read_csv(feedback_csv)
.query(f'id == {fork["id"]}')
.iloc[0]
.drop("id")
.to_dict()
)
return fill_data
@click.command()
@click.argument("forks", type=click.File(mode="r"), default=sys.stdin)
@click.option(
"--token",
"--token-path",
type=click.Path(exists=True),
help="Path to a file containing the Gitlab API token. If not provided, you will be prompted for the token.",
)
......@@ -74,29 +105,22 @@ def fill_template(content: Dict[str, str], template: str) -> str:
default=None,
)
@click.option(
"--feedback",
"--feedback-csv",
type=click.Path(exists=True),
help="CSV file with column 'id', and additional columns matching fields in the template"
"The id column should match a gitlab project ID from the JSON input.",
default=None,
)
@click.option(
"--dry-run",
is_flag=True,
help="Print feedback to stdout instead of opening issues"
"--dry-run", is_flag=True, help="Print feedback to stdout instead of opening issues"
)
def main(forks, feedback, token, template, dry_run):
def main(forks, feedback_csv, token_path, template, dry_run):
"""
Send feedback to repositories in input JSON by opening issues.
"""
# Build header with authentication token
if token is None:
token = click.prompt(
"Please enter your Gitlab API token", hide_input=True, err=True
)
else:
token = open(token).read().strip()
token = ingest_token(token_path)
header = {"PRIVATE-TOKEN": token}
forks = json.load(forks)
......@@ -108,30 +132,11 @@ def main(forks, feedback, token, template, dry_run):
feedback_template = FEEDBACK_TEMPLATE
for fork in forks:
# Get basic fields from repo metadata in json
base, group, repo = parse_repo_url(fork["url"])
members = "\n".join([f"* {member['name']}" for member in fork["members"]])
fill_data = {
"project": repo.removesuffix(".git"),
"group": group,
"members": members,
}
# add commit, url and visibility fields from fork data
fill_data |= {key: fork.get(key) for key in ["url", "commit", "visibility"]}
# If provided, get additional fields from feedback table
if feedback:
feedback_fields = (
pd.read_csv(feedback)
.query(f'id == {fork["id"]}')
.iloc[0]
.drop("id")
.to_dict()
)
fill_data |= feedback_fields
base = parse_repo_url(fork["url"])[0]
fill_data = gather_fill_data(fork, feedback_csv)
# Replace fields in the template by their value for the current fork
description = fill_template(fill_data, feedback_template)
# Create issue
# Create issue, or print to stdout if dry run
if dry_run:
print(fork)
print(description)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment