Ejemplo n.º 1
0
Archivo: status.py Proyecto: LLNL/GRAPE
    def printStatus(self, args):
        wsDir = utility.workspaceDir()
        statusArgs = ""
        if args["-u"]:
            statusArgs += "-u "
        if args["--uno"]:
            statusArgs += "-uno "

        launcher = utility.MultiRepoCommandLauncher(
            getStatus,
            runInSubmodules=True,
            runInSubprojects=True,
            runInOuter=True,
            globalArgs=[statusArgs, wsDir])

        stati = launcher.launchFromWorkspaceDir(noPause=True)
        status = {}
        for s, r in (zip(stati, launcher.repos)):
            status[r] = s

        for sub in status.keys():
            for line in status[sub]:
                lstripped = line.strip()
                if lstripped:
                    # filter out branch tracking status
                    # ## bugfix/bugfixday/DLThreadSafety...remotes/origin/bugfix/bugfixday/DLThreadSafety [ahead 1]
                    # ## bugfix/bugfixday/DLThreadSafety...remotes/origin/bugfix/bugfixday/DLThreadSafety [behind 29]
                    if lstripped[0:2] == "##":
                        if "[ahead" in lstripped or "[behind" in lstripped:
                            print os.path.abspath(os.path.join(
                                wsDir, sub)) + ': ' + lstripped
                        continue
                    # print other statuses
                    print ' ' + lstripped
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    def execute(self,args):
        if not "<<cmd>>" in args:
            args["<<cmd>>"] = "mr"
        otherBranch = args['<branch>']
        if not otherBranch:
            # list remote branches that are available
            print git.branch('-r')
            otherBranch = utility.userInput("Enter name of branch you would like to merge into this branch (without the origin/ prefix)")

        # make sure remote references are up to date
        utility.printMsg("Fetching remote references in all projects...")
        try:
            utility.MultiRepoCommandLauncher(fetchHelper).launchFromWorkspaceDir()
        except utility.MultiRepoException as mre:
            commError = False
            commErrorRepos = []
            for e, r in zip(mre.exceptions(), mre.repos()):
                if e.commError:
                    commErrorRepos.append(r)
                    commError = True
                
            if commError:
                utility.printMsg("ERROR: can't communicate with remotes for %s. Halting remote merge." % commErrorRepos)
                return False
            
            
        
        
        # update our local reference to the remote branch so long as it's fast-forwardable or we don't have it yet..)
        hasRemote = ("origin/%s" % otherBranch) in git.remoteBranches()
        hasBranch = git.hasBranch(otherBranch)
        currentBranch = git.currentBranch()
        remoteUpToDateWithLocal = git.branchUpToDateWith("remotes/origin/%s" % otherBranch, otherBranch)
        updateLocal =  hasRemote and  (remoteUpToDateWithLocal or not hasBranch) and currentBranch != otherBranch
        if  updateLocal:
            utility.printMsg("updating local branch %s from %s" % (otherBranch, "origin/%s" % otherBranch))
            utility.MultiRepoCommandLauncher(updateBranchHelper, branch=otherBranch).launchFromWorkspaceDir(handleMRE=updateBranchHandleMRE)
        
        args["<branch>"] = otherBranch if updateLocal else "origin/%s" % otherBranch
        # we've handled the update, we don't want m or md to update the local branch. 
        args["--noUpdate"] = True
        # if mr is called by the user, need to initialize the --continue argument. 
        # if it is called by md, it will be set already. 
        if not "--continue" in args:
            args["--continue"] = False        
        
        return grapeMenu.menu().getOption('m').execute(args)
Ejemplo n.º 4
0
def safeSwitchWorkspaceToBranch(branch, checkoutArgs, sync):
    # Ensure local branches that you are about to check out are up to date with the remote
    if sync:
        launcher = utility.MultiRepoCommandLauncher(
            ensureLocalUpToDateWithRemote,
            branch=branch,
            globalArgs=[checkoutArgs])
        launcher.launchFromWorkspaceDir(handleMRE=handleEnsureLocalUpToDateMRE)
    # Do a checkout
    # Pass False instead of sync since if sync is True ensureLocalUpToDateWithRemote will have already performed the fetch
    launcher = utility.MultiRepoCommandLauncher(
        checkout.handledCheckout,
        branch=branch,
        globalArgs=[checkoutArgs, False])
    launcher.launchFromWorkspaceDir(handleMRE=checkout.handleCheckoutMRE)

    return
