import re import sys import os from cement import shell from cement.utils.misc import minimal_logger from dhwp.core.utils import is_debug LOG = minimal_logger(__name__) class Git: def __init__(self, path, app=None): self.path = path self.app = app self.git_path = path + '/.git' shell.cmd('cd %s && git config --global user.email "robot@dreamhost.com"' % self.path) shell.cmd('cd %s && git config --global user.name "Robot"' % self.path) def cmd(self, cmd, args=''): out, err, code = shell.cmd('which git') if code > 0: LOG.fatal("cannot find git, please install it first") sys.exit(1) if not os.path.isdir(self.path): LOG.fatal("ERROR: %s is not a directory" % self.path) sys.exit(1) # TODO put this somewhere else command = "cd %s && git --git-dir=%s %s %s" % (self.path, self.git_path, cmd, args) LOG.info("git command : %s" % command) out, err, code = shell.cmd(command) out = out.decode("utf-8") err = err.decode("utf-8") LOG.info("git output : %s %s" % (out, err)) if code > 0: if not is_debug(app=self.app) and self.app is not None: self.app.log.error("GIT failed with error\n%s" % err) LOG.fatal("GIT failed with error %s" % err) sys.exit(1) return out def commit(self, message='', exclude_media=False, exclude_live_archives=False): git_ignore_file = self.path + '/.gitignore' self.git_ignore(exclude_media, exclude_live_archives) self.cmd('add', '.') commit_args = '-a -m \"%s\"' % message if self.has_changes(): self.cmd('commit', commit_args) if os.path.isfile(git_ignore_file): os.unlink(git_ignore_file) def _find_git_dirs(self, start_path): git_parent_dirs = [] for root, dirs, files in os.walk(start_path): if '.git' in dirs: parent_dir = os.path.relpath(root, self.path) if parent_dir != '.': git_parent_dirs.append(parent_dir) dirs.remove('.git') return git_parent_dirs def git_ignore(self, exclude_media=False, exclude_live_archives=False): git_ignore_file = self.path + '/.gitignore' git_parent_dirs = self._find_git_dirs(self.path) with open(git_ignore_file, 'w') as gi: gi.write("/.gitignore\nwp-content/cache\nwp-content/upgrade\nwp-config.php\n/.htaccess\n.maintenance\nwp-content/object-cache.php\n") for parent_dir in git_parent_dirs: gi.write(f"/{parent_dir}/\n") if exclude_media: gi.write("wp-content/uploads/*\nwp-content/gallery/*\n") if exclude_live_archives: gi.write("wp-content/updraft\n**/*.sql\nwp-content/backups\n" "wp-snapshot\nwp-content/ai1wm-backups\nwp-content/**/*.zip\n" "wp-content/**/*.gz\nwp-content/**/*.tar\n") def has_changes(self): result = self.cmd('status') if 'nothing to commit' in result: return 0 else: return 1 def wipe(self): git_ignore_file = self.path + '/.gitignore' if os.path.isfile(git_ignore_file): os.unlink(git_ignore_file) if os.path.isdir(self.git_path): shell.cmd("git --git-dir=%s worktree prune" % self.git_path) shell.cmd("rm -rf " + self.git_path)