コード例 #1
0
ファイル: updateLocal.py プロジェクト: LLNL/GRAPE
    def execute(self, args):
        wsDir = args["--wd"] if args["--wd"] else utility.workspaceDir()
        wsDir = os.path.abspath(wsDir)
        os.chdir(wsDir)
        cwd = os.getcwd()

        config = grapeConfig.grapeConfig()
        recurseSubmodules = config.getboolean(
            "workspace", "manageSubmodules") or args["--recurse"]
        skipSubmodules = args["--noRecurse"]

        recurseNestedSubprojects = not args["--noRecurse"] or args[
            "--recurseSubprojects"]
        publicBranches = [x.strip() for x in args["--public"].split()]
        launchers = []
        for branch in publicBranches:
            launchers.append(
                utility.MultiRepoCommandLauncher(
                    fetchLocal,
                    runInSubmodules=recurseSubmodules,
                    runInSubprojects=recurseNestedSubprojects,
                    branch=branch,
                    listOfRepoBranchArgTuples=None,
                    skipSubmodules=skipSubmodules,
                    outer=wsDir))

        if len(launchers):
            launcher = launchers[0]
            for l in launchers[1:]:
                launcher.MergeLaunchSet(l)
            launcher.collapseLaunchSetBranches()
            launcher.launchFromWorkspaceDir(handleMRE=fetchLocalHandler)

        return True
コード例 #2
0
ファイル: utility.py プロジェクト: LLNL/GRAPE
 def initializeCommands(self):
     config = grapeConfig.grapeConfig()
     currentBranch = git.currentBranch() if not self.branchArg else self.branchArg
     publicBranches = config.getPublicBranchList()
     wsDir = dir
     
     # don't reinit
     if self.repos:
         return
     if self.launchTuple is not None:
         self.repos = [os.path.abspath(x[0]) for x in self.launchTuple]
         self.branches = [x[1] for x in self.launchTuple]
         self.perRepoArgs = [x[2] for x in self.launchTuple]
     else:
         if self.runSubprojects:
             activeSubprojects =  grapeConfig.GrapeConfigParser.getAllActiveNestedSubprojectPrefixes()
             self.repos = self.repos + [os.path.join(workspaceDir(), sub) for sub in activeSubprojects]
             self.branches = self.branches + [currentBranch for x in activeSubprojects]
         if self.runSubmodules:
             activeSubmodules = git.getActiveSubmodules()
             self.repos = self.repos + [os.path.join(workspaceDir(), r) for r in activeSubmodules]
             subPubMap = config.getMapping("workspace", "submodulepublicmappings")
             submoduleBranch =  subPubMap[currentBranch] if currentBranch in publicBranches else currentBranch
             self.branches = self.branches + [ submoduleBranch for x in activeSubmodules ]
         if self.runOuter:
             self.repos.append(self.outer)
             self.branches.append(currentBranch)
         if not self.perRepoArgs:
             if not self.globalArgs:
                 
                 self.perRepoArgs = [[] for x in self.repos]
             else:
                 self.perRepoArgs = [self.globalArgs for x in self.repos]        
コード例 #3
0
ファイル: utility.py プロジェクト: LLNL/GRAPE
 def __init__(self, lmbda, nProcesses=-1, runInSubmodules=False, runInSubprojects=True, runInOuter=True, branch="",
              globalArgs=None,perRepoArgs=[], listOfRepoBranchArgTuples=None, skipSubmodules=False, outer=""):
     self.lmbda = lmbda
     
     config = grapeConfig.grapeConfig()
     recurseSubmodules = config.getboolean("workspace", "manageSubmodules")
     if not recurseSubmodules:
         self.runSubmodules = runInSubmodules
     else:
         self.runSubmodules = recurseSubmodules
     # apply the skipSubmodules override    
     self.runSubmodules = self.runSubmodules and not skipSubmodules
     self.runSubprojects = runInSubprojects
     self.runOuter = runInOuter
     if nProcesses < 0:
         nProcesses = MultiRepoCommandLauncher.numProcs
     self.pool = MyPool(nProcesses)
     self.branchArg = branch
     self.perRepoArgs = perRepoArgs
     self.globalArgs = globalArgs
     self.launchTuple = listOfRepoBranchArgTuples
     
     self.repos = []
     self.branches = []
     if outer:
         self.outer = outer
     else:
         self.outer = workspaceDir()
コード例 #4
0
ファイル: version.py プロジェクト: LLNL/GRAPE
    def readVersion(self, fileName, args):
        config = grapeConfig.grapeConfig()
        prefix = args["--prefix"]
        if args["--suffix"]:
            suffix = args["--suffix"]
        else:
            try:
                suffixMapping = config.getMapping("versioning", "branchSuffixMappings")
                suffix = suffixMapping[config.getPublicBranchFor(git.currentBranch())]
            except KeyError:
                suffix = ""
        args["--suffix"] = suffix
        regex = args["--matchTo"]
        try:
            regexMappings = config.getMapping("versioning", "branchVersionRegexMappings")
            public = config.getPublicBranchFor(git.currentBranch())
            regex = regexMappings[public]
        except ConfigParser.NoOptionError:
            pass

        #tweaked from http://stackoverflow.com/questions/2020180/increment-a-version-id-by-one-and-write-to-mk-file
        regex = regex.replace("<prefix>", prefix)
        regex = regex.replace("<suffix>", suffix)
        self.r = re.compile(regex)

        VERSION_ID = None
        for l in fileName:
            m1 = self.r.match(l)
            if m1:
                VERSION_ID = map(int, m1.group(3).split("."))
                self.matchedLine = l
        if VERSION_ID is None:
            print("GRAPE: .")

        return VERSION_ID
コード例 #5
0
ファイル: utility.py プロジェクト: LLNL/GRAPE
 def launchFromWorkspaceDir(self, handleMRE=None, noPause=False):
     with cd(workspaceDir()):
         argLists = self.perRepoArgs
         config = grapeConfig.grapeConfig()
         
         self.initializeCommands()
         
         retvals = []
         
         if noPause:
             # for purely local operations, run them all at once. 
             if len(self.repos) > 0:            
                 retvals = self.pool.map(runCommandOnRepoBranch, [(repo, branch, self.lmbda, arg) for repo, branch, arg in zip(self.repos, self.branches, self.perRepoArgs)])            
         else:
             # run the first entry first so that things like logging in to the project's server happen up front            
             if len(self.repos) > 0:
                 retvals.append(runCommandOnRepoBranch((self.repos[0], self.branches[0], self.lmbda, self.perRepoArgs[0])))
                 if isinstance(retvals[0], Exception):
                     retvals[0] = runCommandOnRepoBranch((self.repos[0], self.branches[0], self.lmbda, self.perRepoArgs[0]))
             if len(self.repos) > 1:            
                 retvals = retvals + self.pool.map(runCommandOnRepoBranch, [(repo, branch, self.lmbda, arg) for repo, branch, arg in zip(self.repos[1:], self.branches[1:], self.perRepoArgs[1:])])
                 
     self.pool.close()
     MRE = MultiRepoException()
     for val in zip(retvals, self.repos, self.branches, self.perRepoArgs):
         if isinstance(val[0], Exception):
             MRE.addException(val[0], val[1], val[2], val[3])
     if MRE.hasException():
         if handleMRE:
             handleMRE(MRE)
         else:
             raise MRE
     return retvals 
コード例 #6
0
ファイル: updateLocal.py プロジェクト: LLNL/GRAPE
 def execute(self, args):
     wsDir = args["--wd"] if args["--wd"] else utility.workspaceDir()
     wsDir = os.path.abspath(wsDir)
     os.chdir(wsDir)
     cwd = os.getcwd()
     
     config = grapeConfig.grapeConfig()
     recurseSubmodules = config.getboolean("workspace", "manageSubmodules") or args["--recurse"]
     skipSubmodules = args["--noRecurse"]
     
     
     recurseNestedSubprojects = not args["--noRecurse"] or args["--recurseSubprojects"]
     publicBranches = [x.strip() for x in args["--public"].split()]
     launchers = []
     for branch in publicBranches:
         launchers.append(utility.MultiRepoCommandLauncher(fetchLocal,  
                                         runInSubmodules=recurseSubmodules, 
                                         runInSubprojects=recurseNestedSubprojects, 
                                         branch=branch, 
                                         listOfRepoBranchArgTuples=None, 
                                         skipSubmodules=skipSubmodules, outer=wsDir))
         
     if len(launchers):
         launcher = launchers[0]
         for l in launchers[1:]:
             launcher.MergeLaunchSet(l)
         launcher.collapseLaunchSetBranches()
         launcher.launchFromWorkspaceDir(handleMRE=fetchLocalHandler)
         
     return True
コード例 #7
0
ファイル: Atlassian.py プロジェクト: LLNL/GRAPE
 def repoFromWorkspaceRepoPath(self, path, isSubmodule=False, isNested=False, topLevelRepo=None, topLevelProject=None):
     config = grapeConfig.grapeConfig()
     if isNested:
         proj = os.path.split(path)[1]
         nestedProjectURL = config.get("nested-%s" % proj , "url")
         url = utility.parseSubprojectRemoteURL(nestedProjectURL)
         urlTokens = url.split('/')
         proj = urlTokens[-2]
         repo_name = urlTokens[-1]       
         # strip off the git extension
         repo_name = '.'.join(repo_name.split('.')[:-1])
     elif isSubmodule:
         fullpath = os.path.abspath(path)
         wsdir = utility.workspaceDir() + os.path.sep
         proj = fullpath.split(wsdir)[1].replace("\\","/")
         url =  git.config("--get submodule.%s.url" % proj).split('/')
         proj = url[-2]
         repo_name = url[-1]
 
         # strip off the .git extension
         repo_name = '.'.join(repo_name.split('.')[:-1])   
     else:
         if topLevelRepo is None:
             topLevelRepo = config.get("repo", "name")
         if topLevelProject is None:
             topLevelProject = config.get("project", "name")
             
         repo_name = topLevelRepo
         proj = topLevelProject
         
     repo = self.project(proj).repo(repo_name)
     return repo        
コード例 #8
0
ファイル: grapeGit.py プロジェクト: LLNL/GRAPE
def gitcmd(cmd, errmsg):
    _cmd = None
    try:
        cnfg = grapeConfig.grapeConfig()
        _cmd = cnfg.get("git", "executable")
    except ConfigParser.NoOptionError:
        pass
    except ConfigParser.NoSectionError:
        pass
    if _cmd:
        _cmd += " %s" % cmd
    elif os.name == "nt":
        _cmd = "\"C:\\Program Files\\Git\\bin\\git.exe\" %s" % cmd
    else:
        _cmd = "git %s" % cmd

    cwd = os.getcwd()
    process = utility.executeSubProcess(_cmd, cwd, verbose=-1)
    if process.returncode != 0:
        raise GrapeGitError("Error: %s " % errmsg,
                            process.returncode,
                            process.output,
                            _cmd,
                            cwd=cwd)
    return process.output.strip()
コード例 #9
0
ファイル: clone.py プロジェクト: LLNL/GRAPE
    def execute(self, args):
        remotepath = args["<url>"]
        destpath = args["<path>"]
        rstr = "--recursive" if args["--recursive"] else ""
        utility.printMsg("Cloning %s into %s %s" %
                         (remotepath, destpath,
                          "recursively" if args["--recursive"] else ""))
        git.clone(" %s %s %s" % (rstr, remotepath, destpath))
        utility.printMsg("Clone succeeded!")
        os.chdir(destpath)
        grapeConfig.read()
        # ensure you start on a reasonable publish branch
        menu = grapeMenu.menu()
        config = grapeConfig.grapeConfig()
        publicBranches = config.getPublicBranchList()
        if publicBranches:
            if "develop" in publicBranches:
                initialBranch = "develop"
            elif "master" in publicBranches:
                initialBranch = "master"
            else:
                initialBranch = publicBranches[0]

        menu.applyMenuChoice("checkout", args=[initialBranch])

        if args["--allNested"]:
            configArgs = ["--uv", "--uvArg=--allNestedSubprojects"]
        else:
            configArgs = []
        return menu.applyMenuChoice("config", configArgs)
コード例 #10
0
ファイル: clone.py プロジェクト: LLNL/GRAPE
    def execute(self, args):
        remotepath = args["<url>"]
        destpath = args["<path>"]
        rstr = "--recursive" if args["--recursive"] else ""
        utility.printMsg("Cloning %s into %s %s" % (remotepath, destpath, "recursively" if args["--recursive"] else ""))
        git.clone(" %s %s %s" % (rstr, remotepath, destpath))
        utility.printMsg("Clone succeeded!")
        os.chdir(destpath)
        grapeConfig.read()
        # ensure you start on a reasonable publish branch
        menu = grapeMenu.menu()
        config = grapeConfig.grapeConfig()
        publicBranches = config.getPublicBranchList()
        if publicBranches:
            if "develop" in publicBranches:
                initialBranch = "develop"
            elif "master" in publicBranches:
                initialBranch = "master"
            else:
                initialBranch = publicBranches[0]
                
        menu.applyMenuChoice("checkout", args=[initialBranch])
            


        if args["--allNested"]:
            configArgs = ["--uv","--uvArg=--allNestedSubprojects"]
        else: 
            configArgs = []
        return menu.applyMenuChoice("config", configArgs)
コード例 #11
0
ファイル: resumable.py プロジェクト: LLNL/GRAPE
 def dumpProgress(self, args, msg=""):
     print(msg)
     self._saveProgress(args)
     args["--continue"] = True
     self.progress["args"] = args
     self.progress["config"] = grapeConfig.grapeConfig()
     with open(self.progressFile, 'w') as f:
         p = pickle.Pickler(f)
         p.dump(self.progress)
コード例 #12
0
ファイル: resumable.py プロジェクト: LLNL/GRAPE
 def dumpProgress(self, args,msg=""):
     print(msg)
     self._saveProgress(args)
     args["--continue"] = True
     self.progress["args"] = args
     self.progress["config"] = grapeConfig.grapeConfig()
     with open(self.progressFile,'w') as f:
         p = pickle.Pickler(f)
         p.dump(self.progress)
コード例 #13
0
ファイル: grapeMenu.py プロジェクト: LLNL/GRAPE
    def applyMenuChoice(self,
                        choice,
                        args=None,
                        option_args=None,
                        globalArgs=None):
        chosen_option = self.getOption(choice)
        if chosen_option is None:
            return False
        if args is None or len(args) == 0:
            args = [chosen_option._key]
        #first argument better be the key
        if args[0] != chosen_option._key:
            args = [chosen_option._key] + args

        # use optdoc to parse arguments to the chosen_option.
        # utility.argParse also does the magic of filling in defaults from the config files as appropriate.
        if option_args is None and chosen_option.__doc__:
            try:
                config = chosen_option._config
                if config is None:
                    config = grapeConfig.grapeConfig()
                else:
                    config = grapeConfig.grapeRepoConfig(config)
                option_args = utility.parseArgs(chosen_option.__doc__,
                                                args[1:], config)
            except SystemExit as e:
                if len(args) > 1 and "--help" != args[1] and "-h" != args[1]:
                    print("GRAPE PARSING ERROR: could not parse %s\n" %
                          (args[1:]))
                raise e
        if globalArgs is not None:
            utility.applyGlobalArgs(globalArgs)
        try:
            if isinstance(chosen_option, resumable.Resumable):
                if option_args["--continue"]:
                    return chosen_option._resume(option_args)
            return chosen_option.execute(option_args)

        except git.GrapeGitError as e:
            print traceback.print_exc()
            print(
                "GRAPE: Uncaught Error %s in grape-%s when executing '%s' in '%s'\n%s"
                %
                (e.code, chosen_option._key, e.gitCommand, e.cwd, e.gitOutput))
            exit(e.code)

        except utility.NoWorkspaceDirException as e:
            print("GRAPE: grape %s must be run from a grape workspace." %
                  chosen_option.key)
            print("GRAPE: %s" % e.message)
            exit(1)
        finally:
            if globalArgs is not None:
                utility.popGlobalArgs()
コード例 #14
0
ファイル: version.py プロジェクト: LLNL/GRAPE
 def execute(self, args):
     self.parseArgs(args)
     if args["init"]:
         self.initializeVersioning(args)
     if args["tick"]:
         self.tickVersion(args)
     if args["read"]:
         config = grapeConfig.grapeConfig()
         fileName = config.get("versioning","file")
         try:
             with open(fileName) as f:
                 slots = self.readVersion(f, args)
                 self.ver = self.slotsToString(args, slots)
         except IOError:
             self.ver = ""
     return True
