示例#1
0
文件: pkg.py 项目: LLNL/spack
def pkg(parser, args):
    if not spack_is_git_repo():
        tty.die("This spack is not a git clone. Can't use 'spack pkg'")

    action = {'add': pkg_add,
              'diff': pkg_diff,
              'list': pkg_list,
              'removed': pkg_removed,
              'added': pkg_added}
    action[args.pkg_command](args)
示例#2
0
def pkg(parser, args):
    if not spack_is_git_repo():
        tty.die("This spack is not a git clone. Can't use 'spack pkg'")

    action = {
        'add': pkg_add,
        'diff': pkg_diff,
        'list': pkg_list,
        'removed': pkg_removed,
        'added': pkg_added
    }
    action[args.pkg_command](args)
示例#3
0
文件: blame.py 项目: LLNL/spack
def blame(parser, args):
    # make sure this is a git repo
    if not spack_is_git_repo():
        tty.die("This spack is not a git clone. Can't use 'spack blame'")
    git = which('git', required=True)

    # Get name of file to blame
    blame_file = None
    if os.path.isfile(args.package_name):
        path = os.path.realpath(args.package_name)
        if path.startswith(spack.paths.prefix):
            blame_file = path

    if not blame_file:
        pkg = spack.repo.get(args.package_name)
        blame_file = pkg.module.__file__.rstrip('c')  # .pyc -> .py

    # get git blame for the package
    with working_dir(spack.paths.prefix):
        if args.view == 'git':
            git('blame', blame_file)
            return
        else:
            output = git('blame', '--line-porcelain', blame_file, output=str)
            lines = output.split('\n')

    # Histogram authors
    counts = {}
    emails = {}
    last_mod = {}
    total_lines = 0
    for line in lines:
        match = re.match(r'^author (.*)', line)
        if match:
            author = match.group(1)

        match = re.match(r'^author-mail (.*)', line)
        if match:
            email = match.group(1)

        match = re.match(r'^author-time (.*)', line)
        if match:
            mod = int(match.group(1))
            last_mod[author] = max(last_mod.setdefault(author, 0), mod)

        # ignore comments
        if re.match(r'^\t[^#]', line):
            counts[author] = counts.setdefault(author, 0) + 1
            emails.setdefault(author, email)
            total_lines += 1

    if args.view == 'time':
        rows = sorted(
            counts.items(), key=lambda t: last_mod[t[0]], reverse=True)
    else:  # args.view == 'percent'
        rows = sorted(counts.items(), key=lambda t: t[1], reverse=True)

    # Print a nice table with authors and emails
    table = [['LAST_COMMIT', 'LINES', '%', 'AUTHOR', 'EMAIL']]
    for author, nlines in rows:
        table += [[
            pretty_date(last_mod[author]),
            nlines,
            round(nlines / float(total_lines) * 100, 1),
            author,
            emails[author]]]

    table += [[''] * 5]
    table += [[pretty_date(max(last_mod.values())), total_lines, '100.0'] +
              [''] * 3]

    colify_table(table)
示例#4
0
def git_case_consistency_check(path):
    """Re-sync case of files in a directory with git.

    On case-insensitive but case-preserving filesystems like Mac OS X,
    Git doesn't properly rename files that only had their case changed.

    This checks files in a directory against git and does a
    case-restoring rename (actually two renames, e.g.::

        name -> tmp -> NAME

    We use this in Spack to ensure package directories are named
    correctly.

    TODO: this check can probably be removed once package names have been
    TODO: lowercase for a long while.

    """
    # Don't bother fixing case if Spack isn't in a git repository
    if not spack_is_git_repo():
        return

    git = which('git', required=False)
    if not git:
        return

    with working_dir(path):
        try:
            git_filenames = git('ls-tree', '--name-only', 'HEAD', output=str)
            git_filenames = set(re.split(r'\s+', git_filenames.strip()))
        except ProcessError:
            return  # Ignore errors calling git

        lower_to_mixed = {}
        for fn in git_filenames:
            lower = fn.lower()
            mixed = lower_to_mixed.setdefault(lower, [])
            mixed.append(fn)

        # Iterate through all actual files and make sure their names are
        # the same as corresponding names in git
        actual_filenames = os.listdir('.')
        for actual in actual_filenames:
            lower = actual.lower()

            # not tracked by git
            if lower not in lower_to_mixed:
                continue

            # Don't know what to do with multiple matches
            if len(lower_to_mixed[lower]) != 1:
                continue

            # Skip if case is already correct
            git_name = lower_to_mixed[lower][0]
            if git_name == actual:
                continue

            # restore case with two renames
            tmp_name = actual + '.spack.tmp'
            os.rename(actual, tmp_name)
            os.rename(tmp_name, git_name)
