Skip to content

Commit 332cee9

Browse files
kcranstonLeah Wasser
and
Leah Wasser
authored
Refactor renaming master to main (#369)
* move deprecated method with others * temp comment out to make flake8 pass so I can merge * get git output as text, not binary * refactor changing master branch to main * adding tests for master-to-main * expand github test to verify new branch name * changelog * add dummy git config settings for tests * for git subprocess call, change text param to universal_newlines for backwards compat * Update abcclassroom/github.py * fix CI file indentation * Update .github/workflows/run-tests-mac-win-linux.yml * fix bash indentation * use --global in git config for Actions * add dummy email so that codecov tests don't fail * codecov doesn't like pointy brackets in email? * actually change the codecov workflow... Co-authored-by: Leah Wasser <[email protected]>
1 parent 3a27745 commit 332cee9

File tree

5 files changed

+134
-41
lines changed

5 files changed

+134
-41
lines changed

.github/workflows/code-cov.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ jobs:
2121
uses: actions/setup-python@master
2222
with:
2323
python-version: 3.7
24+
- name: setup git config
25+
run: |
26+
# Setup the git username and email, needed to run tests in test_github
27+
# only local git actions, so have no impact beyong tests.
28+
git config --global user.name "GitHub Actions Bot"
29+
git config --global user.email "[email protected]"
2430
- name: Generate coverage report
2531
run: |
2632
pip install pytest

.github/workflows/run-tests-mac-win-linux.yml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ name: Matrix OS / Python Version - Run Tests & Build Docs
55

66
on:
77
push:
8-
branches:
8+
branches:
99
- '*'
1010
pull_request:
11-
branches:
11+
branches:
1212
- '*'
1313
jobs:
1414
setup-build:
@@ -31,6 +31,13 @@ jobs:
3131
python -m pip install --upgrade pip
3232
pip install -r dev-requirements.txt
3333
pip install -e .
34+
- name: setup git config
35+
run: |
36+
# Setup the git username and email, needed to run tests in test_github
37+
# only local git actions, so have no impact beyong tests.
38+
git config --global user.name "GitHub Actions Bot"
39+
git config --global user.email "[email protected]"
40+
3441
- name: Test with pytest
3542
run: |
3643
pytest

CHANGELOG.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ The format is based on `Keep a Changelog <https://keepachangelog.com/en/1.0.0/>`
1212
- Overhaul fixtures, support moving different type of files & fix codecov ci (@lwasser, #273, #172)
1313
- Modify how we generate an access token for GitHub API access due to upcoming deprecation of username + password authentication (@kcranston, #328)
1414
- Make new repositories use 'main' instead of 'master' as the default branch (@kcranston, #326)
15+
- Refactor the main-to-master branch renaming for better error handling and usability (@kcranston, #363)
1516

1617
[0.1.8]
1718
------------

abcclassroom/github.py

Lines changed: 58 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -150,13 +150,14 @@ def _call_git(*args, directory=None):
150150
cmd,
151151
cwd=directory,
152152
check=True,
153+
universal_newlines=True,
153154
stdout=subprocess.PIPE,
154155
stderr=subprocess.PIPE,
155156
)
156157
except subprocess.CalledProcessError as e:
157-
err = e.stderr.decode("utf-8")
158+
err = e.stderr
158159
if not err:
159-
err = e.stdout.decode("utf-8")
160+
err = e.stdout
160161
raise RuntimeError(err) from e
161162

162163
return ret
@@ -175,31 +176,6 @@ def remote_repo_exists(org, repository, token=None):
175176
return True
176177

177178

178-
def check_student_repo_exists(org, course, student, token=None):
179-
"""Check if the student has a repository for the course.
180-
181-
It happens that students delete their repository or do not accept the
182-
invitation to the course. In either case they will not have a repository
183-
yet.
184-
"""
185-
# temporarily change log level of github3.py as it prints weird messages
186-
# XXX could be done more nicely with a context manager maybe
187-
gh3_log = logging.getLogger("github3")
188-
old_level = gh3_log.level
189-
gh3_log.setLevel("ERROR")
190-
191-
try:
192-
g = gh3.login(token=token)
193-
repository = "{}-{}".format(course, student)
194-
g.repository(org, repository)
195-
196-
except Exception as e:
197-
raise e
198-
199-
finally:
200-
gh3_log.setLevel(old_level)
201-
202-
203179
def clone_repo(organization, repo, dest_dir):
204180
"""Clone `repository` from `org` into a sub-directory in `directory`.
205181
Assumes you have ssh keys setup for github (rather than using GitHub API
@@ -307,25 +283,43 @@ def init_and_commit(directory, custom_message=False):
307283
print("No changes to local repository.")
308284

309285

310-
def _master_branch_to_main(directory):
286+
def _master_branch_to_main(dir):
311287
"""Change the name of the master branch to main
312288
313289
Changes the name of the master branch to main for the repo in the
314290
given directory. Since we create the repo on github first, which now sets
315291
the default branch to 'main', we need the local repo to match
316-
in order to be able to push with error later.
292+
in order to be able to push without errors later.
317293
"""
318-
print(
319-
"""Changing name of 'master' branch to 'main'
320-
in repo {}""".format(
321-
directory
322-
)
323-
)
294+
324295
try:
325-
_call_git("branch", "-m", "master", "main", directory=directory)
296+
# first, verify if the master branch exists (this is only true
297+
# if there are commits on the master branch)
298+
_call_git(
299+
"show-ref",
300+
"--quiet",
301+
"--verify",
302+
"refs/heads/master",
303+
directory=dir,
304+
)
326305
except RuntimeError:
327-
# we get here if the master branch has already been renamed
328-
pass
306+
# master branch verification fails, so we check for main and create
307+
# it if it does not exist
308+
try:
309+
_call_git(
310+
"show-ref",
311+
"--quiet",
312+
"--verify",
313+
"refs/heads/main",
314+
directory=dir,
315+
)
316+
except RuntimeError:
317+
# no main branch, create one
318+
_call_git("checkout", "-b", "main", directory=dir)
319+
else:
320+
# rename branch
321+
print("master exists, renaming")
322+
_call_git("branch", "-m", "master", "main", directory=dir)
329323

330324

331325
def push_to_github(directory, branch="main"):
@@ -346,7 +340,7 @@ def pull_from_github(directory, branch="master"):
346340
raise e
347341

348342

349-
def git_init(directory):
343+
def git_init(directory, defaultbranch="main"):
350344
"""Initialize git repository"""
351345
_call_git("init", directory=directory)
352346

@@ -357,6 +351,31 @@ def git_init(directory):
357351
# about correct function.
358352

359353

354+
def check_student_repo_exists(org, course, student, token=None):
355+
"""Check if the student has a repository for the course.
356+
357+
It happens that students delete their repository or do not accept the
358+
invitation to the course. In either case they will not have a repository
359+
yet.
360+
"""
361+
# temporarily change log level of github3.py as it prints weird messages
362+
# XXX could be done more nicely with a context manager maybe
363+
gh3_log = logging.getLogger("github3")
364+
old_level = gh3_log.level
365+
gh3_log.setLevel("ERROR")
366+
367+
try:
368+
g = gh3.login(token=token)
369+
repository = "{}-{}".format(course, student)
370+
g.repository(org, repository)
371+
372+
except Exception as e:
373+
raise e
374+
375+
finally:
376+
gh3_log.setLevel(old_level)
377+
378+
360379
def close_existing_pullrequests(
361380
org, repository, branch_base="new-material-", token=None
362381
):

abcclassroom/tests/test_github.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Tests for git and github methods
2+
from pathlib import Path
3+
4+
import abcclassroom.github as abcgit
5+
6+
7+
def test_init_and_commit(default_config, tmp_path):
8+
"""
9+
Tests that we can create a directory, initialize it as a git repo,
10+
and commit some changes.
11+
"""
12+
repo_dir = Path(tmp_path, "init-and-commit")
13+
repo_dir.mkdir()
14+
a_file = Path(repo_dir, "testfile.txt")
15+
a_file.write_text("Some text")
16+
abcgit.init_and_commit(repo_dir)
17+
assert Path(repo_dir, ".git").exists()
18+
git_return = abcgit._call_git("log", directory=repo_dir)
19+
assert git_return.stdout.startswith("commit")
20+
21+
22+
def test_master_branch_to_main_repeatedly(tmp_path):
23+
"""
24+
Tests that we can sucessfully change the default master branch to
25+
main, and nothing bad happends if we try and do it again
26+
"""
27+
repo_dir = Path(tmp_path, "change-master")
28+
repo_dir.mkdir()
29+
abcgit.git_init(repo_dir)
30+
31+
# change the default branch name
32+
abcgit._master_branch_to_main(repo_dir)
33+
# in order to test that main exists, we need to add some commits
34+
a_file = Path(repo_dir, "testfile.txt")
35+
a_file.write_text("Some text")
36+
commit_msg = "commit some things"
37+
abcgit.commit_all_changes(repo_dir, msg=commit_msg)
38+
39+
# now test the existance of main
40+
abcgit._call_git(
41+
"show-ref",
42+
"--quiet",
43+
"--verify",
44+
"refs/heads/main",
45+
directory=repo_dir,
46+
)
47+
48+
# trying again should also work without error
49+
abcgit._master_branch_to_main(repo_dir)
50+
51+
52+
def test_master_branch_to_main_no_commits(tmp_path):
53+
"""
54+
Tests that changing the name of the master branch in a initialized
55+
repo without commits works.
56+
"""
57+
repo_dir = Path(tmp_path, "change-master-no-commits")
58+
repo_dir.mkdir()
59+
abcgit.git_init(repo_dir)
60+
abcgit._master_branch_to_main(repo_dir)

0 commit comments

Comments
 (0)