コード例 #15
0
ファイル: push.py プロジェクト: LLNL/GRAPE
    def execute(self, args):
        baseDir = utility.workspaceDir()

        cwd = os.getcwd()
        os.chdir(baseDir)
        currentBranch = git.currentBranch()
        config = grapeConfig.grapeConfig()
        publicBranches = config.getPublicBranchList()

        submodules = git.getActiveSubmodules()

        retvals = utility.MultiRepoCommandLauncher(
            push).launchFromWorkspaceDir(handleMRE=handlePushMRE)

        os.chdir(cwd)
        utility.printMsg("Pushed current branch to origin")
        return False not in retvals
コード例 #16
0
ファイル: version.py プロジェクト: LLNL/GRAPE
 def tickVersion(self, args):
     config = grapeConfig.grapeConfig()
     fileName = config.get("versioning", "file")
     with open(fileName) as f:
         slots = self.readVersion(f, args)
         self.ver = self.slotsToString(args, slots)
         
     if not args["--notick"]:
         slot = args["--slot"]
         if not slot:
             slotMappings = config.getMapping("versioning", "branchSlotMappings")
             if args["--public"]:
                 publicBranch = args["--public"]
             else:
                 publicBranch = config.getPublicBranchFor(git.currentBranch())
             slot = int(slotMappings[publicBranch])
         else:
             slot = int(slot)
         if args["--minor"]:
             slot = 2
         if args["--major"]:
             slot = 1
         # extend the version number if slot comes in too large.
         while len(slots) < slot:
             slots.append(0)
         slots[slot - 1] += 1
         while slot < len(slots):
             slots[slot] = 0
             slot += 1
         # write the new version number to the version file. 
         with open(fileName, 'r+') as f:
             self.ver = self.writeVersion(f, slots, args)
         self.stageVersionFile(fileName)
         if not args["--nocommit"]:
             git.commit("-m \"GRAPE: ticked version to %s\"" % self.ver)
             
     if (not args["--nocommit"]) or args["--tag"]:
         self.tagVersion(self.ver, args)
         if args["--tagNested"]:
             cwd = os.getcwd()
             wsDir = utility.workspaceDir()
             for subproject in grapeConfig.GrapeConfigParser.getAllActiveNestedSubprojectPrefixes():
                 os.chdir(os.path.join(wsDir, subproject))
                 self.tagVersion(self.ver, args)
             os.chdir(cwd)
コード例 #17
0
ファイル: grapeMenu.py プロジェクト: LLNL/GRAPE
    def applyMenuChoice(self, choice, args=None, option_args=None, globalArgs=None):
        chosen_option = self.getOption(choice)
        if chosen_option is None:
            return False
        if args is None or len(args) == 0:
            args = [chosen_option._key]
        #first argument better be the key
        if args[0] != chosen_option._key:
            args = [chosen_option._key]+args

        # use optdoc to parse arguments to the chosen_option.
        # utility.argParse also does the magic of filling in defaults from the config files as appropriate.
        if option_args is None and chosen_option.__doc__:
            try:
                config = chosen_option._config
                if config is None:
                    config = grapeConfig.grapeConfig()
                else:
                    config = grapeConfig.grapeRepoConfig(config)
                option_args = utility.parseArgs(chosen_option.__doc__, args[1:], config)
            except SystemExit as e:
                if len(args) > 1 and "--help" != args[1] and "-h" != args[1]:
                    print("GRAPE PARSING ERROR: could not parse %s\n" % (args[1:]))
                raise e
        if globalArgs is not None:
            utility.applyGlobalArgs(globalArgs)
        try:
            if isinstance(chosen_option, resumable.Resumable):
                if option_args["--continue"]:
                    return chosen_option._resume(option_args)
            return chosen_option.execute(option_args)

        except git.GrapeGitError as e:
            print traceback.print_exc()            
            print ("GRAPE: Uncaught Error %s in grape-%s when executing '%s' in '%s'\n%s" %
                   (e.code, chosen_option._key,  e.gitCommand, e.cwd, e.gitOutput))
            exit(e.code)
            
        except utility.NoWorkspaceDirException as e:
            print ("GRAPE: grape %s must be run from a grape workspace." % chosen_option.key)
            print ("GRAPE: %s" % e.message)
            exit(1)
        finally:
            if globalArgs is not None:
                utility.popGlobalArgs()
コード例 #18
0
ファイル: version.py プロジェクト: LLNL/GRAPE
 def initializeVersioning(self, args):
     config = grapeConfig.grapeConfig()
     version = StringIO.StringIO()
     version.write("VERSION_ID = %s" % args["<version>"])
     version.seek(0)
     version = self.readVersion(version, args)
     if args["--file"]:
         fname = args["--file"]
         with open(fname, 'w+') as f:
             version = self.writeVersion(f, version, args)
         self.stageVersionFile(fname)
         config.set("versioning", "file", fname)
         configFile = os.path.join(git.baseDir(), ".grapeconfig")
         grapeConfig.writeConfig(config, configFile)
         self.stageGrapeconfigFile(configFile)
         if not args["--nocommit"]:
             git.commit("%s %s -m \"GRAPE: added initial version info file %s\"" % (fname, configFile, fname))
             self.tagVersion(version, args)
コード例 #19
0
ファイル: mergeDevelop.py プロジェクト: LLNL/GRAPE
 def lookupPublicBranch():
     config = grapeConfig.grapeConfig()
     try:
         currentBranch = git.currentBranch()
     except git.GrapeGitError:
         return 'unknown'
     if currentBranch in config.get('flow', 'publicBranches'):
         return currentBranch
     try:
         branch = config.getPublicBranchFor(currentBranch)
     except KeyError:
         branchPrefix = git.branchPrefix(currentBranch)
         print("WARNING: prefix %s does not have an associated topic branch, nor is a default"
               "public branch configured. \n"
               "use --public=<branch> to define, or add %s:<branch> or ?:<branch> to \n"
               "[flow].publicBranches in your .grapeconfig or .git/.grapeuserconfig. " % (branchPrefix, branchPrefix))
         branch = None
     return branch
コード例 #20
0
ファイル: push.py プロジェクト: LLNL/GRAPE
    def execute(self, args):
        baseDir = utility.workspaceDir()

        cwd = os.getcwd()
        os.chdir(baseDir)
        currentBranch = git.currentBranch()
        config = grapeConfig.grapeConfig()
        publicBranches = config.getPublicBranchList()


            
        submodules = git.getActiveSubmodules()
        
        retvals = utility.MultiRepoCommandLauncher(push).launchFromWorkspaceDir(handleMRE=handlePushMRE)
        
        os.chdir(cwd)        
        utility.printMsg("Pushed current branch to origin")
        return False not in retvals
コード例 #21
0
ファイル: updateSubproject.py プロジェクト: LLNL/GRAPE
 def updateSubtree(self, args):
     clean = utility.isWorkspaceClean()
     os.chdir(utility.workspaceDir())
     if not clean:
         utility.printMsg("git-subtree requires a clean working tree before attempting a subtree update")
         return False
     name = args["--name"]
     branch = args["--branch"]
     config = grapeConfig.grapeConfig()
     subtreePrefix = config.get("subtree-%s" % name, "prefix")
     subtreeRemote = config.get("subtree-%s" % name, "remote")
     fullURL = utility.parseSubprojectRemoteURL(subtreeRemote)
     doSquash = config.get("subtrees", "mergePolicy").strip().lower() == "squash"
     squashArg = "--squash" if doSquash else ""
     git.subtree("pull --prefix %s %s %s %s" %
                 (subtreePrefix, fullURL, branch, squashArg))
     
     return True
コード例 #22
0
ファイル: mergeDevelop.py プロジェクト: LLNL/GRAPE
 def lookupPublicBranch():
     config = grapeConfig.grapeConfig()
     try:
         currentBranch = git.currentBranch()
     except git.GrapeGitError:
         return 'unknown'
     if currentBranch in config.get('flow', 'publicBranches'):
         return currentBranch
     try:
         branch = config.getPublicBranchFor(currentBranch)
     except KeyError:
         branchPrefix = git.branchPrefix(currentBranch)
         print(
             "WARNING: prefix %s does not have an associated topic branch, nor is a default"
             "public branch configured. \n"
             "use --public=<branch> to define, or add %s:<branch> or ?:<branch> to \n"
             "[flow].publicBranches in your .grapeconfig or .git/.grapeuserconfig. "
             % (branchPrefix, branchPrefix))
         branch = None
     return branch
コード例 #23
0
    def execute(self, args):
        start = args["--start"]
        if not start:
            start = self._public

        # decide whether to recurse
        recurse = grapeConfig.grapeConfig().get('workspace',
                                                'manageSubmodules')
        if args["--recurse"]:
            recurse = True
        if args["--noRecurse"]:
            recurse = False

        if not args["<descr>"]:
            args["<descr>"] = utility.userInput(
                "Enter one word description for branch:")

        if not args["--user"]:
            args["--user"] = utility.getUserName()

        branchName = self._key + "/" + args["--user"] + "/" + args["<descr>"]

        launcher = utility.MultiRepoCommandLauncher(createBranch,
                                                    runInSubmodules=recurse,
                                                    runInSubprojects=recurse,
                                                    runInOuter=True,
                                                    branch=start,
                                                    globalArgs=branchName)

        launcher.initializeCommands()
        utility.printMsg("About to create the following branches:")
        for repo, branch in zip(launcher.repos, launcher.branches):
            utility.printMsg("\t%s off of %s in %s" %
                             (branchName, branch, repo))
        proceed = utility.userInput("Proceed? [y/n]", default="y")
        if proceed:
            grapeMenu.menu().applyMenuChoice(
                'up', ['up', '--public=%s' % start])
            launcher.launchFromWorkspaceDir()
        else:
            utility.printMsg("branches not created")
コード例 #24
0
ファイル: addSubproject.py プロジェクト: LLNL/GRAPE
 def activateNestedSubproject(subprojectName, userconfig):
     wsDir = utility.workspaceDir()
     config = grapeConfig.grapeConfig()
     prefix = config.get("nested-%s" % subprojectName, "prefix")
     url = config.get("nested-%s" % subprojectName, "url")
     fullurl = utility.parseSubprojectRemoteURL(url)
     section = "nested-%s" % subprojectName
     userconfig.ensureSection(section)
     currentlyActive = userconfig.getboolean(section, "active")
     if not currentlyActive:
         destDir = os.path.join(wsDir, prefix)
         if not (os.path.isdir(destDir) and os.listdir(destDir)):
             git.clone("%s %s" % (fullurl, prefix))
         elif '.git' in os.listdir(destDir):
             pass
         else:
             utility.printMsg("WARNING: inactive nested subproject %s has files but is not a git repo" % prefix)
             return False
     userconfig.set(section, "active", "True")
     grapeConfig.writeConfig(userconfig, os.path.join(wsDir, ".git", ".grapeuserconfig"))
     return True
コード例 #25
0
ファイル: merge.py プロジェクト: LLNL/GRAPE
    def execute(self, args):
        # this is necessary due to the unholy relationships between mr, m, and md. 
        if not "<<cmd>>" in args:
            args["<<cmd>>"] = 'm'
        otherBranch = args["<branch>"] if args["<branch>"] else utility.userInput("Enter name of branch you would like"
                                                                                  " to merge into this branch")
        args["<branch>"] = otherBranch
        config = grapeConfig.grapeConfig()
        publicBranches = config.getPublicBranchList()
        toks = otherBranch.split("origin/")
        if toks[-1] in publicBranches:
            public = toks[-1]
            publicMapping = config.getMapping("workspace", "submodulePublicMappings")
            subpublic = publicMapping[public]
            toks[-1] = subpublic
            subpublic = 'origin/'.join(toks)
        else:
            subpublic = otherBranch
            
        

        mdArgs = {}
        mdArgs["--am"] = args["--am"]
        mdArgs["--as"] = args["--as"]
        mdArgs["--at"] = args["--at"]
        mdArgs["--aT"] = args["--aT"]
        mdArgs["--ay"] = args["--ay"]
        mdArgs["--aY"] = args["--aY"]
        mdArgs["--askAll"] = args["--askAll"]
        mdArgs["--public"] = args["<branch>"]
        mdArgs["--subpublic"] = subpublic
        mdArgs["--recurse"] = not args["--noRecurse"]
        mdArgs["--noRecurse"] = args["--noRecurse"]
        mdArgs["--continue"] = args["--continue"]
        mdArgs["<<cmd>>"] = args["<<cmd>>"]
        mdArgs["--noUpdate"] = args["--noUpdate"]
        mdArgs["--squash"] = args["--squash"]
        
        
        return grapeMenu.menu().getOption("md").execute(mdArgs)
コード例 #26
0
ファイル: newFlowBranch.py プロジェクト: LLNL/GRAPE
    def execute(self, args):
        start = args["--start"]
        if not start: 
            start = self._public
            
        
        # decide whether to recurse
        recurse = grapeConfig.grapeConfig().get('workspace', 'manageSubmodules')
        if args["--recurse"]:
            recurse = True
        if args["--noRecurse"]:
            recurse = False

        
        if not args["<descr>"]:
            args["<descr>"] =  utility.userInput("Enter one word description for branch:")
            
        if not args["--user"]:
            args["--user"] = utility.getUserName()
            
        branchName = self._key + "/" + args["--user"] + "/" + args["<descr>"]

            
        launcher = utility.MultiRepoCommandLauncher(createBranch, 
                                                   runInSubmodules=recurse, 
                                                   runInSubprojects=recurse, 
                                                   runInOuter=True, 
                                                   branch=start, 
                                                   globalArgs=branchName)
        
        launcher.initializeCommands()
        utility.printMsg("About to create the following branches:")
        for repo, branch in zip(launcher.repos, launcher.branches):
            utility.printMsg("\t%s off of %s in %s" % (branchName, branch, repo))
        proceed = utility.userInput("Proceed? [y/n]", default="y")
        if proceed:
            grapeMenu.menu().applyMenuChoice('up', ['up', '--public=%s' % start])
            launcher.launchFromWorkspaceDir()
        else:
            utility.printMsg("branches not created")
コード例 #27
0
    def execute(self, args):
        # this is necessary due to the unholy relationships between mr, m, and md.
        if not "<<cmd>>" in args:
            args["<<cmd>>"] = 'm'
        otherBranch = args["<branch>"] if args[
            "<branch>"] else utility.userInput(
                "Enter name of branch you would like"
                " to merge into this branch")
        args["<branch>"] = otherBranch
        config = grapeConfig.grapeConfig()
        publicBranches = config.getPublicBranchList()
        toks = otherBranch.split("origin/")
        if toks[-1] in publicBranches:
            public = toks[-1]
            publicMapping = config.getMapping("workspace",
                                              "submodulePublicMappings")
            subpublic = publicMapping[public]
            toks[-1] = subpublic
            subpublic = 'origin/'.join(toks)
        else:
            subpublic = otherBranch

        mdArgs = {}
        mdArgs["--am"] = args["--am"]
        mdArgs["--as"] = args["--as"]
        mdArgs["--at"] = args["--at"]
        mdArgs["--aT"] = args["--aT"]
        mdArgs["--ay"] = args["--ay"]
        mdArgs["--aY"] = args["--aY"]
        mdArgs["--askAll"] = args["--askAll"]
        mdArgs["--public"] = args["<branch>"]
        mdArgs["--subpublic"] = subpublic
        mdArgs["--recurse"] = not args["--noRecurse"]
        mdArgs["--noRecurse"] = args["--noRecurse"]
        mdArgs["--continue"] = args["--continue"]
        mdArgs["<<cmd>>"] = args["<<cmd>>"]
        mdArgs["--noUpdate"] = args["--noUpdate"]
        mdArgs["--squash"] = args["--squash"]

        return grapeMenu.menu().getOption("md").execute(mdArgs)
