コード例 #1
0
def read(additionalFileNames=None):
    # initialize a ConfigParser with all defaults needed by the grapeMenu
    if additionalFileNames is None:
        additionalFileNames = []
    defaultFiles = []
    if os.name == "nt":
        defaultFiles.append(
            os.path.join(os.environ["USERPROFILE"], ".grapeconfig"))
    else:
        defaultFiles.append(os.path.join(os.environ["HOME"], ".grapeconfig"))
    globalconfigfile = defaultFiles[0]
    try:
        defaultFiles.append(
            os.path.join(
                utility.workspaceDir(warnIfNotFound=False,
                                     throwIfNotFound=False), ".grapeconfig"))
    except:
        pass
    try:
        defaultFiles.append(
            os.path.join(
                utility.workspaceDir(warnIfNotFound=False,
                                     throwIfNotFound=False), ".git",
                ".grapeuserconfig"))
    except:
        pass

    files = defaultFiles + additionalFileNames
    readFiles = grapeConfig().read(files)
    if len(readFiles) == 0:
        utility.writeDefaultConfig(globalconfigfile)
コード例 #2
0
def ensureLocalUpToDateWithRemote(repo='', branch='master'):
    utility.printMsg(
        "Ensuring local branch %s in %s is up to date with origin" %
        (branch, repo))
    with utility.cd(repo):
        # attempt to fetch the requested branch
        try:
            git.fetch("origin", "%s:%s" % (branch, branch))
        except:
            # the branch may not exist, but this is ok
            pass

        if git.currentBranch() == branch:
            return

        if not git.hasBranch(branch):
            # switch to corresponding public branch if the branch does not exist
            public = grapeConfig.workspaceConfig().getPublicBranchFor(branch)
            # figure out if this is a submodule
            relpath = os.path.relpath(repo, utility.workspaceDir())
            relpath = relpath.replace('\\', "/")
            with utility.cd(utility.workspaceDir()):
                # if this is a submodule, get the appropriate public mapping
                if relpath in git.getAllSubmoduleURLMap().keys():
                    public = grapeConfig.workspaceConfig().getMapping(
                        "workspace", "submodulepublicmappings")[public]
            utility.printMsg(
                "Branch %s does not exist in %s, switching to %s and detaching"
                % (branch, repo, public))
            git.checkout(public)
            git.pull("origin %s" % (public))
            git.checkout("--detach HEAD")
コード例 #3
0
ファイル: updateView.py プロジェクト: LLNL/GRAPE
def ensureLocalUpToDateWithRemote(repo = '', branch = 'master'):
    utility.printMsg( "Ensuring local branch %s in %s is up to date with origin" % (branch, repo))
    with utility.cd(repo):
        # attempt to fetch the requested branch
        try:
            git.fetch("origin", "%s:%s" % (branch, branch))
        except:
            # the branch may not exist, but this is ok
            pass
        
        if git.currentBranch() == branch:
            return

        if not git.hasBranch(branch):
            # switch to corresponding public branch if the branch does not exist
            public = grapeConfig.workspaceConfig().getPublicBranchFor(branch)
            # figure out if this is a submodule
            relpath = os.path.relpath(repo, utility.workspaceDir())
            relpath = relpath.replace('\\',"/")
            with utility.cd(utility.workspaceDir()):
                # if this is a submodule, get the appropriate public mapping
                if relpath in git.getAllSubmoduleURLMap().keys():
                    public = grapeConfig.workspaceConfig().getMapping("workspace", "submodulepublicmappings")[public]
            utility.printMsg("Branch %s does not exist in %s, switching to %s and detaching" % (branch, repo, public))
            git.checkout(public)
            git.pull("origin %s" % (public))
            git.checkout("--detach HEAD")
コード例 #4
0
 def readWorkspaceUserConfigFile(self):
     try:
         self.read(
             os.path.join(utility.workspaceDir(), ".git",
                          ".grapeuserconfig"))
     except IOError:
         pass
コード例 #5
0
ファイル: updateLocal.py プロジェクト: LLNL/GRAPE
    def execute(self, args):
        wsDir = args["--wd"] if args["--wd"] else utility.workspaceDir()
        wsDir = os.path.abspath(wsDir)
        os.chdir(wsDir)
        cwd = os.getcwd()

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

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

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

        return True
コード例 #6
0
ファイル: resumable.py プロジェクト: LLNL/GRAPE
 def _resume(self, args, deleteProgressFile=True):
     try:
         self._readProgressFile()
     except IOError:
         # give the workspace level progress file a shot
         try:
             self.progressFile = os.path.join(utility.workspaceDir(),
                                              ".git", "grapeProgress")
             self._readProgressFile()
         except IOError as e:
             try:
                 # look for it at the home directory level
                 self.progressFile = os.path.join(os.path.expanduser('~'),
                                                  ".grapeProgress")
                 self._readProgressFile()
             except:
                 utility.printMsg(
                     "No progress file found to continue from. Please enter a command without the "
                     "--continue option. ")
                 raise e
     newArgs = self.progress["args"]
     #overwrite args with the loaded args
     for key in newArgs.keys():
         args[key] = newArgs[key]
     #load the config
     grapeConfig.resetGrapeConfig(self.progress["config"])
     if deleteProgressFile:
         self._removeProgressFile()
コード例 #7
0
ファイル: commit.py プロジェクト: LLNL/GRAPE
    def execute(self, args):
        commitargs = ""
        if args['-a']:
            commitargs = commitargs + " -a"
        elif args["<filetree>"]:
            commitargs = commitargs + " %s" % args["<filetree>"]
        if not args['-m']:
            args["-m"] = utility.userInput("Please enter commit message:")
        commitargs += " -m \"%s\"" % args["-m"]

        wsDir = utility.workspaceDir()
        os.chdir(wsDir)

        submodules = [(True, x) for x in git.getModifiedSubmodules()]
        subprojects = [(False, x) for x in grapeConfig.GrapeConfigParser.
                       getAllActiveNestedSubprojectPrefixes()]
        for stage, sub in submodules + subprojects:
            os.chdir(os.path.join(wsDir, sub))
            subStatus = git.status("--porcelain -uno")
            if subStatus:
                utility.printMsg("Committing in %s..." % sub)
                if self.commit(commitargs, sub) and stage:
                    os.chdir(wsDir)
                    utility.printMsg("Staging committed change in %s..." % sub)
                    git.add(sub)

        os.chdir(wsDir)
        if submodules or git.status("--porcelain"):
            utility.printMsg("Performing commit in outer level project...")
            self.commit(commitargs, wsDir)
        return True