Ejemplo n.º 5
0
Archivo: stash.py Proyecto: LLNL/GRAPE
    def execute(self, args):

        if args["pop"]:
            launcher = utility.MultiRepoCommandLauncher(popHelper)
        elif args["list"]:
            launcher = utility.MultiRepoCommandLauncher(listHelper)
        else:
            launcher = utility.MultiRepoCommandLauncher(stashHelper)
        try:
            retvals = launcher.launchFromWorkspaceDir()
            for r in retvals:
                if r[1]:
                    print "%s: %s" % (r[0], r[1])
        except utility.MultiRepoException as mre:
            for e, r in zip(mre, mre.repos):
                print("%s:\n%s" % (r, e.gitOutput))

        return True
Ejemplo n.º 6
0
 def execute(self, args):
     cmd = args["<cmd>"]
     retvals = utility.MultiRepoCommandLauncher(
         foreach,
         runInOuter=not args["--noTopLevel"],
         skipSubmodules=args["--noSubmodules"],
         runInSubprojects=not args["--noSubprojects"],
         globalArgs=args).launchFromWorkspaceDir(handleMRE=handleForeachMRE)
     return retvals
Ejemplo n.º 7
0
def handleEnsureLocalUpToDateMRE(mre):
    _pushBranch = False
    _skipPush = False
    cleanupPushArgs = []
    for e1, repo, branch in zip(mre.exceptions(), mre.repos(), mre.branches()):
        try:
            raise e1
        except git.GrapeGitError as e:
            if ("[rejected]" in e.gitOutput
                    and "(non-fast-forward)" in e.gitOutput
                ) or "Couldn't find remote ref" in e.gitOutput:
                if "Couldn't find remote ref" in e.gitOutput:
                    if not _pushBranch:
                        utility.printMsg(
                            "No remote reference to %s in %s's origin. You may want to push this branch."
                            % (branch, repo))
                else:
                    utility.printMsg(
                        "Fetch of %s rejected as non-fast-forward in repo %s" %
                        (branch, repo))
                pushBranch = _pushBranch
                if _skipPush:
                    pushBranch = False
                elif not pushBranch:
                    pushBranch = utility.userInput(
                        "Would you like to push your local branch? \n"
                        "(select 'a' to say yes for (a)ll subprojects, 's' to (s)kip push for all subprojects)"
                        "\n(y,n,a,s)", 'y')

                if str(pushBranch).lower()[0] == 'a':
                    _pushBranch = True
                    pushBranch = True
                if str(pushBranch).lower()[0] == 's':
                    _skipPush = True
                    pushBranch = False
                if pushBranch:

                    cleanupPushArgs.append((repo, branch, None))
                else:
                    utility.printMsg("Skipping push of local %s in %s" %
                                     (branch, repo))

            elif e.commError:
                utility.printMsg(
                    "Could not update %s from origin due to a connectivity issue. Checking out most recent\n"
                    "local version. " % branch)
            else:
                raise (e)

    # do another MRC launch to do any follow up pushes that were requested.
    utility.MultiRepoCommandLauncher(
        cleanupPush,
        listOfRepoBranchArgTuples=cleanupPushArgs).launchFromWorkspaceDir(
            handleMRE=handleCleanupPushMRE)
    return
Ejemplo n.º 8
0
Archivo: push.py Proyecto: 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
Ejemplo n.º 9
0
def handleDeleteBranchMRE(mre, force=False):
    detachTuples = []
    for e1, branch, repo in zip(mre.exceptions(), mre.branches(), mre.repos()):
        try:
            raise e1
        except git.GrapeGitError as e:
            with utility.cd(repo):
                if "Cannot delete the branch" in e.gitOutput and \
                   "which you are currently on." in e.gitOutput:
                    if force:
                        detachTuples.append((repo, branch, None))
                    else:
                        utility.printMsg(
                            "call grape db -D %s to force deletion of branch you are currently on."
                            % branch)
                elif "not deleting branch" in e.gitOutput and "even though it is merged to HEAD." in e.gitOutput:
                    git.branch("-D %s" % branch)
                elif "error: branch" in e.gitOutput and "not found" in e.gitOutput:
                    "%s not found in %s" % (branch, repo)
                    pass
                elif "is not fully merged" in e.gitOutput:
                    if force:
                        utility.printMsg("**DELETING UNMERGED BRANCH %s" %
                                         branch)
                        git.branch("-D %s" % branch)
                    else:
                        print "%s is not fully merged in %s. Run grape db -D %s to force the deletion" % (
                            branch, repo, branch)
                elif e.commError:
                    utility.printMsg(
                        "Could not connect to origin to delete remote references to your branch "
                        "You may want to call grape db %s again once you've reconnected."
                        % branch)
                else:
                    utility.printMsg(
                        "Deletion of %s failed for unhandled reason." % branch)
                    print e.gitOutput
                    raise e

    utility.MultiRepoCommandLauncher(
        detachThenForceDeleteBranch,
        listOfRepoBranchArgTuples=detachTuples).launchFromWorkspaceDir(
            handleMRE=handleDetachThenForceMRE)