コード例 #28
0
ファイル: Atlassian.py プロジェクト: LLNL/GRAPE
    def repoFromWorkspaceRepoPath(self,
                                  path,
                                  isSubmodule=False,
                                  isNested=False,
                                  topLevelRepo=None,
                                  topLevelProject=None):
        config = grapeConfig.grapeConfig()
        if isNested:
            proj = os.path.split(path)[1]
            nestedProjectURL = config.get("nested-%s" % proj, "url")
            url = utility.parseSubprojectRemoteURL(nestedProjectURL)
            urlTokens = url.split('/')
            proj = urlTokens[-2]
            repo_name = urlTokens[-1]
            # strip off the git extension
            repo_name = '.'.join(repo_name.split('.')[:-1])
        elif isSubmodule:
            fullpath = os.path.abspath(path)
            wsdir = utility.workspaceDir() + os.path.sep
            proj = fullpath.split(wsdir)[1].replace("\\", "/")
            url = git.config("--get submodule.%s.url" % proj).split('/')
            proj = url[-2]
            repo_name = url[-1]

            # strip off the .git extension
            repo_name = '.'.join(repo_name.split('.')[:-1])
        else:
            if topLevelRepo is None:
                topLevelRepo = config.get("repo", "name")
            if topLevelProject is None:
                topLevelProject = config.get("project", "name")

            repo_name = topLevelRepo
            proj = topLevelProject

        repo = self.project(proj).repo(repo_name)
        return repo
コード例 #29
0
 def activateNestedSubproject(subprojectName, userconfig):
     wsDir = utility.workspaceDir()
     config = grapeConfig.grapeConfig()
     prefix = config.get("nested-%s" % subprojectName, "prefix")
     url = config.get("nested-%s" % subprojectName, "url")
     fullurl = utility.parseSubprojectRemoteURL(url)
     section = "nested-%s" % subprojectName
     userconfig.ensureSection(section)
     currentlyActive = userconfig.getboolean(section, "active")
     if not currentlyActive:
         destDir = os.path.join(wsDir, prefix)
         if not (os.path.isdir(destDir) and os.listdir(destDir)):
             git.clone("%s %s" % (fullurl, prefix))
         elif '.git' in os.listdir(destDir):
             pass
         else:
             utility.printMsg(
                 "WARNING: inactive nested subproject %s has files but is not a git repo"
                 % prefix)
             return False
     userconfig.set(section, "active", "True")
     grapeConfig.writeConfig(
         userconfig, os.path.join(wsDir, ".git", ".grapeuserconfig"))
     return True
コード例 #30
0
    def execute(self, args):
        if TkinterImportError:
            utility.printMsg(
                "grape w requires Tkinter.\n  The following error was raised during the import:\n\n%s\n"
                % TkinterImportError)
            return True
        config = grapeConfig.grapeConfig()
        difftool = args["--difftool"]
        height = args["--height"]
        width = args["--width"]
        doMergeDiff = True
        if args["--rawDiff"]:
            doMergeDiff = False
        elif args["--mergeDiff"]:
            # This is already the default
            doMergeDiff = True

        cwd = os.getcwd()
        os.chdir(utility.workspaceDir())

        b1 = args["<b1>"]
        if not b1:
            b1 = git.currentBranch()

        b2 = args["<b2>"]

        if args["--staged"]:
            b2 = b1
            b1 = "--cached"
            doMergeDiff = False
        elif args["--workspace"]:
            b2 = "--"
            doMergeDiff = False
        else:
            if not b2:
                try:
                    # put the public branch first so merge diff shows
                    # changes on the current branch.
                    b2 = b1
                    b1 = config.getPublicBranchFor(b2)
                except:
                    b2 = ""
                    doMergeDiff = False

        diffargs = ""

        root = Tk.Tk()
        root.title("GRAPE walkthrough")

        diffmanager = DiffManager(
            master=root,
            height=height,
            width=width,
            branchA=b1,
            branchB=b2,
            difftool=difftool,
            diffargs=diffargs,
            doMergeDiff=doMergeDiff,
            showUnchanged=args["--showUnchanged"],
            showInactive=not args["--noInactive"],
            showToplevel=not args["--noTopLevel"],
            showSubmodules=not args["--noSubmodules"],
            showSubtrees=not args["--noSubtrees"],
            showNestedSubprojects=not args["--noNestedSubprojects"],
            noFetch=args["--noFetch"])

        root.mainloop()

        os.chdir(cwd)

        try:
            root.destroy()
        except:
            pass
        return True
コード例 #31
0
ファイル: walkthrough.py プロジェクト: LLNL/GRAPE
    def execute(self,args):
        if TkinterImportError:
           utility.printMsg("grape w requires Tkinter.\n  The following error was raised during the import:\n\n%s\n" % TkinterImportError)
           return True
        config = grapeConfig.grapeConfig()
        difftool = args["--difftool"]
        height = args["--height"]
        width = args["--width"]
        doMergeDiff = True
        if args["--rawDiff"]:
           doMergeDiff = False
        elif args["--mergeDiff"]:
           # This is already the default
           doMergeDiff = True

        cwd = os.getcwd()
        os.chdir(utility.workspaceDir())

        b1 = args["<b1>"] 
        if not b1: 
           b1 = git.currentBranch()

        b2 = args["<b2>"]

        if args["--staged"]:
           b2 = b1
           b1 = "--cached"
           doMergeDiff = False
        elif args["--workspace"]:
           b2 = "--"
           doMergeDiff = False
        else:
           if not b2: 
              try:
                 # put the public branch first so merge diff shows
                 # changes on the current branch.
                 b2 = b1
                 b1 = config.getPublicBranchFor(b2)
              except:
                 b2 = ""
                 doMergeDiff = False

        diffargs = ""
               
        root = Tk.Tk()
        root.title("GRAPE walkthrough")
        
        diffmanager = DiffManager(master=root, height=height, width=width,
                                  branchA=b1, branchB=b2,
                                  difftool=difftool, diffargs=diffargs, doMergeDiff=doMergeDiff,
                                  showUnchanged=args["--showUnchanged"],
                                  showInactive=not args["--noInactive"], showToplevel=not args["--noTopLevel"],
                                  showSubmodules=not args["--noSubmodules"], showSubtrees=not args["--noSubtrees"],
                                  showNestedSubprojects=not args["--noNestedSubprojects"],
                                  noFetch=args["--noFetch"])
        
        root.mainloop()
        
        os.chdir(cwd)

        try:
           root.destroy()
        except:
           pass
        return True
コード例 #32
0
ファイル: checkout.py プロジェクト: LLNL/GRAPE
    def execute(self, args):
        sync = args["--sync"].lower().strip()
        sync = sync == "true" or sync == "yes"
        args["--sync"] = sync
        checkoutargs = ''
        branch = args["<branch>"]
        if args['-b']:
            checkoutargs += " -b"

        workspaceDir = utility.workspaceDir()
        os.chdir(workspaceDir)
        currentSHA = git.shortSHA("HEAD")

        utility.printMsg("Performing checkout of %s in outer level project." %
                         branch)
        launcher = utility.MultiRepoCommandLauncher(handledCheckout,
                                                    listOfRepoBranchArgTuples=[
                                                        (workspaceDir, branch,
                                                         [checkoutargs, sync])
                                                    ])

        if not launcher.launchFromWorkspaceDir(handleMRE=handleCheckoutMRE)[0]:
            return False
        previousSHA = currentSHA

        submoduleListDidChange = ".gitmodules" in git.diff(
            "--name-only %s %s" % (previousSHA, branch))
        addedModules = []
        removedModules = []
        uvArgs = []
        submodulesDidChange = False
        if submoduleListDidChange and grapeConfig.grapeConfig().getboolean(
                "workspace", "manageSubmodules"):

            self.parseGitModulesDiffOutput(
                git.diff("%s %s --no-ext-diff -- .gitmodules" %
                         (previousSHA, branch)), addedModules, removedModules)
            if not addedModules and not removedModules:
                pass
            else:
                submodulesDidChange = True

                if removedModules:
                    for sub in removedModules:
                        try:
                            os.chdir(os.path.join(workspaceDir, sub))
                            if git.isWorkingDirectoryClean():
                                cleanBehaviorSet = args[
                                    "--noUpdateView"] or args["--updateView"]
                                if not cleanBehaviorSet:
                                    clean = utility.userInput(
                                        "Would you like to remove the submodule %s ?"
                                        % sub, 'n')
                                elif args["--noUpdateView"]:
                                    clean = False
                                elif args["--updateView"]:
                                    clean = True
                                if clean:
                                    utility.printMsg(
                                        "Removing clean submodule %s." % sub)
                                    os.chdir(workspaceDir)
                                    shutil.rmtree(
                                        os.path.join(workspaceDir, sub))
                            else:
                                utility.printMsg(
                                    "Unstaged / committed changes in %s, not removing."
                                    % sub)
                                os.chdir(workspaceDir)
                        except OSError:
                            pass

        # check to see if nested project list changed
        addedProjects = []
        removedProjects = []
        removedProjectPrefices = {}
        nestedProjectListDidChange = False
        os.chdir(workspaceDir)
        if ".grapeconfig" in git.diff("--name-only %s %s" %
                                      (previousSHA, branch)):
            configDiff = git.diff("--no-ext-diff %s %s -- %s" %
                                  (previousSHA, branch, ".grapeconfig"))
            nestedProjectListDidChange = "[nestedprojects]" in configDiff.lower(
            )
            self.parseGrapeConfigNestedProjectDiffOutput(
                configDiff, addedProjects, removedProjects,
                removedProjectPrefices)

            if removedProjects:
                config = grapeConfig.grapeConfig()
                for proj in removedProjects:
                    projPrefix = removedProjectPrefices[proj]
                    try:
                        os.chdir(os.path.join(workspaceDir, proj))
                    except OSError as e:
                        if e.errno == 2:
                            # directory doesn't exist, that's OK since we're thinking about removing it
                            # anyways at this point...
                            continue
                    if git.isWorkingDirectoryClean():
                        removeBehaviorSet = args["--noUpdateView"] or args[
                            "--updateView"]
                        if not removeBehaviorSet:
                            remove = utility.userInput(
                                "Would you like to remove the nested subproject %s? \n"
                                "All work that has not been pushed will be lost. "
                                % projPrefix, 'n')
                        elif args["--noUpdateView"]:
                            remove = False
                        elif args["--updateView"]:
                            remove = True
                        if remove:
                            remove = utility.userInput(
                                "Are you sure you want to remove %s? When you switch back to the previous branch, you will have to\n"
                                "reclone %s." % (projPrefix, projPrefix), 'n')
                        if remove:
                            os.chdir(workspaceDir)
                            shutil.rmtree(
                                os.path.join(workspaceDir, projPrefix))
                    else:
                        utility.printMsg(
                            "Unstaged / committed changes in %s, not removing. \n"
                            "Note this project is NOT active in %s. " %
                            (projPrefix, branch))
                        os.chdir(workspaceDir)

        if not submodulesDidChange and not nestedProjectListDidChange:
            uvArgs.append("--checkSubprojects")
        else:
            updateViewSet = args["--noUpdateView"] or args["--updateView"]
            if not updateViewSet:
                updateView = utility.userInput(
                    "Submodules or subprojects were added/removed as a result of this checkout. \n"
                    + "%s" %
                    ("Added Projects: %s\n" %
                     ','.join(addedProjects) if addedProjects else "") + "%s" %
                    ("Added Submodules: %s\n" %
                     ','.join(addedModules) if addedModules else "") + "%s" %
                    ("Removed Projects: %s\n" %
                     ','.join(removedProjects) if removedProjects else "") +
                    "%s" %
                    ("Removed Submodules: %s\n" %
                     ','.join(removedModules) if removedModules else "") +
                    "Would you like to update your workspace view? [y/n]", 'n')
            elif args["--noUpdateView"]:
                updateView = False
            elif args["--updateView"]:
                updateView = True
            if not updateView:
                uvArgs.append("--checkSubprojects")

        if args["-b"]:
            uvArgs.append("-b")
        if sync:
            uvArgs.append("--sync=True")
        else:
            uvArgs.append("--sync=False")

        # in case the user switches to a branch without corresponding branches in the submodules, make sure active submodules
        # are at the right commit before possibly creating new branches at the current HEAD.
        git.submodule("update")
        utility.printMsg(
            "Calling grape uv %s to ensure branches are consistent across all active subprojects and submodules."
            % ' '.join(uvArgs))
        grapeConfig.read()
        grapeMenu.menu().applyMenuChoice('uv', uvArgs)

        os.chdir(workspaceDir)

        if sync:
            utility.printMsg(
                "Switched to %s. Updating from remote...\n\t (use --sync=False or .grapeconfig.post-checkout.syncWithOrigin to change behavior.)"
                % branch)
            if args["-b"]:
                grapeMenu.menu().applyMenuChoice("push")
            else:
                grapeMenu.menu().applyMenuChoice("pull")
        else:
            utility.printMsg("Switched to %s." % branch)

        global _skipBranchCreation
        global _createNewBranch
        _skipBranchCreation = False
        _createNewBranch = False
        return True
コード例 #33
0
ファイル: version.py プロジェクト: LLNL/GRAPE
 def parseArgs(self, args): 
     config = grapeConfig.grapeConfig()
     # parse tagSuffix for version mappings
     if args["--tagSuffix"] is None: 
         branch2suffix = config.getMapping("versioning", "branchtagsuffixmappings")
         args["--tagSuffix"] = branch2suffix[git.currentBranch()]
コード例 #34
0
ファイル: config.py プロジェクト: LLNL/GRAPE
    def execute(self,args):
        base = git.baseDir()
        if base == "":
            return False
        dotGit = git.gitDir()
         
        utility.printMsg("Optimizing git performance on slow file systems...")
        #runs file system intensive tasks such as git status and git commit
        # in parallel (important for NFS systems such as LC)
        git.config("core.preloadindex","true")

        #have git automatically do some garbage collection / optimization
        utility.printMsg("Setting up automatic git garbage collection...")
        git.config("gc.auto","1")

        #prevents false conflict detection due to differences in filesystem
        # time stamps
        utility.printMsg("Optimizing cross platform portability...")
        git.config("core.trustctime","false")

        # stores login info for 12 hrs (max allowed by RZBitbucket)

        if not args["--nocredcache"]:
            cache = args["--credcache"]
            if not cache:
                cache = utility.userInput("Would you like to enable git-managed credential caching?", 'y')
            if cache:
                utility.printMsg("Enabling 12 hr caching of https credentials...")
                if os.name == "nt":
                    git.config("--global credential.helper", "wincred")
                else :
                    git.config("--global credential.helper", "cache --timeout=43200")

        # enables 'as' option for merge strategies -forces a conflict if two branches
        # modify the same file
        mergeVerifyPath = os.path.join(os.path.dirname(__file__),"..","merge-and-verify-driver")
        
        if os.path.exists(mergeVerifyPath): 
            utility.printMsg("Enabling safe merges (triggers conflicts any time same file is modified),\n\t see 'as' option for grape m and grape md...")
            git.config("merge.verify.name","merge and verify driver")
            git.config("merge.verify.driver","%s/merge-and-verify-driver %A %O %B")
        else:
            utility.printMsg("WARNING: merge and verify script not detected, safe merges ('as' option to grape m / md) will not work!")
        # enables lg as an alias to print a pretty-font summary of
        # key junctions in the history for this branch.
        utility.printMsg("Setting lg as an alias for a pretty log call...")
        git.config("alias.lg","log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative --simplify-by-decoration")
        
        # perform an update of the active subprojects if asked.
        ask = not args["--nouv"]
        updateView = ask and (args["--uv"] or utility.userInput("Do you want to edit your active subprojects?"
                                                                " (you can do this later using grape uv) [y/n]", "n"))
        if updateView:
            grapeMenu.menu().applyMenuChoice("uv", args["--uvArg"])

        # configure git to use p4merge for conflict resolution
        # and diffing

        useP4Merge = not args["--nop4merge"] and (args["--p4merge"] or utility.userInput("Would you like to use p4merge as your merge tool? [y/n]","y"))
        # note that this relies on p4merge being in your path somewhere
        if (useP4Merge):
            git.config("merge.keepBackup","false")
            git.config("merge.tool","p4merge")
            git.config("mergetool.keepBackup","false")
            git.config("mergetool.p4merge.cmd",'p4merge \"\$BASE\" \"\$LOCAL\" \"\$REMOTE\" \"\$MERGED\"')
            git.config("mergetool.p4merge.keepTemporaries","false")
            git.config("mergetool.p4merge.trustExitCode","false")
            git.config("mergetool.p4merge.keepBackup","false")
            utility.printMsg("Configured repo to use p4merge for conflict resolution")
        else:
            git.config("merge.tool","tkdiff")

        useP4Diff = not args["--nop4diff"] and (args["--p4diff"] or utility.userInput("Would you like to use p4merge as your diff tool? [y/n]","y"))
        # this relies on p4diff being defined as a custom bash script, with the following one-liner:
        # [ $# -eq 7 ] && p4merge "$2" "$5"
        if (useP4Diff):
            p4diffScript = os.path.join(os.path.dirname(__file__),"..","p4diff")
            if os.path.exists(p4diffScript): 
                git.config("diff.external",p4diffScript)
                utility.printMsg("Configured repo to use p4merge for diff calls - p4merge must be in your path")
            else: 
                utility.printMsg("Could not find p4diff script at %s" % p4diffScript)
        useGitP4 = args["--git-p4"]
        if (useGitP4 ):
            git.config("git-p4.useclientspec","true")
            # create p4 references to enable imports from p4
            p4remotes = os.path.join(dotGit,"refs","remotes","p4","")
            utility.ensure_dir(p4remotes)
            commit = utility.userInput("Please enter a descriptor (e.g. SHA, branch if tip, tag name) of the current git commit that mirrors the p4 repo","master")
            sha = git.SHA(commit)
            with open(os.path.join(p4remotes,"HEAD"),'w') as f:
                f.write(sha)
            with open(os.path.join(p4remotes,"master"),'w') as f:
                f.write(sha)

            # to enable exports to p4, a maindev client needs to be set up
            haveCopied = False
            while (not haveCopied):
                p4settings = utility.userInput("Enter a path to a .p4settings file describing the maindev client you'd like to use for p4 updates",".p4settings")
                try:
                    shutil.copyfile(p4settings,os.path.join(base,".p4settings"))
                    haveCopied = True
                except:
                    print("could not find p4settings file, please check your path and try again")
                    return False

        # install hooks here and in all submodules
        utility.printMsg("Installing hooks in all repos...")
        cwd = git.baseDir()
        grapeMenu.menu().applyMenuChoice("installHooks")
        
        #  ensure all public branches are available in all repos
        submodules = git.getActiveSubmodules()
        config = grapeConfig.grapeConfig()
        publicBranches = config.getPublicBranchList()
        submodulePublicBranches = set(config.getMapping('workspace', 'submoduleTopicPrefixMappings').values())
        for sub in submodules:
            self.ensurePublicBranchesExist(grapeConfig.grapeRepoConfig(sub),sub, submodulePublicBranches)
        
        # reset config to the workspace grapeconfig, use that one for all nested projects' public branches.
        wsDir = utility.workspaceDir()
        config = grapeConfig.grapeRepoConfig(wsDir)    
        for proj in grapeConfig.GrapeConfigParser.getAllActiveNestedSubprojectPrefixes():
            self.ensurePublicBranchesExist(config, os.path.join(wsDir,proj), publicBranches)
        
        self.ensurePublicBranchesExist(config, wsDir, publicBranches)
            
        return True
