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

Add git branch finder and test #14

Merged
merged 13 commits into from
Mar 9, 2013
Empty file.
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import os
from os.path import join, exists

import git


class GitPlugin(object):
class GitProvider(object):

def __init__(self, **configuration):
pass
def __init__(self, code_dir='.'):
self.code_dir = code_dir

def get_repo_branches_involved(self, feature_id):
"""
Expand All @@ -20,7 +23,17 @@ def get_repo_branches_involved(self, feature_id):
1: branch name
2: latest commit
"""
return [] # no info available for now
# Every folder in side self.code_dir that is a git repo will be looked
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inside?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

# at
repo_branches = []
for repo_name in os.listdir(self.code_dir):
repo_location = join(self.code_dir, repo_name)
if exists(join(repo_location, ".git")):
branches = self.get_branches_involved(repo_location,
feature_id)
repo_branches.extend([(repo_name, ) + branch
for branch in branches])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weird indent, is this valid PEP8?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently so - at least I don't get an error on mine. Reformatted anyway.

return repo_branches

def get_branches_involved(self, repo_location, feature_id):
"""
Expand All @@ -42,8 +55,9 @@ def get_branches_involved(self, repo_location, feature_id):
.format(repo_location=repo_location))
remote = git.remote.Remote(repo, 'origin')
affected = []
lower_feature = feature_id.lower()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds like lowly feature :P

for remote_ref in remote.refs:
if feature_id in remote_ref.remote_head:
if lower_feature in remote_ref.remote_head.lower():
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is a purposefully naive implementation of matching for now...
Are you planning to define a way to match branches according to defined rules/conventions? Such as <user>/<feature_id>-<text> or <feature_id><.*> or include things like a develop or staging branch in the mix etc...?

Maybe it is premature optimization, but I think if we keep VCS-service-specific code separate from process-related code (e.g. how the team approaches branching) it will make the architecture better, and adaptors to other VCS easier to write. In this case, I would rather keep the adaptors to VCS dumb and just tell them to give me a list of branches that match one in a list of regexes or sthg like that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW this service could be implemented with the Github provider as well... and the code is actually simpler. Which makes a stronger case for keeping the source control provider API so that implementations can be as dumb as possible.

I guess as long as you do not need local copies of your code (which AFAIR we only used for deploying, and deployment is very specific to each company) we could do everything with the github API.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re: everything via github api.

I still think its worth having the git provider. Reason being that it allows the system to work against any git provider rather than just github.

I think it's worth adding a github source code provider though. Added as #19.

Re: Regexes.
The user story in my mind for get_branches_involved is #22. I'm planning on changing the code here now to allow the plugin to take a feature_breakup regex and a branch_finder regex.

Hopefully that matches what you're after too...

affected.append((remote_ref.remote_head,
str(remote_ref.commit)))

Expand Down
4 changes: 2 additions & 2 deletions deploystream/settings.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from local_settings import GITHUB_CONFIG
from local_settings import GITHUB_CONFIG, GIT_CONFIG


SOURCE_CODE_PLUGINS = [
('deploystream.providers.git_plugin.plugin.GitPlugin', {}),
('deploystream.providers.git_provider.GitProvider', GIT_CONFIG),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason for the git_provider name rather than git is because git is also the name of a library that we use.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah I remember that problem from gdfabric and storyboard

]

PLANNING_PLUGINS = [
Expand Down
5 changes: 5 additions & 0 deletions local_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,8 @@
'repositories': [('pretenders', 'deploystream')],
'token': TOKEN,
}


GIT_CONFIG = {
'code_dir': None
}
1 change: 1 addition & 0 deletions tests/test_providers/data/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# This folder is used to house data for tests.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is never going to be a package, why __init__.py? can use use .empty or similar?
And add to .gitignore?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

39 changes: 39 additions & 0 deletions tests/test_providers/test_git_provider.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import os
from os.path import join, exists, dirname

from nose.tools import assert_equal

from deploystream.providers.git_provider import GitProvider

DUMMY_CODE_DIR = join(dirname(__file__), 'data')


def ensure_dummy_clone_available():
"""
Check that we have access to pretenderers' dummyrepo
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

them ones who pretend even more...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

"""
folder_name = join(DUMMY_CODE_DIR, 'dummyrepo')
if not exists(folder_name):
os.system('git clone git+ssh://[email protected]/pretenders/dummyrepo {0}'
.format(folder_name))
else:
os.system('git --git-dir={0} fetch'.format(folder_name))


def test_git_plugin_finds_branches_across_repos():
"""
Test that the GitPlugin finds branches in repos in the dir given.

Clone the dummyrepo into the data folder if not already there.

The data in this test is found by looking at the dummyrepo and getting
the branch names and latest commit of any branches that match "FeAtUrE".
"""
ensure_dummy_clone_available()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

provider = GitProvider(code_dir=DUMMY_CODE_DIR)
branches = provider.get_repo_branches_involved('FeAtUrE')

assert_equal([
('dummyrepo', 'my/feature_branch',
'cf9130d3c07b061a88569153f10a7c7779338cfa'),
], branches)