示例#5
0
def blame(parser, args):
    # make sure this is a git repo
    if not spack_is_git_repo():
        tty.die("This spack is not a git clone. Can't use 'spack blame'")
    git = which('git', required=True)

    # Get name of file to blame
    blame_file = None
    if os.path.isfile(args.package_or_file):
        path = os.path.realpath(args.package_or_file)
        if path.startswith(spack.paths.prefix):
            blame_file = path

    if not blame_file:
        pkg = spack.repo.get(args.package_or_file)
        blame_file = pkg.module.__file__.rstrip('c')  # .pyc -> .py

    # get git blame for the package
    with working_dir(spack.paths.prefix):
        if args.view == 'git':
            git('blame', blame_file)
            return
        else:
            output = git('blame', '--line-porcelain', blame_file, output=str)
            lines = output.split('\n')

    # Histogram authors
    counts = {}
    emails = {}
    last_mod = {}
    total_lines = 0
    for line in lines:
        match = re.match(r'^author (.*)', line)
        if match:
            author = match.group(1)

        match = re.match(r'^author-mail (.*)', line)
        if match:
            email = match.group(1)

        match = re.match(r'^author-time (.*)', line)
        if match:
            mod = int(match.group(1))
            last_mod[author] = max(last_mod.setdefault(author, 0), mod)

        # ignore comments
        if re.match(r'^\t[^#]', line):
            counts[author] = counts.setdefault(author, 0) + 1
            emails.setdefault(author, email)
            total_lines += 1

    if args.view == 'time':
        rows = sorted(counts.items(),
                      key=lambda t: last_mod[t[0]],
                      reverse=True)
    else:  # args.view == 'percent'
        rows = sorted(counts.items(), key=lambda t: t[1], reverse=True)

    # Print a nice table with authors and emails
    table = [['LAST_COMMIT', 'LINES', '%', 'AUTHOR', 'EMAIL']]
    for author, nlines in rows:
        table += [[
            pretty_date(last_mod[author]), nlines,
            round(nlines / float(total_lines) * 100, 1), author, emails[author]
        ]]

    table += [[''] * 5]
    table += [[pretty_date(max(last_mod.values())), total_lines, '100.0'] +
              [''] * 3]

    colify_table(table)
示例#6
0
文件: blame.py 项目: key4hep/spack
def blame(parser, args):
    # make sure this is a git repo
    if not spack_is_git_repo():
        tty.die("This spack is not a git clone. Can't use 'spack blame'")
    git = which('git', required=True)

    # Get name of file to blame
    blame_file = None
    if os.path.isfile(args.package_or_file):
        path = os.path.realpath(args.package_or_file)
        if path.startswith(spack.paths.prefix):
            blame_file = path

    if not blame_file:
        pkg = spack.repo.get(args.package_or_file)
        blame_file = pkg.module.__file__.rstrip('c')  # .pyc -> .py

    # get git blame for the package
    with working_dir(spack.paths.prefix):
        if args.view == 'git':
            git('blame', blame_file)
            return
        else:
            output = git('blame', '--line-porcelain', blame_file, output=str)
            lines = output.split('\n')

    # Histogram authors
    counts = {}
    emails = {}
    last_mod = {}
    total_lines = 0
    for line in lines:
        match = re.match(r'^author (.*)', line)
        if match:
            author = match.group(1)

        match = re.match(r'^author-mail (.*)', line)
        if match:
            email = match.group(1)

        match = re.match(r'^author-time (.*)', line)
        if match:
            mod = int(match.group(1))
            last_mod[author] = max(last_mod.setdefault(author, 0), mod)

        # ignore comments
        if re.match(r'^\t[^#]', line):
            counts[author] = counts.setdefault(author, 0) + 1
            emails.setdefault(author, email)
            total_lines += 1

    if args.view == 'time':
        rows = sorted(counts.items(),
                      key=lambda t: last_mod[t[0]],
                      reverse=True)
    else:  # args.view == 'percent'
        rows = sorted(counts.items(), key=lambda t: t[1], reverse=True)

    # Dump as json
    if args.json:
        dump_json(rows, last_mod, total_lines, emails)

    # Print a nice table with authors and emails
    else:
        print_table(rows, last_mod, total_lines, emails)