Files
fixtures-git/fixtures_git/gitfixture.py
Darragh Bailey bb831cb4c4 Move commit creation code to GitTree class
Move all the code required to construct a git tree into the same class
and update references.

Change-Id: I5c0df30febcdd114c5e49c28adb7383897ecdd5c
2019-05-22 18:13:04 +01:00

139 lines
4.7 KiB
Python

# Copyright (c) 2013-2016 Hewlett-Packard Development Company, L.P.
# Copyright (c) 2018 Hewlett Packard Enterprise Development Company LP
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import os
import shutil
import fixtures
import git
from . import gittree
try:
import urlparse as parse
except ImportError:
from urllib import parse
class GitFixture(fixtures.Fixture):
"""Create a git repo in which to operate.
By default creates an empty git repository under a temporary
directory and deletes it after use.
It accepts options to automatically define a git repository
layout based on list of commits setting the given branches to
the relevant node once built.
:ivar graph: Iterable describing the tree of git commits to create.
:ivar branches: Dict of node to branch names to set once finished.
:ivar path: Custom path to use, otherwise will create a temporary
directory to use and set the 'path' attribute to it.
:ivar user: Dict describing a user to use for commits, defaults
to 'Example User <user@example.com>',
:ivar clean_on_exit: Control whether to delete the tempoary path
once complete, defaults to 'True', but is ignored if 'path'
is provided.
"""
def __init__(self, graph=None, branches=None, path=None, user=None,
clean_on_exit=True):
# set attributes for use
self.path = path
self.gittree = None
self.repo = None
# internal attributes
self._graph = graph or []
self._branches = branches or []
self._user = {
'name': 'Example User',
'email': 'user@example.com',
}
self._user.update(user or {})
self._clean_on_exit = clean_on_exit
def _setUp(self):
if not self.path:
tempdir = self.useFixture(fixtures.TempDir())
self.path = os.path.join(tempdir.path, 'git')
if self._clean_on_exit is True:
self.addCleanup(shutil.rmtree, tempdir.path)
os.mkdir(self.path)
g = git.Git(self.path)
g.init()
self.repo = git.Repo(self.path)
self.repo.git.config('user.email', self._user['email'])
self.repo.git.config('user.name', self._user['name'])
self.repo.git.commit(m="Initialize empty repo", allow_empty=True)
if self._graph:
self.gittree = gittree.GitTree(
self.repo, self._graph, self._branches
)
class GitCloneFixture(fixtures.Fixture):
def __init__(self, repo_url, username=None, password=None, directory=None):
"""
Setup a fixture with a cloned git repo
Clones a repo to a temporary directory that is deleted once the
fixture is cleaned up.
To use tokens for cloning from Github private repos for testing,
set the username to '' and password to your token and it will
reconstruct a suitable URL to use if it doesn't make sense to
set the token in the original url passed.
:param repo_url: Url to repository
:param username: Username to use when cloning, set to '' if you wish
to do authenticated clones using a token as the password without
a user.
:param password: Password to use when cloning
:param directory: target directory to clone to
"""
self.username = username
self.password = password
self.repo_url = repo_url
self.directory = directory
def _setUp(self):
if self.directory is None:
self.directory = self.useFixture(fixtures.TempDir()).path
project = self.repo_url.rstrip('/').split('/')[-1]
if project.endswith('.git'):
project = project[:-4]
clone_dir = os.path.join(self.directory, project)
if os.path.exists(clone_dir):
shutil.rmtree(clone_dir)
if self.username is not None:
url_parts = list(parse.urlparse(self.repo_url))
auth = ":".join(filter(None, (self.username, self.password)))
netloc = "@".join((auth, url_parts[1]))
url_parts[1] = netloc
clone_url = parse.urlunparse(url_parts)
else:
clone_url = self.repo_url
self.repo = git.Repo.clone_from(url=clone_url, to_path=clone_dir)