コード例 #35
0
ファイル: grapeMenu.py プロジェクト: LLNL/GRAPE
 def postInit(self):
     # add dynamically generated (dependent on grapeConfig) options here
     self._options = self._options + newFlowBranch.NewBranchOptionFactory(
     ).createNewBranchOptions(grapeConfig.grapeConfig())
     for currOption in self._options:
         self._optionLookup[currOption.key] = currOption
コード例 #36
0
    def __init__(self, master, **kwargs):
        height = kwargs.get('height', 0)
        width = kwargs.get('width', 0)

        self.master = master
        self.grapeconfig = grapeConfig.grapeConfig()
        self.oldprojindex = 0
        self.showInactive = kwargs.get('showInactive', True)
        self.showToplevel = kwargs.get('showToplevel', True)
        self.showSubmodules = kwargs.get('showSubmodules', True)
        self.showSubtrees = kwargs.get('showSubtrees', True)
        self.showNestedSubprojects = kwargs.get('showNestedSubprojects', True)

        # Colors
        self.fginit = kwargs.get('fginit', 'black')
        self.bginit = kwargs.get('bginit', 'gray')
        self.fgvisited = kwargs.get('fgvisited', 'slate gray')
        self.bgvisited = kwargs.get('bgvisited', 'light gray')
        self.fgselected = kwargs.get('fgselected', 'black')
        self.bgselected = kwargs.get('bgselected', 'goldenrod')
        self.fgactive = kwargs.get('fgactive', 'black')
        self.bgactive = kwargs.get('bgactive', 'light goldenrod')

        # Panel labels
        # These variables should be set by derived classes
        self.filepanelabel = Tk.StringVar()
        self.projpanelabel = Tk.StringVar()

        # Main resizable window
        self.main = Tk.PanedWindow(master,
                                   height=height,
                                   width=width,
                                   sashwidth=4)
        # Create file navigation pane widgets
        self.filepanel = Tk.Frame()
        self.filelabel = Tk.Label(self.filepanel,
                                  textvariable=self.filepanelabel)
        self.filescroll = Tk.Scrollbar(self.filepanel, width=10)
        self.filelist = Tk.Listbox(self.filepanel,
                                   background=self.bginit,
                                   foreground=self.fginit,
                                   selectbackground=self.bgselected,
                                   selectforeground=self.fgselected,
                                   yscrollcommand=self.filescroll.set,
                                   selectmode=Tk.SINGLE)
        self.filescroll.config(command=self.filelist.yview)
        self.filelist.bind("<Double-Button-1>", lambda e: self.spawnDiff())

        # Place file navigation pane widgets
        self.filelabel.pack(side=Tk.TOP, fill=Tk.X)
        self.filescroll.pack(side=Tk.RIGHT, fill=Tk.Y)
        self.filelist.pack(side=Tk.LEFT, fill=Tk.BOTH, expand=1)
        self.filepanel.pack(fill=Tk.BOTH, expand=1)

        # Create subproject navigation widgets
        self.projpanel = Tk.Frame()
        self.projlabel = Tk.Label(self.projpanel,
                                  textvariable=self.projpanelabel)
        self.projscroll = Tk.Scrollbar(self.projpanel, width=10)
        self.projlist = Tk.Listbox(self.projpanel,
                                   background=self.bginit,
                                   foreground=self.fginit,
                                   selectbackground=self.bgselected,
                                   selectforeground=self.fgselected,
                                   yscrollcommand=self.projscroll.set,
                                   selectmode=Tk.SINGLE)
        self.projscroll.config(command=self.projlist.yview)
        self.projlist.bind("<Double-Button-1>", lambda e: self.chooseProject())

        # Place subproject navigation widgets
        self.projscroll.pack(side=Tk.LEFT, fill=Tk.Y)
        self.projlabel.pack(side=Tk.TOP, fill=Tk.X)
        self.projlist.pack(side=Tk.LEFT, fill=Tk.BOTH, expand=1)
        self.projpanel.pack(fill=Tk.BOTH, expand=1)

        # Populate subproject navigation list
        utility.printMsg("Populating projects list...")

        self.projects = []
        self.projstatus = []
        self.projtype = []

        # Outer level repo
        if self.showToplevel:
            status = "?"
            self.projects.append("")
            self.projlist.insert(Tk.END, "%s <Outer Level Project>" % status)
            self.projstatus.append(status)
            self.projtype.append("Outer")

        # Nested subprojects
        self.subprojects = []
        if self.showNestedSubprojects:
            activeNestedSubprojects = (grapeConfig.GrapeConfigParser.
                                       getAllActiveNestedSubprojectPrefixes())
            self.projects.extend(activeNestedSubprojects)
            self.subprojects.extend(activeNestedSubprojects)
            for proj in activeNestedSubprojects:
                status = "?"
                self.projlist.insert(
                    Tk.END, "%s %s <Nested Subproject>" % (status, proj))
                self.projstatus.append(status)
                self.projtype.append("Active Nested")
            if self.showInactive:
                inactiveNestedSubprojects = list(
                    set(grapeConfig.grapeConfig().getAllNestedSubprojects()) -
                    set(grapeConfig.GrapeConfigParser.
                        getAllActiveNestedSubprojects()))
                self.projects.extend(inactiveNestedSubprojects)
                self.subprojects.extend(inactiveNestedSubprojects)
                for proj in inactiveNestedSubprojects:
                    status = "?"
                    self.projlist.insert(
                        Tk.END,
                        "%s %s <Inactive Nested Subproject>" % (status, proj))
                    self.projstatus.append(status)
                    self.projtype.append("Inactive Nested")

        # Submodules
        self.submodules = []
        if self.showSubmodules:
            activeSubmodules = (git.getActiveSubmodules())
            self.projects.extend(activeSubmodules)
            self.submodules.extend(activeSubmodules)
            for proj in activeSubmodules:
                status = "?"
                self.projlist.insert(Tk.END,
                                     "%s %s <Submodule>" % (status, proj))
                self.projstatus.append(status)
                self.projtype.append("Submodule")
            if self.showInactive:
                inactiveSubmodules = list(
                    set(git.getAllSubmodules()) -
                    set(git.getActiveSubmodules()))
                self.projects.extend(inactiveSubmodules)
                self.submodules.extend(inactiveSubmodules)
                for proj in inactiveSubmodules:
                    status = "?"
                    self.projlist.insert(
                        Tk.END, "%s %s <Inactive Submodule>" % (status, proj))
                    self.projstatus.append(status)
                    self.projtype.append("Inactive Submodule")

        # Subtrees
        self.subtrees = []
        if self.showSubtrees:
            self.subtrees = [
                self.grapeconfig.get('subtree-%s' % proj, 'prefix') for proj in
                self.grapeconfig.get('subtrees', 'names').strip().split()
            ]
            self.projects.extend(self.subtrees)
            for proj in self.subtrees:
                status = "?"
                self.projlist.insert(Tk.END,
                                     "%s %s <Subtree>" % (status, proj))
                self.projstatus.append(status)
                self.projtype.append("Subtree")

        utility.printMsg("Done.")

        # Resize the project pane based on its contents
        self.projlistwidth = 0
        self.numprojects = 0
        for proj in self.projlist.get(0, Tk.END):
            if len(proj) > self.projlistwidth:
                self.projlistwidth = len(proj)
            self.numprojects += 1
        self.projlist.config(width=self.projlistwidth)

        # Place the panes in the main window
        self.main.add(self.projpanel)
        self.main.add(self.filepanel)
        self.main.pack(fill=Tk.BOTH, expand=1, side=Tk.BOTTOM)
コード例 #37
0
    def defineActiveSubmodules(projectType="submodule"):
        """
        Queries the user for the submodules (projectType == "submodule") or nested subprojects
        (projectType == "nested subproject") they would like to activate.

        """
        if projectType == "submodule":
            allSubprojects = git.getAllSubmodules()
            activeSubprojects = git.getActiveSubmodules()

        if projectType == "nested subproject":
            config = grapeConfig.grapeConfig()
            allSubprojectNames = config.getAllNestedSubprojects()
            allSubprojects = []
            for project in allSubprojectNames:
                allSubprojects.append(
                    config.get("nested-%s" % project, "prefix"))
            activeSubprojects = grapeConfig.GrapeConfigParser.getAllActiveNestedSubprojectPrefixes(
            )

        toplevelDirs = {}
        toplevelActiveDirs = {}
        toplevelSubs = []
        for sub in allSubprojects:
            # we are taking advantage of the fact that branchPrefixes are the same as directory prefixes for local
            # top-level dirs.
            prefix = git.branchPrefix(sub)
            if sub != prefix:
                toplevelDirs[prefix] = []
                toplevelActiveDirs[prefix] = []
        for sub in allSubprojects:
            prefix = git.branchPrefix(sub)
            if sub != prefix:
                toplevelDirs[prefix].append(sub)
            else:
                toplevelSubs.append(sub)
        for sub in activeSubprojects:
            prefix = git.branchPrefix(sub)
            if sub != prefix:
                toplevelActiveDirs[prefix].append(sub)

        included = {}
        for directory, subprojects in toplevelDirs.items():

            activeDir = toplevelActiveDirs[directory]
            if len(activeDir) == 0:
                defaultValue = "none"
            elif set(activeDir) == set(subprojects):
                defaultValue = "all"
            else:
                defaultValue = "some"

            opt = utility.userInput(
                "Would you like all, some, or none of the %ss in %s?" %
                (projectType, directory),
                default=defaultValue)
            if opt.lower()[0] == "a":
                for subproject in subprojects:
                    included[subproject] = True

            if opt.lower()[0] == "n":
                for subproject in subprojects:
                    included[subproject] = False
            if opt.lower()[0] == "s":
                for subproject in subprojects:
                    included[subproject] = utility.userInput(
                        "Would you like %s %s? [y/n]" %
                        (projectType, subproject), 'y' if
                        (subproject in activeSubprojects) else 'n')
        for subproject in toplevelSubs:
            included[subproject] = utility.userInput(
                "Would you like %s %s? [y/n]" % (projectType, subproject),
                'y' if (subproject in activeSubprojects) else 'n')
        return included