コード例 #8
0
ファイル: resumable.py プロジェクト: LLNL/GRAPE
 def _resume(self, args, deleteProgressFile=True):
     try:
         self._readProgressFile()
     except IOError:
         # give the workspace level progress file a shot
         try:
             self.progressFile = os.path.join(utility.workspaceDir(), ".git", "grapeProgress")
             self._readProgressFile()
         except IOError as e:
             try:
                 # look for it at the home directory level
                 self.progressFile = os.path.join(os.path.expanduser('~'), ".grapeProgress")
                 self._readProgressFile()
             except:
                 utility.printMsg("No progress file found to continue from. Please enter a command without the "
                                  "--continue option. ")
                 raise e
     newArgs = self.progress["args"]
     #overwrite args with the loaded args
     for key in newArgs.keys():
         args[key] = newArgs[key]
     #load the config
     grapeConfig.resetGrapeConfig(self.progress["config"])
     if deleteProgressFile:
         self._removeProgressFile()
コード例 #9
0
ファイル: updateLocal.py プロジェクト: LLNL/GRAPE
 def execute(self, args):
     wsDir = args["--wd"] if args["--wd"] else utility.workspaceDir()
     wsDir = os.path.abspath(wsDir)
     os.chdir(wsDir)
     cwd = os.getcwd()
     
     config = grapeConfig.grapeConfig()
     recurseSubmodules = config.getboolean("workspace", "manageSubmodules") or args["--recurse"]
     skipSubmodules = args["--noRecurse"]
     
     
     recurseNestedSubprojects = not args["--noRecurse"] or args["--recurseSubprojects"]
     publicBranches = [x.strip() for x in args["--public"].split()]
     launchers = []
     for branch in publicBranches:
         launchers.append(utility.MultiRepoCommandLauncher(fetchLocal,  
                                         runInSubmodules=recurseSubmodules, 
                                         runInSubprojects=recurseNestedSubprojects, 
                                         branch=branch, 
                                         listOfRepoBranchArgTuples=None, 
                                         skipSubmodules=skipSubmodules, outer=wsDir))
         
     if len(launchers):
         launcher = launchers[0]
         for l in launchers[1:]:
             launcher.MergeLaunchSet(l)
         launcher.collapseLaunchSetBranches()
         launcher.launchFromWorkspaceDir(handleMRE=fetchLocalHandler)
         
     return True
コード例 #10
0
ファイル: Atlassian.py プロジェクト: LLNL/GRAPE
 def repoFromWorkspaceRepoPath(self, path, isSubmodule=False, isNested=False, topLevelRepo=None, topLevelProject=None):
     config = grapeConfig.grapeConfig()
     if isNested:
         proj = os.path.split(path)[1]
         nestedProjectURL = config.get("nested-%s" % proj , "url")
         url = utility.parseSubprojectRemoteURL(nestedProjectURL)
         urlTokens = url.split('/')
         proj = urlTokens[-2]
         repo_name = urlTokens[-1]       
         # strip off the git extension
         repo_name = '.'.join(repo_name.split('.')[:-1])
     elif isSubmodule:
         fullpath = os.path.abspath(path)
         wsdir = utility.workspaceDir() + os.path.sep
         proj = fullpath.split(wsdir)[1].replace("\\","/")
         url =  git.config("--get submodule.%s.url" % proj).split('/')
         proj = url[-2]
         repo_name = url[-1]
 
         # strip off the .git extension
         repo_name = '.'.join(repo_name.split('.')[:-1])   
     else:
         if topLevelRepo is None:
             topLevelRepo = config.get("repo", "name")
         if topLevelProject is None:
             topLevelProject = config.get("project", "name")
             
         repo_name = topLevelRepo
         proj = topLevelProject
         
     repo = self.project(proj).repo(repo_name)
     return repo        
コード例 #11
0
ファイル: grapeGit.py プロジェクト: LLNL/GRAPE
def getModifiedSubmodules(branch1="", branch2=""):
    cwd = os.getcwd()
    wsDir = utility.workspaceDir()
    os.chdir(wsDir)
    submodules = getAllSubmodules()
    # if there are no submodules, then return the empty list
    if len(submodules) == 0 or (len(submodules) == 1 and not submodules[0]):
        return []
    submodulesString = ' '.join(submodules)
    try:

        modifiedSubmodules = diff(
            "--name-only %s %s -- %s" %
            (branch1, branch2, submodulesString)).split('\n')
    except GrapeGitError as e:
        if "bad revision" in e.gitOutput:
            utility.printMsg(
                "getModifiedSubmodules: requested difference between one or more branches that do not exist. Assuming no modifications."
            )
            return []
    if len(modifiedSubmodules) == 1 and not modifiedSubmodules[0]:
        return []

    # make sure everything in modifiedSubmodules is in the original list of submodules
    # (this can not be the case if the module existed as a regular directory / subtree in the other branch,
    #  in which case the diff command will list the contents of the directory as opposed to just the submodule)
    verifiedSubmodules = []
    for s in modifiedSubmodules:
        if s in submodules:
            verifiedSubmodules.append(s)

    os.chdir(cwd)
    return verifiedSubmodules
コード例 #12
0
ファイル: commit.py プロジェクト: LLNL/GRAPE
    def execute(self, args):
        commitargs = ""
        if args['-a']: 
            commitargs = commitargs +  " -a"
        elif args["<filetree>"]:
            commitargs = commitargs + " %s"% args["<filetree>"]
        if not args['-m']:
            args["-m"] = utility.userInput("Please enter commit message:")
        commitargs += " -m \"%s\"" % args["-m"]
         
        wsDir = utility.workspaceDir()
        os.chdir(wsDir)

        submodules = [(True, x ) for x in git.getModifiedSubmodules()]
        subprojects = [(False, x) for x in grapeConfig.GrapeConfigParser.getAllActiveNestedSubprojectPrefixes()]
        for stage,sub in submodules +  subprojects:
            os.chdir(os.path.join(wsDir,sub))
            subStatus = git.status("--porcelain -uno")
            if subStatus:
                utility.printMsg("Committing in %s..." % sub)
                if self.commit(commitargs, sub) and stage: 
                    os.chdir(wsDir)
                    utility.printMsg("Staging committed change in %s..." % sub)
                    git.add(sub)
        
        os.chdir(wsDir)
        if submodules or git.status("--porcelain"): 
            utility.printMsg("Performing commit in outer level project...")
            self.commit(commitargs, wsDir)
        return True
