Skip to content

Instantly share code, notes, and snippets.

@tiffany352
Last active August 24, 2022 22:01
Show Gist options
  • Save tiffany352/c0a17b6ef0dd8ff5ee0276b9d3bad43f to your computer and use it in GitHub Desktop.
Save tiffany352/c0a17b6ef0dd8ff5ee0276b9d3bad43f to your computer and use it in GitHub Desktop.

Revisions

  1. tiffany352 revised this gist Aug 24, 2022. 1 changed file with 26 additions and 0 deletions.
    26 changes: 26 additions & 0 deletions all_owners.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,26 @@
    import io
    import subprocess
    import whoowns
    import argparse

    def main():
    parser = argparse.ArgumentParser(description="Generates a CSV of all files in the repo and which codeowner is set.")
    parser.add_argument("out")
    args = parser.parse_args()

    owners = whoowns.get_owners('./CODEOWNERS')

    file = io.open(args.out, "w", encoding="utf-8")
    file.write("path,owners\n")

    all_files = subprocess.run(["git", "ls-files"], capture_output=True, text=True).stdout.split('\n')
    for path in all_files:
    file_owners = owners.of(path)
    file.write("%s,%s\n" % (path, " ".join(map(lambda o: o[1], file_owners))))

    file.flush()
    file.close()


    if __name__ == "__main__":
    main()
  2. tiffany352 created this gist Aug 24, 2022.
    41 changes: 41 additions & 0 deletions commands.nu
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,41 @@

    # Returns list of codeowners for files touched in current branch.
    def "whoowns" [] {
    let root = (git rev-parse --show-toplevel | str trim)
    enter $root
    let changed_files = (git diff --name-only upstream/master...HEAD | lines)
    let files = (python ~\Documents\Scripts\whoowns.py $changed_files)
    exit
    $files | from csv | sort-by owner file
    }

    def "flag-status" [] {
    ls flags\tbennett\ |
    par-each {|it|
    do -i {
    git log -1 --pretty=format:%ci $it.name
    } |
    complete |
    select stdout |
    update stdout { |it|
    $it.stdout |
    into datetime
    } |
    insert flag {
    $it.name |
    parse "flags\\tbennett\\{flag}.json" |
    get flag
    }
    } |
    rename date flag |
    flatten |
    sort-by date
    }

    def "merge-stable" [branch] {
    git checkout $branch;
    git pull --set-upstream origin $branch;
    git fetch upstream;
    git merge upstream/stable;
    git push
    }
    82 changes: 82 additions & 0 deletions team_flags.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,82 @@
    import glob
    import argparse
    import json
    import os
    import subprocess
    import re
    import sys

    from codeowners import CodeOwners
    import whoowns

    flag_regex = re.compile('FASTFLAGVARIABLE\((\w+),\s*\w+\)')

    def main():
    parser = argparse.ArgumentParser(description="Find fast flags owned by the given team")
    parser.add_argument("team")
    parser.add_argument("fflags_repo")
    args = parser.parse_args()
    team = args.team
    fflags_repo = args.fflags_repo
    co_path = whoowns.find_codeowners_path(os.getcwd())
    dir, filename = os.path.split(co_path)
    os.chdir(dir)

    files = list(filter(lambda f: f.endswith((".h", ".cpp")), subprocess.run(["git", "ls-files"], capture_output=True, text=True).stdout.split('\n')))

    owner = ('TEAM', team)

    with open(co_path, "rt") as f:
    owners = CodeOwners(f.read())
    found = []
    count = 0
    last = None
    for file in files:
    next = count / len(files) * 100.0
    if last != next:
    if last != None:
    sys.stdout.write("\x1b[1A\x1b[2K") # move up cursor and delete whole line
    print("Running... %d%%" % (next))
    last = next
    count += 1
    # print("testing", file)
    # print("owners", owners.of(file))
    # print("needle", owner)
    if owner in owners.of(file):
    # print("have match!!!!", file)
    with open(file, "rt") as f:
    for flag in flag_regex.findall(f.read()):
    # print(file, flag)
    flag_glob = "flags/*/*%s.json" % flag
    # print(flag_glob)
    # print(fflags_repo)
    flag_value = None
    flag_age = ''
    flag_timestamp = 0
    for match in glob.glob(flag_glob, root_dir=fflags_repo, recursive=True):
    with open(fflags_repo + "/" + match, "rt") as f:
    data = json.load(f)
    flag_age = subprocess.run(["git", "log", "-n", "1", "--pretty=format:%cr", file], capture_output=True, text=True).stdout
    flag_timestamp = int(subprocess.run(["git", "log", "-n", "1", "--pretty=format:%ct", file], capture_output=True, text=True).stdout)
    if 'Buckets' in data:
    flag_value = "complex"
    else:
    for bucket, value in data.items():
    flag_value = "%s in %s" % (value, bucket)
    # print("| % 50s | % 50s | % 20s | % 15s |" % (file, flag, flag_value, flag_age))
    found.append({
    "file": file.removeprefix('Client/'),
    "flag": flag,
    "value": flag_value,
    "age": flag_age,
    "timestamp": flag_timestamp,
    })

    found.sort(key=lambda item: item["timestamp"])
    sys.stdout.write("\x1b[1A\x1b[2K") # delete progress bar
    for item in found:
    print("| % 50s | % 50s | % 20s | % 15s |" % (item["file"], item["flag"], item["value"], item["age"]))


    if __name__ == "__main__":
    main()
    66 changes: 66 additions & 0 deletions whoowns.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,66 @@
    import argparse
    import codeowners
    import os

    def find_codeowners_path(p):
    """Searches the folder containing the path 'p' and all parents until
    a CODEOWNERS file is found. Returns 'None' if no file is found."""
    head, tail = os.path.split(p)
    if tail == '':
    return None
    co_path = os.path.join(head, 'CODEOWNERS')
    if os.path.exists(co_path):
    return os.path.normpath(co_path)
    else:
    return find_codeowners_path(head)

    def make_relative(root, path):
    """Converts a path to a unix-style path relative to the root folder"""
    p = os.path.normpath(os.path.abspath(path))
    abs_root = os.path.abspath(root)
    prefix = os.path.commonprefix([abs_root, p])
    if prefix != abs_root:
    raise Exception(f'{p} does not exist under the root folder {abs_root}')
    relpath = os.path.relpath(p, abs_root)
    return relpath.replace('\\', '/')

    def describe_owners(file_path):
    co_path = find_codeowners_path(file_path)
    if co_path:
    owners = get_owners(co_path)
    rel_path = make_relative(os.path.split(co_path)[0], file_path)
    results = owners.of(rel_path)
    if len(results) == 0:
    print(f'"{file_path}",none,"No matching entries in CODEOWNERS"')
    else:
    for result in results:
    print(f'"{file_path}",{result[0].lower()},"{result[1]}"')
    else:
    print(f'"{file_path}",none,"Unable to find CODEOWNERS file"')

    def get_owners(co_path):
    """Get a CodeOwners object for the specified CODEOWNERS file path"""
    with open(co_path, "rt") as f:
    # process the file to remove leading /'s which don't seem to be handled properly by the
    # codeowners python module.
    contents = []
    for line in f.readlines():
    stripped_line = line.strip()
    if stripped_line.startswith('/'):
    stripped_line = stripped_line[1:]
    contents.append(stripped_line)
    processed = "\n".join(contents)

    return codeowners.CodeOwners(processed)

    def main():
    parser = argparse.ArgumentParser(description="Show user/team ownership information for specified files")
    parser.add_argument("files", nargs='+')
    args = parser.parse_args()

    print('file,owner_type,owner')
    for file in args.files:
    describe_owners(file)

    if __name__ == "__main__":
    main()