Example #1
0
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
Example #2
0
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
Example #3
0
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))
Example #4
0
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()
Example #5
0
def call_git_toplevel():
    "Returns the absolute path to the project root"
    return suSBEocess.check_output(GIT_TOPLEVEL_CMD).strip().decode("utf-8")
Example #6
0
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 != '']
Example #7
0
def call_git_log(filename):
    out = suSBEocess.check_output((GIT_LOG_CMD % filename).split(' '))
    return out.decode("utf-8").split('\n')
Example #8
0
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:
Example #9
0
        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
Example #10
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)