Пример #1
0
 def PUSH(self, sRepoUrl):
     sChangeId = gerrit.getChangeId()
     if not sChangeId:
         raise FatalError("Unable to extract Change-Id")
     sProject = gerrit.getProjectName()
     oRepoData = self.getRepoData()
     sLocalCommit = git.getLastCommit()
     try:
         dChangeData = self.getApiClient().getChangeData(
             sChangeId, sProject, lAdditionalData=["CURRENT_REVISION"])
     except requests.HTTPError as e:
         if e.response.status_code != 404:
             raise
     else:
         sRemoteCommit = dChangeData["current_revision"]
         sLastPushedCommit = oRepoData.getLastPushedCommit(
             sProject, sChangeId)
         if sRemoteCommit == sLocalCommit:
             warning("No new changes")
             return
         elif sRemoteCommit != sLastPushedCommit:
             warning("You are about to overwrite unknown changes.")
             sInput = input("Continue? (y/n): ")
             if sInput != "y":
                 raise FatalError("Operation aborted")
     print("Pushing changes to %s" % sRepoUrl)
     gerrit.push()
     oRepoData.setLastPushedCommit(sProject, sChangeId, sLocalCommit)
     self.saveRepoData(oRepoData)
Пример #2
0
    def DOWNLOAD(self, dRepos):
        bFound = False

        def download(sRepoUrl):
            nonlocal bFound
            sPatchRef = self.getPatchRef(sRepoUrl, self.oArgs.change)
            if sPatchRef:
                print("Downloading change %s from %s" %
                      (self.oArgs.change, sRepoUrl))
                gerrit.download(sPatchRef, bDetach=self.oArgs.detach)
                bFound = True
            else:
                sErrMsg = "Change %s not found within this project" % self.oArgs.change
                if self.oArgs.project:
                    raise FatalError(sErrMsg)
                else:
                    print("Skipped: %s" % sErrMsg)

        dFilteredRepos = {
            sRepoUrl: sDirPath
            for sRepoUrl, sDirPath in dRepos.items()
            if not self.oArgs.project or self.oArgs.project == urlparse(
                sRepoUrl, allow_fragments=True).path[1:]
        }
        if not dFilteredRepos:
            raise FatalError("No project \"%s\" found." % self.oArgs.project)

        lErrorRepos = self.runInRepos(dFilteredRepos, download)
        if not lErrorRepos and not bFound:
            raise FatalError("Change %s was not found in any project." %
                             self.oArgs.change)
        return lErrorRepos
Пример #3
0
 def readManifest(self, bKeepInvalid=False):
     if not os.path.isfile(self.oArgs.manifest):
         raise FatalError("The manifest file %s does not exist." %
                          self.oArgs.manifest)
     dRepos = OrderedDict()
     try:
         with open(self.oArgs.manifest) as oFile:
             for sLine in oFile:
                 sLine = sLine.strip()
                 if sLine:
                     lElements = sLine.split(" ")
                     (sRepoUrl,
                      sDirPath) = lElements[0], " ".join(lElements[1:])
                     if not sDirPath:
                         sDirPath = unquote(
                             urlparse(
                                 sRepoUrl,
                                 allow_fragments=True).path.split("/")[-1])
                     sDirPath = os.path.join(self.sRootFolder, sDirPath)
                     if not bKeepInvalid and not os.path.isdir(sDirPath):
                         warning("Directory %s does not exist, skipped." %
                                 sDirPath)
                     else:
                         dRepos[sRepoUrl] = sDirPath
     except OSError as e:
         raise FatalError(e)
     return dRepos
