-
Notifications
You must be signed in to change notification settings - Fork 5
/
repo_unarchiver.py
executable file
·166 lines (139 loc) · 5.08 KB
/
repo_unarchiver.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#!/usr/bin/env python
"""
Script for unarchiving repo
Assumes that the repo was archived with the repo_archiver script
Takes an Owner/repo and does the following
reverts topic changes
uses the ARCHIVED label to reopen issues/PRs
Reverts description changes
un-archives the repo
Unlike the archiver - this works with 1 repo only.
assumption being that unarchiving is rarer than archiving.
Per GitHub API docs, MUST manually unarchive:
https://docs.github.com/en/rest/reference/repos#update-a-repository
Note: You cannot unarchive repositories through the API.
"""
import sys
from github3 import exceptions as gh_exceptions
from github3 import login
from github_scripts import utils
# TODO: CUSTOM LABEL TEXT REMEDIATION
def parse_args():
"""
Go through the command line.
If no token is specified prompt for it.
:return: Returns the parsed CLI datastructures.
"""
parser = utils.GH_ArgParser(
description="Reverse archival closing of issues of the specified repo, Note, repo "
"MUST be manually unarchived before this script"
)
parser.add_argument("repo", help="owner/repo to unarchive", action="store")
parser.add_argument(
"-q",
help="DO NOT print, or request confirmations",
dest="quiet",
action="store_true",
default=False,
)
args = parser.parse_args()
return args
def handle_issues(repo, quiet):
"""
Find any custom label, and reopen and unlabel issues.
Return the label name that was found. (Assumption - "ARCHIVED" is the seed)
:param repo: initialized gh repo object
:param quiet: if true, we won't print out things.
return: labelname that was found.
"""
do_the_label_remove = True
if not quiet:
print("\tFinding if there's a custom label")
labelname = "ARCHIVED"
labellist = repo.labels()
for label in labellist:
if label.name.find("ARCHIVED") != -1:
labelname = label.name
if not quiet:
print(f"\tFound labelname: {labelname}")
issues = repo.issues(state="closed", labels=labelname)
for issue in issues:
try:
issue.edit(state="open")
if not quiet:
print(f"\tReopening issue/PR {issue.title}")
except gh_exceptions.UnprocessableEntity:
# Hit an un-reopenable issue
do_the_label_remove = False
if not quiet:
print(f"\t\tUnable to reopen issue {issue.title}")
if do_the_label_remove:
for issue in issues:
issue.remove_label(labelname)
try:
repo.label(labelname).delete()
except gh_exceptions.NotFoundError:
print(
"No ARCHIVED label found, was this archived? manually remove topics and update description..."
)
sys.exit()
return labelname
def handle_topics(repo, quiet):
"""
Remove the unmaintained, abandoned, inactive topics if they're there.
:param repo: is the initialized repo object
:param quiet: should we not print out?
"""
topics = repo.topics().names
if "unmaintained" in topics:
topics.remove("unmaintained")
if "abandoned" in topics:
topics.remove("abandoned")
if "inactive" in topics:
topics.remove("inactive")
if not quiet:
print("\tFixing topics")
repo.replace_topics(topics)
def main():
"""
Main logic for the archiver
"""
args = parse_args()
gh_sess = login(token=args.token)
try:
org = args.repo.split("/")[0].strip()
repo = args.repo.split("/")[1].strip()
except IndexError:
print(f"{args.repo} needs to be in the form ORG/REPO")
sys.exit()
try:
gh_repo = gh_sess.repository(owner=org, repository=repo)
except gh_exceptions.NotFoundError:
print(f"Trying to open {org=}, {repo=}, failed with 404")
sys.exit()
if gh_repo.archived:
print(
"This repo is still archived, per "
"https://docs.github.com/en/rest/reference/repos#update-a-repository "
"you must manually unarchive, then this script can clean up the other changes."
)
sys.exit()
if not args.quiet:
print(f"Working with repo: {gh_repo.name}")
print("\tRe-opening issues/PRs")
# TODO: find custom label
labelname = handle_issues(repo=gh_repo, quiet=args.quiet)
handle_topics(repo=gh_repo, quiet=args.quiet)
customstr = labelname.replace("ARCHIVED - ", "")
if gh_repo.description is not None:
# Remove the DEPRECATED if it exists.
new_desc = gh_repo.description.replace("DEPRECATED - ", "", 1).replace("DEPRECATED", "", 1)
# Remove the INACTIVE if it exists.
new_desc = new_desc.replace("INACTIVE - ", "", 1).replace("INACTIVE", "", 1)
# Remove the custom label if it exists.
new_desc = new_desc.replace(customstr + " - ", "", 1).replace(customstr, "", 1)
if not args.quiet:
print(f"\tFixing description, completed revert of repo {repo}")
gh_repo.edit(name=gh_repo.name, description=new_desc)
if __name__ == "__main__":
main()