Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support git unicode branches #4433

Merged
merged 5 commits into from
Dec 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 28 additions & 24 deletions readthedocs/rtd_tests/tests/test_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,30 +49,34 @@ def setUp(self):
self.dummy_conf.submodules.include = ALL
self.dummy_conf.submodules.exclude = []

def test_parse_branches(self):
data = """
develop
master
release/2.0.0
origin/2.0.X
origin/HEAD -> origin/master
origin/master
origin/release/2.0.0
origin/release/foo/bar
"""

expected_ids = [
('develop', 'develop'),
('master', 'master'),
('release/2.0.0', 'release/2.0.0'),
('origin/2.0.X', '2.0.X'),
('origin/master', 'master'),
('origin/release/2.0.0', 'release/2.0.0'),
('origin/release/foo/bar', 'release/foo/bar'),
def test_git_branches(self):
repo_path = self.project.repo
default_branches = [
# comes from ``make_test_git`` function
'submodule',
'relativesubmodule',
'invalidsubmodule',
]
given_ids = [(x.identifier, x.verbose_name) for x in
self.project.vcs_repo().parse_branches(data)]
self.assertEqual(expected_ids, given_ids)
branches = [
'develop',
'master',
'2.0.X',
'release/2.0.0',
'release/foo/bar',
'release-ünîø∂é',
]
for branch in branches:
create_git_branch(repo_path, branch)

repo = self.project.vcs_repo()
# We aren't cloning the repo,
# so we need to hack the repo path
repo.working_dir = repo_path

self.assertEqual(
set(branches + default_branches),
{branch.verbose_name for branch in repo.branches},
)

def test_git_checkout(self):
repo = self.project.vcs_repo()
Expand All @@ -90,7 +94,7 @@ def test_git_tags(self):
repo.working_dir = repo_path
self.assertEqual(
set(['v01', 'v02', 'release-ünîø∂é']),
set(vcs.verbose_name for vcs in repo.tags)
{vcs.verbose_name for vcs in repo.tags},
)

def test_check_for_submodules(self):
Expand Down
8 changes: 6 additions & 2 deletions readthedocs/rtd_tests/tests/test_celery.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,9 @@ def test_sync_repository(self):
self.assertTrue(result.successful())

@patch('readthedocs.projects.tasks.api_v2')
def test_check_duplicate_reserved_version_latest(self, api_v2):
@patch('readthedocs.projects.models.Project.checkout_path')
def test_check_duplicate_reserved_version_latest(self, checkout_path, api_v2):
checkout_path.return_value = self.project.repo
create_git_branch(self.repo, 'latest')
create_git_tag(self.repo, 'latest')

Expand All @@ -144,7 +146,9 @@ def test_check_duplicate_reserved_version_latest(self, api_v2):
api_v2.project().sync_versions.post.assert_called()

@patch('readthedocs.projects.tasks.api_v2')
def test_check_duplicate_reserved_version_stable(self, api_v2):
@patch('readthedocs.projects.models.Project.checkout_path')
def test_check_duplicate_reserved_version_stable(self, checkout_path, api_v2):
checkout_path.return_value = self.project.repo
create_git_branch(self.repo, 'stable')
create_git_tag(self.repo, 'stable')

Expand Down
62 changes: 16 additions & 46 deletions readthedocs/vcs_support/backends/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from __future__ import (
absolute_import, division, print_function, unicode_literals)

import csv
import logging
import os
import re
Expand All @@ -13,7 +12,6 @@
from builtins import str
from django.core.exceptions import ValidationError
from git.exc import BadName
from six import PY2, StringIO

from readthedocs.config import ALL
from readthedocs.projects.exceptions import RepositoryError
Expand Down Expand Up @@ -174,51 +172,23 @@ def tags(self):

@property
def branches(self):
# Only show remote branches
retcode, stdout, _ = self.run(
'git',
'branch',
'-r',
record_as_success=True,
)
# error (or no branches found)
if retcode != 0:
return []
return self.parse_branches(stdout)

def parse_branches(self, data):
"""
Parse output of git branch -r.

e.g.:
repo = git.Repo(self.working_dir)
versions = []

origin/2.0.X
origin/HEAD -> origin/master
origin/develop
origin/master
origin/release/2.0.0
origin/release/2.1.0
"""
clean_branches = []
# StringIO below is expecting Unicode data, so ensure that it gets it.
if not isinstance(data, str):
data = str(data)
delimiter = str(' ').encode('utf-8') if PY2 else str(' ')
raw_branches = csv.reader(StringIO(data), delimiter=delimiter)
for branch in raw_branches:
branch = [f for f in branch if f not in ('', '*')]
# Handle empty branches
if branch:
branch = branch[0]
if branch.startswith('origin/'):
verbose_name = branch.replace('origin/', '')
if verbose_name in ['HEAD']:
continue
clean_branches.append(
VCSVersion(self, branch, verbose_name))
else:
clean_branches.append(VCSVersion(self, branch, branch))
return clean_branches
# ``repo.branches`` returns local branches and
branches = repo.branches
stsewd marked this conversation as resolved.
Show resolved Hide resolved
# ``repo.remotes.origin.refs`` returns remote branches
if repo.remotes:
branches += repo.remotes.origin.refs

for branch in branches:
verbose_name = branch.name
if verbose_name.startswith('origin/'):
verbose_name = verbose_name.replace('origin/', '')
if verbose_name == 'HEAD':
continue
versions.append(VCSVersion(self, str(branch), verbose_name))
return versions

@property
def commit(self):
Expand Down