Пример #4
0
    def runInRepos(self, dRepos, xFunction, bPrint=True, bCheckTopic=True):
        if bCheckTopic:
            lBranches = set()
            try:
                for sDirPath in dRepos.values():
                    if os.path.isdir(sDirPath):
                        with changeWorkingDir(sDirPath):
                            lBranches.add(
                                strOrDefault(git.getCurrentBranch(), "(none)"))
            except (subprocess.CalledProcessError, OSError) as e:
                raise FatalError(e)

            if len(lBranches) > 1:
                warning("Topic is not consistent across your repositories. "
                        "Found following topics: %s" % ", ".join(lBranches))
                sInput = input("Do you wish to proceed anyway? (y/n): ")
                if sInput != "y":
                    raise FatalError("Operation cancelled")

        lErrorRepos = []
        for sRepoUrl, sDirPath in dRepos.items():
            sRepoName = os.path.basename(sDirPath)
            try:
                os.makedirs(sDirPath, exist_ok=True)
                with changeWorkingDir(sDirPath):
                    if bPrint:
                        highlight("\n### %s ###" %
                                  os.path.basename(os.getcwd()))
                    xFunction(sRepoUrl)
                    if bPrint:
                        success("Done")
            except (subprocess.CalledProcessError, FatalError, OSError) as e:
                error("[%s] %s" % (sRepoName, e))
                lErrorRepos.append(sDirPath)
        return lErrorRepos
Пример #5
0
 def run(self):
     oMethod = getattr(self, self.oArgs.command.upper())
     if oMethod is not None and callable(oMethod):
         try:
             return oMethod()
         except (subprocess.CalledProcessError, OSError) as e:
             raise FatalError(e)
     raise FatalError("Command %s is not implemented." % self.oArgs.command)
Пример #6
0
    def getApiClient(self):
        sConfigFilePath = os.path.join(os.path.expanduser("~"), ".repolite")
        if not os.path.isfile(sConfigFilePath):
            raise FatalError("The config file %s does not exist." %
                             sConfigFilePath)

        sWorkingDir = os.path.normcase(
            os.path.abspath(os.path.dirname(os.getcwd())))
        oConfig = ConfigParser()
        oConfig.read(sConfigFilePath)
        dSection = oConfig["DEFAULT"]
        for sSection in oConfig.sections():
            sTarget = oConfig.get(sSection, "target", fallback=None)
            if sTarget:
                sTarget = os.path.normcase(
                    os.path.abspath(
                        os.path.join(os.path.dirname(sConfigFilePath),
                                     sTarget)))
                if sWorkingDir == sTarget:
                    dSection = oConfig[sSection]
                    break

        def getNotEmpty(sKey):
            sValue = dSection.get(sKey, fallback=None)
            if sValue is None:
                raise FatalError(
                    "No value provided for %s in the config file" % sKey)
            return sValue

        self.oApiClient = gerrit.ApiClient(getNotEmpty("url"),
                                           getNotEmpty("username"),
                                           getNotEmpty("password"))
        return self.oApiClient
Пример #7
0
 def DOWNLOAD(self):
     oMatch = re.match(r"(\d+)/\d+", self.oArgs.patch)
     if oMatch is None:
         raise FatalError("%s is not a valid patch ID" % self.oArgs.patch)
     sPatchChecksum = "%02d" % int(oMatch.group(1)[-2:])
     gerrit.download("refs/changes/%s/%s" %
                     (sPatchChecksum, self.oArgs.patch),
                     bDetach=self.oArgs.detach)
Пример #8
0
 def RENAME(self):
     sCurrentBranch = git.getCurrentBranch()
     if sCurrentBranch:
         print("Renaming topic: %s -> %s" %
               (sCurrentBranch, self.oArgs.topic))
         subprocess.run(["git", "branch", "-m", self.oArgs.topic],
                        check=True)
     else:
         raise FatalError("There is no topic")