コード例 #13
0
ファイル: status.py プロジェクト: 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
コード例 #14
0
 def getAllActiveNestedSubprojectPrefixes(workspaceDir=None):
     config = grapeConfig() if (workspaceDir is None
                                or workspaceDir is utility.workspaceDir()
                                ) else GrapeConfigParser(workspaceDir)
     return [
         config.get("nested-%s" % name, "prefix") for name in
         GrapeConfigParser.getAllActiveNestedSubprojects(workspaceDir)
     ]
コード例 #15
0
ファイル: hooks.py プロジェクト: LLNL/GRAPE
 def execute(self, args):
     workspaceDir = utility.workspaceDir()
     utility.printMsg("Installing hooks in %s." % workspaceDir)
     self.installHooksInRepo(workspaceDir, args)
     if not args["--noRecurse"]:
         for sub in utility.getActiveSubprojects():
             utility.printMsg("Installing hooks in %s." % sub)
             self.installHooksInRepo(os.path.join(workspaceDir, sub), args)
     return True
コード例 #16
0
 def execute(self, args):
     workspaceDir = utility.workspaceDir()
     utility.printMsg("Installing hooks in %s." % workspaceDir)
     self.installHooksInRepo(workspaceDir, args)
     if not args["--noRecurse"]:
         for sub in utility.getActiveSubprojects():
             utility.printMsg("Installing hooks in %s." % sub)
             self.installHooksInRepo(os.path.join(workspaceDir, sub), args)
     return True
コード例 #17
0
ファイル: grapeGit.py プロジェクト: LLNL/GRAPE
def getActiveSubmodules():
    cwd = os.getcwd()
    wsDir = utility.workspaceDir()
    os.chdir(wsDir)
    if os.name == "nt":
        submoduleList = submodule("foreach --quiet \"echo $path\"")
    else:
        submoduleList = submodule("foreach --quiet \"echo \$path\"")
    submoduleList = [] if not submoduleList else submoduleList.split('\n')
    submoduleList = [x.strip() for x in submoduleList]
    os.chdir(cwd)
    return submoduleList
コード例 #18
0
ファイル: grapeConfig.py プロジェクト: LLNL/GRAPE
def read(additionalFileNames=None):
    # initialize a ConfigParser with all defaults needed by the grapeMenu
    if additionalFileNames is None:
        additionalFileNames = []
    defaultFiles = []
    if os.name == "nt":
        defaultFiles.append(os.path.join(os.environ["USERPROFILE"], ".grapeconfig"))
    else:
        defaultFiles.append(os.path.join(os.environ["HOME"], ".grapeconfig"))
    globalconfigfile = defaultFiles[0]
    try:
        defaultFiles.append(os.path.join(utility.workspaceDir(warnIfNotFound=False, throwIfNotFound=False), ".grapeconfig"))
    except:
        pass
    try:
        defaultFiles.append(os.path.join(utility.workspaceDir(warnIfNotFound=False, throwIfNotFound=False), ".git", ".grapeuserconfig"))
    except:
        pass

    files = defaultFiles + additionalFileNames
    readFiles = grapeConfig().read(files)
    if len(readFiles) == 0:
        utility.writeDefaultConfig(globalconfigfile)
コード例 #19
0
ファイル: push.py プロジェクト: LLNL/GRAPE
    def execute(self, args):
        baseDir = utility.workspaceDir()

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

        submodules = git.getActiveSubmodules()

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

        os.chdir(cwd)
        utility.printMsg("Pushed current branch to origin")
        return False not in retvals
コード例 #20
0
ファイル: version.py プロジェクト: LLNL/GRAPE
 def tickVersion(self, args):
     config = grapeConfig.grapeConfig()
     fileName = config.get("versioning", "file")
     with open(fileName) as f:
         slots = self.readVersion(f, args)
         self.ver = self.slotsToString(args, slots)
         
     if not args["--notick"]:
         slot = args["--slot"]
         if not slot:
             slotMappings = config.getMapping("versioning", "branchSlotMappings")
             if args["--public"]:
                 publicBranch = args["--public"]
             else:
                 publicBranch = config.getPublicBranchFor(git.currentBranch())
             slot = int(slotMappings[publicBranch])
         else:
             slot = int(slot)
         if args["--minor"]:
             slot = 2
         if args["--major"]:
             slot = 1
         # extend the version number if slot comes in too large.
         while len(slots) < slot:
             slots.append(0)
         slots[slot - 1] += 1
         while slot < len(slots):
             slots[slot] = 0
             slot += 1
         # write the new version number to the version file. 
         with open(fileName, 'r+') as f:
             self.ver = self.writeVersion(f, slots, args)
         self.stageVersionFile(fileName)
         if not args["--nocommit"]:
             git.commit("-m \"GRAPE: ticked version to %s\"" % self.ver)
             
     if (not args["--nocommit"]) or args["--tag"]:
         self.tagVersion(self.ver, args)
         if args["--tagNested"]:
             cwd = os.getcwd()
             wsDir = utility.workspaceDir()
             for subproject in grapeConfig.GrapeConfigParser.getAllActiveNestedSubprojectPrefixes():
                 os.chdir(os.path.join(wsDir, subproject))
                 self.tagVersion(self.ver, args)
             os.chdir(cwd)
コード例 #21
0
ファイル: grapeConfig.py プロジェクト: LLNL/GRAPE
    def getAllModifiedNestedSubprojects(since, now="HEAD", workspaceDir=None): 
        config = grapeConfig() if workspaceDir is None else GrapeConfigParser(workspaceDir) 
        publicBranches = config.getPublicBranchList()
        if workspaceDir is None:
            workspaceDir = utility.workspaceDir()
        active = GrapeConfigParser.getAllActiveNestedSubprojects(workspaceDir)
        modified = []
        cwd = os.getcwd()
        for repo in active:
            prefix = config.get("nested-%s" % repo, "prefix")
            os.chdir(os.path.join(workspaceDir,prefix))
            configOption.Config.ensurePublicBranchesExist(config,os.path.join(workspaceDir,prefix), publicBranches)

            if git.log("--oneline %s..%s" % (since, now)): 
                modified.append(repo)

        os.chdir(cwd)
        return modified
