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

Resolves "gitdist: Add Default Development Branch Support #236

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
75 changes: 73 additions & 2 deletions test/python_utils/gitdist_UnitTests.py
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,8 @@ def assertContainsAllGitdistHelpSections(testObj, cmndOut):
GeneralScriptSupport.extractLinesMatchingRegex(cmndOut,"^USAGE TIPS:$"), "USAGE TIPS:\n")
testObj.assertEqual(
GeneralScriptSupport.extractLinesMatchingRegex(cmndOut,"^SCRIPT DEPENDENCIES:$"), "SCRIPT DEPENDENCIES:\n")
testObj.assertEqual(
GeneralScriptSupport.extractLinesMatchingRegex(cmndOut,"^DEFAULT BRANCH SPECIFICATION:$"), "DEFAULT BRANCH SPECIFICATION:\n")


class test_gitdist(unittest.TestCase):
Expand Down Expand Up @@ -676,15 +678,15 @@ def test_dist_help_all_help(self):
# Tet that --dist-help --help prints nice error message
def test_dist_help_help(self):
cmndOut = getCmndOutput(gitdistPath+" --dist-help --help")
cmndOut_expected = "gitdist: error: option --dist-help: invalid choice: '--help' (choose from '', 'overview', 'repo-selection-and-setup', 'dist-repo-status', 'repo-versions', 'aliases', 'usage-tips', 'script-dependencies', 'all')\n"
cmndOut_expected = "gitdist: error: option --dist-help: invalid choice: '--help' (choose from '', 'overview', 'repo-selection-and-setup', 'dist-repo-status', 'repo-versions', 'aliases', 'default-branch', 'usage-tips', 'script-dependencies', 'all')\n"
self.assertEqual(s(cmndOut), s(cmndOut_expected))


# Test --dist-helps=invalid-pick picked up as invalid value.
def test_dist_help_invalid_pick_help(self):
cmndOut = getCmndOutput(gitdistPath+" --dist-help=invalid-pick --help")
assertContainsGitdistHelpHeader(self, cmndOut)
errorToFind = "gitdist: error: option --dist-help: invalid choice: 'invalid-pick' (choose from '', 'overview', 'repo-selection-and-setup', 'dist-repo-status', 'repo-versions', 'aliases', 'usage-tips', 'script-dependencies', 'all')"
errorToFind = "gitdist: error: option --dist-help: invalid choice: 'invalid-pick' (choose from '', 'overview', 'repo-selection-and-setup', 'dist-repo-status', 'repo-versions', 'aliases', 'default-branch', 'usage-tips', 'script-dependencies', 'all')"
self.assertEqual(
GeneralScriptSupport.extractLinesMatchingSubstr(cmndOut,errorToFind), errorToFind+"\n")

Expand Down Expand Up @@ -1400,5 +1402,74 @@ def test_dist_repo_status_extra_args_fail(self):
os.chdir(testBaseDir)


def test_dist_default_branch(self):
os.chdir(testBaseDir)
try:

# Create a mock git meta-project

testDir = createAndMoveIntoTestDir("gitdist_default_branch")
os.mkdir("ExtraRepo1")
os.makedirs("Path/To/ExtraRepo2")
os.mkdir("ExtraRepo3")

# Make sure .gitdist.default is found and read correctly
open(".gitdist.default", "w").write(
". master\n" \
"ExtraRepo1 develop\n" \
"Path/To/ExtraRepo2 app-devel\n" \
"MissingExtraRepo\n" \
"ExtraRepo3\n"
)
cmndOut = GeneralScriptSupport.getCmndOutput(
gitdistPathMock+" checkout _DEFAULT_BRANCH_", workingDir=testDir)
cmndOut_expected = \
"\n*** Base Git Repo: MockProjectDir\n" \
"['mockgit', 'checkout', 'master']\n\n" \
"*** Git Repo: ExtraRepo1\n" \
"['mockgit', 'checkout', 'develop']\n\n" \
"*** Git Repo: Path/To/ExtraRepo2\n" \
"['mockgit', 'checkout', 'app-devel']\n\n" \
"*** Git Repo: ExtraRepo3\n" \
"['mockgit', 'checkout', 'master']\n\n"
self.assertEqual(s(cmndOut), s(cmndOut_expected))
# NOTE: Above ensures that all of the paths are read correctly and that
# missing paths (MissingExtraRepo) are ignored.

