diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..fe7159848 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.linting.pylintEnabled": false +} \ No newline at end of file diff --git a/bin/compile b/bin/compile index ff01f8b36..08117af52 100755 --- a/bin/compile +++ b/bin/compile @@ -205,12 +205,19 @@ fi export CACHED_PYTHON_STACK # Pipenv Python version support. -# Detect the version of Python requested from a Pipfile (e.g. python_version or python_full_version). +# Detect the version of Python requested from a Pipfile or Pipfile.lock file. # Convert it to a runtime.txt file. # shellcheck source=bin/steps/pipenv-python-version source "$BIN_DIR/steps/pipenv-python-version" +# Poetry Python version support. +# Detect the version of Python requested from a pyproject.toml or poetry.lock file. +# Convert it to a runtime.txt file. + +# shellcheck source=bin/steps/poetry-python-version +source "$BIN_DIR/steps/poetry-python-version" + # If no runtime was provided by the user, assume the default Python runtime version. if [ ! -f runtime.txt ]; then echo "$DEFAULT_PYTHON_VERSION" > runtime.txt @@ -240,10 +247,14 @@ fi source "$BIN_DIR/steps/python" mtime "python.install.time" "${start}" -# Install Pipenv dependencies, if a Pipfile was provided. +# Install Pipenv dependencies if Pipenv managed project. # shellcheck source=bin/steps/pipenv source "$BIN_DIR/steps/pipenv" +# Install Poetry dependencies if Poetry managed project. +# shellcheck source=bin/steps/poetry +source "$BIN_DIR/steps/poetry" + # Uninstall removed dependencies with Pip. # The buildpack will automatically remove any declared dependencies (in requirements.txt) # that were explicitly removed. This machinery is a bit complex, but it is not complicated. @@ -256,7 +267,7 @@ mtime "pip.uninstall.time" "${start}" # This allows for people to ship a setup.py application to Heroku # (which is rare, but I vouch that it should work!) -if [ ! -f requirements.txt ] && [ ! -f Pipfile ]; then +if [ ! -f requirements.txt ] && [ ! -f Pipfile ] && [ ! -f Pipfile.lock ] && [ ! -f pyproject.toml ] && [ ! -f poetry.lock ]; then echo "-e ." > requirements.txt fi diff --git a/bin/detect b/bin/detect index eeb965b0f..13ab74ce4 100755 --- a/bin/detect +++ b/bin/detect @@ -15,8 +15,8 @@ BUILD_DIR=$1 # Exit early if app is clearly not Python. -if [ ! -f "$BUILD_DIR/requirements.txt" ] && [ ! -f "$BUILD_DIR/setup.py" ] && [ ! -f "$BUILD_DIR/Pipfile" ]; then +if [ -f "$BUILD_DIR/requirements.txt" ] || [ -f "$BUILD_DIR/setup.py" ] || [ -f "$BUILD_DIR/Pipfile" ] || [ -f "$BUILD_DIR/Pipfile.lock"] || [ -f "$BUILD_DIR/pyproject.py"] || [ -f "$BUILD_DIR/poetry.lock"]; then + echo Python Project Detected... +else exit 1 -fi - -echo Python +fi \ No newline at end of file diff --git a/bin/steps/pipenv b/bin/steps/pipenv index 119062121..db6d339fe 100755 --- a/bin/steps/pipenv +++ b/bin/steps/pipenv @@ -6,81 +6,70 @@ source "$BIN_DIR/utils" set -e -if [[ -f Pipfile.lock ]]; then - if [[ -f .heroku/python/Pipfile.lock.sha256 ]]; then - if [[ $(openssl dgst -sha256 Pipfile.lock) == $(cat .heroku/python/Pipfile.lock.sha256) ]]; then - # Measure that we're using Pipenv. - mcount "tool.pipenv" +if [[ -f Pipfile || -f Pipfile.lock ]]; then + mcount "tool.pipenv" - # Don't skip installation of there are git deps. - if ! grep -q 'git' Pipfile.lock; then - echo "Skipping installation, as Pipfile.lock hasn't changed since last deploy." | indent - - mcount "tool.pipenv" - export SKIP_PIPENV_INSTALL=1 - export SKIP_PIP_INSTALL=1 - fi - fi + # Set Pip env vars + # This reads certain environment variables set on the Heroku app config + # and makes them accessible to the pip install process. + # PIP_EXTRA_INDEX_URL allows for an alternate pypi URL to be used. + if [[ -r "$ENV_DIR/PIP_EXTRA_INDEX_URL" ]]; then + PIP_EXTRA_INDEX_URL="$(cat "$ENV_DIR/PIP_EXTRA_INDEX_URL")" + export PIP_EXTRA_INDEX_URL + mcount "buildvar.PIP_EXTRA_INDEX_URL" fi -fi - -if [ ! "$SKIP_PIPENV_INSTALL" ]; then - # Pipenv support (Generate requriements.txt with pipenv). - if [[ -f Pipfile ]]; then - # Measure that we're using Pipenv. - mcount "tool.pipenv" + # Set SLUGIFY_USES_TEXT_UNIDECODE, required for Airflow versions >=1.10 + if [[ -r "$ENV_DIR/SLUGIFY_USES_TEXT_UNIDECODE" ]]; then + SLUGIFY_USES_TEXT_UNIDECODE="$(cat "$ENV_DIR/SLUGIFY_USES_TEXT_UNIDECODE")" + export SLUGIFY_USES_TEXT_UNIDECODE + mcount "buildvar.SLUGIFY_USES_TEXT_UNIDECODE" + fi - # Skip pip install, later. - export SKIP_PIP_INSTALL=1 + # Set PIPEN_VERSION implicitly + if [[ -r "$ENV_DIR/PIPENV_VERSION" ]]; then + PIPENV_VERSION="$(cat "$ENV_DIR/PIPENV_VERSION")" + export PIPENV_VERSION + mcount "buildvar.PIPENV_VERSION" + else + export PIPENV_VERSION="2018.5.18" + fi - # Set Pip env vars - # This reads certain environment variables set on the Heroku app config - # and makes them accessible to the pip install process. - # - # PIP_EXTRA_INDEX_URL allows for an alternate pypi URL to be used. - if [[ -r "$ENV_DIR/PIP_EXTRA_INDEX_URL" ]]; then - PIP_EXTRA_INDEX_URL="$(cat "$ENV_DIR/PIP_EXTRA_INDEX_URL")" - export PIP_EXTRA_INDEX_URL - mcount "buildvar.PIP_EXTRA_INDEX_URL" - fi + # Install pipenv. + # Due to weird old pip behavior and pipenv behavior, pipenv upgrades pip + # to latest if only --upgrade is specified. Specify upgrade strategy to + # avoid this eager behavior. + /app/.heroku/python/bin/pip install pipenv==$PIPENV_VERSION --upgrade --upgrade-strategy only-if-needed &> /dev/null - # Set SLUGIFY_USES_TEXT_UNIDECODE, required for Airflow versions >=1.10 - if [[ -r "$ENV_DIR/SLUGIFY_USES_TEXT_UNIDECODE" ]]; then - SLUGIFY_USES_TEXT_UNIDECODE="$(cat "$ENV_DIR/SLUGIFY_USES_TEXT_UNIDECODE")" - export SLUGIFY_USES_TEXT_UNIDECODE - mcount "buildvar.SLUGIFY_USES_TEXT_UNIDECODE" - fi + # Install the dependencies. + if [[ ! -f Pipfile.lock ]]; then + + /app/.heroku/python/bin/pipenv lock 2>&1 | cleanup | indent - export PIPENV_VERSION="2018.5.18" - - # Install pipenv. - # Due to weird old pip behavior and pipenv behavior, pipenv upgrades pip - # to latest if only --upgrade is specified. Specify upgrade strategy to - # avoid this eager behavior. - /app/.heroku/python/bin/pip install pipenv==$PIPENV_VERSION --upgrade --upgrade-strategy only-if-needed &> /dev/null + fi - # Install the dependencies. + # Install the dependencies. if [[ ! -f Pipfile.lock ]]; then - puts-step "Installing dependencies with Pipenv $PIPENV_VERSION…" - /app/.heroku/python/bin/pipenv install --system --skip-lock 2>&1 | indent + if [ "$INSTALL_TEST" ]; then + puts-step "Installing default and development dependencies with Pipenv (Pipfile) $PIPENV_VERSION…" + /app/.heroku/python/bin/pipenv install --system --skip-lock --dev 2>&1 | cleanup | indent + else + puts-step "Installing default dependencies with Pipenv (Pipfile) $PIPENV_VERSION…" + /app/.heroku/python/bin/pipenv install --system --skip-lock 2>&1 | cleanup | indent + fi else - pipenv-to-pip Pipfile.lock > requirements.txt - "$BIN_DIR/steps/pip-uninstall" - cp requirements.txt .heroku/python/requirements-declared.txt - openssl dgst -sha256 Pipfile.lock > .heroku/python/Pipfile.lock.sha256 - - puts-step "Installing dependencies with Pipenv $PIPENV_VERSION…" - /app/.heroku/python/bin/pipenv install --system --deploy 2>&1 | indent - fi - - # Install the test dependencies, for CI. - if [ "$INSTALL_TEST" ]; then - puts-step "Installing test dependencies…" - /app/.heroku/python/bin/pipenv install --dev --system --deploy 2>&1 | cleanup | indent + if [ "$INSTALL_TEST" ]; then + puts-step "Installing default and development dependencies with Pipenv (Pipfile.lock) $PIPENV_VERSION…" + /app/.heroku/python/bin/pipenv install --system --deploy --dev 2>&1 | cleanup | indent + else + puts-step "Installing default dependencies with Pipenv (Pipfile.lock) $PIPENV_VERSION…" + /app/.heroku/python/bin/pipenv install --system --deploy 2>&1 | cleanup | indent + fi fi - fi -else + + # Skip pip install later on. export SKIP_PIP_INSTALL=1 - pipenv-to-pip Pipfile.lock > requirements.txt + fi +set +e + diff --git a/bin/steps/pipenv-python-version b/bin/steps/pipenv-python-version index dcdf3c261..11075e345 100755 --- a/bin/steps/pipenv-python-version +++ b/bin/steps/pipenv-python-version @@ -1,35 +1,60 @@ #!/usr/bin/env bash - -# Detect Python-version with Pipenv. - -if [[ -f $BUILD_DIR/Pipfile ]]; then +if [[ -f $BUILD_DIR/Pipfile || -f $BUILD_DIR/Pipfile.lock ]]; then if [[ ! -f $BUILD_DIR/runtime.txt ]]; then if [[ ! -f $BUILD_DIR/Pipfile.lock ]]; then puts-warn "No 'Pipfile.lock' found! We recommend you commit this into your repository." - fi - if [[ -f $BUILD_DIR/Pipfile.lock ]]; then set +e - PYTHON=$(jq -r '._meta.requires.python_full_version' "$BUILD_DIR/Pipfile.lock") - if [[ "$PYTHON" != "null" ]]; then + PYTHON=$(sed -nr "/^\[requires\]/ { :l /^python_full_version[ ]*=/ { s/.*=[ ]*//; p; q;}; n; b l;}" "$BUILD_DIR/Pipfile" | tr -d '"') + if ! [ -z "$PYTHON"]; then echo "python-$PYTHON" > "$BUILD_DIR/runtime.txt" + else + PYTHON=$(sed -nr "/^\[requires\]/ { :l /^python_version[ ]*=/ { s/.*=[ ]*//; p; q;}; n; b l;}" "$BUILD_DIR/Pipfile" | tr -d '"') + if ! [ -z "$PYTHON"]; then + if [ "$PYTHON" = 2.7 ]; then + echo "$LATEST_27" > "$BUILD_DIR/runtime.txt" + fi + if [ "$PYTHON" = 3.4 ]; then + echo "$LATEST_34" > "$BUILD_DIR/runtime.txt" + fi + if [ "$PYTHON" = 3.5 ]; then + echo "$LATEST_35" > "$BUILD_DIR/runtime.txt" + fi + if [ "$PYTHON" = 3.6 ]; then + echo "$LATEST_36" > "$BUILD_DIR/runtime.txt" + fi + if [ "$PYTHON" = 3.7 ]; then + echo "$LATEST_37" > "$BUILD_DIR/runtime.txt" + fi + fi fi set -e - - if [[ "$PYTHON" == "null" ]]; then + else + set +e + PYTHON=$(jq -r '._meta.requires.python_full_version' "$BUILD_DIR/Pipfile.lock") + if [[ "$PYTHON" != "null" ]]; then + echo "python-$PYTHON" > "$BUILD_DIR/runtime.txt" + else PYTHON=$(jq -r '._meta.requires.python_version' "$BUILD_DIR/Pipfile.lock") - if [ "$PYTHON" = 2.7 ]; then - echo "$LATEST_27" > "$BUILD_DIR/runtime.txt" - fi - if [ "$PYTHON" = 3.6 ]; then - echo "$LATEST_36" > "$BUILD_DIR/runtime.txt" - fi - if [ "$PYTHON" = 3.7 ]; then - echo "$LATEST_37" > "$BUILD_DIR/runtime.txt" + if [[ "$PYTHON" != "null" ]]; then + if [ "$PYTHON" = 2.7 ]; then + echo "$LATEST_27" > "$BUILD_DIR/runtime.txt" + fi + if [ "$PYTHON" = 3.4 ]; then + echo "$LATEST_34" > "$BUILD_DIR/runtime.txt" + fi + if [ "$PYTHON" = 3.5 ]; then + echo "$LATEST_35" > "$BUILD_DIR/runtime.txt" + fi + if [ "$PYTHON" = 3.6 ]; then + echo "$LATEST_36" > "$BUILD_DIR/runtime.txt" + fi + if [ "$PYTHON" = 3.7 ]; then + echo "$LATEST_37" > "$BUILD_DIR/runtime.txt" + fi fi fi - - + set -e fi fi fi diff --git a/bin/steps/poetry b/bin/steps/poetry new file mode 100644 index 000000000..4b998e264 --- /dev/null +++ b/bin/steps/poetry @@ -0,0 +1,55 @@ +#!/usr/bin/env bash + +# shellcheck source=bin/utils +source "$BIN_DIR/utils" +set -e + +if [[ -f pyproject.toml || -f poetry.lock ]]; then + mcount "tool.poetry" + + # Set Pip env varsz + # This reads certain environment variables set on the Heroku app config + # and makes them accessible to the pip install process. + # PIP_EXTRA_INDEX_URL allows for an alternate pypi URL to be used. + if [[ -r "$ENV_DIR/PIP_EXTRA_INDEX_URL" ]]; then + PIP_EXTRA_INDEX_URL="$(cat "$ENV_DIR/PIP_EXTRA_INDEX_URL")" + export PIP_EXTRA_INDEX_URL + mcount "buildvar.PIP_EXTRA_INDEX_URL" + fi + + # Set SLUGIFY_USES_TEXT_UNIDECODE, required for Airflow versions >=1.10 + if [[ -r "$ENV_DIR/SLUGIFY_USES_TEXT_UNIDECODE" ]]; then + SLUGIFY_USES_TEXT_UNIDECODE="$(cat "$ENV_DIR/SLUGIFY_USES_TEXT_UNIDECODE")" + export SLUGIFY_USES_TEXT_UNIDECODE + mcount "buildvar.SLUGIFY_USES_TEXT_UNIDECODE" + fi + + # # Get Poetry Version from file + if [[ -r "$ENV_DIR/POETRY_VERSION" ]]; then + POETRY_VERSION="$(cat "$ENV_DIR/POETRY_VERSION")" + export POETRY_VERSION + mcount "buildvar.POETRY_VERSION" + else + export POETRY_VERSION="0.12.11" + fi + + # Install poetry. + /app/.heroku/python/bin/pip install poetry==$POETRY_VERSION 2>&1 | cleanup | indent + + # Install the dependencies. + if [ "$INSTALL_TEST" ]; then + puts-step "Installing default and development dependencies with Poetry $POETRY_VERSION…" + /app/.heroku/python/bin/poetry install 2>&1 | cleanup | indent + else + puts-step "Installing default dependencies with Poetry $POETRY_VERSION…" + /app/.heroku/python/bin/poetry install --no-dev 2>&1 | cleanup | indent + fi + + /app/.heroku/python/bin/poetry run pip freeze > requirements.txt + + # Skip pip install later on. + export SKIP_PIP_INSTALL=1 + +fi +set +e + diff --git a/bin/steps/poetry-python-version b/bin/steps/poetry-python-version new file mode 100644 index 000000000..0c3d30307 --- /dev/null +++ b/bin/steps/poetry-python-version @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +set +e +if [[ -f $BUILD_DIR/pyproject.toml || -f $BUILD_DIR/poetry.lock ]]; then + + if [[ ! -f $BUILD_DIR/runtime.txt ]]; then + + if [[ ! -f $BUILD_DIR/poetry.lock ]]; then + + puts-warn "No 'poetry.lock' found! We recommend you commit this into your repository." + PYTHON=$(sed -nr "/^\[tool.poetry.dependencies\]/ { :l /^python[ ]*=/ { s/.*=[ ]*//; p; q;}; n; b l;}" "$BUILD_DIR/pyproject.toml" | tr -d '"^') + echo $PYTHON + if ! [ -z $PYTHON]; then + if [[ "$PYTHON" == +([0-9]).+([0-9]).+([0-9]) ]]; then + echo "python-$PYTHON" > "$BUILD_DIR/runtime.txt" + elif [ $PYTHON = 2.7 ]; then + echo "$LATEST_27" > "$BUILD_DIR/runtime.txt" + elif [ "$PYTHON" = 3.4 ]; then + echo "$LATEST_34" > "$BUILD_DIR/runtime.txt" + elif [ "$PYTHON" = 3.5 ]; then + echo "$LATEST_35" > "$BUILD_DIR/runtime.txt" + elif [ "$PYTHON" = 3.6 ]; then + echo "$LATEST_36" > "$BUILD_DIR/runtime.txt" + elif [ "$PYTHON" = 3.7 ]; then + echo "$LATEST_37" > "$BUILD_DIR/runtime.txt" + fi + fi + else + PYTHON=$(sed -nr "/^\[metadata\]/ { :l /^python-versions[ ]*=/ { s/.*=[ ]*//; p; q;}; n; b l;}" "$BUILD_DIR/poetry.lock" | tr -d '"^') + if ! [ -z $PYTHON]; then + if [[ "$PYTHON" == +([0-9]).+([0-9]).+([0-9]) ]]; then + echo "python-$PYTHON" > "$BUILD_DIR/runtime.txt" + elif [ $PYTHON = 2.7 ]; then + echo "$LATEST_27" > "$BUILD_DIR/runtime.txt" + elif [ "$PYTHON" = 3.4 ]; then + echo "$LATEST_34" > "$BUILD_DIR/runtime.txt" + elif [ "$PYTHON" = 3.5 ]; then + echo "$LATEST_35" > "$BUILD_DIR/runtime.txt" + elif [ "$PYTHON" = 3.6 ]; then + echo "$LATEST_36" > "$BUILD_DIR/runtime.txt" + elif [ "$PYTHON" = 3.7 ]; then + echo "$LATEST_37" > "$BUILD_DIR/runtime.txt" + fi + fi + fi + fi +fi + +set -e diff --git a/bin/utils b/bin/utils index f625645df..4a7440561 100755 --- a/bin/utils +++ b/bin/utils @@ -20,7 +20,6 @@ indent() { sed "s/^/ /" } - # Clean up pip output cleanup() { sed -e 's/\.\.\.\+/.../g' | sed -e '/already satisfied/Id' | sed -e '/No files were found to uninstall/Id' | sed -e '/Overwriting/Id' | sed -e '/python executable/Id' | sed -e '/no previously-included files/Id' diff --git a/test/fixtures/collectstatic-poetry/.gitignore b/test/fixtures/collectstatic-poetry/.gitignore new file mode 100644 index 000000000..f95d164a6 --- /dev/null +++ b/test/fixtures/collectstatic-poetry/.gitignore @@ -0,0 +1,5 @@ +venv +*.pyc +staticfiles +.env +db.sqlite3 diff --git a/test/fixtures/collectstatic-poetry/Procfile b/test/fixtures/collectstatic-poetry/Procfile new file mode 100644 index 000000000..b6f89307b --- /dev/null +++ b/test/fixtures/collectstatic-poetry/Procfile @@ -0,0 +1 @@ +web: gunicorn gettingstarted.wsgi diff --git a/test/fixtures/collectstatic-poetry/Procfile.windows b/test/fixtures/collectstatic-poetry/Procfile.windows new file mode 100644 index 000000000..69789e554 --- /dev/null +++ b/test/fixtures/collectstatic-poetry/Procfile.windows @@ -0,0 +1 @@ +web: python manage.py runserver 0.0.0.0:5000 diff --git a/test/fixtures/collectstatic-poetry/README.md b/test/fixtures/collectstatic-poetry/README.md new file mode 100644 index 000000000..23ff5a077 --- /dev/null +++ b/test/fixtures/collectstatic-poetry/README.md @@ -0,0 +1,44 @@ +# Python: Getting Started + +A barebones Django app, which can easily be deployed to Heroku. + +This application supports the [Getting Started with Python on Heroku](https://devcenter.heroku.com/articles/getting-started-with-python) article - check it out. + +## Running Locally + +Make sure you have Python [installed properly](http://install.python-guide.org). Also, install the [Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli) and [Postgres](https://devcenter.heroku.com/articles/heroku-postgresql#local-setup). + +```sh +$ git clone git@github.com:heroku/python-getting-started.git +$ cd python-getting-started + +$ pipenv install + +$ createdb python_getting_started + +$ python manage.py migrate +$ python manage.py collectstatic + +$ heroku local +``` + +Your app should now be running on [localhost:5000](http://localhost:5000/). + +## Deploying to Heroku + +```sh +$ heroku create +$ git push heroku master + +$ heroku run python manage.py migrate +$ heroku open +``` +or + +[](https://heroku.com/deploy) + +## Documentation + +For more information about using Python on Heroku, see these Dev Center articles: + +- [Python on Heroku](https://devcenter.heroku.com/categories/python) diff --git a/test/fixtures/collectstatic-poetry/app.json b/test/fixtures/collectstatic-poetry/app.json new file mode 100644 index 000000000..8721c4994 --- /dev/null +++ b/test/fixtures/collectstatic-poetry/app.json @@ -0,0 +1,22 @@ +{ + "name": "Start on Heroku: Python", + "description": "A barebones Python app, which can easily be deployed to Heroku.", + "image": "heroku/python", + "repository": "https://github.com/heroku/python-getting-started", + "keywords": ["python", "django" ], + "addons": [ "heroku-postgresql" ], + "env": { + "SECRET_KEY": { + "description": "The secret key for the Django application.", + "generator": "secret" + } + }, + "environments": { + "test": { + "scripts": { + "test-setup": "python manage.py collectstatic --noinput", + "test": "python manage.py test" + } + } + } +} diff --git a/test/fixtures/collectstatic-poetry/gettingstarted/__init__.py b/test/fixtures/collectstatic-poetry/gettingstarted/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/test/fixtures/collectstatic-poetry/gettingstarted/settings.py b/test/fixtures/collectstatic-poetry/gettingstarted/settings.py new file mode 100644 index 000000000..b23e28bc2 --- /dev/null +++ b/test/fixtures/collectstatic-poetry/gettingstarted/settings.py @@ -0,0 +1,125 @@ +""" +Django settings for gettingstarted project. + +Generated by 'django-admin startproject' using Django 2.0. + +For more information on this file, see +https://docs.djangoproject.com/en/2.0/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/2.0/ref/settings/ +""" + +import os +import django_heroku + + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'CHANGE_ME!!!! (P.S. the SECRET_KEY environment variable will be used, if set, instead).' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'hello' +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'gettingstarted.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'gettingstarted.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/2.0/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } +} + + +# Password validation +# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/2.0/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/2.0/howto/static-files/ + +STATIC_URL = '/static/' + +django_heroku.settings(locals()) \ No newline at end of file diff --git a/test/fixtures/collectstatic-poetry/gettingstarted/static/humans.txt b/test/fixtures/collectstatic-poetry/gettingstarted/static/humans.txt new file mode 100644 index 000000000..e69de29bb diff --git a/test/fixtures/collectstatic-poetry/gettingstarted/urls.py b/test/fixtures/collectstatic-poetry/gettingstarted/urls.py new file mode 100644 index 000000000..36492ed3c --- /dev/null +++ b/test/fixtures/collectstatic-poetry/gettingstarted/urls.py @@ -0,0 +1,17 @@ +from django.conf.urls import include, url +from django.urls import path + +from django.contrib import admin +admin.autodiscover() + +import hello.views + +# Examples: +# url(r'^$', 'gettingstarted.views.home', name='home'), +# url(r'^blog/', include('blog.urls')), + +urlpatterns = [ + url(r'^$', hello.views.index, name='index'), + url(r'^db', hello.views.db, name='db'), + path('admin/', admin.site.urls), +] diff --git a/test/fixtures/collectstatic-poetry/gettingstarted/wsgi.py b/test/fixtures/collectstatic-poetry/gettingstarted/wsgi.py new file mode 100644 index 000000000..feb0af46f --- /dev/null +++ b/test/fixtures/collectstatic-poetry/gettingstarted/wsgi.py @@ -0,0 +1,15 @@ +""" +WSGI config for gettingstarted project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/1.6/howto/deployment/wsgi/ +""" + +import os +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "gettingstarted.settings") + +from django.core.wsgi import get_wsgi_application + +application = get_wsgi_application() diff --git a/test/fixtures/collectstatic-poetry/hello/__init__.py b/test/fixtures/collectstatic-poetry/hello/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/test/fixtures/collectstatic-poetry/hello/admin.py b/test/fixtures/collectstatic-poetry/hello/admin.py new file mode 100644 index 000000000..8c38f3f3d --- /dev/null +++ b/test/fixtures/collectstatic-poetry/hello/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/test/fixtures/collectstatic-poetry/hello/migrations/0001_initial.py b/test/fixtures/collectstatic-poetry/hello/migrations/0001_initial.py new file mode 100644 index 000000000..99c4a82a5 --- /dev/null +++ b/test/fixtures/collectstatic-poetry/hello/migrations/0001_initial.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.1 on 2016-01-27 21:54 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Greeting', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('when', models.DateTimeField(auto_now_add=True, verbose_name=b'date created')), + ], + ), + ] diff --git a/test/fixtures/collectstatic-poetry/hello/migrations/__init__.py b/test/fixtures/collectstatic-poetry/hello/migrations/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/test/fixtures/collectstatic-poetry/hello/models.py b/test/fixtures/collectstatic-poetry/hello/models.py new file mode 100644 index 000000000..89d76fd1b --- /dev/null +++ b/test/fixtures/collectstatic-poetry/hello/models.py @@ -0,0 +1,5 @@ +from django.db import models + +# Create your models here. +class Greeting(models.Model): + when = models.DateTimeField('date created', auto_now_add=True) diff --git a/test/fixtures/collectstatic-poetry/hello/static/lang-logo.png b/test/fixtures/collectstatic-poetry/hello/static/lang-logo.png new file mode 100644 index 000000000..f04aff1e3 Binary files /dev/null and b/test/fixtures/collectstatic-poetry/hello/static/lang-logo.png differ diff --git a/test/fixtures/collectstatic-poetry/hello/templates/base.html b/test/fixtures/collectstatic-poetry/hello/templates/base.html new file mode 100644 index 000000000..97ec07386 --- /dev/null +++ b/test/fixtures/collectstatic-poetry/hello/templates/base.html @@ -0,0 +1,83 @@ + + +
+This is a sample Python application deployed to Heroku. It's a reasonably simple app - but a good foundation for understanding how to get the most out of the Heroku platform.
+ Getting Started with Python + Source on GitHub +git clone https://github.com/heroku/python-getting-started.git
- this will create a local copy of the source code for the appcd python-getting-started
- change directory into the local source code repositoryheroku git:remote -a <your-app-name>
- associate the Heroku app with the repository