コード例 #22
0
ファイル: updateSubproject.py プロジェクト: LLNL/GRAPE
 def updateSubtree(self, args):
     clean = utility.isWorkspaceClean()
     os.chdir(utility.workspaceDir())
     if not clean:
         utility.printMsg("git-subtree requires a clean working tree before attempting a subtree update")
         return False
     name = args["--name"]
     branch = args["--branch"]
     config = grapeConfig.grapeConfig()
     subtreePrefix = config.get("subtree-%s" % name, "prefix")
     subtreeRemote = config.get("subtree-%s" % name, "remote")
     fullURL = utility.parseSubprojectRemoteURL(subtreeRemote)
     doSquash = config.get("subtrees", "mergePolicy").strip().lower() == "squash"
     squashArg = "--squash" if doSquash else ""
     git.subtree("pull --prefix %s %s %s %s" %
                 (subtreePrefix, fullURL, branch, squashArg))
     
     return True
コード例 #23
0
ファイル: push.py プロジェクト: LLNL/GRAPE
    def execute(self, args):
        baseDir = utility.workspaceDir()

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


            
        submodules = git.getActiveSubmodules()
        
        retvals = utility.MultiRepoCommandLauncher(push).launchFromWorkspaceDir(handleMRE=handlePushMRE)
        
        os.chdir(cwd)        
        utility.printMsg("Pushed current branch to origin")
        return False not in retvals
コード例 #24
0
    def getAllModifiedNestedSubprojects(since, now="HEAD", workspaceDir=None):
        config = grapeConfig() if workspaceDir is None else GrapeConfigParser(
            workspaceDir)
        publicBranches = config.getPublicBranchList()
        if workspaceDir is None:
            workspaceDir = utility.workspaceDir()
        active = GrapeConfigParser.getAllActiveNestedSubprojects(workspaceDir)
        modified = []
        cwd = os.getcwd()
        for repo in active:
            prefix = config.get("nested-%s" % repo, "prefix")
            os.chdir(os.path.join(workspaceDir, prefix))
            configOption.Config.ensurePublicBranchesExist(
                config, os.path.join(workspaceDir, prefix), publicBranches)

            if git.log("--oneline %s..%s" % (since, now)):
                modified.append(repo)

        os.chdir(cwd)
        return modified
コード例 #25
0
ファイル: status.py プロジェクト: LLNL/GRAPE
    def checkForLocalPublicBranches(self, args):
        publicBranchesExist = True
        # Check that all public branches exist locally.
        cfg = config.grapeConfig.grapeConfig()
        publicBranches = cfg.getPublicBranchList()
        missingBranches = config.Config.checkIfPublicBranchesExist(
            cfg, utility.workspaceDir(), publicBranches)

        if (len(missingBranches) > 0):
            for mb in missingBranches:
                utility.printMsg(
                    "Repository is missing public branch %s, attempting to fetch it now..."
                    % mb)
                try:
                    git.fetch("origin %s:%s" % (mb, mb))
                    utility.printMsg("%s added as a local branch" % mb)
                except git.GrapeGitError as e:
                    print e.gitOutput
                    publicBranchesExist = False
        return publicBranchesExist
コード例 #26
0
ファイル: addSubproject.py プロジェクト: LLNL/GRAPE
 def activateNestedSubproject(subprojectName, userconfig):
     wsDir = utility.workspaceDir()
     config = grapeConfig.grapeConfig()
     prefix = config.get("nested-%s" % subprojectName, "prefix")
     url = config.get("nested-%s" % subprojectName, "url")
     fullurl = utility.parseSubprojectRemoteURL(url)
     section = "nested-%s" % subprojectName
     userconfig.ensureSection(section)
     currentlyActive = userconfig.getboolean(section, "active")
     if not currentlyActive:
         destDir = os.path.join(wsDir, prefix)
         if not (os.path.isdir(destDir) and os.listdir(destDir)):
             git.clone("%s %s" % (fullurl, prefix))
         elif '.git' in os.listdir(destDir):
             pass
         else:
             utility.printMsg("WARNING: inactive nested subproject %s has files but is not a git repo" % prefix)
             return False
     userconfig.set(section, "active", "True")
     grapeConfig.writeConfig(userconfig, os.path.join(wsDir, ".git", ".grapeuserconfig"))
     return True
コード例 #27
0
ファイル: status.py プロジェクト: LLNL/GRAPE
    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
コード例 #28
0
ファイル: status.py プロジェクト: LLNL/GRAPE
    def execute(self, args):

        with utility.cd(utility.workspaceDir()):

            if not args["--checkWSOnly"]:
                self.printStatus(args)

            # Sanity check workspace layout
            publicBranchesExist = self.checkForLocalPublicBranches(args)

            # Check that submodule branching is consistent
            consistentBranchState = self.checkForConsistentWorkspaceBranches(
                args)

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

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

            repo_name = topLevelRepo
            proj = topLevelProject

        repo = self.project(proj).repo(repo_name)
        return repo
コード例 #30
0
 def activateNestedSubproject(subprojectName, userconfig):
     wsDir = utility.workspaceDir()
     config = grapeConfig.grapeConfig()
     prefix = config.get("nested-%s" % subprojectName, "prefix")
     url = config.get("nested-%s" % subprojectName, "url")
     fullurl = utility.parseSubprojectRemoteURL(url)
     section = "nested-%s" % subprojectName
     userconfig.ensureSection(section)
     currentlyActive = userconfig.getboolean(section, "active")
     if not currentlyActive:
         destDir = os.path.join(wsDir, prefix)
         if not (os.path.isdir(destDir) and os.listdir(destDir)):
             git.clone("%s %s" % (fullurl, prefix))
         elif '.git' in os.listdir(destDir):
             pass
         else:
             utility.printMsg(
                 "WARNING: inactive nested subproject %s has files but is not a git repo"
                 % prefix)
             return False
     userconfig.set(section, "active", "True")
     grapeConfig.writeConfig(
         userconfig, os.path.join(wsDir, ".git", ".grapeuserconfig"))
     return True
