Exemple #1
0
 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]        
Exemple #2
0
def getModifiedInactiveSubmodules(branch1, branch2):
    modifiedSubs = git.getModifiedSubmodules(branch1=branch1, branch2=branch2)
    activeSubs = git.getActiveSubmodules()
    missing = []
    for sub in modifiedSubs:
        if sub not in activeSubs:
            missing.append(sub)
    return missing
Exemple #3
0
    def checkForConsistentWorkspaceBranches(self, args):
        consistentBranchState = True
        cfg = config.grapeConfig.grapeConfig()
        publicBranches = cfg.getPublicBranchList()
        wsDir = utility.workspaceDir()
        os.chdir(wsDir)
        wsBranch = git.currentBranch()
        subPubMap = cfg.getMapping("workspace", "submodulepublicmappings")
        if wsBranch in publicBranches:
            for sub in git.getActiveSubmodules():
                os.chdir(os.path.join(wsDir, sub))
                subbranch = git.currentBranch()
                if subbranch != subPubMap[wsBranch]:
                    consistentBranchState = False
                    utility.printMsg(
                        "Submodule %s on branch %s when grape expects it to be on %s"
                        % (sub, subbranch, subPubMap[wsBranch]))
        else:
            for sub in git.getActiveSubmodules():
                os.chdir(os.path.join(wsDir, sub))
                subbranch = git.currentBranch()
                if subbranch != wsBranch:
                    consistentBranchState = False
                    utility.printMsg(
                        "Submodule %s on branch %s when grape expects it to be on %s"
                        % (sub, subbranch, wsBranch))

        # check that nested subproject branching is consistent
        for nested in config.grapeConfig.GrapeConfigParser.getAllActiveNestedSubprojectPrefixes(
        ):
            os.chdir(os.path.join(wsDir, nested))
            nestedbranch = git.currentBranch()
            if nestedbranch != wsBranch:
                consistentBranchState = False
                utility.printMsg(
                    "Nested Project %s on branch %s when grape expects it to be on %s"
                    % (nested, nestedbranch, wsBranch))

        return consistentBranchState
Exemple #4
0
    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
Exemple #5
0
    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
Exemple #6
0
    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
Exemple #7
0
    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
Exemple #8
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
Exemple #9
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
Exemple #10
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
Exemple #11
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
Exemple #12
0
def getActiveSubprojects():
    return git.getActiveSubmodules() + grapeConfig.GrapeConfigParser.getAllActiveNestedSubprojectPrefixes()
Exemple #13
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)
Exemple #14
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)
Exemple #15
0
    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
Exemple #16
0
    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