def clone_watcher(repo, base=None, name=None): """clone a watcher from Github (or other version control with git) meaning that we clone to a temporary folder, and then move to a new folder. By default, the user gets all tasks associated with the watcher, along with the git folder so that removing is also done with version control. Parameters ========== repo: the repository to clone base: the watchme base, defaults to $HOME/.watchme name: a new name for the watcher, if a rename is desired. """ if base is None: base = WATCHME_BASE_DIR # clone_watcher(repo=repo, base=args.base, name=extra) # STOPPED HERE - need to test this. # Validate the repository address if not re.search("^git@|http", repo): bot.exit("Please provide a valid url to git repository") # if the name is None, use the repo name if name is None: name = os.path.basename(repo) # Ensure we aren't overwriting dest = os.path.join(base, name) if os.path.exists(dest): bot.exit("%s already exists, choose a different watcher name." % name) clone_dest = get_tmpdir(prefix="watchme-clone", create=False) run_command("git clone %s %s" % (repo, clone_dest)) # Valid by default - will copy over if valid valid = True # Iterate over watchers watchers = os.listdir(clone_dest) for watcher in watchers: watcher = os.path.join(clone_dest, watcher) tasks = os.listdir(watcher) # Check that tasks include watchme.cfg for task in tasks: if not task.startswith("task"): continue task_folder = os.path.join(watcher, task) content = os.listdir(task_folder) if "watcher.cfg" not in content: bot.error("%s is missing a watcher.cfg" % task) valid = False break if valid: shutil.move(clone_dest, dest) if os.path.exists(clone_dest): shutil.rmtree(clone_dest)
def git_clone(repo, name=None, base=None, force=False): """clone a git repo to a destination. The user can provide the following groupings of arguments: base without name: destination is ignored, the repo is cloned (named as it is) to the base. If the folder exists, --force must be used to remove it first. base with name: destination is ignored, repo is cloned (and named based on name variable) to the base. The same applies for force. dest provided: the repo is cloned to the destination, if it doesn't exist and/or force is True. Parameters ========== name: the name of the watcher to add base: the base of the watcher (defaults to $HOME/.watchme force: remove first if already exists """ if base is None: base = WATCHME_BASE_DIR # Derive the repository name if name is None: name = os.path.basename(repo).replace(".git", "") # First clone to temporary directory tmpdir = get_tmpdir() command = "git clone %s %s" % (repo, tmpdir) bot.debug(command) run_command(command) # ensure there is a watchme.cfg if not os.path.exists(os.path.join(tmpdir, "watchme.cfg")): shutil.rmtree(tmpdir) bot.exit("No watchme.cfg found in %s, aborting." % repo) # If it's good, move the repository dest = os.path.join(base, name) # Don't allow for overwrite if os.path.exists(dest): if force is False: shutil.rmtree(tmpdir) bot.exit("%s exists. Use --force to overwrite" % dest) else: shutil.rmtree(dest) # Move the repository there shutil.move(tmpdir, dest) # Ensure we don't sign gpg key run_command("git --git-dir=%s/.git config commit.gpgsign false" % dest) bot.info("Added watcher %s" % name)
def test_files(self): print('Testing utils.generate_temporary_files') from watchme.utils import generate_temporary_file tmpfile = generate_temporary_file() from watchme.utils import run_command run_command('touch %s' %tmpfile) print('Testing utils.copyfile') from watchme.utils import copyfile copyfile(tmpfile, '%s.booga' % tmpfile) self.assertTrue(os.path.exists('%s.booga' %tmpfile)) self.assertTrue(os.path.exists(tmpfile)) os.remove(tmpfile) os.remove("%s.booga" % tmpfile)
def git_add(repo, files): """add one or more files to the git repo. Parameters ========== repo: the repository to commit to. files: one or more files to add. """ if not isinstance(files, list): files = [files] for f in files: command = "git add %s" % f bot.debug(command) run_command(command)
def git_commit(repo, task, message): """Commit to the git repo with a particular message. folder. Parameters ========== repo: the repository to commit to. task: the name of the task to add to the commit message message: the message for the commit, passed from the client """ # Commit with the watch group and date string message = "watchme %s %s" % (task, message) # Commit command = 'git commit -a -m "%s"' % message bot.debug(command) run_command(command)
def get_latest_commit(): """get the latest commit for a repository in the present working directory Parameters ========== repo: the repository path to get the commit from """ commit = run_command('git log -n 1 --pretty=format:"%H"')["message"] return commit.strip("\n")
def get_latest_commit(): '''get the latest commit for a repository in the present working directory Parameters ========== repo: the repository path to get the commit from ''' commit = run_command('git log -n 1 --pretty=format:"%H"')['message'] return commit.strip('\n')
def get_earliest_commit(): """get the earliest commit for a repository. This is intended to be used when in the present working directory Parameters ========== repo: the repository path to get the commit from """ commit = run_command("git rev-list --max-parents=0 HEAD")["message"] return commit.strip("\n")
def get_earliest_commit(): '''get the earliest commit for a repository. This is intended to be used when in the present working directory Parameters ========== repo: the repository path to get the commit from ''' commit = run_command('git rev-list --max-parents=0 HEAD')['message'] return commit.strip('\n')
def test_terminal(self): print('Testing utils.run_command') from watchme.utils import run_command from watchme.utils import which result = run_command('echo Las Papas Fritas') self.assertEqual(result['message'], 'Las Papas Fritas\n') self.assertEqual(result['return_code'], 0) print('Testing utils.which') result = which('echo') self.assertEqual(result, '/bin/echo')
def create_watcher(name=None, watcher_type=None, base=None, exporter=None): '''create a watcher, meaning a folder with a configuration and initialized git repo. Parameters ========== name: the watcher to create, uses default or WATCHME_WATCHER watcher_type: the type of watcher to create. defaults to WATCHER_DEFAULT_TYPE ''' if name == None: name = WATCHME_WATCHER if base == None: base = WATCHME_BASE_DIR # Create the repository folder repo = os.path.join(base, name) if not os.path.exists(repo): bot.info('Adding watcher %s...' % repo) mkdir_p(repo) # Ensure no gpg signing happens run_command("git --git-dir=%s/.git init" % repo) run_command("git --git-dir=%s/.git config commit.gpgsign false" % repo) # Add the watcher configuration file generate_watcher_config(repo, watcher_type, exporter) run_command("git -C %s add watchme.cfg" % repo) return repo else: bot.info('%s already exists: %s' % (name, repo))
def test_terminal(self): print("Testing utils.run_command") from watchme.utils import run_command from watchme.utils import which result = run_command("echo Las Papas Fritas") self.assertEqual(result["message"], "Las Papas Fritas\n") self.assertEqual(result["return_code"], 0) print("Testing utils.which") result = which("echo") self.assertEqual(result, "/bin/echo")
def git_date(repo, commit): """get the date for a particular commit. Parameters ========== repo: the full path to the repository commit: the commit to get the date for """ command = "git show -s --format=" + "%ci " + commit bot.debug(command) result = run_command(command) if result["return_code"] == 0: return result["message"].strip("\n")
def git_date(repo, commit): '''get the date for a particular commit. Parameters ========== repo: the full path to the repository commit: the commit to get the date for ''' command = 'git show -s --format=' + "%ci " + commit bot.debug(command) result = run_command(command) if result['return_code'] == 0: return result['message'].strip('\n')
def git_show(repo, commit, filename): """git show is used to pipe the content of a file at a particular commit to the screen (and calling python client). We must be in the $PWD of the repo for this to work. Parameters ========== repo: the repository to interact with commit: the commit to investigate for the file filename: the relative path to the file """ command = "git show %s:%s" % (commit, filename) bot.debug(command) result = run_command(command) if result["return_code"] == 0: return result["message"].strip("\n")
def get_commits(repo, from_commit=None, to_commit=None, grep=None, filename=None): """get commits, starting from and going to a particular commit. if grep is defined, filter commits to those with messages that match that particular expression Parameters ========== from_commit: the commit to start at to_commit: the commit to go to grep: the expression to match (not used if None) filename: the filename to filter to. Includes all files if not specified. """ command = 'git log --all --oneline --pretty=tformat:"%H"' # The earliest commit if from_commit is None: from_commit = get_earliest_commit() # The latest commit if to_commit is None: to_commit = get_latest_commit() # A regular expression to search for (and filter commits) if grep is not None: command = '%s --grep "ADD results"' % command # Add the commit range command = "%s %s..%s" % (command, from_commit, to_commit) if filename is not None: command = "%s -- %s" % (command, filename) bot.info(command) results = run_command(command)["message"] results = [x for x in results.split("\n") if x] return results