コード例 #31
0
ファイル: mergeDevelop.py プロジェクト: LLNL/GRAPE
    def execute(self, args):
        if not "<<cmd>>" in args:
            args["<<cmd>>"] = "md"
        branch = args["--public"]
        if not branch:
            currentBranch = git.currentBranch()
            branch = grapeConfig.grapeConfig().getPublicBranchFor(
                git.currentBranch())
            if not branch:
                utility.printMsg(
                    "ERROR: public branches must be configured for grape md to work."
                )
        args["--public"] = branch
        # determine whether to merge in subprojects that have changed
        try:
            submodules = self.progress["submodules"]
        except KeyError:
            modifiedSubmodules = git.getModifiedSubmodules(
                branch, git.currentBranch())
            activeSubmodules = git.getActiveSubmodules()
            submodules = [
                sub for sub in modifiedSubmodules if sub in activeSubmodules
            ]

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

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

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

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

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

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

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

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

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

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

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

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

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

        return True
コード例 #32
0
ファイル: config.py プロジェクト: LLNL/GRAPE
    def execute(self, args):
        base = git.baseDir()
        if base == "":
            return False
        dotGit = git.gitDir()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        self.ensurePublicBranchesExist(config, wsDir, publicBranches)

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

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

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

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

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

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

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

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



                
        if conflictedFiles:
            self.progress["stopPoint"] = "resolve conflicts"
            self.progress["cwd"] = cwd
            self.dumpProgress(args, "GRAPE: Outer level merge generated conflicts. Please resolve using git mergetool "
                                    "and then \n continue by calling 'grape md --continue' .")
            return False
        else:
            grapeMenu.menu().applyMenuChoice("runHook", ["post-merge", '0', "--noExit"])
            
        # ensure all submodules are currently present in WS if all submodules were present at the beginning of merge
        if self.progress["allActive"]:
            activeSubmodulesCheck1 = git.getActiveSubmodules()
            if (set(activeSubmodulesCheck0) != set(activeSubmodulesCheck1)):
                utility.printMsg("Updating new submodules using grape uv --allSubmodules")
                grapeMenu.menu().applyMenuChoice("uv", ["--allSubmodules", "--skipNestedSubprojects"])
        
        return True
コード例 #34
0
ファイル: walkthrough.py プロジェクト: LLNL/GRAPE
   def initFiles(self, index):
      self.filelist.delete(0,Tk.END)
      dir = self.projects[index]
      type = self.projtype[index]

      self.diffbranchA = self.branchA
      self.diffbranchB = self.branchB

      if type.endswith("Submodule"):
         self.diffbranchA = self.getSubBranch(self.branchA) 
         self.diffbranchB = self.getSubBranch(self.branchB) 

      if type.startswith("Inactive"):
         remotels = git.gitcmd("ls-remote")
         self.filelist.insert(Tk.END, "<Unable to diff>")
         self.filenames.append("")
      else:
         # TODO handle non-existent branches on subprojects
         os.chdir(os.path.join(utility.workspaceDir(), dir))

         self.diffbranchA = self.getBranch(self.diffbranchA)
         self.diffbranchB = self.getBranch(self.diffbranchB)
         self.filenames = []
         diffoutput = git.diff("--name-status --find-renames --find-copies %s %s ." % (self.diffargs, self.diffBranchSpec(self.diffbranchA, self.diffbranchB))).splitlines()
         statusdict = { "A":"<Only in B>",
                        "C":"<File copied>",
                        "D":"<Only in A>", 
                        "M":"",
                        "R":"<File renamed>",
                        "T":"<File type changed>", 
                        "U":"<File unmerged>", 
                        "X":"<Unknown status>" }
            
         if len(diffoutput) > 0:
            for line in diffoutput:
               [status, file] = line.split(None, 1) 
               statusstring = statusdict[status[0]]
               if status[0] == 'R' or status[0] == 'C':
                  files = file.split(None,1)
                  if status[1:] == '100':
                     filename = ""
                  else:
                     statusstring += "*"
                  filename = files
                  filedisplay = " -> ".join(files)
               else:
                  filedisplay = file
                  filename = file
               if type == "Outer":
                  if filename in self.submodules:
                     continue
                  inSubtree = False
                  for subtree in self.subtrees:
                     if filename.startswith(subtree+os.path.sep):
                        inSubtree = True
                        break
                  if inSubtree:
                     continue
                   
               self.filelist.insert(Tk.END, "%s %s" % (filedisplay, statusstring))
               self.filenames.append(filename)
         if len(self.filelist) == 0:
            self.filelist.insert(Tk.END, "<No differences>")
            self.filenames.append("")

      if self.branchA == "--cached":
         self.diffAnnotationA.set("%s <cached>" % self.diffbranchB)
         self.diffAnnotationB.set("<staged>")
      elif self.branchB == "--":
         self.diffAnnotationA.set(self.diffbranchA)
         self.diffAnnotationB.set("<workspace>")
      else:
         self.diffAnnotationA.set(self.diffbranchA)
         self.diffAnnotationB.set(self.diffbranchB)