コード例 #38
0
    def execute(self, args):
        sync = args["--sync"].lower().strip()
        sync = sync == "true" or sync == "yes"
        args["--sync"] = sync
        config = grapeConfig.grapeConfig()
        origwd = os.getcwd()
        wsDir = utility.workspaceDir()
        os.chdir(wsDir)
        base = git.baseDir()
        if base == "":
            return False
        hasSubmodules = len(
            git.getAllSubmodules()) > 0 and not args["--skipSubmodules"]
        includedSubmodules = {}
        includedNestedSubprojectPrefixes = {}

        allSubmodules = git.getAllSubmodules()
        allNestedSubprojects = config.getAllNestedSubprojects()

        addedSubmodules = []
        addedNestedSubprojects = []
        addedProjects = args["--add"]
        notFound = []

        for proj in addedProjects:
            if proj in allSubmodules:
                addedSubmodules.append(proj)
            elif proj in allNestedSubprojects:
                addedNestedSubprojects.append(proj)
            else:
                notFound.append(proj)

        rmSubmodules = []
        rmNestedSubprojects = []
        rmProjects = args["--rm"]

        for proj in rmProjects:
            if proj in allSubmodules:
                rmSubmodules.append(proj)
            elif proj in allNestedSubprojects:
                rmNestedSubprojects.append(proj)
            else:
                notFound.append(proj)

        if notFound:
            utility.printMsg(
                "\"%s\" not found in submodules %s \nor\n nested subprojects %s"
                % (",".join(notFound), ",".join(allSubmodules),
                   ",".join(allNestedSubprojects)))
            return False

        if not args["--checkSubprojects"]:
            # get submodules to update
            if hasSubmodules:
                if args["--allSubmodules"]:
                    includedSubmodules = {sub: True for sub in allSubmodules}
                elif args["--add"] or args["--rm"]:
                    includedSubmodules = {
                        sub: True
                        for sub in git.getActiveSubmodules()
                    }
                    includedSubmodules.update(
                        {sub: True
                         for sub in addedSubmodules})
                    includedSubmodules.update(
                        {sub: False
                         for sub in rmSubmodules})
                else:
                    includedSubmodules = self.defineActiveSubmodules()

            # get subprojects to update
            if not args["--skipNestedSubprojects"]:

                nestedPrefixLookup = lambda x: config.get(
                    "nested-%s" % x, "prefix")
                if args["--allNestedSubprojects"]:
                    includedNestedSubprojectPrefixes = {
                        nestedPrefixLookup(sub): True
                        for sub in allNestedSubprojects
                    }
                elif args["--add"] or args["--rm"]:
                    includedNestedSubprojectPrefixes = {
                        sub: True
                        for sub in grapeConfig.GrapeConfigParser.
                        getAllActiveNestedSubprojectPrefixes()
                    }
                    includedNestedSubprojectPrefixes.update({
                        nestedPrefixLookup(sub): True
                        for sub in addedNestedSubprojects
                    })
                    includedNestedSubprojectPrefixes.update({
                        nestedPrefixLookup(sub): False
                        for sub in rmNestedSubprojects
                    })
                else:
                    includedNestedSubprojectPrefixes = self.defineActiveNestedSubprojects(
                    )

            if hasSubmodules:
                initStr = ""
                deinitStr = ""
                rmCachedStr = ""
                resetStr = ""
                for submodule, nowActive in includedSubmodules.items():
                    if nowActive:
                        initStr += ' %s' % submodule
                    else:
                        deinitStr += ' %s' % submodule
                        rmCachedStr += ' %s' % submodule
                        resetStr += ' %s' % submodule
                if args["-f"] and deinitStr:
                    deinitStr = "-f" + deinitStr

                utility.printMsg("Configuring submodules...")
                utility.printMsg("Initializing submodules...")
                git.submodule("init %s" % initStr.strip())
                if deinitStr:
                    utility.printMsg(
                        "Deiniting submodules that were not requested... (%s)"
                        % deinitStr)
                    done = False
                    while not done:
                        try:
                            git.submodule("deinit %s" % deinitStr.strip())
                            done = True
                        except git.GrapeGitError as e:
                            if "the following file has local modifications" in e.gitOutput:
                                print e.gitOutput
                                utility.printMsg(
                                    "A submodule that you wanted to remove has local modifications. "
                                    "Use grape uv -f to force removal.")
                                return False

                            elif "use 'rm -rf' if you really want to remove it including all of its history" in e.gitOutput:
                                if not args["-f"]:
                                    raise e
                                # it is safe to move the .git of the submodule to the .git/modules area of the workspace...
                                module = None
                                for l in e.gitOutput.split('\n'):
                                    if "Submodule work tree" in l and "contains a .git directory" in l:
                                        module = l.split("'")[1]
                                        break
                                if module:
                                    src = os.path.join(module, ".git")
                                    dest = os.path.join(
                                        wsDir, ".git", "modules", module)
                                    utility.printMsg("Moving %s to %s" %
                                                     (src, dest))
                                    shutil.move(src, dest)
                                else:
                                    raise e
                            else:
                                raise e
                    git.rm("--cached %s" % rmCachedStr)
                    git.reset(" %s" % resetStr)

                if initStr:
                    utility.printMsg("Updating active submodules...(%s)" %
                                     initStr)
                    git.submodule("update")

            # handle nested subprojects
            if not args["--skipNestedSubprojects"]:
                reverseLookupByPrefix = {
                    nestedPrefixLookup(sub): sub
                    for sub in allNestedSubprojects
                }
                userConfig = grapeConfig.grapeUserConfig()
                updatedActiveList = []
                for subproject, nowActive in includedNestedSubprojectPrefixes.items(
                ):
                    subprojectName = reverseLookupByPrefix[subproject]
                    section = "nested-%s" % reverseLookupByPrefix[subproject]
                    userConfig.ensureSection(section)
                    previouslyActive = userConfig.getboolean(section, "active")
                    previouslyActive = previouslyActive and os.path.exists(
                        os.path.join(base, subproject, ".git"))
                    userConfig.set(section, "active",
                                   "True" if previouslyActive else "False")
                    if nowActive and previouslyActive:
                        updatedActiveList.append(subprojectName)

                    if nowActive and not previouslyActive:
                        utility.printMsg("Activating Nested Subproject %s" %
                                         subproject)
                        if not addSubproject.AddSubproject.activateNestedSubproject(
                                subprojectName, userConfig):
                            utility.printMsg("Can't activate %s. Exiting..." %
                                             subprojectName)
                            return False

                        updatedActiveList.append(subprojectName)

                    if not nowActive and not previouslyActive:
                        pass
                    if not nowActive and previouslyActive:
                        #remove the subproject
                        subprojectdir = os.path.join(
                            base, utility.makePathPortable(subproject))
                        proceed = args["-f"] or \
                                  utility.userInput("About to delete all contents in %s. Any uncommitted changes, committed changes "
                                                    "that have not been pushed, or ignored files will be lost.  Proceed?" %
                                                    subproject, 'n')
                        if proceed:
                            shutil.rmtree(subprojectdir)
                userConfig.setActiveNestedSubprojects(updatedActiveList)
                grapeConfig.writeConfig(
                    userConfig,
                    os.path.join(utility.workspaceDir(), ".git",
                                 ".grapeuserconfig"))

        checkoutArgs = "-b" if args["-b"] else ""

        safeSwitchWorkspaceToBranch(git.currentBranch(), checkoutArgs, sync)

        os.chdir(origwd)

        return True
コード例 #39
0
    def execute(self, args):
        name = args["--name"]
        prefix = args["--prefix"]
        url = args["--url"]
        fullurl = utility.parseSubprojectRemoteURL(url)
        branch = args["--branch"]
        config = grapeConfig.grapeConfig()
        projectType = self.parseSubprojectType(config, args)
        proceed = args["--noverify"]
        if projectType == "subtree":
            #  whether or not to squash
            squash = args["--squash"] or config.get(
                "subtrees", "mergePolicy").strip().lower() == "squash"
            squash = squash and not args["--nosquash"]
            squash_arg = "--squash" if squash else ""
            # expand the URL
            if not proceed:
                proceed = utility.userInput(
                    "About to create a subtree called %s at path %s,\n"
                    "cloned from %s at %s " % (name, prefix, fullurl, branch) +
                    ("using a squash merge." if squash else "") +
                    "\nProceed? [y/n]", "y")

            if proceed:
                os.chdir(utility.workspaceDir())
                git.subtree("add %s --prefix=%s %s %s" %
                            (squash_arg, prefix, fullurl, branch))

                #update the configuration file
                current_cfg_names = config.get("subtrees", "names").split()
                if not current_cfg_names or current_cfg_names[0].lower(
                ) == "none":
                    config.set("subtrees", "names", name)
                else:
                    current_cfg_names.append(name)
                    config.set("subtrees", "names",
                               ' '.join(current_cfg_names))

                section = "subtree-%s" % name
                config.add_section(section)
                config.set(section, "prefix", prefix)
                config.set(section, "remote", url)
                config.set(section, "topicPrefixMappings", "?:%s" % branch)
                with open(os.path.join(utility.workspaceDir(), ".grapeconfig"),
                          "w") as f:
                    config.write(f)
                utility.printMsg(
                    "Successfully added subtree branch. \n"
                    "Updated .grapeconfig file. Review changes and then commit. "
                )
        elif projectType == "submodule":
            if not proceed:
                proceed = utility.userInput(
                    "about to add %s as a submodule at path %s,\n"
                    "cloned from %s at branch %s.\nproceed? [y/n]" %
                    (name, prefix, url, branch), "y")
            if proceed:
                git.submodule("add --name %s --branch %s %s %s" %
                              (name, branch, url, prefix))
                print(
                    "Successfully added submodule %s at %s. Please review changes and commit."
                    % (name, prefix))
        elif projectType == "nested":
            if not proceed:
                proceed = utility.userInput(
                    " about to clone %s as a nested git repo at path %s,\n"
                    "cloned from %s at branch %s.\nProceed? [y/n]" %
                    (name, prefix, url, branch), 'y')
            if proceed:
                git.clone("%s %s" % (fullurl, prefix))
                ignorePath = os.path.join(git.baseDir(), ".gitignore")
                with open(ignorePath, 'a') as ignore:
                    ignore.writelines([prefix + '\n'])
                git.add(ignorePath)
                wsConfig = grapeConfig.workspaceConfig()
                currentSubprojects = wsConfig.getList("nestedProjects",
                                                      "names")
                currentSubprojects.append(name)
                wsConfig.set("nestedProjects", "names",
                             ' '.join(currentSubprojects))
                newSection = "nested-%s" % name
                wsConfig.ensureSection(newSection)
                wsConfig.set(newSection, "prefix", prefix)
                wsConfig.set(newSection, "url", url)
                configFileName = os.path.join(utility.workspaceDir(),
                                              ".grapeconfig")
                with open(os.path.join(configFileName), 'w') as f:
                    wsConfig.write(f)
                git.add(configFileName)
                git.commit("%s %s -m \"GRAPE: Added nested subproject %s\"" %
                           (ignorePath, configFileName, prefix))
                # update the runtime config with the new workspace .grapeconfig's settings.
                grapeConfig.read()

                userConfig = grapeConfig.grapeUserConfig()
                userConfig.ensureSection(newSection)
                userConfig.set(newSection, "active", "True")
                grapeConfig.writeConfig(
                    userConfig,
                    os.path.join(utility.workspaceDir(), ".git",
                                 ".grapeuserconfig"))

        return True
コード例 #40
0
ファイル: addSubproject.py プロジェクト: LLNL/GRAPE
    def execute(self, args):
        name = args["--name"]
        prefix = args["--prefix"]
        url = args["--url"]
        fullurl = utility.parseSubprojectRemoteURL(url)
        branch = args["--branch"]
        config = grapeConfig.grapeConfig()
        projectType = self.parseSubprojectType(config, args)
        proceed = args["--noverify"]
        if projectType == "subtree":
            #  whether or not to squash
            squash = args["--squash"] or config.get("subtrees", "mergePolicy").strip().lower() == "squash"
            squash = squash and not args["--nosquash"]
            squash_arg = "--squash" if squash else ""
            # expand the URL
            if not proceed:
                proceed = utility.userInput("About to create a subtree called %s at path %s,\n"
                                            "cloned from %s at %s " % (name, prefix, fullurl, branch) +
                                            ("using a squash merge." if squash else "") + "\nProceed? [y/n]", "y")

            if proceed:
                os.chdir(utility.workspaceDir())
                git.subtree("add %s --prefix=%s %s %s" % (squash_arg, prefix, fullurl, branch))

                #update the configuration file
                current_cfg_names = config.get("subtrees", "names").split()
                if not current_cfg_names or current_cfg_names[0].lower() == "none":
                    config.set("subtrees", "names", name)
                else:
                    current_cfg_names.append(name)
                    config.set("subtrees", "names", ' '.join(current_cfg_names))

                section = "subtree-%s" % name
                config.add_section(section)
                config.set(section, "prefix", prefix)
                config.set(section, "remote", url)
                config.set(section, "topicPrefixMappings", "?:%s" % branch)
                with open(os.path.join(utility.workspaceDir(), ".grapeconfig"), "w") as f:
                    config.write(f)
                utility.printMsg("Successfully added subtree branch. \n"
                      "Updated .grapeconfig file. Review changes and then commit. ")
        elif projectType == "submodule":
            if not proceed:
                proceed = utility.userInput("about to add %s as a submodule at path %s,\n"
                                            "cloned from %s at branch %s.\nproceed? [y/n]" %
                                            (name, prefix, url, branch), "y")
            if proceed:
                git.submodule("add --name %s --branch %s %s %s" % (name, branch, url, prefix))
                print("Successfully added submodule %s at %s. Please review changes and commit." % (name, prefix))
        elif projectType == "nested":
            if not proceed:
                proceed = utility.userInput(" about to clone %s as a nested git repo at path %s,\n"
                                            "cloned from %s at branch %s.\nProceed? [y/n]" %
                                            (name, prefix, url, branch), 'y')
            if proceed:
                git.clone("%s %s" % (fullurl, prefix))
                ignorePath = os.path.join(git.baseDir(), ".gitignore")
                with open(ignorePath, 'a') as ignore:
                    ignore.writelines([prefix+'\n'])
                git.add(ignorePath)
                wsConfig = grapeConfig.workspaceConfig()
                currentSubprojects = wsConfig.getList("nestedProjects", "names")
                currentSubprojects.append(name)
                wsConfig.set("nestedProjects", "names", ' '.join(currentSubprojects))
                newSection = "nested-%s" % name
                wsConfig.ensureSection(newSection)
                wsConfig.set(newSection, "prefix", prefix)
                wsConfig.set(newSection, "url", url)
                configFileName = os.path.join(utility.workspaceDir(), ".grapeconfig")
                with open(os.path.join(configFileName), 'w') as f:
                    wsConfig.write(f)
                git.add(configFileName)
                git.commit("%s %s -m \"GRAPE: Added nested subproject %s\"" % (ignorePath, configFileName, prefix))
                # update the runtime config with the new workspace .grapeconfig's settings.
                grapeConfig.read()

                userConfig = grapeConfig.grapeUserConfig()
                userConfig.ensureSection(newSection)
                userConfig.set(newSection, "active", "True")
                grapeConfig.writeConfig(userConfig, os.path.join(utility.workspaceDir(), ".git", ".grapeuserconfig"))

        return True
コード例 #41
0
ファイル: review.py プロジェクト: LLNL/GRAPE
    def execute(self, args):
        """
        A fair chunk of this stuff relies on stashy's wrapping of the STASH REST API, which is posted at
        https://developer.atlassian.com/static/rest/stash/2.12.1/stash-rest.html
        """
        config = grapeConfig.grapeConfig()
        name = args["--user"]
        if not name:
            name = utility.getUserName()
            
        utility.printMsg("Logging onto %s" % args["--bitbucketURL"])
        if args["--test"]:
            bitbucket = Atlassian.TestAtlassian(name)
        else:
            verify = True if args["--verifySSL"].lower() == "true" else False
            bitbucket = Atlassian.Atlassian(name, url=args["--bitbucketURL"], verify=verify)

        # default project (outer level project)
        project_name = args["--project"]
        
        # default repo (outer level repo)
        repo_name = args["--repo"]

        # determine source branch and target branch
        branch = args["--source"]
        if not branch:
            branch = git.currentBranch()

        # make sure we are in the outer level repo before we push
        wsDir = utility.workspaceDir()
        os.chdir(wsDir)

        #ensure branch is pushed
        utility.printMsg("Pushing %s to bitbucket..." % branch)
        git.push("origin %s" % branch)
        #target branch for outer level repo
        target_branch = args["--target"]
        if not target_branch:
            target_branch = config.getPublicBranchFor(branch)        
        # load pull request from Bitbucket if it already exists
        wsRepo =  bitbucket.project(project_name).repo(repo_name)
        existingOuterLevelRequest = getReposPullRequest(wsRepo, branch, target_branch, args)  

        # determine pull request title
        title = args["--title"]
        if existingOuterLevelRequest is not None and not title:
            title = existingOuterLevelRequest.title()

        
        #determine pull request URL
        outerLevelURL = None
        if existingOuterLevelRequest:
            outerLevelURL = existingOuterLevelRequest.link()
        
        # determine pull request description
        descr = self.parseDescriptionArgs(args)

        if not descr and existingOuterLevelRequest:
            descr = existingOuterLevelRequest.description()

    
        # determine pull request reviewers
        reviewers = self.parseReviewerArgs(args)
        if reviewers is None and existingOuterLevelRequest is not None:
            reviewers = [r[0] for r in existingOuterLevelRequest.reviewers()]

        # if we're in append mode, only append what was asked for:
        if args["--append"] or args["--prepend"]:
            title = args["--title"]
            descr = self.parseDescriptionArgs(args)
            reviewers = self.parseReviewerArgs(args)
            
        ##  Submodule Repos
        missing = utility.getModifiedInactiveSubmodules(target_branch, branch)
        if missing:
            utility.printMsg("The following submodules that you've modified are not currently present in your workspace.\n"
                             "You should activate them using grape uv  and then call grape review again. If you haven't modified "
                             "these submodules, you may need to do a grape md to proceed.")
            utility.printMsg(','.join(missing))
            return False        
        pullRequestLinks = {}
        if not args["--norecurse"] and (args["--recurse"] or config.getboolean("workspace", "manageSubmodules")):
            
            modifiedSubmodules = git.getModifiedSubmodules(target_branch, branch)
            submoduleBranchMappings = config.getMapping("workspace", "submoduleTopicPrefixMappings")
                        
            for submodule in modifiedSubmodules:
                if not submodule:
                    continue
                # push branch
                os.chdir(submodule)
                utility.printMsg("Pushing %s to bitbucket..." % branch)
                git.push("origin %s" % branch)
                os.chdir(wsDir)
                repo = bitbucket.repoFromWorkspaceRepoPath(submodule, 
                                                         isSubmodule=True)
                # determine branch prefix
                prefix = branch.split('/')[0]
                sub_target_branch = submoduleBranchMappings[prefix]
                
                prevSubDescr = getReposPullRequestDescription(repo, branch, 
                                                             sub_target_branch, 
                                                             args)
                #amend the subproject pull request description with the link to the outer pull request
                subDescr = addLinkToDescription(descr, outerLevelURL, True)
                if args["--prepend"] or args["--append"]:
                    subDescr = descr
                newRequest = postPullRequest(repo, title, branch, sub_target_branch, subDescr, reviewers, args)
                if newRequest:
                    pullRequestLinks[newRequest.link()] = True
                else:
                    # if a pull request could not be generated, just add a link to browse the branch
                    pullRequestLinks["%s%s/browse?at=%s" % (bitbucket.rzbitbucketURL,
                                                            repo.repo.url(),
                                                            urllib.quote_plus("refs/heads/%s" % branch))] = False
        
        ## NESTED SUBPROJECT REPOS 
        nestedProjects = grapeConfig.GrapeConfigParser.getAllModifiedNestedSubprojects(target_branch)
        nestedProjectPrefixes = grapeConfig.GrapeConfigParser.getAllModifiedNestedSubprojectPrefixes(target_branch)
        
        for proj, prefix in zip(nestedProjects, nestedProjectPrefixes):
            with utility.cd(prefix):
                git.push("origin %s" % branch)
            repo = bitbucket.repoFromWorkspaceRepoPath(proj, isSubmodule=False, isNested=True)
            
            newRequest = postPullRequest(repo, title, branch, target_branch,descr, reviewers, args)
            if newRequest:
                pullRequestLinks[newRequest.link()] = True
            else:
                # if a pull request could not be generated, just add a link to browse the branch
                pullRequestLinks["%s%s/browse?at=%s" % (bitbucket.rzbitbucketURL,
                                                        repo.repo.url(),
                                                        urllib.quote_plus("refs/heads/%s" % branch))] = False
            

        ## OUTER LEVEL REPO
        # load the repo level REST resource
        if not args["--subprojectsOnly"]:
            if not git.hasBranch(branch):
                utility.printMsg("Top level repository does not have a branch %s, not generating a Pull Request" % (branch))
                return True
            if git.branchUpToDateWith(target_branch, branch):
                utility.printMsg("%s up to date with %s, not generating a Pull Request in Top Level repo" % (target_branch, branch))
                return True
            
                
            repo_name = args["--repo"]
            repo = bitbucket.repoFromWorkspaceRepoPath(wsDir, topLevelRepo=repo_name, topLevelProject=project_name)
            utility.printMsg("Posting pull request to %s,%s" % (project_name, repo_name))
            request = postPullRequest(repo, title, branch, target_branch, descr, reviewers, args)
            updatedDescription = request.description()
            for link in pullRequestLinks:
                updatedDescription = addLinkToDescription(updatedDescription, link, pullRequestLinks[link])

            if updatedDescription != request.description(): 
                request = postPullRequest(repo, title, branch, target_branch, 
                                         updatedDescription, 
                                         reviewers, 
                                         args)
                       
            utility.printMsg("Request generated/updated:\n\n%s" % request)
        return True
