def check_unstaged_changes(self): """Checks if there exists any unstaged changes for code Raises ------ UnstagedChanges error if not there exists unstaged changes in environment GitExecutionError error if there exists any error while using git """ try: process = subprocess.Popen([self.execpath, "status"], cwd=self.filepath, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = process.communicate() if process.returncode > 0: raise GitExecutionError( __("error", "controller.code.driver.git.status", str(stderr))) stdout = stdout.decode().strip() if "working tree clean" not in stdout: raise UnstagedChanges() except subprocess.CalledProcessError as e: raise GitExecutionError( __("error", "controller.code.driver.git.status", str(e))) return False
def init(self): try: process = subprocess.Popen( [self.execpath, "init", str(self.filepath)], cwd=self.filepath, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = process.communicate() if process.returncode > 0: raise GitExecutionError( __("error", "controller.code.driver.git.init", str(stderr))) except subprocess.CalledProcessError as e: raise GitExecutionError( __("error", "controller.code.driver.git.init", str(e))) try: code_refs_success = self.ensure_code_refs_dir() except Exception as e: raise FileIOError( __("error", "controller.code.driver.git.init.file", str(e))) try: datmo_files_ignored_success = self.ensure_datmo_files_ignored() except Exception as e: raise FileIOError( __("error", "controller.code.driver.git.init.file", str(e))) return code_refs_success and datmo_files_ignored_success
def __init__(self, filepath, execpath, remote_url=None): super(GitCodeDriver, self).__init__() self.filepath = filepath # Check if filepath exists if not os.path.exists(self.filepath): raise PathDoesNotExist( __("error", "controller.code.driver.git.__init__.dne", filepath)) self.execpath = execpath # Check the execpath and the version try: p = subprocess.Popen( [self.execpath, "version"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self.filepath) out, err = p.communicate() out, err = out.decode(), err.decode() if err: raise GitExecutionError( __("error", "controller.code.driver.git.__init__.giterror", err)) version = str(out.split()[2].split(".windows")[0]) if not semver.match(version, ">=1.9.7"): raise GitExecutionError( __("error", "controller.code.driver.git.__init__.gitversion", out.split()[2])) except Exception as e: raise GitExecutionError( __("error", "controller.code.driver.git.__init__.giterror", str(e))) # TODO: handle multiple remote urls # self.git_host_driver = GitHostDriver() self.remote_url = remote_url self._is_initialized = self.is_initialized if self._is_initialized: # If initialized ensure .datmo is not in working tree else error if self.exists_datmo_files_in_worktree(): raise DatmoFolderInWorkTree( __("error", "controller.code.driver.git.__init__.datmo")) # If initialized ensure .datmo is ignored (in .git/info/exclude) self.ensure_datmo_files_ignored() # If initialized update remote information # if remote_url: # self.remote("set-url", "origin", remote_url) # self._remote_url = self.remote_url # self._remote_access = False self.type = "git"
def reset(self, git_commit): try: process = subprocess.Popen([self.execpath, "reset", git_commit], cwd=self.filepath, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = process.communicate() _ = stdout.decode().strip() if process.returncode > 0: raise GitExecutionError( __("error", "controller.code.driver.git.reset", str(stderr))) except subprocess.CalledProcessError as e: raise GitExecutionError( __("error", "controller.code.driver.git.reset", str(e))) return True
def exists_datmo_files_in_worktree(self): try: process = subprocess.Popen( [self.execpath, "ls-files", "|", "grep", ".datmo"], cwd=self.filepath, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = process.communicate() if process.returncode > 0: raise GitExecutionError( __("error", "controller.code.driver.git.init", str(stderr))) result = stdout.decode().strip() return True if result else False except subprocess.CalledProcessError as e: raise GitExecutionError( __("error", "controller.code.driver.git.init", str(e)))
def latest_commit(self): try: process = subprocess.Popen( [self.execpath, "log", "--format=%H", "-n", "1"], cwd=self.filepath, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = process.communicate() if process.returncode > 0: raise GitExecutionError( __("error", "controller.code.driver.git.latest_commit", str(stderr))) git_commit = stdout.decode().strip() except subprocess.CalledProcessError as e: raise GitExecutionError( __("error", "controller.code.driver.git.latest_commit", str(e))) return git_commit
def check_git_work_tree(self): try: process = subprocess.Popen( [self.execpath, "rev-parse", "--is-inside-work-tree"], cwd=self.filepath, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = process.communicate() git_work_tree_exists = stdout.decode().strip() if process.returncode > 0: raise GitExecutionError( __("error", "controller.code.driver.git.check_git_work_tree", str(stderr))) except subprocess.CalledProcessError as e: raise GitExecutionError( __("error", "controller.code.driver.git.check_git_work_tree", str(e))) return True if git_work_tree_exists == "true" else False
def checkout_ref(self, commit_id): try: # Run checkout for the specific ref as usual datmo_ref = "refs/datmo/" + commit_id checkout_result = self.checkout(datmo_ref) return checkout_result except Exception as e: raise GitExecutionError( __("error", "controller.code.driver.git.checkout_ref", (commit_id, str(e))))
def checkout(self, name, option=None): try: if option: process = subprocess.Popen( [self.execpath, "checkout", option, name], cwd=self.filepath, stdout=subprocess.PIPE, stderr=subprocess.PIPE) else: process = subprocess.Popen([self.execpath, "checkout", name], cwd=self.filepath, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = process.communicate() if process.returncode > 0: raise GitExecutionError( __("error", "controller.code.driver.git.checkout", (name, str(stderr)))) except subprocess.CalledProcessError as e: raise GitExecutionError( __("error", "controller.code.driver.git.checkout", (name, str(e)))) return True
def commit(self, options): """Git commit wrapper Parameters ---------- options: list List of strings for the command (e.g. ["-m", "hello"]) Returns ------- bool True if new commit was created, False if no commit was created Raises ------ GitExecutionError If any errors occur in running git """ try: process = subprocess.Popen( [self.execpath, "commit"] + options, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self.filepath) stdout, stderr = process.communicate() stdout, stderr = stdout.decode(), stderr.decode() if "nothing" in stdout: return False if process.returncode > 0: raise GitExecutionError( __("error", "controller.code.driver.git.commit", (options, stderr))) except subprocess.CalledProcessError as e: raise GitExecutionError( __("error", "controller.code.driver.git.commit", (options, str(e)))) return True