コード例 #35
0
ファイル: walkthrough.py プロジェクト: LLNL/GRAPE
   def __init__(self, master, **kwargs):
      validDiffTools = [ 'kdiff3', 'kompare', 'tkdiff', 'meld', 'xxdiff', 'emerge', 'gvimdiff', 'ecmerge', 'diffuse', 'opendiff', 'p4merge', 'araxis' ]

      # Configurable parameters
      difftool = kwargs.get('difftool', None)
      if difftool == None: 
         try:
            difftool = git.config("--get diff.tool")
         except:
            pass

         if difftool == "vimdiff":
            utility.printMsg("Using gvimdiff instead of vimdiff.")
            difftool = "gvimdiff"

      if difftool not in validDiffTools:
         utility.printMsg("Using default difftool.")
         self.difftool = "default difftool"
         self.difftoolarg = ""
      else:
         self.difftool = difftool
         self.difftoolarg = "-t %s" % difftool

      self.diffargs = kwargs.get('diffargs', "")
      self.noFetch = kwargs.get('noFetch', False)
      self.branchA = self.getBranch(kwargs.get('branchA', ""))
      self.branchB = self.getBranch(kwargs.get('branchB', ""))
      self.diffbranchA = ""
      self.diffAnnotationA = Tk.StringVar()
      self.diffAnnotationA.set(self.branchA)
      self.diffbranchB = ""
      self.diffAnnotationB = Tk.StringVar()
      self.diffAnnotationB.set(self.branchB)
      self.showUnchanged = kwargs.get('showUnchanged', False)
      self.doMergeDiff = kwargs.get('doMergeDiff', True)

      # Branch specification pane
      self.branchpane = Tk.Frame(master)
      self.branchlabelA= Tk.Label(self.branchpane, text="Branch A:")
      self.branchnameA= Tk.Label(self.branchpane, textvariable=self.diffAnnotationA)
      self.branchlabelB= Tk.Label(self.branchpane, text="Branch B:")
      self.branchnameB= Tk.Label(self.branchpane, textvariable=self.diffAnnotationB)
      self.branchlabelA.pack(side=Tk.LEFT, fill=Tk.Y)
      self.branchnameA.pack(side=Tk.LEFT, fill=Tk.Y)
      self.branchlabelB.pack(side=Tk.LEFT, fill=Tk.Y)
      self.branchnameB.pack(side=Tk.LEFT, fill=Tk.Y)
      self.branchpane.pack(side=Tk.TOP)

      ProjectManager.__init__(self, master, **kwargs)

      # If we are diffing against the workspace, get the status of the workspace
      # and save the set of changed files in the outer project (including submodules).
      changedFiles = None
      
      if self.showToplevel or len(self.submodules) > 0:
         utility.printMsg("Gathering status in outer level project...")
         changedFiles = git.diff("--name-only %s" % self.diffBranchSpec(self.branchA, self.branchB)).split()
         utility.printMsg("Done.")

      # Get the url mapping for all submodules
      if len(self.submodules) > 0:
         submoduleURLMap = git.getAllSubmoduleURLMap()

      utility.printMsg("Examining projects...")

      os.chdir(utility.workspaceDir())
      # Loop over list backwards so we can delete entries
      for index in reversed(range(self.numprojects)):
         dir = self.projects[index]
         type = self.projtype[index]
         haveDiff = False
         if type == "Outer":
            # Outer is always last in the reverse iteration,
            # so all submodule entries should have already been removed.
            haveDiff = len(changedFiles) > 0
         elif type.endswith("Submodule"):
            if not type.startswith("Inactive") or self.showInactive:
               if dir in changedFiles:
                  haveDiff = True
                  changedFiles.remove(dir)
         elif type.endswith("Nested"):
            if type.startswith("Inactive"):
               # It might not be worth the time to check for differences in inactive subprojects
               #TODO
               pass
            else:
               os.chdir(os.path.join(utility.workspaceDir(), dir))
               utility.printMsg("Gathering status in %s..." % dir)
               try:
                  haveDiff = len(git.diff("--name-only %s" % self.diffBranchSpec(self.branchA, self.branchB)).split()) > 0
               except git.GrapeGitError as e:
                  if "unknown revision or path not in the working tree" in e.gitOutput:
                     utility.printMsg("Could not diff %s.  Branch may not exist in %s." % (self.diffBranchSpec(self.branchA, self.branchB), dir))
                  else:
                     raise
                  haveDiff = False
               utility.printMsg("Done.")
               os.chdir(utility.workspaceDir())
            pass
         elif type.endswith("Subtree"):
            nestedFiles = git.diff("--name-only %s %s" % (self.diffBranchSpec(self.branchA, self.branchB), dir)).split()
            if len(nestedFiles) > 0:
               haveDiff = True
               for changedFile in changedFiles:
                  if changedFile.startswith(dir+os.path.sep):
                     changedFiles.remove(changedFile)

         if haveDiff:
            self.setProjectStatus(index, "*")
         elif self.showUnchanged:
            self.setProjectStatus(index, " ")
         else:
            self.removeProjectEntry(index)

      utility.printMsg("Done.")

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

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

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

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

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

        return True
コード例 #37
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
コード例 #38
0
 def readWorkspaceGrapeConfigFile(self):
     self.read(os.path.join(utility.workspaceDir(), ".grapeconfig"))
コード例 #39
0
    def execute(self, args):
        if TkinterImportError:
            utility.printMsg(
                "grape w requires Tkinter.\n  The following error was raised during the import:\n\n%s\n"
                % TkinterImportError)
            return True
        config = grapeConfig.grapeConfig()
        difftool = args["--difftool"]
        height = args["--height"]
        width = args["--width"]
        doMergeDiff = True
        if args["--rawDiff"]:
            doMergeDiff = False
        elif args["--mergeDiff"]:
            # This is already the default
            doMergeDiff = True

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

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

        b2 = args["<b2>"]

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

        diffargs = ""

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

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

        root.mainloop()

        os.chdir(cwd)

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

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

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

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

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

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

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

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

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

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

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

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

        os.chdir(workspaceDir)

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

        global _skipBranchCreation
        global _createNewBranch
        _skipBranchCreation = False
        _createNewBranch = False
        return True
コード例 #42
0
ファイル: updateView.py プロジェクト: LLNL/GRAPE
    def execute(self, args):
        sync = args["--sync"].lower().strip()
        sync = sync == "true" or sync == "yes"
        args["--sync"] = sync
        config = grapeConfig.grapeConfig()
        origwd = os.getcwd()
        wsDir = utility.workspaceDir()
        os.chdir(wsDir)
        base = git.baseDir()
        if base == "":
            return False
        hasSubmodules = len(git.getAllSubmodules()) > 0 and not args["--skipSubmodules"]
        includedSubmodules = {}
        includedNestedSubprojectPrefixes = {}

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

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

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

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

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

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

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

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

        os.chdir(origwd)

        return True