コード例 #42
0
ファイル: walkthrough.py プロジェクト: LLNL/GRAPE
   def __init__(self, master, **kwargs):
      height = kwargs.get('height', 0)
      width  = kwargs.get('width', 0)

      self.master = master
      self.grapeconfig = grapeConfig.grapeConfig()
      self.oldprojindex = 0
      self.showInactive          = kwargs.get('showInactive', True)
      self.showToplevel          = kwargs.get('showToplevel', True)
      self.showSubmodules        = kwargs.get('showSubmodules', True)
      self.showSubtrees          = kwargs.get('showSubtrees', True)
      self.showNestedSubprojects = kwargs.get('showNestedSubprojects', True)

      # Colors
      self.fginit     = kwargs.get('fginit', 'black')
      self.bginit     = kwargs.get('bginit', 'gray')
      self.fgvisited  = kwargs.get('fgvisited', 'slate gray')
      self.bgvisited  = kwargs.get('bgvisited', 'light gray')
      self.fgselected = kwargs.get('fgselected', 'black')
      self.bgselected = kwargs.get('bgselected', 'goldenrod')
      self.fgactive   = kwargs.get('fgactive', 'black')
      self.bgactive   = kwargs.get('bgactive', 'light goldenrod')

      # Panel labels
      # These variables should be set by derived classes
      self.filepanelabel = Tk.StringVar()
      self.projpanelabel = Tk.StringVar()

      # Main resizable window
      self.main = Tk.PanedWindow(master, height=height, width=width, sashwidth=4)
      # Create file navigation pane widgets
      self.filepanel = Tk.Frame()
      self.filelabel = Tk.Label(self.filepanel, textvariable=self.filepanelabel)
      self.filescroll = Tk.Scrollbar(self.filepanel, width=10)
      self.filelist = Tk.Listbox(self.filepanel, background=self.bginit, foreground=self.fginit, selectbackground=self.bgselected, selectforeground=self.fgselected, yscrollcommand=self.filescroll.set, selectmode=Tk.SINGLE)
      self.filescroll.config(command=self.filelist.yview)
      self.filelist.bind("<Double-Button-1>", lambda e: self.spawnDiff())

      # Place file navigation pane widgets
      self.filelabel.pack(side=Tk.TOP, fill=Tk.X)
      self.filescroll.pack(side=Tk.RIGHT, fill=Tk.Y)
      self.filelist.pack(side=Tk.LEFT, fill=Tk.BOTH, expand=1)
      self.filepanel.pack(fill=Tk.BOTH, expand=1)
      
      # Create subproject navigation widgets
      self.projpanel = Tk.Frame()
      self.projlabel = Tk.Label(self.projpanel, textvariable=self.projpanelabel)
      self.projscroll = Tk.Scrollbar(self.projpanel, width=10)
      self.projlist = Tk.Listbox(self.projpanel, background=self.bginit, foreground=self.fginit, selectbackground=self.bgselected, selectforeground=self.fgselected, yscrollcommand=self.projscroll.set, selectmode=Tk.SINGLE)
      self.projscroll.config(command=self.projlist.yview)
      self.projlist.bind("<Double-Button-1>", lambda e: self.chooseProject())

      # Place subproject navigation widgets
      self.projscroll.pack(side=Tk.LEFT, fill=Tk.Y)
      self.projlabel.pack(side=Tk.TOP, fill=Tk.X)
      self.projlist.pack(side=Tk.LEFT, fill=Tk.BOTH, expand=1)
      self.projpanel.pack(fill=Tk.BOTH, expand=1)

      # Populate subproject navigation list 
      utility.printMsg("Populating projects list...")

      self.projects = []
      self.projstatus = []
      self.projtype = []

      # Outer level repo
      if self.showToplevel:
         status = "?"
         self.projects.append("")
         self.projlist.insert(Tk.END, "%s <Outer Level Project>" % status)
         self.projstatus.append(status)
         self.projtype.append("Outer")

      # Nested subprojects
      self.subprojects = []
      if self.showNestedSubprojects:
         activeNestedSubprojects = (grapeConfig.GrapeConfigParser.getAllActiveNestedSubprojectPrefixes())
         self.projects.extend(activeNestedSubprojects)
         self.subprojects.extend(activeNestedSubprojects)
         for proj in activeNestedSubprojects:
            status = "?"
            self.projlist.insert(Tk.END, "%s %s <Nested Subproject>" % (status, proj))
            self.projstatus.append(status)
            self.projtype.append("Active Nested")
         if self.showInactive:
            inactiveNestedSubprojects = list(set(grapeConfig.grapeConfig().getAllNestedSubprojects()) - set(grapeConfig.GrapeConfigParser.getAllActiveNestedSubprojects()))
            self.projects.extend(inactiveNestedSubprojects)
            self.subprojects.extend(inactiveNestedSubprojects)
            for proj in inactiveNestedSubprojects:
               status = "?"
               self.projlist.insert(Tk.END, "%s %s <Inactive Nested Subproject>" % (status, proj))
               self.projstatus.append(status)
               self.projtype.append("Inactive Nested")

      # Submodules
      self.submodules = []
      if self.showSubmodules:
         activeSubmodules = (git.getActiveSubmodules())
         self.projects.extend(activeSubmodules)
         self.submodules.extend(activeSubmodules)
         for proj in activeSubmodules:
            status = "?"
            self.projlist.insert(Tk.END, "%s %s <Submodule>" % (status, proj))
            self.projstatus.append(status)
            self.projtype.append("Submodule")
         if self.showInactive:
            inactiveSubmodules = list(set(git.getAllSubmodules()) - set(git.getActiveSubmodules()))
            self.projects.extend(inactiveSubmodules)
            self.submodules.extend(inactiveSubmodules)
            for proj in inactiveSubmodules:
               status = "?"
               self.projlist.insert(Tk.END, "%s %s <Inactive Submodule>" % (status, proj))
               self.projstatus.append(status)
               self.projtype.append("Inactive Submodule")

      # Subtrees
      self.subtrees = []
      if self.showSubtrees:
         self.subtrees = [ self.grapeconfig.get('subtree-%s' % proj, 'prefix') for proj in self.grapeconfig.get('subtrees', 'names').strip().split() ]
         self.projects.extend(self.subtrees)
         for proj in self.subtrees:
            status = "?"
            self.projlist.insert(Tk.END, "%s %s <Subtree>" % (status, proj))
            self.projstatus.append(status)
            self.projtype.append("Subtree")

      utility.printMsg("Done.")

      # Resize the project pane based on its contents
      self.projlistwidth = 0
      self.numprojects = 0
      for proj in self.projlist.get(0, Tk.END):
         if len(proj) > self.projlistwidth:
            self.projlistwidth = len(proj)
         self.numprojects += 1
      self.projlist.config(width=self.projlistwidth)

      # Place the panes in the main window 
      self.main.add(self.projpanel)
      self.main.add(self.filepanel)
      self.main.pack(fill=Tk.BOTH, expand=1, side=Tk.BOTTOM)
コード例 #43
0
ファイル: config.py プロジェクト: LLNL/GRAPE
    def execute(self, args):
        base = git.baseDir()
        if base == "":
            return False
        dotGit = git.gitDir()

        utility.printMsg("Optimizing git performance on slow file systems...")
        #runs file system intensive tasks such as git status and git commit
        # in parallel (important for NFS systems such as LC)
        git.config("core.preloadindex", "true")

        #have git automatically do some garbage collection / optimization
        utility.printMsg("Setting up automatic git garbage collection...")
        git.config("gc.auto", "1")

        #prevents false conflict detection due to differences in filesystem
        # time stamps
        utility.printMsg("Optimizing cross platform portability...")
        git.config("core.trustctime", "false")

        # stores login info for 12 hrs (max allowed by RZBitbucket)

        if not args["--nocredcache"]:
            cache = args["--credcache"]
            if not cache:
                cache = utility.userInput(
                    "Would you like to enable git-managed credential caching?",
                    'y')
            if cache:
                utility.printMsg(
                    "Enabling 12 hr caching of https credentials...")
                if os.name == "nt":
                    git.config("--global credential.helper", "wincred")
                else:
                    git.config("--global credential.helper",
                               "cache --timeout=43200")

        # enables 'as' option for merge strategies -forces a conflict if two branches
        # modify the same file
        mergeVerifyPath = os.path.join(os.path.dirname(__file__), "..",
                                       "merge-and-verify-driver")

        if os.path.exists(mergeVerifyPath):
            utility.printMsg(
                "Enabling safe merges (triggers conflicts any time same file is modified),\n\t see 'as' option for grape m and grape md..."
            )
            git.config("merge.verify.name", "merge and verify driver")
            git.config("merge.verify.driver",
                       "%s/merge-and-verify-driver %A %O %B")
        else:
            utility.printMsg(
                "WARNING: merge and verify script not detected, safe merges ('as' option to grape m / md) will not work!"
            )
        # enables lg as an alias to print a pretty-font summary of
        # key junctions in the history for this branch.
        utility.printMsg("Setting lg as an alias for a pretty log call...")
        git.config(
            "alias.lg",
            "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative --simplify-by-decoration"
        )

        # perform an update of the active subprojects if asked.
        ask = not args["--nouv"]
        updateView = ask and (args["--uv"] or utility.userInput(
            "Do you want to edit your active subprojects?"
            " (you can do this later using grape uv) [y/n]", "n"))
        if updateView:
            grapeMenu.menu().applyMenuChoice("uv", args["--uvArg"])

        # configure git to use p4merge for conflict resolution
        # and diffing

        useP4Merge = not args["--nop4merge"] and (
            args["--p4merge"] or utility.userInput(
                "Would you like to use p4merge as your merge tool? [y/n]",
                "y"))
        # note that this relies on p4merge being in your path somewhere
        if (useP4Merge):
            git.config("merge.keepBackup", "false")
            git.config("merge.tool", "p4merge")
            git.config("mergetool.keepBackup", "false")
            git.config(
                "mergetool.p4merge.cmd",
                'p4merge \"\$BASE\" \"\$LOCAL\" \"\$REMOTE\" \"\$MERGED\"')
            git.config("mergetool.p4merge.keepTemporaries", "false")
            git.config("mergetool.p4merge.trustExitCode", "false")
            git.config("mergetool.p4merge.keepBackup", "false")
            utility.printMsg(
                "Configured repo to use p4merge for conflict resolution")
        else:
            git.config("merge.tool", "tkdiff")

        useP4Diff = not args["--nop4diff"] and (
            args["--p4diff"] or utility.userInput(
                "Would you like to use p4merge as your diff tool? [y/n]", "y"))
        # this relies on p4diff being defined as a custom bash script, with the following one-liner:
        # [ $# -eq 7 ] && p4merge "$2" "$5"
        if (useP4Diff):
            p4diffScript = os.path.join(os.path.dirname(__file__), "..",
                                        "p4diff")
            if os.path.exists(p4diffScript):
                git.config("diff.external", p4diffScript)
                utility.printMsg(
                    "Configured repo to use p4merge for diff calls - p4merge must be in your path"
                )
            else:
                utility.printMsg("Could not find p4diff script at %s" %
                                 p4diffScript)
        useGitP4 = args["--git-p4"]
        if (useGitP4):
            git.config("git-p4.useclientspec", "true")
            # create p4 references to enable imports from p4
            p4remotes = os.path.join(dotGit, "refs", "remotes", "p4", "")
            utility.ensure_dir(p4remotes)
            commit = utility.userInput(
                "Please enter a descriptor (e.g. SHA, branch if tip, tag name) of the current git commit that mirrors the p4 repo",
                "master")
            sha = git.SHA(commit)
            with open(os.path.join(p4remotes, "HEAD"), 'w') as f:
                f.write(sha)
            with open(os.path.join(p4remotes, "master"), 'w') as f:
                f.write(sha)

            # to enable exports to p4, a maindev client needs to be set up
            haveCopied = False
            while (not haveCopied):
                p4settings = utility.userInput(
                    "Enter a path to a .p4settings file describing the maindev client you'd like to use for p4 updates",
                    ".p4settings")
                try:
                    shutil.copyfile(p4settings,
                                    os.path.join(base, ".p4settings"))
                    haveCopied = True
                except:
                    print(
                        "could not find p4settings file, please check your path and try again"
                    )
                    return False

        # install hooks here and in all submodules
        utility.printMsg("Installing hooks in all repos...")
        cwd = git.baseDir()
        grapeMenu.menu().applyMenuChoice("installHooks")

        #  ensure all public branches are available in all repos
        submodules = git.getActiveSubmodules()
        config = grapeConfig.grapeConfig()
        publicBranches = config.getPublicBranchList()
        submodulePublicBranches = set(
            config.getMapping('workspace',
                              'submoduleTopicPrefixMappings').values())
        for sub in submodules:
            self.ensurePublicBranchesExist(grapeConfig.grapeRepoConfig(sub),
                                           sub, submodulePublicBranches)

        # reset config to the workspace grapeconfig, use that one for all nested projects' public branches.
        wsDir = utility.workspaceDir()
        config = grapeConfig.grapeRepoConfig(wsDir)
        for proj in grapeConfig.GrapeConfigParser.getAllActiveNestedSubprojectPrefixes(
        ):
            self.ensurePublicBranchesExist(config, os.path.join(wsDir, proj),
                                           publicBranches)

        self.ensurePublicBranchesExist(config, wsDir, publicBranches)

        return True