Пример #9
0
 def download(sRepoUrl):
     nonlocal bFound
     sPatchRef = self.getPatchRef(sRepoUrl, self.oArgs.change)
     if sPatchRef:
         print("Downloading change %s from %s" %
               (self.oArgs.change, sRepoUrl))
         gerrit.download(sPatchRef, bDetach=self.oArgs.detach)
         bFound = True
     else:
         sErrMsg = "Change %s not found within this project" % self.oArgs.change
         if self.oArgs.project:
             raise FatalError(sErrMsg)
         else:
             print("Skipped: %s" % sErrMsg)
Пример #10
0
 def onError():
     while True:
         sInput = input(
             "You may have merge conflicts. Fix them and press enter, or enter 'abort' now to quit: "
         )
         if sInput == "abort":
             print("Aborting.")
             subprocess.run(["git", "cherry-pick", "--abort"])
             if xOnAbort is not None:
                 xOnAbort()
             raise FatalError("Process aborted.")
         elif not sInput:
             print("Continuing...")
             break
Пример #11
0
 def PULL(self, sRepoUrl):
     sChangeId = gerrit.getChangeId()
     if not sChangeId:
         raise FatalError("Unable to extract Change-Id")
     sProject = gerrit.getProjectName()
     try:
         dChangeData = self.getApiClient().getChangeData(
             sChangeId, sProject, lAdditionalData=["ALL_REVISIONS"])
     except requests.HTTPError as e:
         if e.response.status_code == 404:
             warning("No remote patch")
             return
         raise e
     sRemoteCommit = dChangeData["current_revision"]
     sLocalCommit = git.getLastCommit()
     sLastPushedCommit = self.getRepoData().getLastPushedCommit(
         sProject, sChangeId)
     if sRemoteCommit == sLocalCommit:
         print("Already up-to-date.")
         return
     elif sRemoteCommit == sLastPushedCommit:
         print("You are ahead of Gerrit.")
         return
     elif sLocalCommit in dChangeData["revisions"]:
         print("Pulling changes from %s" % sRepoUrl)
         sBranch = git.getCurrentBranch()
         dFetchData = dChangeData["revisions"][sRemoteCommit]["fetch"][
             "ssh"]
         subprocess.run(
             ["git", "fetch", dFetchData["url"], dFetchData["ref"]],
             check=True)
         subprocess.run(["git", "checkout", "FETCH_HEAD"], check=True)
         if sBranch:
             subprocess.run(["git", "branch", "-D", sBranch], check=True)
             subprocess.run(["git", "checkout", "-b", sBranch], check=True)
     else:
         raise FatalError("You have local commits unknown to Gerrit")
Пример #12
0
    def executeForAll(self, xFunction):
        dRepos = self.readManifest(
            bKeepInvalid=getattr(xFunction, "bKeepInvalid", False))
        if not dRepos:
            raise FatalError("There is no valid repository defined.")
        if getattr(xFunction, "bForAll", False):
            return xFunction(dRepos)
        else:

            def doCallFunction(sRepoUrl):
                if len(inspect.getfullargspec(xFunction)[0]) > 1:
                    xFunction(sRepoUrl)
                else:
                    xFunction()

            return self.runInRepos(dRepos, doCallFunction)
Пример #13
0
 def save(self, sFile):
     try:
         with open(sFile, "w") as oFile:
             json.dump(self.dRaw, oFile)
     except (ValueError, OSError) as e:
         raise FatalError(e)
Пример #14
0
 def load(self, sFile):
     try:
         with open(sFile, "r") as oFile:
             self.dRaw = json.load(oFile)
     except (ValueError, OSError) as e:
         raise FatalError(e)
Пример #15
0
 def run(self):
     oMethod = getattr(self, self.oArgs.command.upper())
     if oMethod is not None and callable(oMethod):
         return self.executeForAll(oMethod)
     raise FatalError("Command %s is not implemented." % self.oArgs.command)
Пример #16
0
 def getNotEmpty(sKey):
     sValue = dSection.get(sKey, fallback=None)
     if sValue is None:
         raise FatalError(
             "No value provided for %s in the config file" % sKey)
     return sValue