コード例 #43
0
ファイル: config.py プロジェクト: LLNL/GRAPE
    def execute(self,args):
        base = git.baseDir()
        if base == "":
            return False
        dotGit = git.gitDir()
         
        utility.printMsg("Optimizing git performance on slow file systems...")
        #runs file system intensive tasks such as git status and git commit
        # in parallel (important for NFS systems such as LC)
        git.config("core.preloadindex","true")

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

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

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

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

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

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

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

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

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

        # install hooks here and in all submodules
        utility.printMsg("Installing hooks in all repos...")
        cwd = git.baseDir()
        grapeMenu.menu().applyMenuChoice("installHooks")
        
        #  ensure all public branches are available in all repos
        submodules = git.getActiveSubmodules()
        config = grapeConfig.grapeConfig()
        publicBranches = config.getPublicBranchList()
        submodulePublicBranches = set(config.getMapping('workspace', 'submoduleTopicPrefixMappings').values())
        for sub in submodules:
            self.ensurePublicBranchesExist(grapeConfig.grapeRepoConfig(sub),sub, submodulePublicBranches)
        
        # reset config to the workspace grapeconfig, use that one for all nested projects' public branches.
        wsDir = utility.workspaceDir()
        config = grapeConfig.grapeRepoConfig(wsDir)    
        for proj in grapeConfig.GrapeConfigParser.getAllActiveNestedSubprojectPrefixes():
            self.ensurePublicBranchesExist(config, os.path.join(wsDir,proj), publicBranches)
        
        self.ensurePublicBranchesExist(config, wsDir, publicBranches)
            
        return True
コード例 #44
0
ファイル: grapeConfig.py プロジェクト: LLNL/GRAPE
 def getAllActiveNestedSubprojectPrefixes(workspaceDir = None): 
     config = grapeConfig() if (workspaceDir is None or workspaceDir is utility.workspaceDir()) else GrapeConfigParser(workspaceDir) 
     return [config.get("nested-%s" % name, "prefix") for name in GrapeConfigParser.getAllActiveNestedSubprojects(workspaceDir)]
コード例 #45
0
ファイル: review.py プロジェクト: LLNL/GRAPE
    def execute(self, args):
        """
        A fair chunk of this stuff relies on stashy's wrapping of the STASH REST API, which is posted at
        https://developer.atlassian.com/static/rest/stash/2.12.1/stash-rest.html
        """
        config = grapeConfig.grapeConfig()
        name = args["--user"]
        if not name:
            name = utility.getUserName()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            utility.printMsg("Request generated/updated:\n\n%s" % request)
        return True
コード例 #46
0
    def initFiles(self, index):
        self.filelist.delete(0, Tk.END)
        dir = self.projects[index]
        type = self.projtype[index]

        self.diffbranchA = self.branchA
        self.diffbranchB = self.branchB

        if type.endswith("Submodule"):
            self.diffbranchA = self.getSubBranch(self.branchA)
            self.diffbranchB = self.getSubBranch(self.branchB)

        if type.startswith("Inactive"):
            remotels = git.gitcmd("ls-remote")
            self.filelist.insert(Tk.END, "<Unable to diff>")
            self.filenames.append("")
        else:
            # TODO handle non-existent branches on subprojects
            os.chdir(os.path.join(utility.workspaceDir(), dir))

            self.diffbranchA = self.getBranch(self.diffbranchA)
            self.diffbranchB = self.getBranch(self.diffbranchB)
            self.filenames = []
            diffoutput = git.diff(
                "--name-status --find-renames --find-copies %s %s ." %
                (self.diffargs,
                 self.diffBranchSpec(self.diffbranchA,
                                     self.diffbranchB))).splitlines()
            statusdict = {
                "A": "<Only in B>",
                "C": "<File copied>",
                "D": "<Only in A>",
                "M": "",
                "R": "<File renamed>",
                "T": "<File type changed>",
                "U": "<File unmerged>",
                "X": "<Unknown status>"
            }

            if len(diffoutput) > 0:
                for line in diffoutput:
                    [status, file] = line.split(None, 1)
                    statusstring = statusdict[status[0]]
                    if status[0] == 'R' or status[0] == 'C':
                        files = file.split(None, 1)
                        if status[1:] == '100':
                            filename = ""
                        else:
                            statusstring += "*"
                        filename = files
                        filedisplay = " -> ".join(files)
                    else:
                        filedisplay = file
                        filename = file
                    if type == "Outer":
                        if filename in self.submodules:
                            continue
                        inSubtree = False
                        for subtree in self.subtrees:
                            if filename.startswith(subtree + os.path.sep):
                                inSubtree = True
                                break
                        if inSubtree:
                            continue

                    self.filelist.insert(Tk.END,
                                         "%s %s" % (filedisplay, statusstring))
                    self.filenames.append(filename)
            if len(self.filelist) == 0:
                self.filelist.insert(Tk.END, "<No differences>")
                self.filenames.append("")

        if self.branchA == "--cached":
            self.diffAnnotationA.set("%s <cached>" % self.diffbranchB)
            self.diffAnnotationB.set("<staged>")
        elif self.branchB == "--":
            self.diffAnnotationA.set(self.diffbranchA)
            self.diffAnnotationB.set("<workspace>")
        else:
            self.diffAnnotationA.set(self.diffbranchA)
            self.diffAnnotationB.set(self.diffbranchB)
コード例 #47
0
ファイル: walkthrough.py プロジェクト: LLNL/GRAPE
    def execute(self,args):
        if TkinterImportError:
           utility.printMsg("grape w requires Tkinter.\n  The following error was raised during the import:\n\n%s\n" % TkinterImportError)
           return True
        config = grapeConfig.grapeConfig()
        difftool = args["--difftool"]
        height = args["--height"]
        width = args["--width"]
        doMergeDiff = True
        if args["--rawDiff"]:
           doMergeDiff = False
        elif args["--mergeDiff"]:
           # This is already the default
           doMergeDiff = True

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

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

        b2 = args["<b2>"]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            if updatedDescription != request.description(): 
                request = postPullRequest(repo, title, branch, target_branch, 
                                         updatedDescription, 
                                         reviewers, 
                                         args)
                       
            utility.printMsg("Request generated/updated:\n\n%s" % request)
        return True
