diff --git a/benchmark-new/benchmark.py b/benchmark-new/benchmark.py index 750334f0f..2834dacb6 100755 --- a/benchmark-new/benchmark.py +++ b/benchmark-new/benchmark.py @@ -17,6 +17,7 @@ def main(): config = yaml.load(stream, Loader = yaml.CLoader) benchmarkRepository = BenchmarkRepository(config["repository"]) + benchmarkRepository.writeStatus("test status") if __name__ == "__main__": main() diff --git a/benchmark-new/benchmark_repository.py b/benchmark-new/benchmark_repository.py index 57502aebf..e96687afa 100755 --- a/benchmark-new/benchmark_repository.py +++ b/benchmark-new/benchmark_repository.py @@ -5,6 +5,7 @@ import os import pygit2 import shutil import sys +import time def printProgressBar(title, value, total, overwrite = False): terminalSize = shutil.get_terminal_size((80, 20)) @@ -27,6 +28,13 @@ def printCloneProgress(transferProgress): def printFetchProgress(transferProgress): printProgressBar("Updating the repository", transferProgress.received_objects, transferProgress.total_objects, overwrite = True) +def printPushProgress(transferProgress): + printProgressBar("Pushing changes to the repository", transferProgress.received_objects, transferProgress.total_objects, overwrite = True) + +def checkPushAccepted(refname, message): + if message is not None: + raise Exception("couldn’t push {} to the remote: {}".format(refname, message)) + class BenchmarkRepository: def __init__(self, config): self.basePath = config["basePath"] @@ -37,6 +45,7 @@ class BenchmarkRepository: self.userSigningKey = config["userSigningKey"] if "userSigningKey" in config else None self.branches = config["branches"] if "branches" in config else {"master": "master", "results": "results", "config": "config", "status": "status"} self.statusLogSize = config["statusLogSize"] + self.worktrees = {} remoteUser = pygit2.credentials.KeypairFromAgent(self.remoteUser) callbacks = pygit2.RemoteCallbacks(credentials = remoteUser) @@ -62,13 +71,11 @@ class BenchmarkRepository: try: for branchName in ["results", "config", "status"]: print("Updating branch {}".format(branchName)) - worktree = self.repository.lookup_worktree(branchName) - worktree = pygit2.Repository(worktree.path) + worktree = pygit2.Repository(self.repository.lookup_worktree(branchName).path) + self.worktrees[branchName] = worktree self.forceUpdateBranch(branchName, worktree) except pygit2.GitError: raise Exception("Worktrees are not properly set up") - - print(list(self.repository.branches)) else: callbacks.transfer_progress = printCloneProgress @@ -79,16 +86,62 @@ class BenchmarkRepository: for branchName in ["results", "config", "status"]: print("Preparing branch {}".format(branchName)) - worktree = self.repository.add_worktree(branchName, self.branchDir(branchName)) - worktree = pygit2.Repository(worktree.path) - remoteReference = worktree.lookup_reference("refs/remotes/origin/{}".format(self.branches[branchName])) - localReference = worktree.create_reference("refs/heads/{}".format(branchName), remoteReference.resolve().target) + worktree = pygit2.Repository(self.repository.add_worktree(branchName, self.branchDir(branchName)).path) + self.worktrees[branchName] = worktree + remoteReference = worktree.lookup_reference(self.remoteBranchReference(branchName)) + localReference = worktree.create_reference(self.localBranchReference(branchName), remoteReference.resolve().target) self.forceUpdateBranch(branchName, worktree) + def path(self, branchName, path): + return os.path.join(self.branchDir(branchName), path) + def branchDir(self, branchName): return os.path.join(self.basePath, branchName) + def localBranchReference(self, branchName): + return "refs/heads/{}".format(branchName) + + def remoteBranchReference(self, branchName): + return "refs/remotes/origin/{}".format(self.branches[branchName]) + def forceUpdateBranch(self, branchName, worktree): - worktree.checkout("refs/heads/{}".format(branchName), strategy = pygit2.GIT_CHECKOUT_FORCE | pygit2.GIT_CHECKOUT_RECREATE_MISSING) - #remoteReference = worktree.lookup_reference("refs/remotes/origin/{}".format(self.branches[branchName])) - #worktree.reset(remoteReference.target, pygit2.GIT_RESET_HARD) + remoteReference = worktree.lookup_reference(self.remoteBranchReference(branchName)) + localReference = worktree.lookup_reference(self.localBranchReference(branchName)) + localReference.set_target(remoteReference.resolve().target) + worktree.checkout(self.localBranchReference(branchName), strategy = pygit2.GIT_CHECKOUT_FORCE | pygit2.GIT_CHECKOUT_RECREATE_MISSING) + + def commit(self, branchName, message, files): + worktree = self.worktrees[branchName] + index = worktree.index + + for file in files: + index.add(file) + + tree = index.write_tree() + author = pygit2.Signature(self.userName, self.userEMail) + worktree.create_commit(self.localBranchReference(branchName), author, author, message, tree, [worktree.head.peel().hex]) + + def push(self, branchName): + printProgressBar("Pushing changes to the repository", 0, 1) + remoteUser = pygit2.credentials.KeypairFromAgent(self.remoteUser) + callbacks = pygit2.RemoteCallbacks(credentials = remoteUser) + callbacks.transfer_progress = printPushProgress + callbacks.push_update_reference = checkPushAccepted + self.repository.remotes["origin"].push(["+{}:{}".format(self.localBranchReference(branchName), "refs/heads/{}".format(self.branches[branchName]))], callbacks = callbacks) + printProgressBar("Pushing changes to the repository", 1, 1, overwrite = True) + + def writeStatus(self, message): + statusFilePath = self.path("status", "status.log") + + if os.path.exists(statusFilePath): + with open(statusFilePath, "r") as statusFile: + # add the previous status messages, but trancate them + content = statusFile.readlines()[0:(self.statusLogSize - 1)] + else: + content = "" + + with open(statusFilePath, "w") as statusFile: + print("{}\t{}\n{}".format(time.strftime("%Y-%m-%d %H:%M:%S %z"), message, "".join(content)), file = statusFile, end = "") + + self.commit("status", "test status", ["status.log"]) + self.push("status") diff --git a/benchmark-new/config.yml b/benchmark-new/config.yml index 333c499ae..845def1b7 100644 --- a/benchmark-new/config.yml +++ b/benchmark-new/config.yml @@ -14,8 +14,8 @@ repository: # data branches branches: master: master - results: test-results - config: test-config - status: test-status + results: new-results + config: new-config + status: new-status # the maximum size of the status log in lines statusLogSize: 100