forked from JOJ/Joint-Teapot
Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 71414ef9c9 | |||
| 128142e965 | |||
| 743331c81b | |||
| 3a69be006d | |||
| a901c2bbde | |||
| 77064ac37c | |||
| 332e522051 | |||
| 69e097e04b | |||
| f4fb5eae05 | |||
| 3a511660bb | |||
| 9fc7649696 | |||
| e160023cbf | |||
| 99d889ee12 | |||
| f755fb44f6 | |||
| 94d3f993b2 | |||
| aa33dcc2f1 | |||
| e24545324d | |||
| 3dc6667716 | |||
| 5b6c61af6d | |||
| 8264152022 | |||
| 992f450004 | |||
| 5478052c23 |
|
|
@ -1,41 +1,41 @@
|
||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
rev: v4.4.0
|
rev: v6.0.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: check-yaml
|
- id: check-yaml
|
||||||
- id: end-of-file-fixer
|
- id: end-of-file-fixer
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
- id: requirements-txt-fixer
|
- id: requirements-txt-fixer
|
||||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||||
rev: "v1.4.1"
|
rev: "v1.18.2"
|
||||||
hooks:
|
hooks:
|
||||||
- id: mypy
|
- id: mypy
|
||||||
additional_dependencies:
|
additional_dependencies:
|
||||||
- pydantic
|
- pydantic
|
||||||
- repo: https://github.com/asottile/pyupgrade
|
- repo: https://github.com/asottile/pyupgrade
|
||||||
rev: v3.9.0
|
rev: v3.20.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: pyupgrade
|
- id: pyupgrade
|
||||||
- repo: https://github.com/hadialqattan/pycln
|
- repo: https://github.com/hadialqattan/pycln
|
||||||
rev: v2.4.0
|
rev: v2.5.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: pycln
|
- id: pycln
|
||||||
args: [-a]
|
args: [-a]
|
||||||
- repo: https://github.com/PyCQA/bandit
|
- repo: https://github.com/PyCQA/bandit
|
||||||
rev: '1.7.5'
|
rev: '1.8.6'
|
||||||
hooks:
|
hooks:
|
||||||
- id: bandit
|
- id: bandit
|
||||||
- repo: https://github.com/PyCQA/isort
|
- repo: https://github.com/PyCQA/isort
|
||||||
rev: 5.12.0
|
rev: 6.0.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: isort
|
- id: isort
|
||||||
args: ["--profile", "black", "--filter-files"]
|
args: ["--profile", "black", "--filter-files"]
|
||||||
- repo: https://github.com/psf/black
|
- repo: https://github.com/psf/black
|
||||||
rev: 23.7.0
|
rev: 25.9.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
- repo: https://github.com/Lucas-C/pre-commit-hooks
|
- repo: https://github.com/Lucas-C/pre-commit-hooks
|
||||||
rev: v1.5.1
|
rev: v1.5.5
|
||||||
hooks:
|
hooks:
|
||||||
- id: remove-crlf
|
- id: remove-crlf
|
||||||
- id: remove-tabs
|
- id: remove-tabs
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ from pathlib import Path
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from typing import TYPE_CHECKING, List, Optional
|
from typing import TYPE_CHECKING, List, Optional
|
||||||
|
|
||||||
# from filelock import FileLock
|
from filelock import FileLock
|
||||||
from git import Repo
|
from git import Repo
|
||||||
from typer import Argument, Exit, Option, Typer, echo
|
from typer import Argument, Exit, Option, Typer, echo
|
||||||
|
|
||||||
|
|
@ -349,6 +349,7 @@ def joj3_all_env(
|
||||||
submitter_repo_name = env.github_repository.split("/")[-1]
|
submitter_repo_name = env.github_repository.split("/")[-1]
|
||||||
penalty_factor = joj3.get_penalty_factor(end_time, penalty_config)
|
penalty_factor = joj3.get_penalty_factor(end_time, penalty_config)
|
||||||
total_score = joj3.get_total_score(env.joj3_output_path)
|
total_score = joj3.get_total_score(env.joj3_output_path)
|
||||||
|
total_score = round(total_score - abs(total_score) * (1 - penalty_factor))
|
||||||
res = {
|
res = {
|
||||||
"totalScore": total_score,
|
"totalScore": total_score,
|
||||||
"cappedTotalScore": (
|
"cappedTotalScore": (
|
||||||
|
|
@ -388,13 +389,12 @@ def joj3_all_env(
|
||||||
lock_file_path = os.path.join(
|
lock_file_path = os.path.join(
|
||||||
settings.repos_dir, grading_repo_name, settings.joj3_lock_file_path
|
settings.repos_dir, grading_repo_name, settings.joj3_lock_file_path
|
||||||
)
|
)
|
||||||
logger.info(
|
logger.debug(
|
||||||
f"try to acquire lock, file path: {lock_file_path}, "
|
f"try to acquire lock, file path: {lock_file_path}, "
|
||||||
+ f"timeout: {settings.joj3_lock_file_timeout}"
|
+ f"timeout: {settings.joj3_lock_file_timeout}"
|
||||||
)
|
)
|
||||||
if True: # disable the file lock temporarily
|
with FileLock(lock_file_path, timeout=settings.joj3_lock_file_timeout).acquire():
|
||||||
# with FileLock(lock_file_path, timeout=settings.joj3_lock_file_timeout).acquire():
|
logger.debug("file lock acquired")
|
||||||
logger.info("file lock acquired")
|
|
||||||
retry_interval = 1
|
retry_interval = 1
|
||||||
git_push_ok = False
|
git_push_ok = False
|
||||||
while not git_push_ok:
|
while not git_push_ok:
|
||||||
|
|
@ -424,7 +424,9 @@ def joj3_all_env(
|
||||||
os.path.join(repo_path, scoreboard_filename),
|
os.path.join(repo_path, scoreboard_filename),
|
||||||
exercise_name,
|
exercise_name,
|
||||||
submitter_repo_name,
|
submitter_repo_name,
|
||||||
|
total_score,
|
||||||
)
|
)
|
||||||
|
failed_stage = joj3.get_failed_stage_from_file(env.joj3_output_path)
|
||||||
tea.pot.git.add_commit(
|
tea.pot.git.add_commit(
|
||||||
grading_repo_name,
|
grading_repo_name,
|
||||||
[scoreboard_filename],
|
[scoreboard_filename],
|
||||||
|
|
@ -434,6 +436,7 @@ def joj3_all_env(
|
||||||
f"gitea actions link: {gitea_actions_url}\n"
|
f"gitea actions link: {gitea_actions_url}\n"
|
||||||
f"gitea issue link: {gitea_issue_url}\n"
|
f"gitea issue link: {gitea_issue_url}\n"
|
||||||
f"groups: {env.joj3_groups}\n"
|
f"groups: {env.joj3_groups}\n"
|
||||||
|
f"failed stage: {failed_stage}\n"
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
if not skip_failed_table:
|
if not skip_failed_table:
|
||||||
|
|
@ -502,6 +505,9 @@ def joj3_check_env(
|
||||||
"Example: --penalty-config 24=0.75,48=0.5"
|
"Example: --penalty-config 24=0.75,48=0.5"
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
ignore_submitter: bool = Option(
|
||||||
|
False, help="ignore submitter when checking submission count"
|
||||||
|
),
|
||||||
) -> None:
|
) -> None:
|
||||||
app.pretty_exceptions_enable = False
|
app.pretty_exceptions_enable = False
|
||||||
set_settings(Settings(_env_file=env_path))
|
set_settings(Settings(_env_file=env_path))
|
||||||
|
|
@ -520,7 +526,7 @@ def joj3_check_env(
|
||||||
penalty_config,
|
penalty_config,
|
||||||
)
|
)
|
||||||
count_msg, count_failed = tea.pot.joj3_check_submission_count(
|
count_msg, count_failed = tea.pot.joj3_check_submission_count(
|
||||||
env, grading_repo_name, group_config, scoreboard_filename
|
env, grading_repo_name, group_config, scoreboard_filename, ignore_submitter
|
||||||
)
|
)
|
||||||
echo(
|
echo(
|
||||||
json.dumps(
|
json.dumps(
|
||||||
|
|
@ -533,6 +539,16 @@ def joj3_check_env(
|
||||||
logger.info("joj3-check-env done")
|
logger.info("joj3-check-env done")
|
||||||
|
|
||||||
|
|
||||||
|
@app.command("joj3-check-gitea-token")
|
||||||
|
def joj3_check_gitea_token(
|
||||||
|
env_path: str = Argument("", help="path to .env file")
|
||||||
|
) -> None:
|
||||||
|
app.pretty_exceptions_enable = False
|
||||||
|
set_settings(Settings(_env_file=env_path))
|
||||||
|
set_logger(settings.stderr_log_level)
|
||||||
|
tea.pot.gitea.organization_api.org_list_repos(settings.gitea_org_name)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
try:
|
try:
|
||||||
app()
|
app()
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ class Settings(BaseSettings):
|
||||||
joj_sid: str = ""
|
joj_sid: str = ""
|
||||||
|
|
||||||
# joj3
|
# joj3
|
||||||
joj3_lock_file_path: str = ".git/teapot.lock"
|
joj3_lock_file_path: str = ".git/teapot-joj3-all-env.lock"
|
||||||
joj3_lock_file_timeout: int = 30
|
joj3_lock_file_timeout: int = 30
|
||||||
|
|
||||||
# moss
|
# moss
|
||||||
|
|
|
||||||
|
|
@ -266,7 +266,6 @@ class Teapot:
|
||||||
):
|
):
|
||||||
if issue.title.startswith(title_prefix):
|
if issue.title.startswith(title_prefix):
|
||||||
joj3_issue = issue
|
joj3_issue = issue
|
||||||
logger.info(f"found joj3 issue: #{joj3_issue.number}")
|
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
new_issue = True
|
new_issue = True
|
||||||
|
|
@ -293,9 +292,7 @@ class Teapot:
|
||||||
submitter_repo_name,
|
submitter_repo_name,
|
||||||
body={"title": title, "body": comment, "labels": [label_id]},
|
body={"title": title, "body": comment, "labels": [label_id]},
|
||||||
)
|
)
|
||||||
logger.info(f"created joj3 issue: #{joj3_issue.number}")
|
|
||||||
gitea_issue_url = joj3_issue.html_url
|
gitea_issue_url = joj3_issue.html_url
|
||||||
logger.info(f"gitea issue url: {gitea_issue_url}")
|
|
||||||
if not new_issue:
|
if not new_issue:
|
||||||
self.gitea.issue_api.issue_edit_issue(
|
self.gitea.issue_api.issue_edit_issue(
|
||||||
self.gitea.org_name,
|
self.gitea.org_name,
|
||||||
|
|
@ -359,7 +356,9 @@ class Teapot:
|
||||||
grading_repo_name: str,
|
grading_repo_name: str,
|
||||||
group_config: str,
|
group_config: str,
|
||||||
scoreboard_filename: str,
|
scoreboard_filename: str,
|
||||||
|
ignore_submitter: bool,
|
||||||
) -> Tuple[str, bool]:
|
) -> Tuple[str, bool]:
|
||||||
|
submitter = env.github_actor
|
||||||
submitter_repo_name = env.github_repository.split("/")[-1]
|
submitter_repo_name = env.github_repository.split("/")[-1]
|
||||||
repo: Repo = self.git.get_repo(grading_repo_name)
|
repo: Repo = self.git.get_repo(grading_repo_name)
|
||||||
now = datetime.now(timezone.utc)
|
now = datetime.now(timezone.utc)
|
||||||
|
|
@ -386,11 +385,13 @@ class Teapot:
|
||||||
time_windows.append(since)
|
time_windows.append(since)
|
||||||
valid_items.append((name, max_count, time_period, since))
|
valid_items.append((name, max_count, time_period, since))
|
||||||
logger.info(f"valid items: {valid_items}, time windows: {time_windows}")
|
logger.info(f"valid items: {valid_items}, time windows: {time_windows}")
|
||||||
all_commits = []
|
matched_commits = []
|
||||||
|
all_commits_length = 0
|
||||||
if time_windows:
|
if time_windows:
|
||||||
earliest_since = min(time_windows).strftime("%Y-%m-%dT%H:%M:%S")
|
earliest_since = min(time_windows).strftime("%Y-%m-%dT%H:%M:%S")
|
||||||
commits = repo.iter_commits(paths=scoreboard_filename, since=earliest_since)
|
commits = repo.iter_commits(paths=scoreboard_filename, since=earliest_since)
|
||||||
for commit in commits:
|
for commit in commits:
|
||||||
|
all_commits_length += 1
|
||||||
lines = commit.message.strip().splitlines()
|
lines = commit.message.strip().splitlines()
|
||||||
if not lines:
|
if not lines:
|
||||||
continue
|
continue
|
||||||
|
|
@ -400,25 +401,28 @@ class Teapot:
|
||||||
d = match.groupdict()
|
d = match.groupdict()
|
||||||
if (
|
if (
|
||||||
env.joj3_conf_name != d["exercise_name"]
|
env.joj3_conf_name != d["exercise_name"]
|
||||||
or env.github_actor != d["submitter"]
|
|
||||||
or submitter_repo_name != d["submitter_repo_name"]
|
or submitter_repo_name != d["submitter_repo_name"]
|
||||||
):
|
):
|
||||||
continue
|
continue
|
||||||
|
if not ignore_submitter and submitter != d["submitter"]:
|
||||||
|
continue
|
||||||
groups_line = next((l for l in lines if l.startswith("groups: ")), None)
|
groups_line = next((l for l in lines if l.startswith("groups: ")), None)
|
||||||
commit_groups = (
|
commit_groups = (
|
||||||
groups_line[len("groups: ") :].split(",") if groups_line else []
|
groups_line[len("groups: ") :].split(",") if groups_line else []
|
||||||
)
|
)
|
||||||
all_commits.append(
|
matched_commits.append(
|
||||||
{
|
{
|
||||||
"time": commit.committed_datetime,
|
"time": commit.committed_datetime,
|
||||||
"groups": [g.strip() for g in commit_groups],
|
"groups": [g.strip() for g in commit_groups],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
logger.info(f"all commits length: {len(all_commits)}")
|
logger.info(
|
||||||
|
f"matched commits length: {len(matched_commits)}, all commits length: {all_commits_length}"
|
||||||
|
)
|
||||||
for name, max_count, time_period, since in valid_items:
|
for name, max_count, time_period, since in valid_items:
|
||||||
submit_count = 0
|
submit_count = 0
|
||||||
time_limit = now - timedelta(hours=time_period)
|
time_limit = now - timedelta(hours=time_period)
|
||||||
for commit in all_commits:
|
for commit in matched_commits:
|
||||||
if commit["time"] < time_limit:
|
if commit["time"] < time_limit:
|
||||||
continue
|
continue
|
||||||
if name:
|
if name:
|
||||||
|
|
@ -428,7 +432,7 @@ class Teapot:
|
||||||
continue
|
continue
|
||||||
submit_count += 1
|
submit_count += 1
|
||||||
logger.info(
|
logger.info(
|
||||||
f"submitter {env.github_actor} is submitting for the {submit_count + 1} time, "
|
f"submitter {submitter} is submitting for the {submit_count + 1} time, "
|
||||||
f"{min(0, max_count - submit_count - 1)} time(s) remaining, "
|
f"{min(0, max_count - submit_count - 1)} time(s) remaining, "
|
||||||
f"group={name}, "
|
f"group={name}, "
|
||||||
f"time period={time_period} hour(s), "
|
f"time period={time_period} hour(s), "
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ from typing import Any, Dict, List, Optional, Tuple
|
||||||
|
|
||||||
from pydantic_settings import BaseSettings
|
from pydantic_settings import BaseSettings
|
||||||
|
|
||||||
|
from joint_teapot.config import settings
|
||||||
from joint_teapot.utils.logger import logger
|
from joint_teapot.utils.logger import logger
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -41,6 +42,7 @@ def generate_scoreboard(
|
||||||
scoreboard_file_path: str,
|
scoreboard_file_path: str,
|
||||||
exercise_name: str,
|
exercise_name: str,
|
||||||
submitter_repo_name: str,
|
submitter_repo_name: str,
|
||||||
|
exercise_total_score: int,
|
||||||
) -> None:
|
) -> None:
|
||||||
if not scoreboard_file_path.endswith(".csv"):
|
if not scoreboard_file_path.endswith(".csv"):
|
||||||
logger.error(
|
logger.error(
|
||||||
|
|
@ -99,11 +101,6 @@ def generate_scoreboard(
|
||||||
for row in data:
|
for row in data:
|
||||||
row.insert(index, "")
|
row.insert(index, "")
|
||||||
|
|
||||||
exercise_total_score = 0
|
|
||||||
for stage in stages:
|
|
||||||
for result in stage["results"]:
|
|
||||||
exercise_total_score += result["score"]
|
|
||||||
exercise_total_score = exercise_total_score
|
|
||||||
submitter_row[columns.index(exercise_name)] = str(exercise_total_score)
|
submitter_row[columns.index(exercise_name)] = str(exercise_total_score)
|
||||||
|
|
||||||
total = 0
|
total = 0
|
||||||
|
|
@ -146,6 +143,18 @@ def get_failed_table_from_file(table_file_path: str) -> List[List[str]]:
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def get_failed_stage_from_file(score_file_path: str) -> str:
|
||||||
|
with open(score_file_path) as json_file:
|
||||||
|
stages: List[Dict[str, Any]] = json.load(json_file)
|
||||||
|
|
||||||
|
failed_stage = ""
|
||||||
|
for stage in stages:
|
||||||
|
if stage["force_quit"] == True:
|
||||||
|
failed_stage = stage["name"]
|
||||||
|
break
|
||||||
|
return failed_stage
|
||||||
|
|
||||||
|
|
||||||
def update_failed_table_from_score_file(
|
def update_failed_table_from_score_file(
|
||||||
data: List[List[str]],
|
data: List[List[str]],
|
||||||
score_file_path: str,
|
score_file_path: str,
|
||||||
|
|
@ -153,31 +162,23 @@ def update_failed_table_from_score_file(
|
||||||
repo_link: str,
|
repo_link: str,
|
||||||
action_link: str,
|
action_link: str,
|
||||||
) -> None:
|
) -> None:
|
||||||
# get info from score file
|
failed_stage = get_failed_stage_from_file(score_file_path)
|
||||||
with open(score_file_path) as json_file:
|
|
||||||
stages: List[Dict[str, Any]] = json.load(json_file)
|
|
||||||
|
|
||||||
failed_name = ""
|
|
||||||
for stage in stages:
|
|
||||||
if stage["force_quit"] == True:
|
|
||||||
failed_name = stage["name"]
|
|
||||||
break
|
|
||||||
|
|
||||||
# append to failed table
|
# append to failed table
|
||||||
now = datetime.now().strftime("%Y-%m-%d %H:%M")
|
now = datetime.now().strftime("%Y-%m-%d %H:%M")
|
||||||
repo = f"[{repo_name}]({repo_link})"
|
repo = f"[{repo_name}]({repo_link})"
|
||||||
failure = f"[{failed_name}]({action_link})"
|
failure = f"[{failed_stage}]({action_link})"
|
||||||
row_found = False
|
row_found = False
|
||||||
for i, row in enumerate(data[:]):
|
for i, row in enumerate(data[:]):
|
||||||
if row[1] == repo:
|
if row[1] == repo:
|
||||||
row_found = True
|
row_found = True
|
||||||
if failed_name == "":
|
if failed_stage == "":
|
||||||
data.remove(row)
|
data.remove(row)
|
||||||
else:
|
else:
|
||||||
data[i][0] = now
|
data[i][0] = now
|
||||||
data[i][2] = failure
|
data[i][2] = failure
|
||||||
break
|
break
|
||||||
if not row_found and failed_name != "":
|
if not row_found and failed_stage != "":
|
||||||
data.append([now, repo, failure])
|
data.append([now, repo, failure])
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -243,7 +244,7 @@ def generate_title_and_comment(
|
||||||
f"Generated at {now} from [Gitea Actions #{run_number}]({action_link}), "
|
f"Generated at {now} from [Gitea Actions #{run_number}]({action_link}), "
|
||||||
f"commit {commit_hash}, "
|
f"commit {commit_hash}, "
|
||||||
f"triggered by @{submitter}, "
|
f"triggered by @{submitter}, "
|
||||||
f"run ID `{run_id}`.\n"
|
f"run ID [`{run_id}`](https://focs.ji.sjtu.edu.cn/joj-mon/d/{settings.gitea_org_name}?var-Filters=RunID%7C%3D%7C{run_id}).\n"
|
||||||
"Powered by [JOJ3](https://github.com/joint-online-judge/JOJ3) and "
|
"Powered by [JOJ3](https://github.com/joint-online-judge/JOJ3) and "
|
||||||
"[Joint-Teapot](https://github.com/BoYanZh/Joint-Teapot) with ❤️.\n"
|
"[Joint-Teapot](https://github.com/BoYanZh/Joint-Teapot) with ❤️.\n"
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -38,10 +38,7 @@ def set_logger(
|
||||||
) -> None:
|
) -> None:
|
||||||
logging.basicConfig(handlers=[InterceptHandler()], level=0, force=True)
|
logging.basicConfig(handlers=[InterceptHandler()], level=0, force=True)
|
||||||
logger.remove()
|
logger.remove()
|
||||||
logger.add(
|
logger.add(stderr, level=stderr_log_level, colorize=stderr.isatty())
|
||||||
stderr,
|
|
||||||
level=stderr_log_level,
|
|
||||||
)
|
|
||||||
logger.add(settings.log_file_path, level="DEBUG")
|
logger.add(settings.log_file_path, level="DEBUG")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -90,28 +90,23 @@ class Git:
|
||||||
retry_interval = 2
|
retry_interval = 2
|
||||||
while retry_interval and auto_retry:
|
while retry_interval and auto_retry:
|
||||||
try:
|
try:
|
||||||
current_branch = ""
|
|
||||||
if repo.head.is_detached:
|
|
||||||
current_branch = repo.head.commit.hexsha
|
|
||||||
else:
|
|
||||||
current_branch = repo.active_branch.name
|
|
||||||
if clean_git_lock:
|
if clean_git_lock:
|
||||||
lock_files = [
|
locks_removed_count = 0
|
||||||
"index.lock",
|
for root, _, files in os.walk(os.path.join(repo_dir, ".git")):
|
||||||
"HEAD.lock",
|
for filename in files:
|
||||||
"fetch-pack.lock",
|
if filename.endswith(".lock"):
|
||||||
"logs/HEAD.lock",
|
lock_file_path = os.path.join(root, filename)
|
||||||
"packed-refs.lock",
|
if (
|
||||||
"config.lock",
|
os.path.relpath(lock_file_path, repo_dir)
|
||||||
f"refs/heads/{current_branch}.lock",
|
== settings.joj3_lock_file_path
|
||||||
f"refs/remotes/origin/{current_branch}.lock",
|
):
|
||||||
f"refs/heads/{checkout_dest}.lock",
|
continue
|
||||||
f"refs/remotes/origin/{checkout_dest}.lock",
|
try:
|
||||||
]
|
os.remove(lock_file_path)
|
||||||
for lock_file in lock_files:
|
locks_removed_count += 1
|
||||||
lock_path = os.path.join(repo_dir, ".git", lock_file)
|
except OSError as e:
|
||||||
if os.path.exists(lock_path):
|
logger.warning(f"error removing lock file: {e}")
|
||||||
os.remove(lock_path)
|
logger.info(f"removed {locks_removed_count} lock files")
|
||||||
repo.git.fetch("--tags", "--all", "-f")
|
repo.git.fetch("--tags", "--all", "-f")
|
||||||
repo.git.reset("--hard", reset_target)
|
repo.git.reset("--hard", reset_target)
|
||||||
repo.git.clean("-d", "-f", "-x")
|
repo.git.clean("-d", "-f", "-x")
|
||||||
|
|
@ -148,9 +143,7 @@ class Git:
|
||||||
try:
|
try:
|
||||||
repo.index.add(file)
|
repo.index.add(file)
|
||||||
except OSError:
|
except OSError:
|
||||||
logger.warning(
|
logger.warning(f'file path "{file}" does not exist, skipped')
|
||||||
f'File path "{file}" does not exist. Skipping this file.'
|
|
||||||
)
|
|
||||||
continue
|
continue
|
||||||
if repo.is_dirty(untracked_files=True) or repo.index.diff(None):
|
if repo.is_dirty(untracked_files=True) or repo.index.diff(None):
|
||||||
repo.index.commit(commit_message)
|
repo.index.commit(commit_message)
|
||||||
|
|
|
||||||
|
|
@ -494,6 +494,7 @@ class Gitea:
|
||||||
self.repository_api.user_current_delete_subscription(
|
self.repository_api.user_current_delete_subscription(
|
||||||
self.org_name, repo.name
|
self.org_name, repo.name
|
||||||
)
|
)
|
||||||
|
logger.info(f"Unwatched {repo.name}")
|
||||||
|
|
||||||
def get_all_teams(self) -> Dict[str, List[str]]:
|
def get_all_teams(self) -> Dict[str, List[str]]:
|
||||||
res: Dict[str, List[str]] = {}
|
res: Dict[str, List[str]] = {}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user