コード例 #50
0
ファイル: checkout.py プロジェクト: LLNL/GRAPE
    def execute(self, args):
        sync = args["--sync"].lower().strip()
        sync = sync == "true" or sync == "yes"
        args["--sync"] = sync
        checkoutargs = ''
        branch = args["<branch>"]
        if args['-b']: 
            checkoutargs += " -b"

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

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

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

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

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


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

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

        os.chdir(workspaceDir)
        
        if sync:
            utility.printMsg("Switched to %s. Updating from remote...\n\t (use --sync=False or .grapeconfig.post-checkout.syncWithOrigin to change behavior.)" % branch)            
            if args["-b"]:
                grapeMenu.menu().applyMenuChoice("push")
            else:
                grapeMenu.menu().applyMenuChoice("pull")
        else:
            utility.printMsg("Switched to %s." % branch)
            
        global _skipBranchCreation
        global _createNewBranch
        _skipBranchCreation = False
        _createNewBranch = False        
        return True
コード例 #51
0
ファイル: grapeConfig.py プロジェクト: LLNL/GRAPE
 def readWorkspaceGrapeConfigFile(self):
     self.read(os.path.join(utility.workspaceDir(), ".grapeconfig"))
コード例 #52
0
    def __init__(self, master, **kwargs):
        validDiffTools = [
            'kdiff3', 'kompare', 'tkdiff', 'meld', 'xxdiff', 'emerge',
            'gvimdiff', 'ecmerge', 'diffuse', 'opendiff', 'p4merge', 'araxis'
        ]

        # Configurable parameters
        difftool = kwargs.get('difftool', None)
        if difftool == None:
            try:
                difftool = git.config("--get diff.tool")
            except:
                pass

            if difftool == "vimdiff":
                utility.printMsg("Using gvimdiff instead of vimdiff.")
                difftool = "gvimdiff"

        if difftool not in validDiffTools:
            utility.printMsg("Using default difftool.")
            self.difftool = "default difftool"
            self.difftoolarg = ""
        else:
            self.difftool = difftool
            self.difftoolarg = "-t %s" % difftool

        self.diffargs = kwargs.get('diffargs', "")
        self.noFetch = kwargs.get('noFetch', False)
        self.branchA = self.getBranch(kwargs.get('branchA', ""))
        self.branchB = self.getBranch(kwargs.get('branchB', ""))
        self.diffbranchA = ""
        self.diffAnnotationA = Tk.StringVar()
        self.diffAnnotationA.set(self.branchA)
        self.diffbranchB = ""
        self.diffAnnotationB = Tk.StringVar()
        self.diffAnnotationB.set(self.branchB)
        self.showUnchanged = kwargs.get('showUnchanged', False)
        self.doMergeDiff = kwargs.get('doMergeDiff', True)

        # Branch specification pane
        self.branchpane = Tk.Frame(master)
        self.branchlabelA = Tk.Label(self.branchpane, text="Branch A:")
        self.branchnameA = Tk.Label(self.branchpane,
                                    textvariable=self.diffAnnotationA)
        self.branchlabelB = Tk.Label(self.branchpane, text="Branch B:")
        self.branchnameB = Tk.Label(self.branchpane,
                                    textvariable=self.diffAnnotationB)
        self.branchlabelA.pack(side=Tk.LEFT, fill=Tk.Y)
        self.branchnameA.pack(side=Tk.LEFT, fill=Tk.Y)
        self.branchlabelB.pack(side=Tk.LEFT, fill=Tk.Y)
        self.branchnameB.pack(side=Tk.LEFT, fill=Tk.Y)
        self.branchpane.pack(side=Tk.TOP)

        ProjectManager.__init__(self, master, **kwargs)

        # If we are diffing against the workspace, get the status of the workspace
        # and save the set of changed files in the outer project (including submodules).
        changedFiles = None

        if self.showToplevel or len(self.submodules) > 0:
            utility.printMsg("Gathering status in outer level project...")
            changedFiles = git.diff(
                "--name-only %s" %
                self.diffBranchSpec(self.branchA, self.branchB)).split()
            utility.printMsg("Done.")

        # Get the url mapping for all submodules
        if len(self.submodules) > 0:
            submoduleURLMap = git.getAllSubmoduleURLMap()

        utility.printMsg("Examining projects...")

        os.chdir(utility.workspaceDir())
        # Loop over list backwards so we can delete entries
        for index in reversed(range(self.numprojects)):
            dir = self.projects[index]
            type = self.projtype[index]
            haveDiff = False
            if type == "Outer":
                # Outer is always last in the reverse iteration,
                # so all submodule entries should have already been removed.
                haveDiff = len(changedFiles) > 0
            elif type.endswith("Submodule"):
                if not type.startswith("Inactive") or self.showInactive:
                    if dir in changedFiles:
                        haveDiff = True
                        changedFiles.remove(dir)
            elif type.endswith("Nested"):
                if type.startswith("Inactive"):
                    # It might not be worth the time to check for differences in inactive subprojects
                    #TODO
                    pass
                else:
                    os.chdir(os.path.join(utility.workspaceDir(), dir))
                    utility.printMsg("Gathering status in %s..." % dir)
                    try:
                        haveDiff = len(
                            git.diff("--name-only %s" % self.diffBranchSpec(
                                self.branchA, self.branchB)).split()) > 0
                    except git.GrapeGitError as e:
                        if "unknown revision or path not in the working tree" in e.gitOutput:
                            utility.printMsg(
                                "Could not diff %s.  Branch may not exist in %s."
                                % (self.diffBranchSpec(self.branchA,
                                                       self.branchB), dir))
                        else:
                            raise
                        haveDiff = False
                    utility.printMsg("Done.")
                    os.chdir(utility.workspaceDir())
                pass
            elif type.endswith("Subtree"):
                nestedFiles = git.diff(
                    "--name-only %s %s" % (self.diffBranchSpec(
                        self.branchA, self.branchB), dir)).split()
                if len(nestedFiles) > 0:
                    haveDiff = True
                    for changedFile in changedFiles:
                        if changedFile.startswith(dir + os.path.sep):
                            changedFiles.remove(changedFile)

            if haveDiff:
                self.setProjectStatus(index, "*")
            elif self.showUnchanged:
                self.setProjectStatus(index, " ")
            else:
                self.removeProjectEntry(index)

        utility.printMsg("Done.")

        self.filepanelabel.set("Double click to launch %s" % self.difftool)
        if len(self.projects) > 0:
            self.projpanelabel.set("Double click to choose a project")
        else:
            self.projpanelabel.set("No differences")