Ejemplo n.º 10
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")
Ejemplo n.º 11
0
    def execute(self, args):
        branch = args["<branch>"]
        force = args["-D"]
        if not branch:
            branch = utility.userInput("Enter name of branch to delete")

        if args["--verify"]:
            proceed = utility.userInput(
                "Would you like to delete the branch %s" % branch, 'y')
            if not proceed:
                return True

        launcher = utility.MultiRepoCommandLauncher(deleteBranch,
                                                    branch=branch,
                                                    globalArgs=[force])
        try:
            launcher.launchFromWorkspaceDir()
        except utility.MultiRepoException as e:
            handleDeleteBranchMRE(e, force)

        return True
Ejemplo n.º 12
0
def handleCheckoutMRE(mre):
    global _skipBranchCreation
    global _createNewBranch
    newBranchReposArgTuples = []
    newBranches = []

    for e1, branch, project, checkoutargs in zip(mre.exceptions(),
                                                 mre.branches(), mre.repos(),
                                                 mre.args()):
        try:
            raise e1
        except git.GrapeGitError as e:
            with utility.cd(project):
                if "pathspec" in e.gitOutput:
                    createNewBranch = _createNewBranch
                    if _skipBranchCreation:
                        utility.printMsg("Skipping checkout of %s in %s" %
                                         (branch, project))
                        createNewBranch = False

                    elif not createNewBranch:
                        createNewBranch = utility.userInput(
                            "Branch not found locally or remotely. Would you like to create a "
                            "new branch called %s in %s? \n"
                            "(select 'a' to say yes for (a)ll, 's' to (s)kip creation for branches that don't exist )"
                            "\n(y,n,a,s)" % (branch, project), 'y')

                    if str(createNewBranch).lower()[0] == 'a':
                        _createNewBranch = True
                        createNewBranch = True
                    if str(createNewBranch).lower()[0] == 's':
                        _skipBranchCreation = True
                        createNewBranch = False
                    if createNewBranch:
                        newBranchReposArgTuples.append((project, branch, {
                            "checkout":
                            checkoutargs[0]
                        }))
                    else:
                        continue

                elif "already exists" in e.gitOutput:
                    utility.printMsg("Branch %s already exists in %s." %
                                     (branch, project))
                    branchDescription = git.commitDescription(branch)
                    headDescription = git.commitDescription("HEAD")
                    if branchDescription == headDescription:
                        utility.printMsg(
                            "Branch %s and HEAD are the same. Switching to %s."
                            % (branch, branch))
                        action = "k"
                    else:
                        utility.printMsg(
                            "Branch %s and HEAD are not the same." % branch)
                        action = ''
                        valid = False
                        while not valid:
                            action = utility.userInput(
                                "Would you like to \n (k)eep it as is at: %s \n"
                                " or \n (f)orce it to: %s? \n(k,f)" %
                                (branchDescription, headDescription), 'k')
                            valid = (action == 'k') or (action == 'f')
                            if not valid:
                                utility.printMsg(
                                    "Invalid input. Enter k or f. ")
                    if action == 'k':
                        git.checkout(branch)
                    elif action == 'f':
                        git.checkout("-B %s" % branch)
                elif "conflict" in e.gitOutput.lower():
                    utility.printMsg(
                        "CONFLICT occurred when pulling %s from origin." %
                        branch)
                elif "does not appear to be a git repository" in e.gitOutput.lower(
                ):
                    utility.printMsg(
                        "Remote 'origin' does not exist. "
                        "This branch was not updated from a remote repository."
                    )
                elif "Couldn't find remote ref" in e.gitOutput:
                    utility.printMsg(
                        "Remote of %s does not have reference to %s. You may want to push this branch. "
                        % (project, branch))
                else:
                    raise e

    if len(newBranchReposArgTuples) > 0:
        utility.MultiRepoCommandLauncher(
            createNewBranches,
            listOfRepoBranchArgTuples=newBranchReposArgTuples
        ).launchFromWorkspaceDir(handleMRE=createNewBranchesMREHandler)
Ejemplo n.º 13
0
    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