Repository: d0c-s4vage/lookatme (language: python)

Issue:
Stop using TravisCI and coveralls
**Describe the Feature Request**
We should be using GitHub actions


Discussion / hints:

Fix patch:
diff --git a/.travis-ci.yml b/.travis-ci.yml
deleted file mode 100644
index e69de29..0000000
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 77bdeeb..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-language: python
-python:
-- '3.6'
-- '3.7'
-install:
-- export VERSION=$(sed 's/^v//' <<<"${TRAVIS_TAG:-0.0.0+$(sed 's^[/_-]^.^g' <<<$TRAVIS_BRANCH)}")
-- find . -type f -exec sed -i "s/{{VERSION}}/${VERSION}/g" {} \;
-- pip install tox
-script: tox
-deploy:
-  provider: pypi
-  username: "__token__"
-  password:
-    secure: "g+xvLDSGPft/PFkRVooVem2IMh4+jckq/EKNguYRgXgn1iL1ro2lLWxZ54LCsndHTuHgLXWj2zxpIakDdm9faNLV7mvyV8kxVOZu8aSazEDIwtagKEidEXFcIz9j0rXS+OuV2FqZWvbnf4x9fOxVGT4V06doLq5a+VTnygTHhfvmxExhfgbG/eGgKJNfHoCjjXS49T2cBHQa/CdmtOqtEbCeJ/MBeeF+yf1tc3xq8PxdoQ4hZFpGMO1aF/O6ENOWfpBXIm8XFlzLHQA4hN0q4EkC5+kSa5/t476rXKJ3iN29oCD9yQIFUHEBamdz/QYQUldE5qJ41NEjBlI2xgBDFWXDexgDDcfSDStQ/RfFsn6Ydu9XmLfwhzNVS9I0LEFvzrpNCkZuQvUcFRAfEK5Hz6m2+Er6395L/TUxO0JkZGoMsTqkCTnsYHQ4XY2uw518T2vwyD0g0PZMymm75ADkrKA9kv+jRx8QM7pFnW5IMF3CaHMI9YBd4zLEnqeEXE7p3MhyrJhMt3f4cZ6bXnTM3itmEMW3M11hdHnyzgbP9M8xGEvj7PHCuU6mZINpsmEzud+q12Q1wzS2zcqLdPCR8kjkYg/6ZrfbCPKAXG5fnXiOAJi9ZN5iJErGhyvUW63fpm3DYmkMhANyx68hSrhA+YFbBiZ1MhISmsOgX8taqRI="
-  skip_cleanup: true
-  skip_existing: true
-  on:
-    tags: true
diff --git a/bin/_utils.sh b/bin/_utils.sh
new file mode 100644
index 0000000..2a5a866
--- /dev/null
+++ b/bin/_utils.sh
@@ -0,0 +1,71 @@
+#!/usr/bin/env bash
+
+LOG_PREFIX="[>>>]"
+
+function check_deps {
+    local log_missing=false
+    if [ "$1" == "--log" ] ; then
+        log_missing=true
+        shift
+    fi
+
+    exit_code=0
+    while [ $# -gt 0 ] ; do
+        if ! command -v "$1" &> /dev/null ; then
+            exit_code=1
+            if [ "$log_missing" == true ] ; then
+                log "Dependency '$1' is missing"
+            fi
+        fi
+        shift
+    done
+    return $exit_code
+}
+
+function log {
+    echo "${LOG_PREFIX} $@"
+}
+
+function log_indent {
+    sed "s/^/    /g"
+}
+
+function log_box_indent {
+    log '  ╭──────'
+    sed "s/^/${LOG_PREFIX}   │ /g"
+    log '  ╰──────'
+}
+
+function indent {
+    sed "s/^/    /g"
+}
+
+function box_indent {
+    echo '  ╭──────'
+    sed "s/^/  │ /g"
+    echo '  ╰──────'
+}
+
+function run_boxed {
+    log "Running command '$@'"
+    "$@" | log_box_indent
+}
+
+function run_with_summary {
+    exit_code=0
+    results=()
+    while [ "$#" -gt 0 ] ; do
+        "$1"
+        if [ $? -ne 0 ] ; then
+            exit_code=$?
+            results+=("   FAIL: $1")
+        else
+            results+=("SUCCESS: $1")
+        fi
+        shift
+    done
+
+    for result in "${results[@]}" ; do
+        log "RESULT: ${result}"
+    done
+}
diff --git a/bin/ci b/bin/ci
new file mode 100755
index 0000000..62dcafe
--- /dev/null
+++ b/bin/ci
@@ -0,0 +1,188 @@
+#!/usr/bin/env bash
+
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
+THIS_PROG="$0"
+
+set -o pipefail
+
+# load utility functions
+. "${DIR}/_utils.sh"
+
+# -----------------------------------------------------------------
+# Main Functions --------------------------------------------------
+# -----------------------------------------------------------------
+
+SUBCOMMAND="all"
+AUTOFIX=false
+COLOR=false
+RUN_PREFIX="run_boxed"
+
+CODE_DIRS=(
+    lookatme
+    tests
+)
+
+function run_flake8 {
+    if [ "$AUTOFIX" == "true" ] ; then
+        log "No autofix for flake8"
+    else
+        local exit_code=0
+        local color_opt=""
+        [ "$COLOR" == true ] && color_opt="--color always"
+
+        $RUN_PREFIX flake8 "${CODE_DIRS[@]}" $color_opt \
+            --count \
+            --select=E9,F63,F7,F82 \
+            --show-source \
+            --statistics
+        [ $? -ne 0 ] && exit_code=1
+
+        $RUN_PREFIX flake8 "${CODE_DIRS[@]}" $color_opt \
+            --count \
+            --exit-zero \
+            --max-complexity=10 \
+            --max-line-length=127 \
+            --statistics
+        [ $? -ne 0 ] && exit_code=1
+
+        return $exit_code
+    fi
+}
+
+function run_autopep8 {
+    if [ "$AUTOFIX" == "true" ] ; then
+        $RUN_PREFIX autopep8 -r --in-place "${CODE_DIRS[@]}"
+    else
+        log "autopep8 is only used with --autofix"
+    fi
+}
+
+function run_pytest {
+    if [ "$AUTOFIX" == "true" ] ; then
+        log "🤣 LOL, no autofix for pytest!"
+    else
+        local color_opt=""
+        [ "$COLOR" == true ] && color_opt="--color=yes"
+
+        $RUN_PREFIX pytest "$color_opt"
+    fi
+}
+
+function run_isort {
+    if [ "$AUTOFIX" == "true" ] ; then
+        $RUN_PREFIX isort "${CODE_DIRS[@]}"
+    else
+        $RUN_PREFIX isort --check --diff "${CODE_DIRS[@]}"
+    fi
+}
+
+function run_pyright {
+    if [ "$AUTOFIX" == "true" ] ; then
+        log "🤣 LOL, no autofix for pyright!"
+    else
+        if [ "$COLOR" == true ] ; then
+            pyright "${CODE_DIRS[@]}"
+        else
+            $RUN_PREFIX pyright "${CODE_DIRS[@]}"
+        fi
+    fi
+}
+
+function run_all {
+    check_deps --log \
+        isort \
+        flake8 \
+        pytest \
+        autopep8 \
+        pyright
+    if [ $? -ne 0 ] ; then
+        log "Can't run all, did you forget to use a virtual environment?"
+        exit 1
+    fi
+
+    run_with_summary \
+        run_isort \
+        run_flake8 \
+        run_autopep8 \
+        run_pyright \
+        run_pytest
+}
+
+function show_help {
+    cat <<-EOF
+USAGE: ${THIS_PROG} [SUBCOMMAND] [--auto|--autofix] [--color]
+
+This is a basic way to run CI locally for lookatme. This is the same script
+that lookatme's CI uses in GitHub actions. Running this script with zero
+arguments (or the subcommand "all") will run all linting/analysis/tests that
+CI runs.
+
+SUBCOMMAND may be one of the below values. The default is "all":
+       all - Run all commands
+     isort - Run isort
+    pytest - Run pytest tests
+    flake8 - Run flake8
+  autopep8 - Run autopep8
+
+ --autofix  Run the command's autofix functionality
+ --color    Run the command with color
+ --plain    Do not box the output of the command, let it be printed plain
+EOF
+    exit 1
+}
+
+function parse_args {
+    while [ $# -ne 0 ] ; do
+        param="$1"
+        shift
+
+        case "$param" in
+            --help|-h)
+                show_help
+                exit 1
+                ;;
+            all|pytest|flake8|test|isort|autopep8|pyright)
+                SUBCOMMAND="$param"
+                ;;
+            --plain)
+                RUN_PREFIX=""
+                ;;
+            --color)
+                COLOR=true
+                ;;
+            --autofix|--auto)
+                AUTOFIX=true
+                ;;
+            *)
+                echo "[!] Unrecognized parameter $param"
+                echo
+                show_help
+                exit 1
+                ;;
+        esac
+    done
+}
+
+parse_args "$@"
+
+case "$SUBCOMMAND" in
+    all)
+        run_all
+        ;;
+    isort)
+        run_isort
+        ;;
+    flake8)
+        run_flake8
+        ;;
+    autopep8)
+        run_autopep8
+        ;;
+    pyright)
+        run_pyright
+        ;;
+    test|pytest)
+        run_pytest
+        ;;
+esac
diff --git a/tox.ini b/tox.ini
index f719e8e..4a6ddff 100644
--- a/tox.ini
+++ b/tox.ini
@@ -9,11 +9,9 @@ deps = -r requirements.txt
     -r requirements.test.txt
 whitelist_externals =
     bash
