You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
555 lines
19 KiB
555 lines
19 KiB
#!/usr/bin/env python
|
|
|
|
# @HEADER
|
|
# ************************************************************************
|
|
#
|
|
# TriBITS: Tribal Build, Integrate, and Test System
|
|
# Copyright 2013 Sandia Corporation
|
|
#
|
|
# Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
|
# the U.S. Government retains certain rights in this software.
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions are
|
|
# met:
|
|
#
|
|
# 1. Redistributions of source code must retain the above copyright
|
|
# notice, this list of conditions and the following disclaimer.
|
|
#
|
|
# 2. Redistributions in binary form must reproduce the above copyright
|
|
# notice, this list of conditions and the following disclaimer in the
|
|
# documentation and/or other materials provided with the distribution.
|
|
#
|
|
# 3. Neither the name of the Corporation nor the names of the
|
|
# contributors may be used to endorse or promote products derived from
|
|
# this software without specific prior written permission.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
|
|
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
|
|
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
#
|
|
# ************************************************************************
|
|
# @HEADER
|
|
|
|
from CheckinTestConstants import *
|
|
from FindGeneralScriptSupport import *
|
|
from GeneralScriptSupport import *
|
|
from gitdist import addOptionParserChoiceOption
|
|
import gitdist
|
|
|
|
|
|
#
|
|
# Constants
|
|
#
|
|
|
|
g_extraReposTypes = g_knownTribitsTestRepoTypes
|
|
g_extraReposTypeDefault = "Nightly"
|
|
g_extraReposTypesDefaulIdx = findInSequence(g_extraReposTypes, g_extraReposTypeDefault)
|
|
|
|
g_extraRerposFileDefault = "cmake/ExtraRepositoriesList.cmake"
|
|
|
|
g_verbosityLevels = [ "none", "minimal", "more", "most" ]
|
|
g_verbosityLevelDefault = "more"
|
|
g_verbosityLevelDefaultIdx = findInSequence(g_verbosityLevels, g_verbosityLevelDefault)
|
|
|
|
|
|
#
|
|
# Help message
|
|
#
|
|
|
|
# This part can be reused in other scripts that are project-specific
|
|
genericUsageHelp = \
|
|
r"""
|
|
By default, this will clone all the 'Nightly' extra repos that are listed in
|
|
the file:
|
|
|
|
<projectDir>/"""+g_extraRerposFileDefault+r"""
|
|
|
|
(other repo types can be selected using --extra-repos-type).
|
|
|
|
The list of which repos to clone can be "white-list" selected with the option
|
|
--extra-repos (see options below for details). Extra repos can in addition be
|
|
"back-listed" using the option --not-extra-repos.
|
|
|
|
To see the full list of repos that can be cloned, pass in just:
|
|
|
|
--skip-clone --verbosity=more
|
|
|
|
That will print out a table like:
|
|
|
|
------------------------------------------------------------------------------
|
|
| ID | Repo Name | Repo Dir | VC | Repo URL | Category |
|
|
|----|------------|------------|-----|--------------------------|------------|
|
|
| 1 | ExtraRepo1 | ExtraRepo1 | GIT | someurl.com.ExtraRepo1 | Continuous |
|
|
| 2 | ExtraRepo3 | ExtraRepo3 | GIT | someurl3.com:/ExtraRepo3 | Continuous |
|
|
------------------------------------------------------------------------------
|
|
|
|
If the git repo server is using gitolite, one can set
|
|
--gitolite-root=<gitolite-root> and that will result in git repos being
|
|
selected only if the selected repos are listed in 'ssh <gitolite-root> info'.
|
|
This allows one to automatically exclude repos from being cloned that the user
|
|
has no permissions to clone. NOTE: See warning about the --gitolite-root option below!
|
|
|
|
TIP: After cloning the set of repos, a nice way to interact with the repos is
|
|
to use the tool 'gitdist'. If your project does not have a version controlled
|
|
.gitdist.default file, you can generate one using the
|
|
--create-gitdist-file=<gitdist-file> argument, for example with:
|
|
|
|
--create-gitdist-file=.gitdist
|
|
|
|
This will restrict the list of repos processed by gitdist to just the repos cloned.
|
|
"""
|
|
|
|
|
|
usageHelp = r"""clone_extra_repos.py [options]
|
|
|
|
This script clones one more extra repos listed in a TriBITS
|
|
ExtraRepositoriesList.cmake file. The standard usage is:
|
|
|
|
$ cd base <projectDir>
|
|
$ ./cmake/tribits/ci_support/clone-extra-repos.py
|
|
|
|
where <projectDir> is the base TriBITS project dir and base git repo.
|
|
""" + \
|
|
genericUsageHelp
|
|
|
|
|
|
#
|
|
# Helper functions
|
|
#
|
|
|
|
|
|
def injectCmndLineOptionsInParser(clp, gitoliteRootDefault=""):
|
|
|
|
clp.add_option(
|
|
"--extra-repos", dest="extraRepos", type="string", default="",
|
|
help="List of names of extra repos to be cloned <extra-repos>" \
|
|
" (i.e. \"repo0,repo1,,...\"). When set to empty '' (the default value)" \
|
|
" then all repos that match <extra-repos-type> listed in <extra-repos-file>" \
|
|
" will be selected. But the repos listed in <extra-repos> must always" \
|
|
" be a subset of the repos of type <extra-repos-type> selected from" \
|
|
" <extra-repos-file>. (Default '')" )
|
|
|
|
clp.add_option(
|
|
"--not-extra-repos", dest="notExtraRepos", type="string", default="",
|
|
help="List of names of extra repos *NOT* to clone (i.e. \"repo0,repo1,...\")." \
|
|
" (Default '')" )
|
|
|
|
clp.add_option(
|
|
"--extra-repos-file", dest="extraReposFile", type="string",
|
|
default=g_extraRerposFileDefault,
|
|
help="The file path <extra-repos-file> for the ExtraRepositoriesList.cmake file." \
|
|
" This can be an absolute or relative path." \
|
|
" (Default = '"+g_extraRerposFileDefault+"')")
|
|
|
|
addOptionParserChoiceOption(
|
|
"--extra-repos-type", "extraReposType",
|
|
g_extraReposTypes , g_extraReposTypesDefaulIdx,
|
|
"Type of extra repositories <extra-repos-type> to select from " \
|
|
"<extra-repos-file>. When --extra-repos is set, then this argument" \
|
|
" is ignored.",
|
|
clp )
|
|
|
|
clp.add_option(
|
|
"--gitolite-root", dest="gitoliteRoot", type="string", default=gitoliteRootDefault,
|
|
help="Gives the root for a gitolite repos <gitolite-root> (e.g. git@<some-url>)." \
|
|
" If specified, then any git repos with the <gitolite-root> listed as their" \
|
|
" root will only be selected if they are listed with 'R' permissions returned" \
|
|
" from 'ssh <gitolite-root> info'. WARNING: Make sure that you have your" \
|
|
" gitoliote SSH registered correctly before using this option by typing" \
|
|
" the command 'ssh <gitlite-root> info' and make sure that it does *not*"
|
|
" ask for a password! (Default = '"+gitoliteRootDefault+"')" )
|
|
|
|
clp.add_option(
|
|
"--with-cmake", dest="withCmake", type="string", default="cmake",
|
|
help="CMake executable to use with cmake -P scripts internally (only set" \
|
|
+" by unit testing code). (Default = 'cmake')")
|
|
|
|
addOptionParserChoiceOption(
|
|
"--verbosity", "verbLevel", g_verbosityLevels, g_verbosityLevelDefaultIdx,
|
|
"Verbosity of the script (levels are cumulative):" \
|
|
" none = no output at all (except for commands with --no-op). " \
|
|
" minimal = print script args echo and clone commands." \
|
|
" more = print basic repo include/exclude logic and print repo table." \
|
|
" most = print output from cmake script called, the output from gitolite," \
|
|
" and other detailed info." \
|
|
,
|
|
clp )
|
|
|
|
clp.add_option(
|
|
"--do-clone", dest="doClone", action="store_true",
|
|
help="Do the clone of the selected repos. [default]")
|
|
clp.add_option(
|
|
"--skip-clone", dest="doClone", action="store_false",
|
|
help="Skip the clone of the repos and just show what would be done.",
|
|
default=True )
|
|
|
|
clp.add_option(
|
|
"--do-op", dest="doOp", action="store_true",
|
|
help="Do the clone of the selected repos. [default]" )
|
|
clp.add_option(
|
|
"--no-op", dest="doOp", action="store_false",
|
|
help="Skip cloning the repos and just show the clone commands.",
|
|
default=True )
|
|
|
|
clp.add_option(
|
|
"--create-gitdist-file", dest="createGitdistFile", type="string", default="",
|
|
help="If specified, the file <gitdist-file> will get generated with the list" \
|
|
" of git repos (the same list that is cloned with --do-clone)." \
|
|
" (Default = '')")
|
|
|
|
clp.add_option(
|
|
"--show-defaults", dest="showDefaults", action="store_true",
|
|
help="Show the default option values and do nothing at all.",
|
|
default=False )
|
|
|
|
|
|
def getCmndLineOptions():
|
|
from optparse import OptionParser
|
|
clp = OptionParser(usage=usageHelp)
|
|
injectCmndLineOptionsInParser(clp)
|
|
(options, args) = clp.parse_args()
|
|
return options
|
|
|
|
|
|
def isVerbosityLevel(inOptions, testVerbLevel):
|
|
requestedVerbLevelInt = findInSequence(g_verbosityLevels, inOptions.verbLevel)
|
|
testVerbLevelInt = findInSequence(g_verbosityLevels, testVerbLevel)
|
|
if testVerbLevelInt <= requestedVerbLevelInt:
|
|
return True
|
|
return False
|
|
|
|
|
|
def fwdCmndLineOptions(inOptions, terminator=""):
|
|
cmndLineOpts = \
|
|
" --extra-repos='"+inOptions.extraRepos+"'"+terminator + \
|
|
" --not-extra-repos='"+inOptions.notExtraRepos+"'"+terminator + \
|
|
" --extra-repos-file='"+inOptions.extraReposFile+"'"+terminator + \
|
|
" --extra-repos-type='"+inOptions.extraReposType+"'"+terminator + \
|
|
" --gitolite-root='"+inOptions.gitoliteRoot+"'"+terminator + \
|
|
" --with-cmake='"+inOptions.withCmake+"'"+terminator + \
|
|
" --verbosity='"+inOptions.verbLevel+"'"+terminator
|
|
if inOptions.doClone:
|
|
cmndLineOpts += " --do-clone" + terminator
|
|
else:
|
|
cmndLineOpts +=" --skip-clone" + terminator
|
|
if inOptions.doOp:
|
|
cmndLineOpts += " --do-op" + terminator
|
|
else:
|
|
cmndLineOpts += " --no-op" + terminator
|
|
cmndLineOpts += \
|
|
" --create-gitdist-file='"+inOptions.createGitdistFile+"'"+terminator
|
|
return cmndLineOpts
|
|
|
|
|
|
def echoCmndLineOptions(inOptions):
|
|
print(fwdCmndLineOptions(inOptions, " \\\n"))
|
|
|
|
|
|
def echoCmndLine(inOptions):
|
|
|
|
print("")
|
|
print("**************************************************************************")
|
|
print("Script: clone_extra_repos.py \\")
|
|
|
|
echoCmndLineOptions(inOptions)
|
|
|
|
|
|
def getHeaderOutputAndExtraReposDictList(rawOutputFromCmakefile):
|
|
rawOutputFromCmakefile = s(rawOutputFromCmakefile)
|
|
headerOuput = ""
|
|
pythonDictListStr = ""
|
|
processingPythonDict = False
|
|
for line in rawOutputFromCmakefile.splitlines():
|
|
if line == "*** Extra Repositories Python Dictionary":
|
|
processingPythonDict=True
|
|
continue
|
|
if processingPythonDict:
|
|
pythonDictListStr += (line + "\n")
|
|
else:
|
|
headerOuput += (line + "\n")
|
|
#print("\nheaderOuput:\n\n", headerOuput)
|
|
#print("\npythonDictListStr = '"+pythonDictListStr+"'")
|
|
pythonDictList = eval(pythonDictListStr)
|
|
return (headerOuput, pythonDictList)
|
|
|
|
|
|
def getExtraReposDictListFromCmakefile(projectDir, extraReposFile, withCmake,
|
|
extraReposType=g_extraReposTypeDefault, extraRepos="",
|
|
tribitsDir=tribitsDir, verbose=True,
|
|
):
|
|
cmnd = "\""+withCmake+"\""+ \
|
|
" -DPROJECT_SOURCE_DIR="+projectDir+ \
|
|
" -DTRIBITS_BASE_DIR="+tribitsDir+ \
|
|
" -DEXTRA_REPOS_FILE="+extraReposFile+ \
|
|
" -DENABLE_KNOWN_EXTERNAL_REPOS_TYPE="+extraReposType+ \
|
|
" -DEXTRA_REPOS="+extraRepos+\
|
|
" -DCHECK_EXTRAREPOS_EXIST=FALSE"
|
|
# " -DTRIBITS_PROCESS_EXTRAREPOS_LISTS_DEBUG=TRUE"
|
|
cmnd += \
|
|
" -P "+ciSupportDir+"/TribitsGetExtraReposForCheckinTest.cmake"
|
|
rawOutput = getCmndOutput(cmnd, throwOnError=True, getStdErr=True)
|
|
(headerOutput, extraReposPytonDictList) = getHeaderOutputAndExtraReposDictList(rawOutput)
|
|
if verbose:
|
|
print("\n" + headerOutput)
|
|
return extraReposPytonDictList
|
|
|
|
|
|
# Parse raw 'ssh <gitolite-root> info' output and return list of gitolite
|
|
# repos.
|
|
def parseRawSshGitoliteRootInfoOutput(rawSshGitoliteRootInfoOutput, verbose=False):
|
|
|
|
rawSshGitoliteRootInfoOutputList = rawSshGitoliteRootInfoOutput.splitlines()
|
|
|
|
gitoliteSshHeader = rawSshGitoliteRootInfoOutputList[0]
|
|
if verbose:
|
|
print(gitoliteSshHeader)
|
|
|
|
gitolioteReposList = []
|
|
parsingRepos = False
|
|
for line in rawSshGitoliteRootInfoOutputList:
|
|
#print("line = '"+line+"'")
|
|
# Look for the first blank line and then the next line will be the first
|
|
# listed repo.
|
|
if line == "":
|
|
parsingRepos = True
|
|
continue
|
|
# Parse the repos
|
|
if parsingRepos:
|
|
# The permissions and the repo name are split by a tab such as:
|
|
# R W ExtraRepo1
|
|
repoSplit = line.split("\t")
|
|
#print("repoSplit =", repoSplit)
|
|
if len(repoSplit) == 2:
|
|
gitolioteReposList.append(repoSplit[1])
|
|
return gitolioteReposList
|
|
|
|
|
|
# Get the list of gitolite repos from 'ssh <gitolite-root> info'.
|
|
def getGitoliteReposList(inOptions, trace=False, dumpGitoliteOutput=False):
|
|
cmnd = "ssh "+inOptions.gitoliteRoot+" info"
|
|
if trace:
|
|
"Running: "+cmnd
|
|
rawSshGitoliteRootInfoOutput = getCmndOutput(cmnd)
|
|
if dumpGitoliteOutput:
|
|
print(rawSshGitoliteRootInfoOutput)
|
|
if (trace and not dumpGitoliteOutput): verbose=True
|
|
else: verbose=False
|
|
return parseRawSshGitoliteRootInfoOutput(rawSshGitoliteRootInfoOutput, verbose=verbose)
|
|
|
|
|
|
def filterOutNotExtraRepos(extraRepoDictList_in, notExtraRepos, verbose=False):
|
|
notExtraReposSet = set(notExtraRepos)
|
|
extraRepoDictList = []
|
|
for extraReposDict in extraRepoDictList_in:
|
|
extraRepoName = extraReposDict["NAME"]
|
|
if extraRepoName in notExtraReposSet:
|
|
if verbose:
|
|
print("Excluding extra repo '"+extraRepoName+"'!")
|
|
else:
|
|
extraRepoDictList.append(extraReposDict)
|
|
return extraRepoDictList
|
|
|
|
|
|
def filterOutMissingGitoliteRepos(extraRepoDictList_in,
|
|
gitoliteRepos, verbose=False):
|
|
gitoliteReposSet = set(gitoliteRepos)
|
|
extraRepoDictList = []
|
|
for extraReposDict in extraRepoDictList_in:
|
|
extraRepoName = extraReposDict["NAME"]
|
|
if not extraRepoName in gitoliteReposSet:
|
|
if verbose:
|
|
print("Excluding extra repo '" + extraRepoName +
|
|
"' not listed by gitolite!")
|
|
else:
|
|
extraRepoDictList.append(extraReposDict)
|
|
return extraRepoDictList
|
|
|
|
|
|
def getExtraReposTable(extraRepoDictList):
|
|
|
|
# Get the lists for each column in the table
|
|
repoIdList = []
|
|
repoNameList = []
|
|
repoDirList = []
|
|
repoVcTypeList = []
|
|
repoUrlList = []
|
|
repoCategoryList = []
|
|
repoId = 1 # Use one-base indexing to match gitdist IDs!
|
|
for extraRepoDict in extraRepoDictList:
|
|
repoIdList.append(str(repoId))
|
|
repoNameList.append(extraRepoDict["NAME"])
|
|
repoDirList.append(extraRepoDict["DIR"])
|
|
repoVcTypeList.append(extraRepoDict["REPOTYPE"])
|
|
repoUrlList.append(extraRepoDict["REPOURL"])
|
|
repoCategoryList.append(extraRepoDict["CATEGORY"])
|
|
repoId += 1
|
|
|
|
# Create the table
|
|
extraReposTableDictList = [
|
|
{ "label":"ID", "align":"R", "fields":repoIdList },
|
|
{ "label":"Repo Name", "align":"L", "fields":repoNameList },
|
|
{ "label":"Repo Dir", "align":"L", "fields":repoDirList },
|
|
{ "label":"VC", "align":"L", "fields":repoVcTypeList },
|
|
{ "label":"Repo URL", "align":"L", "fields":repoUrlList },
|
|
{ "label":"Category", "align":"L", "fields":repoCategoryList },
|
|
]
|
|
#print("extraReposTableDictList =", extraReposTableDictList)
|
|
|
|
extraReposTable = gitdist.createTable(extraReposTableDictList)
|
|
|
|
# Return the table
|
|
return extraReposTable
|
|
|
|
|
|
def createGitDistFile(extraRepoDictList, gitdistFile, verbose=False):
|
|
gitdistFileStr = ""
|
|
for extraRepoDict in extraRepoDictList:
|
|
gitdistFileStr += extraRepoDict["DIR"]+"\n"
|
|
if verbose:
|
|
print("Writing the file '" + gitdistFile + "' ...")
|
|
open(gitdistFile, 'w').write(gitdistFileStr)
|
|
|
|
|
|
def cloneExtraRepo(inOptions, extraRepoDict):
|
|
repoName = extraRepoDict["NAME"]
|
|
repoDir = extraRepoDict["DIR"]
|
|
repoUrl = extraRepoDict["REPOURL"]
|
|
repoVcType = extraRepoDict["REPOTYPE"]
|
|
verbLevelIsMinimum = isVerbosityLevel(inOptions, "minimal")
|
|
if verbLevelIsMinimum:
|
|
print("\nCloning repo " + repoName + " ...")
|
|
if os.path.exists(repoDir):
|
|
if verbLevelIsMinimum:
|
|
print("\n ==> Repo dir = '" + repoDir +
|
|
"' already exists. Skipping clone!")
|
|
return
|
|
if repoVcType != "GIT":
|
|
print("\n ==> ERROR: Repo type '"+repoVcType+"' not supported!")
|
|
sys.exit(1)
|
|
cmnd = "git clone "+repoUrl+" "+repoDir
|
|
if inOptions.doOp:
|
|
echoRunSysCmnd(cmnd, timeCmnd=True, verbose=verbLevelIsMinimum)
|
|
elif verbLevelIsMinimum:
|
|
print("\nRunning: " + cmnd)
|
|
|
|
|
|
def cloneExtraRepos(inOptions):
|
|
|
|
verbLevelIsMinimal = isVerbosityLevel(inOptions, "minimal")
|
|
|
|
#
|
|
# A) Get the list of extra repos
|
|
#
|
|
|
|
extraRepoDictList = getExtraReposDictListFromCmakefile(
|
|
projectDir=os.getcwd(),
|
|
extraReposFile=inOptions.extraReposFile,
|
|
extraReposType=inOptions.extraReposType,
|
|
extraRepos=inOptions.extraRepos,
|
|
withCmake=inOptions.withCmake,
|
|
verbose=isVerbosityLevel(inOptions, "most")
|
|
)
|
|
#print("extraRepoDictList =" + str(extraRepoDictList))
|
|
|
|
#
|
|
# B) Get the list of gitolite repos
|
|
#
|
|
|
|
if inOptions.gitoliteRoot:
|
|
if verbLevelIsMinimal:
|
|
print("\n***")
|
|
print("*** Get the list of repos that can be cloned from gitolite server:")
|
|
print("***\n")
|
|
gitoliteRepos = getGitoliteReposList(inOptions,
|
|
trace=verbLevelIsMinimal,
|
|
dumpGitoliteOutput=isVerbosityLevel(inOptions, "most"))
|
|
else:
|
|
gitoliteRepos = []
|
|
#print("gitoliteRepos =", gitoliteRepos)
|
|
|
|
#
|
|
# C) Filter the list of extra repos
|
|
#
|
|
|
|
if gitoliteRepos:
|
|
if verbLevelIsMinimal:
|
|
print("\n***")
|
|
print("*** Filtering the set of extra repos based on gitolite repos:")
|
|
print("***\n")
|
|
extraRepoDictList = filterOutMissingGitoliteRepos(
|
|
extraRepoDictList, gitoliteRepos, verbose=verbLevelIsMinimal)
|
|
|
|
if inOptions.notExtraRepos:
|
|
if verbLevelIsMinimal:
|
|
print("\n***")
|
|
print("*** Filtering the set of extra repos based on --not-extra-repos:")
|
|
print("***\n")
|
|
extraRepoDictList = filterOutNotExtraRepos(
|
|
extraRepoDictList,
|
|
inOptions.notExtraRepos.split(","),
|
|
verbose=verbLevelIsMinimal)
|
|
|
|
#
|
|
# D) print out table of repos
|
|
#
|
|
|
|
if isVerbosityLevel(inOptions, "more"):
|
|
|
|
print("\n***")
|
|
print("*** List of selected extra repos to clone:")
|
|
print("***\n")
|
|
|
|
extraReposTable = getExtraReposTable(extraRepoDictList)
|
|
print(extraReposTable)
|
|
|
|
#
|
|
# E) Clone the repos
|
|
#
|
|
|
|
if inOptions.doClone:
|
|
|
|
if verbLevelIsMinimal:
|
|
print("\n***")
|
|
print("*** Clone the selected extra repos:")
|
|
print("***\n")
|
|
|
|
for extraRepoDict in extraRepoDictList:
|
|
cloneExtraRepo(inOptions, extraRepoDict)
|
|
|
|
#
|
|
# F) Create the gitdist file
|
|
#
|
|
|
|
if inOptions.createGitdistFile:
|
|
|
|
if verbLevelIsMinimal:
|
|
print("\n***")
|
|
print("*** Create the gitdist file:")
|
|
print("***\n")
|
|
|
|
createGitDistFile(extraRepoDictList, inOptions.createGitdistFile,
|
|
verbose=verbLevelIsMinimal)
|
|
|
|
|
|
#
|
|
# Run the script
|
|
#
|
|
|
|
if __name__ == '__main__':
|
|
|
|
inOptions = getCmndLineOptions()
|
|
if isVerbosityLevel(inOptions, "minimal"):
|
|
echoCmndLine(inOptions)
|
|
if inOptions.showDefaults:
|
|
sys.exit(0)
|
|
|
|
cloneExtraRepos(inOptions)
|
|
|