Repository: digitalfabrik/integreat-cms

Issue:
Add shellcheck to circleci workflow
### Motivation
<!-- A clear and concise description of what the motivation for the new feature is, and what problem it is solving. -->
The bash scripts in our repository are currently not part of any code style or correctness checks.

### Proposed Solution
<!-- A clear and concise description of the feature you would like to add, and how it solves the motivating problem. -->
We could add the tool [shellcheck](https://www.shellcheck.net/) to change this. Fortunately, it has already a pre-built [circleci orb](https://circleci.com/developer/orbs/orb/circleci/shellcheck) which can be easily added to our workflow. The specified directoy  of the job should be `dir: ./dev-tools`.

### Additional Context
<!-- Add any other information or screenshots about the feature request here. -->
Depending on the kind of errors/warnings the tool produces, the [dev-tools](https://github.com/Integreat/cms-django/tree/develop/dev-tools) might need a few changes to make them initially conform to shellcheck's standards.



Discussion:
Shall I give this a shot?
> Shall I give this a shot?

Sure, thanks! Since external PRs are not built in CircleCI, you might install shellcheck locally to test whether our bash scripts need manual adjustments. Is this possible for you?
Haha, kudos for your GitHub profile :muscle: I also love speed cubing :smile: 

![Screenshot_2020-10-11 abhinand5 - Overview](https://user-images.githubusercontent.com/16021269/95682278-b4480580-0be4-11eb-9e0a-4fb21ca4c19e.png)

 > Is this possible for you?

Sure, @timoludwig no problem. 

> Haha, kudos for your GitHub profile 💪 I also love speed cubing 😄

Oh that's cool 😃 🙌 
@abhinand5 Are you still interested in solving the issue? If not, please let us know so that others can take up the issue. Thanks!

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -32,7 +32,7 @@
     install_requires=[
         "aiohttp",
         "cffi",
-        "Django==3.1.8",
+        "Django>=3.2,<4.0",
         "django-cors-headers",
         "django-filer",
         "django-mptt",
diff --git a/src/backend/settings.py b/src/backend/settings.py
--- a/src/backend/settings.py
+++ b/src/backend/settings.py
@@ -240,6 +240,10 @@
 #: Directory for initial database contents (see :setting:`django:FIXTURE_DIRS`)
 FIXTURE_DIRS = (os.path.join(BASE_DIR, "cms/fixtures/"),)
 
+#: Default primary key field type to use for models that don’t have a field with
+#: :attr:`primary_key=True <django.db.models.Field.primary_key>`. (see :setting:`django:DEFAULT_AUTO_FIELD`)
+DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
+
 
 ############
 # SECURITY #
diff --git a/src/sitemap/sitemaps.py b/src/sitemap/sitemaps.py
--- a/src/sitemap/sitemaps.py
+++ b/src/sitemap/sitemaps.py
@@ -241,18 +241,18 @@ def __init__(self, region, language):
         # Filter queryset based on region
         self.queryset = self.queryset.filter(regions=self.region)
 
-    def location(self, obj):
+    def location(self, item):
         """
         This location function returns the absolute path for a given object returned by items().
 
-        :param obj: Objects passed from items() method
-        :type obj: ~cms.models.offers.offer_template.OfferTemplate
+        :param item: Objects passed from items() method
+        :type item: ~cms.models.offers.offer_template.OfferTemplate
 
         :return: The absolute path of the given offer object
         :rtype: str
         """
         return "/" + "/".join(
-            [self.region.slug, self.language.slug, "offers", obj.slug]
+            [self.region.slug, self.language.slug, "offers", item.slug]
         )
 
     def sitemap_alternates(self, obj):


Test patch:
diff --git a/dev-tools/test.sh b/dev-tools/test.sh
--- a/dev-tools/test.sh
+++ b/dev-tools/test.sh
@@ -2,72 +2,11 @@
 
 # This script executes the tests and starts the database docker container if necessary.
 
-if [[ "$VIRTUAL_ENV" != "" ]]
-then
-  export PIPENV_VERBOSITY=-1
-fi
+# Import utility functions
+# shellcheck source=./dev-tools/_functions.sh
+source "$(dirname "${BASH_SOURCE[0]}")/_functions.sh"
 
-# Check if local postgres server is running
-if nc -w1 localhost 5432; then
+require_database
 
-    cd $(dirname "$BASH_SOURCE")/..
-
-    # Execute tests
-    pipenv run integreat-cms-cli test cms
-
-else
-
-    # Check if docker is not installed
-    if ! command -v docker > /dev/null; then
-        echo "In order to run the database, you need either a local postgres server or docker." >&2
-        exit 1
-    fi
-
-    # Check if script is not running as root
-    if ! [ $(id -u) = 0 ]; then
-        echo "This script needs root privileges to connect to the docker deamon. It will be automatically restarted with sudo." >&2
-        # Call this script again as root
-        sudo env PATH="$PATH" $0
-        # Exit with code of subprocess
-        exit $?
-    elif [ -z "$SUDO_USER" ]; then
-        echo "Please do not run this script as your root user, use sudo instead." >&2
-        exit 1
-    fi
-
-    # Check if docker socket is not available
-    if ! docker ps > /dev/null; then
-        exit 1
-    fi
-
-    cd $(dirname "$BASH_SOURCE")/..
-
-    # Check if postgres database container is already running
-    if [ "$(docker ps -q -f name=integreat_django_postgres)" ]; then
-        # Execute tests
-        sudo -u $SUDO_USER env PATH="$PATH" pipenv run integreat-cms-cli test cms --settings=backend.docker_settings
-    else
-        # Check if stopped container is available
-        if [ "$(docker ps -aq -f status=exited -f name=integreat_django_postgres)" ]; then
-            # Start the existing container
-            docker start integreat_django_postgres > /dev/null
-            until docker exec -it integreat_django_postgres psql -U integreat -d integreat -c "select 1" > /dev/null 2>&1; do
-              sleep 0.1
-            done
-        else
-            # Run new container
-            docker run -d --name "integreat_django_postgres" -e "POSTGRES_USER=integreat" -e "POSTGRES_PASSWORD=password" -e "POSTGRES_DB=integreat" -v "$(pwd)/.postgres:/var/lib/postgresql" -p 5433:5432 postgres > /dev/null
-            echo -n "Waiting for postgres database container to be ready..."
-            until docker exec -it integreat_django_postgres psql -U integreat -d integreat -c "select 1" > /dev/null 2>&1; do
-              sleep 0.1
-              echo -n "."
-            done
-            echo ""
-        fi
-        # Execute tests
-        sudo -u $SUDO_USER env PATH="$PATH" pipenv run integreat-cms-cli test cms --settings=backend.docker_settings
-        # Stop the postgres database docker container
-        docker stop integreat_django_postgres > /dev/null
-    fi
-
-fi
+deescalate_privileges pipenv run integreat-cms-cli test cms
+echo "✔ Tests successfully completed " | print_success
diff --git a/dev-tools/test_cov.sh b/dev-tools/test_cov.sh
--- a/dev-tools/test_cov.sh
+++ b/dev-tools/test_cov.sh
@@ -2,78 +2,16 @@
 
 # This script executes the tests and starts the database docker container if necessary.
 
-if [[ "$VIRTUAL_ENV" != "" ]]
-then
-  export PIPENV_VERBOSITY=-1
-fi
+# Import utility functions
+# shellcheck source=./dev-tools/_functions.sh
+source "$(dirname "${BASH_SOURCE[0]}")/_functions.sh"
 
-# Check if local postgres server is running
-if nc -w1 localhost 5432; then
+# Delete outdated code coverage
+rm -rf "${BASE_DIR}/htmlcov/"
 
-    cd $(dirname "$BASH_SOURCE")/..
+require_database
 
-    # prepare code coverage
-    rm -rf ./htmlcov/
-    # Execute tests
-    pipenv run integreat-cms-cli test cms --set=COVERAGE
-
-else
-
-    # Check if docker is not installed
-    if ! command -v docker > /dev/null; then
-        echo "In order to run the database, you need either a local postgres server or docker." >&2
-        exit 1
-    fi
-
-    # Check if script is not running as root
-    if ! [ $(id -u) = 0 ]; then
-        echo "This script needs root privileges to connect to the docker deamon. It will be automatically restarted with sudo." >&2
-        # Call this script again as root
-        sudo env PATH="$PATH" $0
-        # Exit with code of subprocess
-        exit $?
-    elif [ -z "$SUDO_USER" ]; then
-        echo "Please do not run this script as your root user, use sudo instead." >&2
-        exit 1
-    fi
-
-    # Check if docker socket is not available
-    if ! docker ps > /dev/null; then
-        exit 1
-    fi
-
-    cd $(dirname "$BASH_SOURCE")/..
-
-    # Check if postgres database container is already running
-    if [ "$(docker ps -q -f name=integreat_django_postgres)" ]; then
-        # Execute tests
-        sudo -u $SUDO_USER env PATH="$PATH" pipenv run integreat-cms-cli test cms --settings=backend.docker_settings
-    else
-        # Check if stopped container is available
-        if [ "$(docker ps -aq -f status=exited -f name=integreat_django_postgres)" ]; then
-            # Start the existing container
-            docker start integreat_django_postgres > /dev/null
-            until docker exec -it integreat_django_postgres psql -U integreat -d integreat -c "select 1" > /dev/null 2>&1; do
-              sleep 0.1
-            done
-        else
-            # Run new container
-            docker run -d --name "integreat_django_postgres" -e "POSTGRES_USER=integreat" -e "POSTGRES_PASSWORD=password" -e "POSTGRES_DB=integreat" -v "$(pwd)/.postgres:/var/lib/postgresql" -p 5433:5432 postgres > /dev/null
-            echo -n "Waiting for postgres database container to be ready..."
-            until docker exec -it integreat_django_postgres psql -U integreat -d integreat -c "select 1" > /dev/null 2>&1; do
-              sleep 0.1
-              echo -n "."
-            done
-            echo ""
-        fi
-        #prepare code coverage
-        rm -rf ./htmlcov/ 
-        # Execute tests
-
-        sudo -u $SUDO_USER env PATH="$PATH" pipenv run integreat-cms-cli test cms --settings=backend.docker_settings --set=COVERAGE
-
-        # Stop the postgres database docker container
-        docker stop integreat_django_postgres > /dev/null
-    fi
-
-fi
+deescalate_privileges pipenv run integreat-cms-cli test cms --set=COVERAGE
+echo "✔ Tests successfully completed " | print_success
+echo -e "Open the following file in your browser to view the test coverage:\n" | print_info
+echo -e "\tfile://${BASE_DIR}/htmlcov/index.html\n" | print_bold