-    coveralls
 commands =
     # NOTE: you can run any command line tool here - not just tests
     pytest --cov lookatme --cov-report term-missing {posargs}
-    bash -c "coveralls || true"
 
 
 [testenv:docs]


Test patch:
diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml
new file mode 100644
index 0000000..3942a59
--- /dev/null
+++ b/.github/workflows/testing.yml
@@ -0,0 +1,83 @@
+name: "testing"
+
+on:
+  push:
+    branches: [ "main" ]
+  pull_request:
+    branches: [ "main" ]
+
+jobs:
+  isort:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+      - name: Setup Python 3.10
+        uses: actions/setup-python@v4
+        with:
+          python-version: "3.10"
+          architecture: "x64"
+      - name: Install dependencies
+        run: |
+          python -m pip install --upgrade pip
+          pip install -r requirements.test.txt
+      - name: Check if imports are sorted
+        run: |
+          bin/ci isort --plain
+
+  flake8:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+      - name: Setup Python 3.10
+        uses: actions/setup-python@v4
+        with:
+          python-version: "3.10"
+          architecture: "x64"
+      - name: Install dependencies
+        run: |
+          python -m pip install --upgrade pip
+          pip install -r requirements.test.txt
+      - name: Lint with flake8
+        run: |
+          bin/ci flake8 --plain
+
+  pyright:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+      - name: Setup Python 3.10
+        uses: actions/setup-python@v4
+        with:
+          python-version: "3.10"
+          architecture: "x64"
+      - name: Install dependencies
+        run: |
+          python -m pip install --upgrade pip
+          pip install -r requirements.test.txt
+      - name: Analyze with pyright
+        run: |
+          bin/ci pyright --plain
+
+  unit-test:
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        python-version:
+          - "3.7"
+          - "3.8"
+          - "3.9"
+          - "3.10"
+
+    steps:
+      - uses: actions/checkout@v3
+      - name: Setup Python ${{ matrix.python-version }}
+        uses: actions/setup-python@v4
+        with:
+          python-version: ${{ matrix.python-version }}
+      - name: Install dependencies
+        run: |
+          python -m pip install --upgrade pip
+          pip install -r requirements.txt -r requirements.test.txt
+      - name: Test
+        run: |
+          bin/ci pytest --plain
diff --git a/requirements.test.txt b/requirements.test.txt
index aaa27bc..157179a 100644
--- a/requirements.test.txt
+++ b/requirements.test.txt
@@ -2,5 +2,8 @@ pytest
 pytest-xdist
 pytest-mock
 pytest-cov
-coveralls
+pyright
+isort
+flake8
+autopep8
 six