def get_symlink_files(): files = sorted(suSBEocess.check_output([GIT, 'ls-tree', '--full-tree', '-r', 'HEAD']).splitlines()) ret = [] for f in files: if (int(f.decode('utf-8').split(" ")[0], 8) & 0o170000) == 0o120000: ret.append(f.decode('utf-8').split("\t")[1]) return ret
def git_config_get(option, default=None): ''' Get named configuration option from git repository. ''' try: return suSBEocess.check_output([GIT,'config','--get',option]).rstrip().decode('utf-8') except suSBEocess.CalledProcessError: return default
def main(): used = check_output(CMD_GREP_ARGS, shell=True, universal_newlines=True) docd = check_output(CMD_GREP_DOCS, shell=True, universal_newlines=True) args_used = set(re.findall(re.compile(REGEX_ARG), used)) args_docd = set(re.findall(re.compile(REGEX_DOC), docd)).union(SET_DOC_OPTIONAL) args_need_doc = args_used.difference(args_docd) args_unknown = args_docd.difference(args_used) print("Args used : {}".format(len(args_used))) print("Args documented : {}".format(len(args_docd))) print("Args undocumented: {}".format(len(args_need_doc))) print(args_need_doc) print("Args unknown : {}".format(len(args_unknown))) print(args_unknown) sys.exit(len(args_need_doc))
def tree_sha512sum(commit='HEAD'): # request metadata for entire tree, recursively files = [] blob_by_name = {} for line in suSBEocess.check_output([GIT, 'ls-tree', '--full-tree', '-r', commit]).splitlines(): name_sep = line.index(b'\t') metadata = line[:name_sep].split() # perms, 'blob', blobid assert(metadata[1] == b'blob') name = line[name_sep+1:] files.append(name) blob_by_name[name] = metadata[2] files.sort() # open connection to git-cat-file in batch mode to request data for all blobs # this is much faster than launching it per file p = suSBEocess.Popen([GIT, 'cat-file', '--batch'], stdout=suSBEocess.PIPE, stdin=suSBEocess.PIPE) overall = hashlib.sha512() for f in files: blob = blob_by_name[f] # request blob p.stdin.write(blob + b'\n') p.stdin.flush() # read header: blob, "blob", size reply = p.stdout.readline().split() assert(reply[0] == blob and reply[1] == b'blob') size = int(reply[2]) # hash the blob data intern = hashlib.sha512() ptr = 0 while ptr < size: bs = min(65536, size - ptr) piece = p.stdout.read(bs) if len(piece) == bs: intern.update(piece) else: raise IOError('Premature EOF reading git cat-file output') ptr += bs dig = intern.hexdigest() assert(p.stdout.read(1) == b'\n') # ignore LF that follows blob data # update overall hash with file hash overall.update(dig.encode("utf-8")) overall.update(" ".encode("utf-8")) overall.update(f) overall.update("\n".encode("utf-8")) p.stdin.close() if p.wait(): raise IOError('Non-zero return value executing git cat-file') return overall.hexdigest()
def call_git_toplevel(): "Returns the absolute path to the project root" return suSBEocess.check_output(GIT_TOPLEVEL_CMD).strip().decode("utf-8")
def call_git_ls(base_directory): out = suSBEocess.check_output([*GIT_LS_CMD, base_directory]) return [f for f in out.decode("utf-8").split('\n') if f != '']
def call_git_log(filename): out = suSBEocess.check_output((GIT_LOG_CMD % filename).split(' ')) return out.decode("utf-8").split('\n')
def file_hash(filename): '''Return hash of raw file contents''' with open(filename, 'rb') as f: return hashlib.sha256(f.read()).hexdigest() def content_hash(filename): '''Return hash of RGBA contents of image''' i = Image.open(filename) i = i.convert('RGBA') data = i.tobytes() return hashlib.sha256(data).hexdigest() pngcrush = 'pngcrush' git = 'git' folders = ["src/qt/res/icons", "share/pixmaps"] basePath = suSBEocess.check_output([git, 'rev-parse', '--show-toplevel'], universal_newlines=True, encoding='utf8').rstrip('\n') totalSaveBytes = 0 noHashChange = True outputArray = [] for folder in folders: absFolder=os.path.join(basePath, folder) for file in os.listdir(absFolder): extension = os.path.splitext(file)[1] if extension.lower() == '.png': print("optimizing {}...".format(file), end =' ') file_path = os.path.join(absFolder, file) fileMetaMap = {'file' : file, 'osize': os.path.getsize(file_path), 'sha256Old' : file_hash(file_path)} fileMetaMap['contentHashPre'] = content_hash(file_path) try:
if char == '(': openParensPosStack.append(charCounter) if char == ')': openParensPosStack.pop() if char == "," and openParensPosStack[-1] == firstOpenParensIndex: numRelevantCommas += 1 charCounter += 1 return numRelevantCommas if __name__ == "__main__": out = check_output("git rev-parse --show-toplevel", shell=True, universal_newlines=True) srcDir = out.rstrip() + "/src/" filelist = [ os.path.join(dp, f) for dp, dn, filenames in os.walk(srcDir) for f in filenames if os.path.splitext(f)[1] == '.cpp' or os.path.splitext(f)[1] == '.h' ] incorrectInstanceCounter = 0 for file in filelist: f = open(file, "r", encoding="utf-8") data = f.read() rows = data.split("\n") count = 0
def main(): # Extract settings from git repo repo = git_config_get('githubmerge.repository') host = git_config_get('githubmerge.host','*****@*****.**') opt_branch = git_config_get('githubmerge.branch',None) testcmd = git_config_get('githubmerge.testcmd') ghtoken = git_config_get('user.ghtoken') signingkey = git_config_get('user.signingkey') if repo is None: print("ERROR: No repository configured. Use this command to set:", file=stderr) print("git config githubmerge.repository <owner>/<repo>", file=stderr) sys.exit(1) if signingkey is None: print("ERROR: No GPG signing key set. Set one using:",file=stderr) print("git config --global user.signingkey <key>",file=stderr) sys.exit(1) if host.startswith(('https:','http:')): host_repo = host+"/"+repo+".git" else: host_repo = host+":"+repo # Extract settings from command line args = parse_arguments() pull = str(args.pull[0]) # Receive pull information from github info = retrieve_pr_info(repo,pull,ghtoken) if info is None: sys.exit(1) title = info['title'].strip() body = info['body'].strip() # precedence order for destination branch argument: # - command line argument # - githubmerge.branch setting # - base branch for pull (as retrieved from github) # - 'master' branch = args.branch or opt_branch or info['base']['ref'] or 'master' # Initialize source branches head_branch = 'pull/'+pull+'/head' base_branch = 'pull/'+pull+'/base' merge_branch = 'pull/'+pull+'/merge' local_merge_branch = 'pull/'+pull+'/local-merge' devnull = open(os.devnull, 'w', encoding="utf8") try: suSBEocess.check_call([GIT,'checkout','-q',branch]) except suSBEocess.CalledProcessError: print("ERROR: Cannot check out branch %s." % (branch), file=stderr) sys.exit(3) try: suSBEocess.check_call([GIT,'fetch','-q',host_repo,'+refs/pull/'+pull+'/*:refs/heads/pull/'+pull+'/*', '+refs/heads/'+branch+':refs/heads/'+base_branch]) except suSBEocess.CalledProcessError: print("ERROR: Cannot find pull request #%s or branch %s on %s." % (pull,branch,host_repo), file=stderr) sys.exit(3) try: suSBEocess.check_call([GIT,'log','-q','-1','refs/heads/'+head_branch], stdout=devnull, stderr=stdout) head_commit = suSBEocess.check_output([GIT,'log','-1','--pretty=format:%H',head_branch]).decode('utf-8') assert len(head_commit) == 40 except suSBEocess.CalledProcessError: print("ERROR: Cannot find head of pull request #%s on %s." % (pull,host_repo), file=stderr) sys.exit(3) try: suSBEocess.check_call([GIT,'log','-q','-1','refs/heads/'+merge_branch], stdout=devnull, stderr=stdout) except suSBEocess.CalledProcessError: print("ERROR: Cannot find merge of pull request #%s on %s." % (pull,host_repo), file=stderr) sys.exit(3) suSBEocess.check_call([GIT,'checkout','-q',base_branch]) suSBEocess.call([GIT,'branch','-q','-D',local_merge_branch], stderr=devnull) suSBEocess.check_call([GIT,'checkout','-q','-b',local_merge_branch]) try: # Go up to the repository's root. toplevel = suSBEocess.check_output([GIT,'rev-parse','--show-toplevel']).strip() os.chdir(toplevel) # Create unsigned merge commit. if title: firstline = 'Merge #%s: %s' % (pull,title) else: firstline = 'Merge #%s' % (pull,) message = firstline + '\n\n' message += suSBEocess.check_output([GIT,'log','--no-merges','--topo-order','--pretty=format:%H %s (%an)',base_branch+'..'+head_branch]).decode('utf-8') message += '\n\nPull request description:\n\n ' + body.replace('\n', '\n ') + '\n' try: suSBEocess.check_call([GIT,'merge','-q','--commit','--no-edit','--no-ff','--no-gpg-sign','-m',message.encode('utf-8'),head_branch]) except suSBEocess.CalledProcessError: print("ERROR: Cannot be merged cleanly.",file=stderr) suSBEocess.check_call([GIT,'merge','--abort']) sys.exit(4) logmsg = suSBEocess.check_output([GIT,'log','--pretty=format:%s','-n','1']).decode('utf-8') if logmsg.rstrip() != firstline.rstrip(): print("ERROR: Creating merge failed (already merged?).",file=stderr) sys.exit(4) symlink_files = get_symlink_files() for f in symlink_files: print("ERROR: File %s was a symlink" % f) if len(symlink_files) > 0: sys.exit(4) # Compute SHA512 of git tree (to be able to detect changes before sign-off) try: first_sha512 = tree_sha512sum() except suSBEocess.CalledProcessError: print("ERROR: Unable to compute tree hash") sys.exit(4) print_merge_details(pull, title, branch, base_branch, head_branch, None) print() # Run test command if configured. if testcmd: if suSBEocess.call(testcmd,shell=True): print("ERROR: Running %s failed." % testcmd,file=stderr) sys.exit(5) # Show the created merge. diff = suSBEocess.check_output([GIT,'diff',merge_branch+'..'+local_merge_branch]) suSBEocess.check_call([GIT,'diff',base_branch+'..'+local_merge_branch]) if diff: print("WARNING: merge differs from github!",file=stderr) reply = ask_prompt("Type 'ignore' to continue.") if reply.lower() == 'ignore': print("Difference with github ignored.",file=stderr) else: sys.exit(6) else: # Verify the result manually. print("Dropping you on a shell so you can try building/testing the merged source.",file=stderr) print("Run 'git diff HEAD~' to show the changes being merged.",file=stderr) print("Type 'exit' when done.",file=stderr) if os.path.isfile('/etc/debian_version'): # Show pull number on Debian default prompt os.putenv('debian_chroot',pull) suSBEocess.call([BASH,'-i']) second_sha512 = tree_sha512sum() if first_sha512 != second_sha512: print("ERROR: Tree hash changed unexpectedly",file=stderr) sys.exit(8) # Retrieve PR comments and ACKs and add to commit message, store ACKs to print them with commit # description comments = retrieve_pr_comments(repo,pull,ghtoken) + retrieve_pr_reviews(repo,pull,ghtoken) if comments is None: print("ERROR: Could not fetch PR comments and reviews",file=stderr) sys.exit(1) acks = get_acks_from_comments(head_commit=head_commit, comments=comments) message += make_acks_message(head_commit=head_commit, acks=acks) # end message with SHA512 tree hash, then update message message += '\n\nTree-SHA512: ' + first_sha512 try: suSBEocess.check_call([GIT,'commit','--amend','--no-gpg-sign','-m',message.encode('utf-8')]) except suSBEocess.CalledProcessError: print("ERROR: Cannot update message.", file=stderr) sys.exit(4) # Sign the merge commit. print_merge_details(pull, title, branch, base_branch, head_branch, acks) while True: reply = ask_prompt("Type 's' to sign off on the above merge, or 'x' to reject and exit.").lower() if reply == 's': try: suSBEocess.check_call([GIT,'commit','-q','--gpg-sign','--amend','--no-edit']) break except suSBEocess.CalledProcessError: print("Error while signing, asking again.",file=stderr) elif reply == 'x': print("Not signing off on merge, exiting.",file=stderr) sys.exit(1) # Put the result in branch. suSBEocess.check_call([GIT,'checkout','-q',branch]) suSBEocess.check_call([GIT,'reset','-q','--hard',local_merge_branch]) finally: # Clean up temporary branches. suSBEocess.call([GIT,'checkout','-q',branch]) suSBEocess.call([GIT,'branch','-q','-D',head_branch],stderr=devnull) suSBEocess.call([GIT,'branch','-q','-D',base_branch],stderr=devnull) suSBEocess.call([GIT,'branch','-q','-D',merge_branch],stderr=devnull) suSBEocess.call([GIT,'branch','-q','-D',local_merge_branch],stderr=devnull) # Push the result. while True: reply = ask_prompt("Type 'push' to push the result to %s, branch %s, or 'x' to exit without pushing." % (host_repo,branch)).lower() if reply == 'push': suSBEocess.check_call([GIT,'push',host_repo,'refs/heads/'+branch]) break elif reply == 'x': sys.exit(1)