コード例 #44
0
ファイル: review.py プロジェクト: LLNL/GRAPE
    def execute(self, args):
        """
        A fair chunk of this stuff relies on stashy's wrapping of the STASH REST API, which is posted at
        https://developer.atlassian.com/static/rest/stash/2.12.1/stash-rest.html
        """
        config = grapeConfig.grapeConfig()
        name = args["--user"]
        if not name:
            name = utility.getUserName()

        utility.printMsg("Logging onto %s" % args["--bitbucketURL"])
        if args["--test"]:
            bitbucket = Atlassian.TestAtlassian(name)
        else:
            verify = True if args["--verifySSL"].lower() == "true" else False
            bitbucket = Atlassian.Atlassian(name,
                                            url=args["--bitbucketURL"],
                                            verify=verify)

        # default project (outer level project)
        project_name = args["--project"]

        # default repo (outer level repo)
        repo_name = args["--repo"]

        # determine source branch and target branch
        branch = args["--source"]
        if not branch:
            branch = git.currentBranch()

        # make sure we are in the outer level repo before we push
        wsDir = utility.workspaceDir()
        os.chdir(wsDir)

        #ensure branch is pushed
        utility.printMsg("Pushing %s to bitbucket..." % branch)
        git.push("origin %s" % branch)
        #target branch for outer level repo
        target_branch = args["--target"]
        if not target_branch:
            target_branch = config.getPublicBranchFor(branch)
        # load pull request from Bitbucket if it already exists
        wsRepo = bitbucket.project(project_name).repo(repo_name)
        existingOuterLevelRequest = getReposPullRequest(
            wsRepo, branch, target_branch, args)

        # determine pull request title
        title = args["--title"]
        if existingOuterLevelRequest is not None and not title:
            title = existingOuterLevelRequest.title()

        #determine pull request URL
        outerLevelURL = None
        if existingOuterLevelRequest:
            outerLevelURL = existingOuterLevelRequest.link()

        # determine pull request description
        descr = self.parseDescriptionArgs(args)

        if not descr and existingOuterLevelRequest:
            descr = existingOuterLevelRequest.description()

        # determine pull request reviewers
        reviewers = self.parseReviewerArgs(args)
        if reviewers is None and existingOuterLevelRequest is not None:
            reviewers = [r[0] for r in existingOuterLevelRequest.reviewers()]

        # if we're in append mode, only append what was asked for:
        if args["--append"] or args["--prepend"]:
            title = args["--title"]
            descr = self.parseDescriptionArgs(args)
            reviewers = self.parseReviewerArgs(args)

        ##  Submodule Repos
        missing = utility.getModifiedInactiveSubmodules(target_branch, branch)
        if missing:
            utility.printMsg(
                "The following submodules that you've modified are not currently present in your workspace.\n"
                "You should activate them using grape uv  and then call grape review again. If you haven't modified "
                "these submodules, you may need to do a grape md to proceed.")
            utility.printMsg(','.join(missing))
            return False
        pullRequestLinks = {}
        if not args["--norecurse"] and (args["--recurse"] or config.getboolean(
                "workspace", "manageSubmodules")):

            modifiedSubmodules = git.getModifiedSubmodules(
                target_branch, branch)
            submoduleBranchMappings = config.getMapping(
                "workspace", "submoduleTopicPrefixMappings")

            for submodule in modifiedSubmodules:
                if not submodule:
                    continue
                # push branch
                os.chdir(submodule)
                utility.printMsg("Pushing %s to bitbucket..." % branch)
                git.push("origin %s" % branch)
                os.chdir(wsDir)
                repo = bitbucket.repoFromWorkspaceRepoPath(submodule,
                                                           isSubmodule=True)
                # determine branch prefix
                prefix = branch.split('/')[0]
                sub_target_branch = submoduleBranchMappings[prefix]

                prevSubDescr = getReposPullRequestDescription(
                    repo, branch, sub_target_branch, args)
                #amend the subproject pull request description with the link to the outer pull request
                subDescr = addLinkToDescription(descr, outerLevelURL, True)
                if args["--prepend"] or args["--append"]:
                    subDescr = descr
                newRequest = postPullRequest(repo, title, branch,
                                             sub_target_branch, subDescr,
                                             reviewers, args)
                if newRequest:
                    pullRequestLinks[newRequest.link()] = True
                else:
                    # if a pull request could not be generated, just add a link to browse the branch
                    pullRequestLinks[
                        "%s%s/browse?at=%s" %
                        (bitbucket.rzbitbucketURL, repo.repo.url(),
                         urllib.quote_plus("refs/heads/%s" % branch))] = False

        ## NESTED SUBPROJECT REPOS
        nestedProjects = grapeConfig.GrapeConfigParser.getAllModifiedNestedSubprojects(
            target_branch)
        nestedProjectPrefixes = grapeConfig.GrapeConfigParser.getAllModifiedNestedSubprojectPrefixes(
            target_branch)

        for proj, prefix in zip(nestedProjects, nestedProjectPrefixes):
            with utility.cd(prefix):
                git.push("origin %s" % branch)
            repo = bitbucket.repoFromWorkspaceRepoPath(proj,
                                                       isSubmodule=False,
                                                       isNested=True)

            newRequest = postPullRequest(repo, title, branch, target_branch,
                                         descr, reviewers, args)
            if newRequest:
                pullRequestLinks[newRequest.link()] = True
            else:
                # if a pull request could not be generated, just add a link to browse the branch
                pullRequestLinks["%s%s/browse?at=%s" %
                                 (bitbucket.rzbitbucketURL, repo.repo.url(),
                                  urllib.quote_plus(
                                      "refs/heads/%s" % branch))] = False

        ## OUTER LEVEL REPO
        # load the repo level REST resource
        if not args["--subprojectsOnly"]:
            if not git.hasBranch(branch):
                utility.printMsg(
                    "Top level repository does not have a branch %s, not generating a Pull Request"
                    % (branch))
                return True
            if git.branchUpToDateWith(target_branch, branch):
                utility.printMsg(
                    "%s up to date with %s, not generating a Pull Request in Top Level repo"
                    % (target_branch, branch))
                return True

            repo_name = args["--repo"]
            repo = bitbucket.repoFromWorkspaceRepoPath(
                wsDir, topLevelRepo=repo_name, topLevelProject=project_name)
            utility.printMsg("Posting pull request to %s,%s" %
                             (project_name, repo_name))
            request = postPullRequest(repo, title, branch, target_branch,
                                      descr, reviewers, args)
            updatedDescription = request.description()
            for link in pullRequestLinks:
                updatedDescription = addLinkToDescription(
                    updatedDescription, link, pullRequestLinks[link])

            if updatedDescription != request.description():
                request = postPullRequest(repo, title, branch, target_branch,
                                          updatedDescription, reviewers, args)

            utility.printMsg("Request generated/updated:\n\n%s" % request)
        return True
コード例 #45
0
ファイル: mergeDevelop.py プロジェクト: LLNL/GRAPE
    def execute(self, args):
        if not "<<cmd>>" in args:
            args["<<cmd>>"] = "md"
        branch = args["--public"]
        if not branch:
            currentBranch = git.currentBranch()
            branch = grapeConfig.grapeConfig().getPublicBranchFor(
                git.currentBranch())
            if not branch:
                utility.printMsg(
                    "ERROR: public branches must be configured for grape md to work."
                )
        args["--public"] = branch
        # determine whether to merge in subprojects that have changed
        try:
            submodules = self.progress["submodules"]
        except KeyError:
            modifiedSubmodules = git.getModifiedSubmodules(
                branch, git.currentBranch())
            activeSubmodules = git.getActiveSubmodules()
            submodules = [
                sub for sub in modifiedSubmodules if sub in activeSubmodules
            ]

        try:
            nested = self.progress["nested"]
        except KeyError:
            nested = grapeConfig.GrapeConfigParser.getAllActiveNestedSubprojectPrefixes(
            )

        config = grapeConfig.grapeConfig()
        recurse = config.getboolean("workspace",
                                    "manageSubmodules") or args["--recurse"]
        recurse = recurse and (not args["--noRecurse"]) and len(submodules) > 0
        args["--recurse"] = recurse

        # if we stored cwd in self.progress, make sure we end up there
        if "cwd" in self.progress:
            cwd = self.progress["cwd"]
        else:
            cwd = utility.workspaceDir()
        os.chdir(cwd)

        if "conflictedFiles" in self.progress:
            conflictedFiles = self.progress["conflictedFiles"]
        else:
            conflictedFiles = []

        # take note of whether all submodules are currently present, assume user wants to add any new submodules to WS if so
        activeSubmodulesCheck0 = git.getActiveSubmodules()
        self.progress["allActive"] = set(git.getAllSubmodules()) == set(
            git.getActiveSubmodules())

        # checking for a consistent workspace before doing a merge
        utility.printMsg(
            "Checking for a consistent workspace before performing merge...")
        ret = grapeMenu.menu().applyMenuChoice("status",
                                               ['--failIfInconsistent'])
        if ret is False:
            utility.printMsg(
                "Workspace inconsistent! Aborting attempt to do the merge. Please address above issues and then try again."
            )
            return False

        if not "updateLocalDone" in self.progress and not args["--noUpdate"]:
            # make sure public branches are to date in outer level repo.
            utility.printMsg(
                "Calling grape up to ensure topic and public branches are up-to-date. "
            )
            grapeMenu.menu().applyMenuChoice(
                'up', ['up', '--public=%s' % args["--public"]])
            self.progress["updateLocalDone"] = True

        # do an outer merge if we haven't done it yet
        if not "outerLevelDone" in self.progress:
            self.progress["outerLevelDone"] = False
        if not self.progress["outerLevelDone"]:
            conflictedFiles = self.outerLevelMerge(args, branch)

        # outerLevelMerge returns False if there was a non-conflict related issue
        if conflictedFiles is False:
            utility.printMsg(
                "Initial merge failed. Resolve issue and try again. ")
            return False

        # merge nested subprojects
        for subproject in nested:
            if not self.mergeSubproject(
                    args, subproject, branch, nested, cwd, isSubmodule=False):
                # stop for user to resolve conflicts
                self.progress["nested"] = nested
                self.dumpProgress(args)
                os.chdir(cwd)
                return False
        os.chdir(cwd)

        # merge submodules
        if recurse:
            if len(submodules) > 0:
                if args["--subpublic"]:
                    # respect the callers wishes (usually this is grape m , mr, or pull)
                    subPublic = args["--subpublic"]
                else:
                    # default is to merge the submodule branch that is mapped to the public branch
                    subBranchMappings = config.getMapping(
                        "workspace", "submodulePublicMappings")
                    subPublic = subBranchMappings[config.getPublicBranchFor(
                        branch)]
                for submodule in submodules:
                    if not self.mergeSubproject(args,
                                                submodule,
                                                subPublic,
                                                submodules,
                                                cwd,
                                                isSubmodule=True):
                        # stop for user to resolve conflicts
                        self.progress["conflictedFiles"] = conflictedFiles
                        self.dumpProgress(args)
                        return False
                os.chdir(cwd)
                conflictedFiles = git.conflictedFiles()
                # now that we resolved the submodule conflicts, continue the outer level merge
                if len(conflictedFiles) == 0:
                    self.continueLocalMerge(args)
                    conflictedFiles = git.conflictedFiles()

        if conflictedFiles:
            self.progress["stopPoint"] = "resolve conflicts"
            self.progress["cwd"] = cwd
            self.dumpProgress(
                args,
                "GRAPE: Outer level merge generated conflicts. Please resolve using git mergetool "
                "and then \n continue by calling 'grape md --continue' .")
            return False
        else:
            grapeMenu.menu().applyMenuChoice("runHook",
                                             ["post-merge", '0', "--noExit"])

        # ensure all submodules are currently present in WS if all submodules were present at the beginning of merge
        if self.progress["allActive"]:
            activeSubmodulesCheck1 = git.getActiveSubmodules()
            if (set(activeSubmodulesCheck0) != set(activeSubmodulesCheck1)):
                utility.printMsg(
                    "Updating new submodules using grape uv --allSubmodules")
                grapeMenu.menu().applyMenuChoice(
                    "uv", ["--allSubmodules", "--skipNestedSubprojects"])

        return True
コード例 #46
0
ファイル: mergeDevelop.py プロジェクト: LLNL/GRAPE
    def execute(self, args):
        if not "<<cmd>>" in args:
            args["<<cmd>>"] = "md"
        branch = args["--public"]
        if not branch:
            currentBranch = git.currentBranch()
            branch = grapeConfig.grapeConfig().getPublicBranchFor(git.currentBranch())
            if not branch:
                utility.printMsg("ERROR: public branches must be configured for grape md to work.")
        args["--public"] = branch
        # determine whether to merge in subprojects that have changed
        try:
            submodules = self.progress["submodules"]
        except KeyError:
            modifiedSubmodules = git.getModifiedSubmodules(branch, git.currentBranch())
            activeSubmodules = git.getActiveSubmodules()
            submodules = [sub for sub in modifiedSubmodules if sub in activeSubmodules]

        try:
            nested = self.progress["nested"]
        except KeyError:
            nested = grapeConfig.GrapeConfigParser.getAllActiveNestedSubprojectPrefixes()
                                                                                         
                                                                                         
        
        config = grapeConfig.grapeConfig()
        recurse = config.getboolean("workspace", "manageSubmodules") or args["--recurse"]
        recurse = recurse and (not args["--noRecurse"]) and len(submodules) > 0
        args["--recurse"] = recurse

        # if we stored cwd in self.progress, make sure we end up there
        if "cwd" in self.progress:
            cwd = self.progress["cwd"]
        else:
            cwd = utility.workspaceDir()
        os.chdir(cwd)

        if "conflictedFiles" in self.progress:
            conflictedFiles = self.progress["conflictedFiles"]
        else:
            conflictedFiles = []

        # take note of whether all submodules are currently present, assume user wants to add any new submodules to WS if so
        activeSubmodulesCheck0 = git.getActiveSubmodules()
        self.progress["allActive"] = set(git.getAllSubmodules()) == set(git.getActiveSubmodules())

        # checking for a consistent workspace before doing a merge
        utility.printMsg("Checking for a consistent workspace before performing merge...")
        ret = grapeMenu.menu().applyMenuChoice("status", ['--failIfInconsistent'])
        if ret is False:
            utility.printMsg("Workspace inconsistent! Aborting attempt to do the merge. Please address above issues and then try again.")
            return False
            

        if not "updateLocalDone" in self.progress and not args["--noUpdate"]:
            # make sure public branches are to date in outer level repo.
            utility.printMsg("Calling grape up to ensure topic and public branches are up-to-date. ")
            grapeMenu.menu().applyMenuChoice('up', ['up','--public=%s' % args["--public"]])  
            self.progress["updateLocalDone"] = True
        
        # do an outer merge if we haven't done it yet        
        if not "outerLevelDone" in self.progress:
            self.progress["outerLevelDone"] = False
        if not self.progress["outerLevelDone"]:
            conflictedFiles = self.outerLevelMerge(args, branch)
            
        # outerLevelMerge returns False if there was a non-conflict related issue
        if conflictedFiles is False:
            utility.printMsg("Initial merge failed. Resolve issue and try again. ")
            return False
        
        # merge nested subprojects
        for subproject in nested:
            if not self.mergeSubproject(args, subproject, branch, nested, cwd, isSubmodule=False):
                # stop for user to resolve conflicts
                self.progress["nested"] = nested
                self.dumpProgress(args)
                os.chdir(cwd)
                return False
        os.chdir(cwd)

        # merge submodules
        if recurse:
            if len(submodules) > 0:
                if args["--subpublic"]:
                    # respect the callers wishes (usually this is grape m , mr, or pull)
                    subPublic = args["--subpublic"]
                else:
                    # default is to merge the submodule branch that is mapped to the public branch
                    subBranchMappings = config.getMapping("workspace", "submodulePublicMappings")
                    subPublic = subBranchMappings[config.getPublicBranchFor(branch)]
                for submodule in submodules:
                    if not self.mergeSubproject(args, submodule, subPublic, submodules, cwd, isSubmodule=True):
                        # stop for user to resolve conflicts
                        self.progress["conflictedFiles"] = conflictedFiles
                        self.dumpProgress(args)
                        return False
                os.chdir(cwd)
                conflictedFiles = git.conflictedFiles()
                # now that we resolved the submodule conflicts, continue the outer level merge 
                if len(conflictedFiles) == 0:
                    self.continueLocalMerge(args)
                    conflictedFiles = git.conflictedFiles()



                
        if conflictedFiles:
            self.progress["stopPoint"] = "resolve conflicts"
            self.progress["cwd"] = cwd
            self.dumpProgress(args, "GRAPE: Outer level merge generated conflicts. Please resolve using git mergetool "
                                    "and then \n continue by calling 'grape md --continue' .")
            return False
        else:
            grapeMenu.menu().applyMenuChoice("runHook", ["post-merge", '0', "--noExit"])
            
        # ensure all submodules are currently present in WS if all submodules were present at the beginning of merge
        if self.progress["allActive"]:
            activeSubmodulesCheck1 = git.getActiveSubmodules()
            if (set(activeSubmodulesCheck0) != set(activeSubmodulesCheck1)):
                utility.printMsg("Updating new submodules using grape uv --allSubmodules")
                grapeMenu.menu().applyMenuChoice("uv", ["--allSubmodules", "--skipNestedSubprojects"])
        
        return True
