20
20
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
21
# THE SOFTWARE.
22
22
23
+ """An utility to automatically apply the 'hacktoberfest' label to open issues
24
+ marked as 'good first issue', during DigitalOcean's/GitHub's Hacktoberfest
25
+ event.
26
+ """
27
+
23
28
import argparse
24
29
import datetime
25
30
import requests
33
38
"--remove-label" ,
34
39
action = "store_true" ,
35
40
help = "Option to remove Hacktoberfest labels, instead of adding them." ,
36
- dest = "remove_label" ,
41
+ dest = "remove_labels" ,
42
+ )
43
+ cli_args .add_argument (
44
+ "--dry-run" ,
45
+ action = "store_true" ,
46
+ help = "Option to remove Hacktoberfest labels, instead of adding them." ,
47
+ dest = "dry_run" ,
37
48
)
38
49
39
50
@@ -56,7 +67,7 @@ def is_hacktober_season():
56
67
]
57
68
if add_range [0 ] <= today <= add_range [1 ]:
58
69
return True , "add"
59
- elif remove_range [0 ] <= today <= remove_range [1 ]:
70
+ if remove_range [0 ] <= today <= remove_range [1 ]:
60
71
return True , "remove"
61
72
62
73
return False , None
@@ -70,7 +81,7 @@ def get_open_issues(repo):
70
81
}
71
82
response = github .get ("/repos/" + repo ["full_name" ] + "/issues" , params = params )
72
83
if not response .ok :
73
- print ("Failed to retrieve issues for '{}'" . format ( repo [" name" ]) )
84
+ print (f "Failed to retrieve issues for '{ repo [' name' ] } '" )
74
85
return False
75
86
76
87
issues = []
@@ -79,33 +90,21 @@ def get_open_issues(repo):
79
90
[issue for issue in response .json () if "pull_request" not in issue ]
80
91
)
81
92
82
- try :
83
- links = response .headers ["Link" ]
84
- except KeyError :
85
- break
86
- next_url = None
87
- for link in links .split ("," ):
88
- link , rel = link .split (";" )
89
- link = link .strip (" <>" )
90
- rel = rel .strip ()
91
- if rel == 'rel="next"' :
92
- next_url = link
93
- break
94
- if not next_url :
93
+ if response .links .get ("next" ):
94
+ response = requests .get (response .links ["next" ]["url" ])
95
+ else :
95
96
break
96
97
97
- response = requests .get (link , timeout = 30 )
98
-
99
98
return issues
100
99
101
100
102
- def ensure_hacktober_label_exists (repo ):
101
+ def ensure_hacktober_label_exists (repo , dry_run = False ):
103
102
"""Checks if the 'Hacktoberfest' label exists on the repo.
104
103
If not, creates the label.
105
104
"""
106
- response = github .get ("/repos/" + repo [" full_name" ] + " /labels" )
105
+ response = github .get (f "/repos/{ repo [' full_name' ] } /labels" )
107
106
if not response .ok :
108
- print ("Failed to retrieve labels for '{}'" . format ( repo [" name" ]) )
107
+ print (f "Failed to retrieve labels for '{ repo [' name' ] } '" )
109
108
return False
110
109
111
110
repo_labels = [label ["name" ] for label in response .json ()]
@@ -117,17 +116,16 @@ def ensure_hacktober_label_exists(repo):
117
116
"color" : "f2b36f" ,
118
117
"description" : "DigitalOcean's Hacktoberfest" ,
119
118
}
120
- result = github .post ("/repos/" + repo ["full_name" ] + "/labels" , json = params )
121
- if not result .status_code == 201 :
122
- print (
123
- "Failed to create new Hacktoberfest label for: {}" .format (repo ["name" ])
124
- )
125
- return False
119
+ if not dry_run :
120
+ result = github .post (f"/repos/{ repo ['full_name' ]} /labels" , json = params )
121
+ if not result .status_code == 201 :
122
+ print (f"Failed to create new Hacktoberfest label for: { repo ['name' ]} " )
123
+ return False
126
124
127
125
return True
128
126
129
127
130
- def assign_hacktoberfest (repo , issues = None , remove_labels = False ):
128
+ def assign_hacktoberfest (repo , issues = None , remove_labels = False , dry_run = False ):
131
129
"""Gathers open issues on a repo, and assigns the 'Hacktoberfest' label
132
130
to each issue if its not already assigned.
133
131
"""
@@ -150,50 +148,54 @@ def assign_hacktoberfest(repo, issues=None, remove_labels=False):
150
148
update_issue = True
151
149
else :
152
150
if has_good_first and not has_hacktober :
153
- label_exists = ensure_hacktober_label_exists (repo )
151
+ label_exists = ensure_hacktober_label_exists (repo , dry_run )
154
152
if not label_exists :
155
153
continue
156
154
update_issue = True
157
155
158
156
if update_issue :
159
157
params = {"labels" : label_names }
160
- result = github .patch (
161
- "/repos/" + repo ["full_name" ] + "/issues/" + str (issue ["number" ]),
162
- json = params ,
163
- )
164
-
165
- if result .ok :
166
- labels_changed += 1
158
+ if not dry_run :
159
+ result = github .patch (
160
+ f"/repos/{ repo ['full_name' ]} /issues/{ str (issue ['number' ])} " ,
161
+ json = params ,
162
+ )
163
+
164
+ if result .ok :
165
+ labels_changed += 1
166
+ else :
167
+ # sadly, GitHub will only silently ignore labels that are
168
+ # not added and return a 200. so this will most likely only
169
+ # trigger on endpoint/connection failures.
170
+ print (f"Failed to add Hacktoberfest label to: { issue ['url' ]} " )
167
171
else :
168
- # sadly, GitHub will only silently ignore labels that are
169
- # not added and return a 200. so this will most likely only
170
- # trigger on endpoint/connection failures.
171
- print ("Failed to add Hacktoberfest label to: {}" .format (issue ["url" ]))
172
+ labels_changed += 1
172
173
173
174
return labels_changed
174
175
175
176
176
- def process_hacktoberfest (repo , issues = None , remove_labels = False ):
177
- result = assign_hacktoberfest (repo , issues , remove_labels )
177
+ def process_hacktoberfest (repo , issues = None , remove_labels = False , dry_run = False ):
178
+ """Run hacktoberfest functions and return the result."""
179
+ result = assign_hacktoberfest (repo , issues , remove_labels , dry_run )
178
180
return result
179
181
180
182
181
183
if __name__ == "__main__" :
182
- labels_assigned = 0
184
+ LABELS_ASSIGNED = 0
183
185
args = cli_args .parse_args ()
184
186
185
- remove_labels = args .remove_label
186
-
187
- if not remove_labels :
187
+ if not args .remove_labels :
188
188
print ("Checking for open issues to assign the Hacktoberfest label to..." )
189
189
else :
190
190
print ("Checking for open issues to remove the Hacktoberfest label from..." )
191
191
192
192
repos = common_funcs .list_repos ()
193
- for repo in repos :
194
- labels_assigned += process_hacktoberfest (repo , remove_labels )
193
+ for repository in repos :
194
+ LABELS_ASSIGNED += process_hacktoberfest (
195
+ repository , remove_labels = args .remove_labels , dry_run = args .dry_run
196
+ )
195
197
196
- if not remove_labels :
197
- print ("Added the Hacktoberfest label to {} issues." . format ( labels_assigned ) )
198
+ if not args . remove_labels :
199
+ print (f "Added the Hacktoberfest label to { LABELS_ASSIGNED } issues." )
198
200
else :
199
- print ("Removed the Hacktoberfest label from {} issues." . format ( labels_assigned ) )
201
+ print (f "Removed the Hacktoberfest label from { LABELS_ASSIGNED } issues." )
0 commit comments