def run_git_clone(self, clonedir: str) -> None:
        """Clones a repo using git"""
        self.status_message.emit("Cloning module...")
        current_thread = QtCore.QThread.currentThread()

        FreeCAD.Console.PrintMessage("Cloning repo...\n")
        if self.repo.git_lock.locked():
            FreeCAD.Console.PrintMessage("Waiting for lock to be released to us...\n")
            if not self.repo.git_lock.acquire(timeout=2):
                FreeCAD.Console.PrintError(
                    "Timeout waiting for a lock on the git process, failed to clone repo\n"
                )
                return
            self.repo.git_lock.release()

        with self.repo.git_lock:
            FreeCAD.Console.PrintMessage("Lock acquired...\n")
            self.git_manager.clone(self.repo.url, clonedir)
            FreeCAD.Console.PrintMessage("Initial clone complete...\n")
            if current_thread.isInterruptionRequested():
                return

            if current_thread.isInterruptionRequested():
                return

            FreeCAD.Console.PrintMessage("Clone complete\n")

        if self.repo.contains_workbench():
            answer = translate(
                "AddonsInstaller",
                "Workbench successfully installed. Please restart FreeCAD to apply the changes.",
            )
        else:
            answer = translate(
                "AddonsInstaller",
                "Addon successfully installed.",
            )

        if self.repo.repo_type == Addon.Kind.WORKBENCH:
            # symlink any macro contained in the module to the macros folder
            macro_dir = FreeCAD.getUserMacroDir(True)
            if not os.path.exists(macro_dir):
                os.makedirs(macro_dir)
            if os.path.exists(clonedir):
                for f in os.listdir(clonedir):
                    if f.lower().endswith(".fcmacro"):
                        try:
                            utils.symlink(
                                os.path.join(clonedir, f), os.path.join(macro_dir, f)
                            )
                        except OSError:
                            # If the symlink failed (e.g. for a non-admin user on Windows), copy
                            # the macro instead
                            shutil.copy(
                                os.path.join(clonedir, f), os.path.join(macro_dir, f)
                            )
                        FreeCAD.ParamGet(
                            "User parameter:Plugins/" + self.repo.name
                        ).SetString("destination", clonedir)
                        # pylint: disable=line-too-long
                        answer += "\n\n" + translate(
                            "AddonsInstaller",
                            "A macro has been installed and is available under Macro -> Macros menu",
                        )
                        answer += ":\n<b>" + f + "</b>"
        self.update_metadata()
        self.success.emit(self.repo, answer)
Ejemplo n.º 2
0
    def run(self):

        "installs or updates the selected addon"

        git = None
        try:
            import git
        except Exception as e:
            self.info_label.emit("GitPython not found.")
            print(e)
            FreeCAD.Console.PrintWarning(
                translate(
                    "AddonsInstaller",
                    "GitPython not found. Using standard download instead.") +
                "\n")
            try:
                import zipfile
            except:
                self.info_label.emit("no zip support.")
                FreeCAD.Console.PrintError(
                    translate(
                        "AddonsInstaller",
                        "Your version of python doesn't appear to support ZIP files. Unable to proceed."
                    ) + "\n")
                return
            try:
                import StringIO as io
            except ImportError:  # StringIO is not available with python3
                import io
        if not isinstance(self.idx, list):
            self.idx = [self.idx]
        for idx in self.idx:
            if idx < 0:
                return
            if not self.repos:
                return
            if NOGIT:
                git = None
            basedir = FreeCAD.getUserAppDataDir()
            moddir = basedir + os.sep + "Mod"
            if not os.path.exists(moddir):
                os.makedirs(moddir)
            clonedir = moddir + os.sep + self.repos[idx][0]
            self.progressbar_show.emit(True)
            if os.path.exists(clonedir):
                self.info_label.emit("Updating module...")
                if git:
                    if not os.path.exists(clonedir + os.sep + '.git'):
                        # Repair addon installed with raw download
                        bare_repo = git.Repo.clone_from(self.repos[idx][1],
                                                        clonedir + os.sep +
                                                        '.git',
                                                        bare=True)
                        try:
                            with bare_repo.config_writer() as cw:
                                cw.set('core', 'bare', False)
                        except AttributeError:
                            FreeCAD.Console.PrintWarning(
                                translate(
                                    "AddonsInstaller",
                                    "Outdated GitPython detected, consider upgrading with pip."
                                ) + "\n")
                            cw = bare_repo.config_writer()
                            cw.set('core', 'bare', False)
                            del cw
                        repo = git.Repo(clonedir)
                        repo.head.reset('--hard')
                    repo = git.Git(clonedir)
                    try:
                        answer = repo.pull()
                    except:
                        print("Error updating module", self.repos[idx][1],
                              " - Please fix manually")
                        answer = repo.status()
                        print(answer)
                    else:
                        # Update the submodules for this repository
                        repo_sms = git.Repo(clonedir)
                        for submodule in repo_sms.submodules:
                            submodule.update(init=True, recursive=True)
                else:
                    answer = self.download(self.repos[idx][1], clonedir)
            else:
                self.info_label.emit("Checking module dependencies...")
                depsok, answer = self.checkDependencies(self.repos[idx][1])
                if depsok:
                    if git:
                        self.info_label.emit("Cloning module...")
                        repo = git.Repo.clone_from(self.repos[idx][1],
                                                   clonedir,
                                                   branch='master')

                        # Make sure to clone all the submodules as well
                        if repo.submodules:
                            repo.submodule_update(recursive=True)
                    else:
                        self.info_label.emit("Downloading module...")
                        self.download(self.repos[idx][1], clonedir)
                    answer = translate(
                        "AddonsInstaller",
                        "Workbench successfully installed. Please restart FreeCAD to apply the changes."
                    )
            # symlink any macro contained in the module to the macros folder
            macro_dir = FreeCAD.getUserMacroDir(True)
            if not os.path.exists(macro_dir):
                os.makedirs(macro_dir)
            if os.path.exists(clonedir):
                for f in os.listdir(clonedir):
                    if f.lower().endswith(".fcmacro"):
                        print("copying macro:", f)
                        utils.symlink(os.path.join(clonedir, f),
                                      os.path.join(macro_dir, f))
                        FreeCAD.ParamGet('User parameter:Plugins/' +
                                         self.repos[idx][0]).SetString(
                                             "destination", clonedir)
                        answer += "\n\n" + translate(
                            "AddonsInstaller",
                            "A macro has been installed and is available under Macro -> Macros menu"
                        ) + ":"
                        answer += "\n<b>" + f + "</b>"
            self.progressbar_show.emit(False)
            self.info_label.emit(answer)
            self.mark_recompute.emit(self.repos[idx][0])
        self.stop = True