コード例 #47
0
ファイル: checkout.py プロジェクト: LLNL/GRAPE
    def execute(self, args):
        sync = args["--sync"].lower().strip()
        sync = sync == "true" or sync == "yes"
        args["--sync"] = sync
        checkoutargs = ''
        branch = args["<branch>"]
        if args['-b']: 
            checkoutargs += " -b"

        workspaceDir = utility.workspaceDir()
        os.chdir(workspaceDir)
        currentSHA = git.shortSHA("HEAD")

        utility.printMsg("Performing checkout of %s in outer level project." % branch)
        launcher = utility.MultiRepoCommandLauncher(handledCheckout, listOfRepoBranchArgTuples=[(workspaceDir, branch, [checkoutargs, sync])])
       
        if not launcher.launchFromWorkspaceDir(handleMRE=handleCheckoutMRE)[0]:
            return False
        previousSHA = currentSHA

        submoduleListDidChange = ".gitmodules" in git.diff("--name-only %s %s" % (previousSHA, branch))
        addedModules = []
        removedModules = []
        uvArgs = []
        submodulesDidChange = False
        if submoduleListDidChange and grapeConfig.grapeConfig().getboolean("workspace", "manageSubmodules"):

            self.parseGitModulesDiffOutput(git.diff("%s %s --no-ext-diff -- .gitmodules" % (previousSHA, branch)), addedModules,
                                           removedModules)
            if not addedModules and not removedModules:
                pass
            else:
                submodulesDidChange = True

                if removedModules:
                    for sub in removedModules:
                        try:
                            os.chdir(os.path.join(workspaceDir, sub))
                            if git.isWorkingDirectoryClean():
                                cleanBehaviorSet = args["--noUpdateView"] or args["--updateView"]
                                if not cleanBehaviorSet:
                                    clean = utility.userInput("Would you like to remove the submodule %s ?" % sub, 'n')
                                elif args["--noUpdateView"]:
                                    clean = False
                                elif args["--updateView"]:
                                    clean = True
                                if clean:
                                    utility.printMsg("Removing clean submodule %s." % sub)
                                    os.chdir(workspaceDir)
                                    shutil.rmtree(os.path.join(workspaceDir, sub))
                            else:
                                utility.printMsg("Unstaged / committed changes in %s, not removing." % sub)
                                os.chdir(workspaceDir)
                        except OSError:
                            pass


        # check to see if nested project list changed
        addedProjects = []
        removedProjects = []
        removedProjectPrefices = {}
        nestedProjectListDidChange = False
        os.chdir(workspaceDir)
        if ".grapeconfig" in git.diff("--name-only %s %s" % (previousSHA, branch)): 
            configDiff = git.diff("--no-ext-diff %s %s -- %s" % (previousSHA, branch, ".grapeconfig"))
            nestedProjectListDidChange = "[nestedprojects]" in configDiff.lower()
            self.parseGrapeConfigNestedProjectDiffOutput(configDiff, addedProjects, removedProjects, removedProjectPrefices)
            
            if removedProjects: 
                config = grapeConfig.grapeConfig()
                for proj in removedProjects:
                    projPrefix = removedProjectPrefices[proj]
                    try:
                        os.chdir(os.path.join(workspaceDir, proj))
                    except OSError as e:
                        if e.errno == 2:
                            # directory doesn't exist, that's OK since we're thinking about removing it
                            # anyways at this point...
                            continue
                    if git.isWorkingDirectoryClean():
                        removeBehaviorSet = args["--noUpdateView"] or args["--updateView"]
                        if not removeBehaviorSet:
                            remove = utility.userInput("Would you like to remove the nested subproject %s? \n"
                                                       "All work that has not been pushed will be lost. " % projPrefix, 'n'  )
                        elif args["--noUpdateView"]:
                            remove = False
                        elif args["--updateView"]:
                            remove = True
                        if remove:
                            remove = utility.userInput("Are you sure you want to remove %s? When you switch back to the previous branch, you will have to\n"
                                                       "reclone %s." % (projPrefix, projPrefix), 'n')
                        if remove:
                            os.chdir(workspaceDir)
                            shutil.rmtree(os.path.join(workspaceDir,projPrefix))
                    else:
                        utility.printMsg("Unstaged / committed changes in %s, not removing. \n"
                                         "Note this project is NOT active in %s. " % (projPrefix, branch))
                        os.chdir(workspaceDir)                          
                        
        if not submodulesDidChange and not nestedProjectListDidChange:
            uvArgs.append("--checkSubprojects")
        else:
            updateViewSet = args["--noUpdateView"] or args["--updateView"]
            if not updateViewSet:
                updateView = utility.userInput("Submodules or subprojects were added/removed as a result of this checkout. \n" + 
                                               "%s" % ("Added Projects: %s\n" % ','.join(addedProjects) if addedProjects else "") + 
                                               "%s" % ("Added Submodules: %s\n"% ','.join(addedModules) if addedModules else "") +
                                               "%s" % ("Removed Projects: %s\n" % ','.join(removedProjects) if removedProjects else "") +
                                               "%s" % ("Removed Submodules: %s\n" % ','.join(removedModules) if removedModules else "") +
                                               "Would you like to update your workspace view? [y/n]", 'n')
            elif args["--noUpdateView"]:
                updateView = False
            elif args["--updateView"]:
                updateView = True
            if not updateView:
                uvArgs.append("--checkSubprojects")
            
        if args["-b"]: 
            uvArgs.append("-b")
        if sync:
            uvArgs.append("--sync=True")
        else:
            uvArgs.append("--sync=False")

        # in case the user switches to a branch without corresponding branches in the submodules, make sure active submodules
        # are at the right commit before possibly creating new branches at the current HEAD. 
        git.submodule("update")
        utility.printMsg("Calling grape uv %s to ensure branches are consistent across all active subprojects and submodules." % ' '.join(uvArgs))
        grapeConfig.read()
        grapeMenu.menu().applyMenuChoice('uv', uvArgs)

        os.chdir(workspaceDir)
        
        if sync:
            utility.printMsg("Switched to %s. Updating from remote...\n\t (use --sync=False or .grapeconfig.post-checkout.syncWithOrigin to change behavior.)" % branch)            
            if args["-b"]:
                grapeMenu.menu().applyMenuChoice("push")
            else:
                grapeMenu.menu().applyMenuChoice("pull")
        else:
            utility.printMsg("Switched to %s." % branch)
            
        global _skipBranchCreation
        global _createNewBranch
        _skipBranchCreation = False
        _createNewBranch = False        
        return True
コード例 #48
0
ファイル: updateView.py プロジェクト: LLNL/GRAPE
    def defineActiveSubmodules(projectType="submodule"):
        """
        Queries the user for the submodules (projectType == "submodule") or nested subprojects
        (projectType == "nested subproject") they would like to activate.

        """
        if projectType == "submodule":
            allSubprojects = git.getAllSubmodules()
            activeSubprojects = git.getActiveSubmodules()

        if projectType == "nested subproject":
            config = grapeConfig.grapeConfig()
            allSubprojectNames = config.getAllNestedSubprojects()
            allSubprojects = []
            for project in allSubprojectNames:
                allSubprojects.append(config.get("nested-%s" % project, "prefix"))
            activeSubprojects = grapeConfig.GrapeConfigParser.getAllActiveNestedSubprojectPrefixes()

        toplevelDirs = {}
        toplevelActiveDirs = {}
        toplevelSubs = []
        for sub in allSubprojects:
            # we are taking advantage of the fact that branchPrefixes are the same as directory prefixes for local
            # top-level dirs.
            prefix = git.branchPrefix(sub)
            if sub != prefix:
                toplevelDirs[prefix] = []
                toplevelActiveDirs[prefix] = []
        for sub in allSubprojects:
            prefix = git.branchPrefix(sub)
            if sub != prefix:
                toplevelDirs[prefix].append(sub)
            else:
                toplevelSubs.append(sub)
        for sub in activeSubprojects:
            prefix = git.branchPrefix(sub)
            if sub != prefix:
                toplevelActiveDirs[prefix].append(sub)

        included = {}
        for directory, subprojects in toplevelDirs.items():

            activeDir = toplevelActiveDirs[directory]
            if len(activeDir) == 0:
                defaultValue = "none"
            elif set(activeDir) == set(subprojects):
                defaultValue = "all"
            else:
                defaultValue = "some"

            opt = utility.userInput("Would you like all, some, or none of the %ss in %s?" % (projectType,directory),
                                    default=defaultValue)
            if opt.lower()[0] == "a":
                for subproject in subprojects:
                    included[subproject] = True
                        
            if opt.lower()[0] == "n":
                for subproject in subprojects:
                    included[subproject] = False
            if opt.lower()[0] == "s":
                for subproject in subprojects: 
                    included[subproject] = utility.userInput("Would you like %s %s? [y/n]" % (projectType, subproject),
                                                             'y' if (subproject in activeSubprojects) else 'n')
        for subproject in toplevelSubs:
            included[subproject] = utility.userInput("Would you like %s %s? [y/n]" % (projectType, subproject),
                                                     'y' if (subproject in activeSubprojects) else 'n')
        return included
コード例 #49
0
ファイル: updateView.py プロジェクト: LLNL/GRAPE
    def execute(self, args):
        sync = args["--sync"].lower().strip()
        sync = sync == "true" or sync == "yes"
        args["--sync"] = sync
        config = grapeConfig.grapeConfig()
        origwd = os.getcwd()
        wsDir = utility.workspaceDir()
        os.chdir(wsDir)
        base = git.baseDir()
        if base == "":
            return False
        hasSubmodules = len(git.getAllSubmodules()) > 0 and not args["--skipSubmodules"]
        includedSubmodules = {}
        includedNestedSubprojectPrefixes = {}

        allSubmodules = git.getAllSubmodules()
        allNestedSubprojects = config.getAllNestedSubprojects()
        
        addedSubmodules = [] 
        addedNestedSubprojects = [] 
        addedProjects = args["--add"]
        notFound = []
       
        for proj in addedProjects:
            if proj in allSubmodules:
                addedSubmodules.append(proj)
            elif proj in allNestedSubprojects:
                addedNestedSubprojects.append(proj)
            else:
                notFound.append(proj)
        
        rmSubmodules = []
        rmNestedSubprojects = []
        rmProjects = args["--rm"]
        
        for proj in rmProjects:
            if proj in allSubmodules:
                rmSubmodules.append(proj)
            elif proj in allNestedSubprojects:
                rmNestedSubprojects.append(proj)
            else:
                notFound.append(proj)

        if notFound:
            utility.printMsg("\"%s\" not found in submodules %s \nor\n nested subprojects %s" % (",".join(notFound),",".join(allSubmodules),",".join(allNestedSubprojects)))
            return False
                
       
        if not args["--checkSubprojects"]:
            # get submodules to update
            if hasSubmodules:
                if args["--allSubmodules"]: 
                    includedSubmodules = {sub:True for sub in allSubmodules}
                elif args["--add"] or args["--rm"]:
                    includedSubmodules = {sub:True for sub in git.getActiveSubmodules()}
                    includedSubmodules.update({sub:True for sub in addedSubmodules})
                    includedSubmodules.update({sub:False for sub in rmSubmodules})
                else:
                    includedSubmodules = self.defineActiveSubmodules()

            # get subprojects to update
            if not args["--skipNestedSubprojects"]: 
                
                nestedPrefixLookup = lambda x : config.get("nested-%s" % x, "prefix")
                if args["--allNestedSubprojects"]: 
                    includedNestedSubprojectPrefixes = {nestedPrefixLookup(sub):True for sub in allNestedSubprojects}
                elif args["--add"] or args["--rm"]:
                    includedNestedSubprojectPrefixes = {sub:True for sub in grapeConfig.GrapeConfigParser.getAllActiveNestedSubprojectPrefixes()}
                    includedNestedSubprojectPrefixes.update({nestedPrefixLookup(sub):True for sub in addedNestedSubprojects})
                    includedNestedSubprojectPrefixes.update({nestedPrefixLookup(sub):False for sub in rmNestedSubprojects})
                else:
                    includedNestedSubprojectPrefixes = self.defineActiveNestedSubprojects()                    
            
            if hasSubmodules:
                initStr = ""
                deinitStr = ""
                rmCachedStr = ""
                resetStr = ""
                for submodule, nowActive in includedSubmodules.items():
                    if nowActive:
                        initStr += ' %s' % submodule
                    else:
                        deinitStr += ' %s' % submodule
                        rmCachedStr += ' %s' % submodule
                        resetStr += ' %s' % submodule
                if args["-f"] and deinitStr:
                    deinitStr = "-f"+deinitStr

                utility.printMsg("Configuring submodules...")
                utility.printMsg("Initializing submodules...")
                git.submodule("init %s" % initStr.strip())
                if deinitStr:
                    utility.printMsg("Deiniting submodules that were not requested... (%s)" % deinitStr)
                    done = False
                    while not done:
                        try:
                            git.submodule("deinit %s" % deinitStr.strip())
                            done = True
                        except git.GrapeGitError as e:
                            if "the following file has local modifications" in e.gitOutput:
                                print e.gitOutput
                                utility.printMsg("A submodule that you wanted to remove has local modifications. "
                                                 "Use grape uv -f to force removal.")
                                return False
                            
                            elif "use 'rm -rf' if you really want to remove it including all of its history" in e.gitOutput:
                                if not args["-f"]:
                                    raise e
                                # it is safe to move the .git of the submodule to the .git/modules area of the workspace...
                                module = None
                                for l in e.gitOutput.split('\n'):
                                    if "Submodule work tree" in l and "contains a .git directory" in l:
                                        module = l.split("'")[1]
                                        break
                                if module:
                                    src = os.path.join(module, ".git")
                                    dest =  os.path.join(wsDir, ".git", "modules", module)
                                    utility.printMsg("Moving %s to %s"%(src, dest))
                                    shutil.move(src, dest )
                                else:
                                    raise e
                            else:
                                raise e
                    git.rm("--cached %s" % rmCachedStr)
                    git.reset(" %s" % resetStr)

                if initStr:
                    utility.printMsg("Updating active submodules...(%s)" % initStr)
                    git.submodule("update")

            # handle nested subprojects
            if not args["--skipNestedSubprojects"]: 
                reverseLookupByPrefix = {nestedPrefixLookup(sub) : sub for sub in allNestedSubprojects} 
                userConfig = grapeConfig.grapeUserConfig()
                updatedActiveList = []
                for subproject, nowActive in includedNestedSubprojectPrefixes.items():
                    subprojectName = reverseLookupByPrefix[subproject]
                    section = "nested-%s" % reverseLookupByPrefix[subproject]
                    userConfig.ensureSection(section)
                    previouslyActive = userConfig.getboolean(section, "active")
                    previouslyActive = previouslyActive and os.path.exists(os.path.join(base, subproject, ".git"))
                    userConfig.set(section, "active", "True" if previouslyActive else "False")
                    if nowActive and previouslyActive:
                        updatedActiveList.append(subprojectName)
    
                    if nowActive and not previouslyActive:
                        utility.printMsg("Activating Nested Subproject %s" % subproject)
                        if not addSubproject.AddSubproject.activateNestedSubproject(subprojectName, userConfig):
                            utility.printMsg("Can't activate %s. Exiting..." % subprojectName)
                            return False
                        
                        updatedActiveList.append(subprojectName)
    
                    if not nowActive and not previouslyActive:
                        pass
                    if not nowActive and previouslyActive:
                        #remove the subproject
                        subprojectdir = os.path.join(base, utility.makePathPortable(subproject))
                        proceed = args["-f"] or \
                                  utility.userInput("About to delete all contents in %s. Any uncommitted changes, committed changes "
                                                    "that have not been pushed, or ignored files will be lost.  Proceed?" %
                                                    subproject, 'n')
                        if proceed:
                            shutil.rmtree(subprojectdir)
                userConfig.setActiveNestedSubprojects(updatedActiveList)
                grapeConfig.writeConfig(userConfig, os.path.join(utility.workspaceDir(), ".git", ".grapeuserconfig"))

        checkoutArgs = "-b" if args["-b"] else ""

        safeSwitchWorkspaceToBranch( git.currentBranch(), checkoutArgs, sync)

        os.chdir(origwd)

        return True
コード例 #50
0
ファイル: bundle.py プロジェクト: LLNL/GRAPE
 def config(self):
     return grapeConfig.grapeConfig()