From 23fe904517f195f24e338edb7735c37c1b2b1dd3 Mon Sep 17 00:00:00 2001 From: Casper da Costa-Luis Date: Mon, 9 Nov 2020 13:21:19 +0000 Subject: [PATCH 1/5] CI: fix and update test framework --- .travis.yml | 12 ++++-------- tox.ini | 7 +++---- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index b66e73e..371e793 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,7 @@ language: python env: global: - PIP_CACHE_DIR="$HOME/.cache/pip" # unify pip cache location for all platforms + - TOXENV=py cache: pip: true directories: @@ -20,25 +21,20 @@ jobs: - stage: test name: py2.7 python: 2.7 - env: TOXENV=py27 - name: py3.4 python: 3.4 env: TOXENV=py34 - name: py3.5 python: 3.5 - env: TOXENV=py35 - name: py3.6 python: 3.6 - env: TOXENV=py36 - name: py3.7 python: 3.7 - env: TOXENV=py37 - name: py3.8 python: 3.8 - env: TOXENV=py38 - - name: pypy2.7 - python: pypy - env: TOXENV=pypy + - name: pypy2 + python: pypy2 + env: CRYPTOGRAPHY_ALLOW_OPENSSL_102=1 - name: pypy3 python: pypy3 env: TOXENV=pypy3 diff --git a/tox.ini b/tox.ini index ae2102d..598faa1 100644 --- a/tox.ini +++ b/tox.ini @@ -53,8 +53,7 @@ deps = {[extra]deps} [testenv:flake8] deps = flake8 commands = - flake8 --max-line-length=80 --exclude .tox,build \ - --ignore=E111,E114 -j 8 --count --statistics --exit-zero . + flake8 -j 8 --count --statistics --exit-zero . [testenv:setup.py] deps = @@ -62,5 +61,5 @@ deps = pygments py-make>=0.1.0 commands = - python setup.py check --restructuredtext --metadata --strict - python setup.py make none + {envpython} setup.py check --restructuredtext --metadata --strict + {envpython} setup.py make none From e9ab149a3e2b867bfcd684681df64a11f935e157 Mon Sep 17 00:00:00 2001 From: Casper da Costa-Luis Date: Mon, 9 Nov 2020 13:36:50 +0000 Subject: [PATCH 2/5] add `--enum` - fixes #46 --- README.rst | 1 + git-fame_completion.bash | 2 +- gitfame/_gitfame.py | 16 +++++++++------- gitfame/git-fame.1 | 7 ++++++- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/README.rst b/README.rst index a5a69ff..dfda965 100644 --- a/README.rst +++ b/README.rst @@ -187,6 +187,7 @@ Documentation --warn-binary Don't silently skip files which appear to be binary data [default: False]. -e, --show-email Show author email instead of name [default: False]. + --enum Show row numbers [default: False]. -t, --bytype Show stats per file extension [default: False]. -w, --ignore-whitespace Ignore whitespace when comparing the parent's version and the child's to find where the lines diff --git a/git-fame_completion.bash b/git-fame_completion.bash index 714c714..88db9e0 100644 --- a/git-fame_completion.bash +++ b/git-fame_completion.bash @@ -32,7 +32,7 @@ _git_fame() ;; *) if [ ${COMP_WORDS[1]} == fame ]; then - COMPREPLY=($(compgen -dW '-h --help -v --version --cost --branch --since --sort --incl --excl -n --no-regex -s --silent-progress --warn-binary -t --bytype -w --ignore-whitespace -e --show-email -M -C --format --manpath --log' -- ${cur})) + COMPREPLY=($(compgen -dW '-h --help -v --version --cost --branch --since --sort --incl --excl -n --no-regex -s --silent-progress --warn-binary -t --bytype -w --ignore-whitespace -e --show-email --enum -M -C --format --manpath --log' -- ${cur})) fi ;; esac diff --git a/gitfame/_gitfame.py b/gitfame/_gitfame.py index c03892c..161611d 100755 --- a/gitfame/_gitfame.py +++ b/gitfame/_gitfame.py @@ -29,6 +29,7 @@ --warn-binary Don't silently skip files which appear to be binary data [default: False]. -e, --show-email Show author email instead of name [default: False]. + --enum Show row numbers [default: False]. -t, --bytype Show stats per file extension [default: False]. -w, --ignore-whitespace Ignore whitespace when comparing the parent's version and the child's to find where the lines @@ -115,7 +116,7 @@ def hours(dates, maxCommitDiffInSec=120 * 60, firstCommitAdditionInMinutes=120): def tabulate( auth_stats, stats_tot, sort='loc', bytype=False, backend='md', - cost=None): + cost=None, row_nums=False): """ backends : [default: md]|yaml|json|csv|tsv|tabulate| `in tabulate.tabulate_formats` @@ -133,16 +134,14 @@ def tabulate( 100 * len(s.get('files', [])) / max(1, stats_tot['files']) ))).replace('/100.0/', '/ 100/')] for (auth, s) in it_as()] - if cost is None: - cost = '' if cost: - cost = cost.lower() + cost = set(cost.lower().split(',')) stats_tot = dict(stats_tot) - if any(i in cost for i in ['cocomo', 'month']): + if cost & {'cocomo', 'month'}: COL_NAMES.insert(1, 'mths') tab = [i[:1] + [3.2 * (i[1] / 1e3)**1.05] + i[1:] for i in tab] stats_tot.setdefault('months', '%.1f' % sum(i[1] for i in tab)) - if any(i in cost for i in ['commit', 'hour']): + if cost & {'commit', 'hour'}: COL_NAMES.insert(1, 'hrs') tab = [i[:1] + [hours(auth_stats[i[0]]['ctimes'])] + i[1:] for i in tab] @@ -153,6 +152,9 @@ def tabulate( ("months", "mths")]: sort = sort.replace(i, j) tab.sort(key=lambda i: i[COL_NAMES.index(sort)], reverse=True) + if row_nums: + tab = [[str(i)] + j for i, j in enumerate(tab, 1)] + COL_NAMES.insert(0, '#') totals = 'Total ' + '\nTotal '.join( "%s: %s" % i for i in sorted(stats_tot.items())) + '\n' @@ -390,7 +392,7 @@ def run(args): print_unicode(tabulate( auth_stats, stats_tot, - args.sort, args.bytype, args.format, args.cost)) + args.sort, args.bytype, args.format, args.cost, args.enum)) def get_main_parser(): diff --git a/gitfame/git-fame.1 b/gitfame/git-fame.1 index d590ae7..a16a99e 100644 --- a/gitfame/git-fame.1 +++ b/gitfame/git-fame.1 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pandoc 1.19.2.1 +.\" Automatically generated by Pandoc 1.19.2 .\" .TH "GIT\-FAME" "1" "2016\-2018" "git\-fame User Manuals" "" .hy @@ -109,6 +109,11 @@ Show author email instead of name [default: False]. .RS .RE .TP +.B \-\-enum +Show row numbers [default: False]. +.RS +.RE +.TP .B \-t, \-\-bytype Show stats per file extension [default: False]. .RS From 21ee3647f9a0f92ae31c2fc2ae68c985f7ed2de4 Mon Sep 17 00:00:00 2001 From: Casper da Costa-Luis Date: Mon, 9 Nov 2020 14:08:06 +0000 Subject: [PATCH 3/5] add & fix tests --- gitfame/_gitfame.py | 4 ++-- gitfame/tests/tests_gitfame.py | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/gitfame/_gitfame.py b/gitfame/_gitfame.py index 161611d..a5419e7 100755 --- a/gitfame/_gitfame.py +++ b/gitfame/_gitfame.py @@ -137,11 +137,11 @@ def tabulate( if cost: cost = set(cost.lower().split(',')) stats_tot = dict(stats_tot) - if cost & {'cocomo', 'month'}: + if cost & {'cocomo', 'month', 'months'}: COL_NAMES.insert(1, 'mths') tab = [i[:1] + [3.2 * (i[1] / 1e3)**1.05] + i[1:] for i in tab] stats_tot.setdefault('months', '%.1f' % sum(i[1] for i in tab)) - if cost & {'commit', 'hour'}: + if cost & {'commit', 'commits', 'hour', 'hours'}: COL_NAMES.insert(1, 'hrs') tab = [i[:1] + [hours(auth_stats[i[0]]['ctimes'])] + i[1:] for i in tab] diff --git a/gitfame/tests/tests_gitfame.py b/gitfame/tests/tests_gitfame.py index ff42f03..618bc95 100644 --- a/gitfame/tests/tests_gitfame.py +++ b/gitfame/tests/tests_gitfame.py @@ -147,6 +147,15 @@ def test_tabulate_tabulate(): raise SkipTest +def test_tabulate_enum(): + """Test --enum tabulate""" + from json import loads + res = loads(_gitfame.tabulate( + auth_stats, stats_tot, backend='json', row_nums=True)) + assert res['columns'][0] == '#' + assert [int(i[0]) for i in res['data']] == [1, 2] + + def test_tabulate_unknown(): """Test unknown tabulate format""" try: From 13937872921164efe63226e46c58ce9a625223c7 Mon Sep 17 00:00:00 2001 From: Casper da Costa-Luis Date: Mon, 9 Nov 2020 16:45:45 +0000 Subject: [PATCH 4/5] CI: rely more on GHA --- .github/workflows/test.yml | 41 ++++++++++++++++++++++++++++++++++++++ .travis.yml | 20 ------------------- 2 files changed, 41 insertions(+), 20 deletions(-) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..a82ea80 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,41 @@ +name: Test +on: + push: + schedule: + - cron: '3 2 1 * *' # M H d m w (monthly at 2:03) +jobs: + check: + name: Check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: '3.x' + - name: Install + run: | + pip install -U tox + pip install -U . + - name: Test + run: tox + env: + TOXENV: 'flake8,setup.py,nodeps' + test: + strategy: + matrix: + python: [3.4, 3.5, 3.6, 3.8] + name: Python ${{ matrix.python }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python }} + - name: Install + run: | + pip install -U tox setuptools_scm + pip install -U . + - name: Test + run: tox -e py${PYVER/./} + env: + PYVER: ${{ matrix.python }} diff --git a/.travis.yml b/.travis.yml index 371e793..9184f49 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,6 @@ before_cache: notifications: email: false stages: -- check - test - name: deploy if: repo = casperdcl/git-fame AND NOT type = pull_request @@ -21,33 +20,14 @@ jobs: - stage: test name: py2.7 python: 2.7 - - name: py3.4 - python: 3.4 - env: TOXENV=py34 - - name: py3.5 - python: 3.5 - - name: py3.6 - python: 3.6 - name: py3.7 python: 3.7 - - name: py3.8 - python: 3.8 - name: pypy2 python: pypy2 env: CRYPTOGRAPHY_ALLOW_OPENSSL_102=1 - name: pypy3 python: pypy3 env: TOXENV=pypy3 - - stage: check - name: style - python: 3.7 - env: TOXENV=flake8 - - name: setup - python: 3.7 - env: TOXENV=setup.py - - name: nodeps - python: 3.7 - env: TOXENV=nodeps - stage: deploy name: PyPI and GitHub python: 3.7 From b82c212c9ad800d674b76a4145cccc90495b76bc Mon Sep 17 00:00:00 2001 From: Casper da Costa-Luis Date: Mon, 9 Nov 2020 17:01:50 +0000 Subject: [PATCH 5/5] lint --- gitfame/_utils.py | 8 ++++---- setup.cfg | 2 +- setup.py | 10 +++++----- tox.ini | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/gitfame/_utils.py b/gitfame/_utils.py index 794a6cd..3f2d209 100644 --- a/gitfame/_utils.py +++ b/gitfame/_utils.py @@ -3,7 +3,9 @@ import sys import subprocess import logging -log = logging.getLogger(__name__) # NOQA + +from tqdm import tqdm +from tqdm.utils import _screen_shape_wrapper try: # python2 @@ -17,9 +19,6 @@ _range = range from io import StringIO string_types = (str,) - -from tqdm import tqdm -from tqdm.utils import _screen_shape_wrapper try: from threading import RLock except ImportError: @@ -36,6 +35,7 @@ __copyright__ = ' '.join(("Copyright (c)", __date__, __author__, __licence__)) __license__ = __licence__ # weird foreign language +log = logging.getLogger(__name__) TERM_WIDTH = _screen_shape_wrapper()(sys.stdout)[0] if not TERM_WIDTH: # non interactive pipe diff --git a/setup.cfg b/setup.cfg index 192387d..b9bffee 100644 --- a/setup.cfg +++ b/setup.cfg @@ -4,4 +4,4 @@ universal = 1 [flake8] max-line-length=80 ignore=E111,E114 -exclude=.tox,build +exclude=.eggs,.tox,build diff --git a/setup.py b/setup.py index 12ced58..0c3f844 100644 --- a/setup.py +++ b/setup.py @@ -24,11 +24,11 @@ def cythonize(*args, **kwargs): __licence__ = None src_dir = os.path.abspath(os.path.dirname(__file__)) main_file = os.path.join(src_dir, 'gitfame', '_gitfame.py') -for l in io_open(main_file, mode='r'): - if l.startswith('__author__'): - __author__ = literal_eval(l.split('=', 1)[1].strip()) - elif l.startswith('__licence__'): - __licence__ = literal_eval(l.split('=', 1)[1].strip()) +for line in io_open(main_file, mode='r'): + if line.startswith('__author__'): + __author__ = literal_eval(line.split('=', 1)[1].strip()) + elif line.startswith('__licence__'): + __licence__ = literal_eval(line.split('=', 1)[1].strip()) # Executing makefile commands if specified if sys.argv[1].lower().strip() == 'make': diff --git a/tox.ini b/tox.ini index 598faa1..b44eaa4 100644 --- a/tox.ini +++ b/tox.ini @@ -53,7 +53,7 @@ deps = {[extra]deps} [testenv:flake8] deps = flake8 commands = - flake8 -j 8 --count --statistics --exit-zero . + flake8 -j 8 --count --statistics . [testenv:setup.py] deps =