# Make sure that .gitdist overrides .gitdist.default
open(".gitdist", "w").write(
". develop\n" \
"ExtraRepo1 develop\n" \
"ExtraRepo3 develop\n"
)
cmndOut = GeneralScriptSupport.getCmndOutput(
gitdistPathMock+" checkout _DEFAULT_BRANCH_", workingDir=testDir)
cmndOut_expected = \
"\n*** Base Git Repo: MockProjectDir\n" \
"['mockgit', 'checkout', 'develop']\n\n" \
"*** Git Repo: ExtraRepo1\n" \
"['mockgit', 'checkout', 'develop']\n\n" \
"*** Git Repo: ExtraRepo3\n" \
"['mockgit', 'checkout', 'develop']\n\n"
self.assertEqual(s(cmndOut), s(cmndOut_expected))

# Make sure that --dist-repos overrides all files
cmndOut = GeneralScriptSupport.getCmndOutput(
gitdistPathMock+" --dist-repos=.,ExtraRepo1,Path/To/ExtraRepo2 "+ \
"checkout _DEFAULT_BRANCH_",
workingDir=testDir)
cmndOut_expected = \
"\n*** Base Git Repo: MockProjectDir\n" \
"['mockgit', 'checkout', 'master']\n\n" \
"*** Git Repo: ExtraRepo1\n" \
"['mockgit', 'checkout', 'master']\n\n" \
"*** Git Repo: Path/To/ExtraRepo2\n" \
"['mockgit', 'checkout', 'master']\n\n"
self.assertEqual(s(cmndOut), s(cmndOut_expected))

finally:
os.chdir(testBaseDir)


if __name__ == '__main__':
unittest.main()
7 changes: 7 additions & 0 deletions tribits/doc/developers_guide/TribitsDevelopersGuide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8631,6 +8631,7 @@ from `gitdist --help`_ and ``gitdist --dist-help=<topic>``:
* `gitdist --dist-help=dist-repo-status`_
* `gitdist --dist-help=repo-versions`_
* `gitdist --dist-help=aliases`_
* `gitdist --dist-help=default-branch`_
* `gitdist --dist-help=usage-tips`_
* `gitdist --dist-help=script-dependencies`_
* `gitdist --dist-help=all`_
Expand Down Expand Up @@ -8675,6 +8676,12 @@ gitdist --dist-help=aliases
.. include:: gitdist-dist-help-aliases.txt
:literal:

gitdist --dist-help=default-branch
++++++++++++++++++++++++++++++++++

.. include:: gitdist-dist-help-default-branch.txt
:literal:

gitdist --dist-help=usage-tips
++++++++++++++++++++++++++++++

Expand Down
1 change: 1 addition & 0 deletions tribits/doc/developers_guide/generate-dev-guide.sh
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ if [ "$TRIBITS_DEV_GUIDE_SKIP_OTHER_EXTRACTION" == "" ] ; then
generate_gitdist_dist_help_topic dist-repo-status
generate_gitdist_dist_help_topic repo-versions
generate_gitdist_dist_help_topic aliases
generate_gitdist_dist_help_topic default-branch
generate_gitdist_dist_help_topic usage-tips
generate_gitdist_dist_help_topic script-dependencies
generate_gitdist_dist_help_topic all
Expand Down
93 changes: 85 additions & 8 deletions tribits/python_utils/gitdist.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def s(x):
'dist-repo-status',
'repo-versions',
'aliases',
'default-branch',
'usage-tips',
'script-dependencies'
]
Expand Down Expand Up @@ -468,6 +469,47 @@ def getHelpTopicsStr():
helpTopicsDict.update( { 'aliases' : usefulAliasesHelp } )


defaultBranchHelp = r"""
DEFAULT BRANCH SPECIFICATION:

When using any git command that accepts a reference (a SHA1, or branch or tag
name), it is possible to use _DEFAULT_BRANCH_ instead. For instance,

gitdist checkout _DEFAULT_BRANCH_

will check out the default development branch in each repository being managed
by gitdist. You can specify the default branch for each repository in your
.gitdist[.default] file. For instance, if your .gitdist file contains

. master
extraRepo1 develop
extraRepo2 app-devel

then the command above would check out 'master' in the base repo, 'develop' in
extraRepo1, and 'app-devel' in extraRepo2. This makes it convenient when
working with multiple repositories that have different names for their main
development branches. For instance, you can do a topic branch workflow like:

gitdist checkout _DEFAULT_BRANCH_
gitdist pull
gitdist checkout -b newFeatureBranch
<create some commits>
gitdist fetch
gitdist merge origin/_DEFAULT_BRANCH_
<create some commits>
gitdist checkout _DEFAULT_BRANCH_
gitdist pull
gitdist merge newFeatureBranch

and not worry about this 'newFeatureBranch' being off of 'master' in the root
repo, off of 'develop' in extraRepo1, and off of 'app-devel' in extraRepo2.

If no branch name is specified for any given repository in the
.gitdist[.default] file, then 'master' is assumed.
"""
helpTopicsDict.update( { 'default-branch' : defaultBranchHelp } )


