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 @@ ...@@ -10,11 +10,13 @@
import sys import sys
import json import json
from string import Formatter from string import Formatter
from typing import Dict from typing import Dict, Optional
import requests import requests
from pathlib import Path
import click import click
import pandas as pd import pandas as pd
from teach_utils.common_requests import parse_repo_url from teach_utils.common_requests import parse_repo_url
from teach_utils.utils import ingest_token
FEEDBACK_TEMPLATE = """ FEEDBACK_TEMPLATE = """
...@@ -58,10 +60,39 @@ def fill_template(content: Dict[str, str], template: str) -> str: ...@@ -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 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.command()
@click.argument("forks", type=click.File(mode="r"), default=sys.stdin) @click.argument("forks", type=click.File(mode="r"), default=sys.stdin)
@click.option( @click.option(
"--token", "--token-path",
type=click.Path(exists=True), 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.", 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: ...@@ -74,29 +105,22 @@ def fill_template(content: Dict[str, str], template: str) -> str:
default=None, default=None,
) )
@click.option( @click.option(
"--feedback", "--feedback-csv",
type=click.Path(exists=True), type=click.Path(exists=True),
help="CSV file with column 'id', and additional columns matching fields in the template" 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.", "The id column should match a gitlab project ID from the JSON input.",
default=None, default=None,
) )
@click.option( @click.option(
"--dry-run", "--dry-run", is_flag=True, help="Print feedback to stdout instead of opening issues"
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. Send feedback to repositories in input JSON by opening issues.
""" """
# Build header with authentication token # Build header with authentication token
if token is None: token = ingest_token(token_path)
token = click.prompt(
"Please enter your Gitlab API token", hide_input=True, err=True
)
else:
token = open(token).read().strip()
header = {"PRIVATE-TOKEN": token} header = {"PRIVATE-TOKEN": token}
forks = json.load(forks) forks = json.load(forks)
...@@ -108,30 +132,11 @@ def main(forks, feedback, token, template, dry_run): ...@@ -108,30 +132,11 @@ def main(forks, feedback, token, template, dry_run):
feedback_template = FEEDBACK_TEMPLATE feedback_template = FEEDBACK_TEMPLATE
for fork in forks: for fork in forks:
# Get basic fields from repo metadata in json base = parse_repo_url(fork["url"])[0]
base, group, repo = parse_repo_url(fork["url"]) fill_data = gather_fill_data(fork, feedback_csv)
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
# Replace fields in the template by their value for the current fork # Replace fields in the template by their value for the current fork
description = fill_template(fill_data, feedback_template) description = fill_template(fill_data, feedback_template)
# Create issue # Create issue, or print to stdout if dry run
if dry_run: if dry_run:
print(fork) print(fork)
print(description) 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