usageTipsHelp = r"""
USAGE TIPS:

Expand Down Expand Up @@ -819,6 +861,22 @@ def addColorToErrorMsg(useColor, strIn):
return strIn


# Get the paths to all the repos gitdist will work on, along with any optional
# default branches.
def parseGitdistFile(gitdistfile):
reposFullList = []
defaultBranchDict = {}
with open(gitdistfile, 'r') as file:
for line in file:
entries = line.split()
reposFullList.append(entries[0])
if len(entries) > 1:
defaultBranchDict[entries[0]] = entries[1]
else:
defaultBranchDict[entries[0]] = "master"
return (reposFullList, defaultBranchDict)


# Get the commandline options
def getCommandlineOps():

Expand Down Expand Up @@ -1075,6 +1133,9 @@ def getCommandlineOps():

if options.repos:
reposFullList = options.repos.split(",")
defaultBranchDict = {}
for repo in reposFullList:
defaultBranchDict[repo] = "master"
else:
if os.path.exists(".gitdist"):
gitdistfile = ".gitdist"
Expand All @@ -1083,9 +1144,10 @@ def getCommandlineOps():
else:
gitdistfile = None
if gitdistfile:
reposFullList = open(gitdistfile, 'r').read().split()
(reposFullList, defaultBranchDict) = parseGitdistFile(gitdistfile)
else:
reposFullList = ["."] # The default is the base repo
defaultBranchDict = {".": "master"}

# Get list of not extra repos

Expand All @@ -1098,7 +1160,7 @@ def getCommandlineOps():
# G) Return
#

return (options, nativeCmnd, otherArgs, reposFullList,
return (options, nativeCmnd, otherArgs, reposFullList, defaultBranchDict,
notReposFullList)


Expand Down Expand Up @@ -1205,13 +1267,28 @@ def replaceRepoVersionInCmndLineArgs(cmndLineArgsArray, repoDirName, \
return cmndLineArgsArrayRepo


# Replace _DEFAULT_BRANCH_ in the command line arguments with the appropriate
# default branch name.
def replaceDefaultBranchInCmndLineArgs(cmndLineArgsArray, repoDirName, \
defaultBranchDict \
):
cmndLineArgsArrayDefaultBranch = []
for cmndLineArg in cmndLineArgsArray:
newCmndLineArg = re.sub("_DEFAULT_BRANCH_", \
defaultBranchDict[repoDirName], cmndLineArg)
cmndLineArgsArrayDefaultBranch.append(newCmndLineArg)
return cmndLineArgsArrayDefaultBranch


# Generate the command line arguments
def runRepoCmnd(options, cmndLineArgsArray, repoDirName, baseDir, \
repoVersionDict, repoVersionDict2 \
repoVersionDict, repoVersionDict2, defaultBranchDict \
):
cmndLineArgsArryRepo = replaceRepoVersionInCmndLineArgs(cmndLineArgsArray, \
cmndLineArgsArrayRepo = replaceRepoVersionInCmndLineArgs(cmndLineArgsArray, \
repoDirName, repoVersionDict, repoVersionDict2)
egCmndArray = [ options.useGit ] + cmndLineArgsArryRepo
cmndLineArgsArrayDefaultBranch = replaceDefaultBranchInCmndLineArgs( \
cmndLineArgsArrayRepo, repoDirName, defaultBranchDict)
egCmndArray = [ options.useGit ] + cmndLineArgsArrayDefaultBranch
runCmnd(options, egCmndArray)


Expand Down Expand Up @@ -1423,8 +1500,8 @@ def getRepoName(repoDir, baseRepoName):

if __name__ == '__main__':

(options, nativeCmnd, otherArgs, reposFullList, notReposList) = \
getCommandlineOps()
(options, nativeCmnd, otherArgs, reposFullList, defaultBranchDict, \
notReposList) = getCommandlineOps()

if nativeCmnd == "dist-repo-status":
distRepoStatus = True
Expand Down Expand Up @@ -1496,7 +1573,7 @@ def getRepoName(repoDir, baseRepoName):
print("*** Tracking branch for git repo '" + repoName + "' = '" +
repoStats.trackingBranch + "'")
runRepoCmnd(options, cmndLineArgsArray, repo, baseDir, \
repoVersionDict, repoVersionDict2)
repoVersionDict, repoVersionDict2, defaultBranchDict)
if options.debug:
print("*** Changing to directory " + baseDir)

Expand Down