From 00947abe7a4a6508ac1377c14f8903a610f7671c Mon Sep 17 00:00:00 2001 From: Kenneth Reitz <me@kennethreitz.org> Date: Wed, 14 Mar 2018 13:06:56 -0400 Subject: [PATCH] collectstatic metrics (#660) --- bin/steps/collectstatic | 22 ++- test/fixtures/collectstatic/.gitignore | 5 + test/fixtures/collectstatic/Pipfile | 16 +++ test/fixtures/collectstatic/Pipfile.lock | 118 +++++++++++++++++ test/fixtures/collectstatic/Procfile | 1 + test/fixtures/collectstatic/Procfile.windows | 1 + test/fixtures/collectstatic/README.md | 44 ++++++ test/fixtures/collectstatic/app.json | 22 +++ .../collectstatic/gettingstarted/__init__.py | 0 .../collectstatic/gettingstarted/settings.py | 125 ++++++++++++++++++ .../gettingstarted/static/humans.txt | 0 .../collectstatic/gettingstarted/urls.py | 17 +++ .../collectstatic/gettingstarted/wsgi.py | 15 +++ test/fixtures/collectstatic/hello/__init__.py | 0 test/fixtures/collectstatic/hello/admin.py | 3 + .../hello/migrations/0001_initial.py | 23 ++++ .../hello/migrations/__init__.py | 0 test/fixtures/collectstatic/hello/models.py | 5 + .../collectstatic/hello/static/lang-logo.png | Bin 0 -> 2217 bytes .../collectstatic/hello/templates/base.html | 83 ++++++++++++ .../collectstatic/hello/templates/db.html | 21 +++ .../collectstatic/hello/templates/index.html | 58 ++++++++ test/fixtures/collectstatic/hello/tests.py | 18 +++ test/fixtures/collectstatic/hello/views.py | 20 +++ test/fixtures/collectstatic/manage.py | 10 ++ test/run | 5 + 26 files changed, 631 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/collectstatic/.gitignore create mode 100644 test/fixtures/collectstatic/Pipfile create mode 100644 test/fixtures/collectstatic/Pipfile.lock create mode 100644 test/fixtures/collectstatic/Procfile create mode 100644 test/fixtures/collectstatic/Procfile.windows create mode 100644 test/fixtures/collectstatic/README.md create mode 100644 test/fixtures/collectstatic/app.json create mode 100644 test/fixtures/collectstatic/gettingstarted/__init__.py create mode 100644 test/fixtures/collectstatic/gettingstarted/settings.py create mode 100644 test/fixtures/collectstatic/gettingstarted/static/humans.txt create mode 100644 test/fixtures/collectstatic/gettingstarted/urls.py create mode 100644 test/fixtures/collectstatic/gettingstarted/wsgi.py create mode 100644 test/fixtures/collectstatic/hello/__init__.py create mode 100644 test/fixtures/collectstatic/hello/admin.py create mode 100644 test/fixtures/collectstatic/hello/migrations/0001_initial.py create mode 100644 test/fixtures/collectstatic/hello/migrations/__init__.py create mode 100644 test/fixtures/collectstatic/hello/models.py create mode 100644 test/fixtures/collectstatic/hello/static/lang-logo.png create mode 100644 test/fixtures/collectstatic/hello/templates/base.html create mode 100644 test/fixtures/collectstatic/hello/templates/db.html create mode 100644 test/fixtures/collectstatic/hello/templates/index.html create mode 100644 test/fixtures/collectstatic/hello/tests.py create mode 100644 test/fixtures/collectstatic/hello/views.py create mode 100755 test/fixtures/collectstatic/manage.py diff --git a/bin/steps/collectstatic b/bin/steps/collectstatic index b779b7e4..73f03cf0 100755 --- a/bin/steps/collectstatic +++ b/bin/steps/collectstatic @@ -32,7 +32,11 @@ if [ ! "$DISABLE_COLLECTSTATIC" ] && [ -f "$MANAGE_FILE" ] && [ "$DJANGO_INSTALL # Run collectstatic, cleanup some of the noisy output. PYTHONPATH=${PYTHONPATH:-.} export PYTHONPATH - python "$MANAGE_FILE" collectstatic --noinput --traceback 2>&1 | sed '/^Post-processed/d;/^Copying/d;/^$/d' | indent + + # Create a temporary file for collecting the collectstaic logs. + COLLECTSTATIC_LOG=$(mktemp) + + python "$MANAGE_FILE" collectstatic --noinput --traceback 2>&1 | tee "$COLLECTSTATIC_LOG" | sed '/^Post-processed/d;/^Copying/d;/^$/d' | indent COLLECTSTATIC_STATUS="${PIPESTATUS[0]}" set -e @@ -42,6 +46,22 @@ if [ ! "$DISABLE_COLLECTSTATIC" ] && [ -f "$MANAGE_FILE" ] && [ "$DJANGO_INSTALL mcount "failure.collectstatic" + if grep -q 'SyntaxError' "$COLLECTSTATIC_LOG"; then + mcount "failure.collectstatic.syntax-error" + fi + + if grep -q 'ImproperlyConfigured' "$COLLECTSTATIC_LOG"; then + mcount "failure.collectstatic.improper-configuration" + fi + + if grep -q 'The CSS file' "$COLLECTSTATIC_LOG"; then + mcount "failure.collectstatic.fancy-references" + fi + + if grep -q 'OSError' "$COLLECTSTATIC_LOG"; then + mcount "failure.collectstatic.missing-file" + fi + echo echo " ! Error while running '$ python $MANAGE_FILE collectstatic --noinput'." echo " See traceback above for details." diff --git a/test/fixtures/collectstatic/.gitignore b/test/fixtures/collectstatic/.gitignore new file mode 100644 index 00000000..f95d164a --- /dev/null +++ b/test/fixtures/collectstatic/.gitignore @@ -0,0 +1,5 @@ +venv +*.pyc +staticfiles +.env +db.sqlite3 diff --git a/test/fixtures/collectstatic/Pipfile b/test/fixtures/collectstatic/Pipfile new file mode 100644 index 00000000..70ca30fd --- /dev/null +++ b/test/fixtures/collectstatic/Pipfile @@ -0,0 +1,16 @@ +[[source]] + +url = "https://pypi.python.org/simple" +verify_ssl = true + + +[packages] + +django = "*" +gunicorn = "*" +django-heroku = "*" + + +[requires] + +python_version = "3.6" diff --git a/test/fixtures/collectstatic/Pipfile.lock b/test/fixtures/collectstatic/Pipfile.lock new file mode 100644 index 00000000..397a1c9d --- /dev/null +++ b/test/fixtures/collectstatic/Pipfile.lock @@ -0,0 +1,118 @@ +{ + "_meta": { + "hash": { + "sha256": "7843aa61794626156c5dbfa26d6be61df24889c396f04a8dead353d23e2899d6" + }, + "host-environment-markers": { + "implementation_name": "cpython", + "implementation_version": "3.6.3", + "os_name": "posix", + "platform_machine": "x86_64", + "platform_python_implementation": "CPython", + "platform_release": "17.3.0", + "platform_system": "Darwin", + "platform_version": "Darwin Kernel Version 17.3.0: Thu Nov 9 18:09:22 PST 2017; root:xnu-4570.31.3~1/RELEASE_X86_64", + "python_full_version": "3.6.3", + "python_version": "3.6", + "sys_platform": "darwin" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.6" + }, + "sources": [ + { + "url": "https://pypi.python.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "dj-database-url": { + "hashes": [ + "sha256:e16d94c382ea0564c48038fa7fe8d9c890ef1ab1a8ec4cb48e732c124b9482fd", + "sha256:a6832d8445ee9d788c5baa48aef8130bf61fdc442f7d9a548424d25cd85c9f08" + ], + "version": "==0.4.2" + }, + "django": { + "hashes": [ + "sha256:af18618ce3291be5092893d8522fe3919661bf3a1fb60e3858ae74865a4f07c2", + "sha256:9614851d4a7ff8cbd32b73c6076441f377c45a5bbff7e771798fb02c43c31f47" + ], + "version": "==2.0" + }, + "django-heroku": { + "hashes": [ + "sha256:193bacbe644a607642f6b60acd0a382d6abf4a1f7578f8d3eb10659457efe904", + "sha256:af6c723872553b7427121a865eb9fce70d566b9ad26d7defcdcd03a8acea56c8" + ], + "version": "==0.1.0" + }, + "gunicorn": { + "hashes": [ + "sha256:75af03c99389535f218cc596c7de74df4763803f7b63eb09d77e92b3956b36c6", + "sha256:eee1169f0ca667be05db3351a0960765620dad53f53434262ff8901b68a1b622" + ], + "version": "==19.7.1" + }, + "psycopg2": { + "hashes": [ + "sha256:594aa9a095de16614f703d759e10c018bdffeafce2921b8e80a0e8a0ebbc12e5", + "sha256:1cf5d84290c771eeecb734abe2c6c3120e9837eb12f99474141a862b9061ac51", + "sha256:0344b181e1aea37a58c218ccb0f0f771295de9aa25a625ed076e6996c6530f9e", + "sha256:25250867a4cd1510fb755ef9cb38da3065def999d8e92c44e49a39b9b76bc893", + "sha256:317612d5d0ca4a9f7e42afb2add69b10be360784d21ce4ecfbca19f1f5eadf43", + "sha256:9d6266348b15b4a48623bf4d3e50445d8e581da413644f365805b321703d0fac", + "sha256:ddca39cc55877653b5fcf59976d073e3d58c7c406ef54ae8e61ddf8782867182", + "sha256:988d2ec7560d42ef0ac34b3b97aad14c4f068792f00e1524fa1d3749fe4e4b64", + "sha256:7a9c6c62e6e05df5406e9b5235c31c376a22620ef26715a663cee57083b3c2ea", + "sha256:7a75565181e75ba0b9fb174b58172bf6ea9b4331631cfe7bafff03f3641f5d73", + "sha256:94e4128ba1ea56f02522fffac65520091a9de3f5c00da31539e085e13db4771b", + "sha256:92179bd68c2efe72924a99b6745a9172471931fc296f9bfdf9645b75eebd6344", + "sha256:b9358e203168fef7bfe9f430afaed3a2a624717a1d19c7afa7dfcbd76e3cd95c", + "sha256:009e0bc09a57dbef4b601cb8b46a2abad51f5274c8be4bba276ff2884cd4cc53", + "sha256:d3ac07240e2304181ffdb13c099840b5eb555efc7be9344503c0c03aa681de79", + "sha256:40fa5630cd7d237cd93c4d4b64b9e5ed9273d1cfce55241c7f9066f5db70629d", + "sha256:6c2f1a76a9ebd9ecf7825b9e20860139ca502c2bf1beabf6accf6c9e66a7e0c3", + "sha256:37f54452c7787dbdc0a634ca9773362b91709917f0b365ed14b831f03cbd34ba", + "sha256:8f5942a4daf1ffac42109dc4a72f786af4baa4fa702ede1d7c57b4b696c2e7d6", + "sha256:bf708455cd1e9fa96c05126e89a0c59b200d086c7df7bbafc7d9be769e4149a3", + "sha256:82c40ea3ac1555e0462803380609fbe8b26f52620f3d4f8eb480cfd8ceed8a14", + "sha256:207ba4f9125a0a4200691e82d5eee7ea1485708eabe99a07fc7f08696fae62f4", + "sha256:0cd4c848f0e9d805d531e44973c8f48962e20eb7fc0edac3db4f9dbf9ed5ab82", + "sha256:57baf63aeb2965ca4b52613ce78e968b6d2bde700c97f6a7e8c6c236b51ab83e", + "sha256:2954557393cfc9a5c11a5199c7a78cd9c0c793a047552d27b1636da50d013916", + "sha256:7c31dade89634807196a6b20ced831fbd5bec8a21c4e458ea950c9102c3aa96f", + "sha256:1286dd16d0e46d59fa54582725986704a7a3f3d9aca6c5902a7eceb10c60cb7e", + "sha256:697ff63bc5451e0b0db48ad205151123d25683b3754198be7ab5fcb44334e519", + "sha256:fc993c9331d91766d54757bbc70231e29d5ceb2d1ac08b1570feaa0c38ab9582", + "sha256:9d64fed2681552ed642e9c0cc831a9e95ab91de72b47d0cb68b5bf506ba88647", + "sha256:5c3213be557d0468f9df8fe2487eaf2990d9799202c5ff5cb8d394d09fad9b2a" + ], + "version": "==2.7.3.2" + }, + "pytz": { + "hashes": [ + "sha256:80af0f3008046b9975242012a985f04c5df1f01eed4ec1633d56cc47a75a6a48", + "sha256:feb2365914948b8620347784b6b6da356f31c9d03560259070b2f30cff3d469d", + "sha256:59707844a9825589878236ff2f4e0dc9958511b7ffaae94dc615da07d4a68d33", + "sha256:d0ef5ef55ed3d37854320d4926b04a4cb42a2e88f71da9ddfdacfde8e364f027", + "sha256:c41c62827ce9cafacd6f2f7018e4f83a6f1986e87bfd000b8cfbd4ab5da95f1a", + "sha256:8cc90340159b5d7ced6f2ba77694d946fc975b09f1a51d93f3ce3bb399396f94", + "sha256:dd2e4ca6ce3785c8dd342d1853dd9052b19290d5bf66060846e5dc6b8d6667f7", + "sha256:699d18a2a56f19ee5698ab1123bbcc1d269d061996aeb1eda6d89248d3542b82", + "sha256:fae4cffc040921b8a2d60c6cf0b5d662c1190fe54d718271db4eb17d44a185b7" + ], + "version": "==2017.3" + }, + "whitenoise": { + "hashes": [ + "sha256:15f43b2e701821b95c9016cf469d29e2a546cb1c7dead584ba82c36f843995cf", + "sha256:9d81515f2b5b27051910996e1e860b1332e354d9e7bcf30c98f21dcb6713e0dd" + ], + "version": "==3.3.1" + } + }, + "develop": {} +} diff --git a/test/fixtures/collectstatic/Procfile b/test/fixtures/collectstatic/Procfile new file mode 100644 index 00000000..b6f89307 --- /dev/null +++ b/test/fixtures/collectstatic/Procfile @@ -0,0 +1 @@ +web: gunicorn gettingstarted.wsgi diff --git a/test/fixtures/collectstatic/Procfile.windows b/test/fixtures/collectstatic/Procfile.windows new file mode 100644 index 00000000..69789e55 --- /dev/null +++ b/test/fixtures/collectstatic/Procfile.windows @@ -0,0 +1 @@ +web: python manage.py runserver 0.0.0.0:5000 diff --git a/test/fixtures/collectstatic/README.md b/test/fixtures/collectstatic/README.md new file mode 100644 index 00000000..23ff5a07 --- /dev/null +++ b/test/fixtures/collectstatic/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/app.json b/test/fixtures/collectstatic/app.json new file mode 100644 index 00000000..8721c499 --- /dev/null +++ b/test/fixtures/collectstatic/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/gettingstarted/__init__.py b/test/fixtures/collectstatic/gettingstarted/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/test/fixtures/collectstatic/gettingstarted/settings.py b/test/fixtures/collectstatic/gettingstarted/settings.py new file mode 100644 index 00000000..b23e28bc --- /dev/null +++ b/test/fixtures/collectstatic/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/gettingstarted/static/humans.txt b/test/fixtures/collectstatic/gettingstarted/static/humans.txt new file mode 100644 index 00000000..e69de29b diff --git a/test/fixtures/collectstatic/gettingstarted/urls.py b/test/fixtures/collectstatic/gettingstarted/urls.py new file mode 100644 index 00000000..36492ed3 --- /dev/null +++ b/test/fixtures/collectstatic/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/gettingstarted/wsgi.py b/test/fixtures/collectstatic/gettingstarted/wsgi.py new file mode 100644 index 00000000..feb0af46 --- /dev/null +++ b/test/fixtures/collectstatic/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/hello/__init__.py b/test/fixtures/collectstatic/hello/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/test/fixtures/collectstatic/hello/admin.py b/test/fixtures/collectstatic/hello/admin.py new file mode 100644 index 00000000..8c38f3f3 --- /dev/null +++ b/test/fixtures/collectstatic/hello/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/test/fixtures/collectstatic/hello/migrations/0001_initial.py b/test/fixtures/collectstatic/hello/migrations/0001_initial.py new file mode 100644 index 00000000..99c4a82a --- /dev/null +++ b/test/fixtures/collectstatic/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/hello/migrations/__init__.py b/test/fixtures/collectstatic/hello/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/test/fixtures/collectstatic/hello/models.py b/test/fixtures/collectstatic/hello/models.py new file mode 100644 index 00000000..89d76fd1 --- /dev/null +++ b/test/fixtures/collectstatic/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/hello/static/lang-logo.png b/test/fixtures/collectstatic/hello/static/lang-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f04aff1e38eeaeadba93390eb5cd356388b8a9f7 GIT binary patch literal 2217 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 aZ$a%}dZnx*#!~kSf(m2>Gtbhu?D`$|L6nF9 literal 0 HcmV?d00001 diff --git a/test/fixtures/collectstatic/hello/templates/base.html b/test/fixtures/collectstatic/hello/templates/base.html new file mode 100644 index 00000000..97ec0738 --- /dev/null +++ b/test/fixtures/collectstatic/hello/templates/base.html @@ -0,0 +1,83 @@ +<!DOCTYPE html> +<html> +<head> +<title>Python Getting Started on Heroku</title> + <link rel="stylesheet" type="text/css" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" /> + <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> + <script type="text/javascript" src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> + <style type="text/css"> + .jumbotron { + background: #532f8c; + color: white; + padding-bottom: 80px + } + .jumbotron .btn-primary { + background: #845ac7; + border-color: #845ac7 + } + .jumbotron .btn-primary:hover { + background: #7646c1 + } + .jumbotron p { + color: #d9ccee; + max-width: 75%; + margin: 1em auto 2em + } + .navbar+.jumbotron { + margin-top: -20px + } + .jumbotron .lang-logo { + display: block; + background: #b01302; + border-radius: 50%; + overflow: hidden; + width: 100px; + height: 100px; + margin: auto; + border: 2px solid white + } + .jumbotron .lang-logo img { + max-width: 100% + } + + + </style> +</head> +<body> +<nav class="navbar navbar-default navbar-static-top navbar-inverse"> + <div class="container"> + <ul class="nav navbar-nav"> + <li class="active"> + <a href="/"><span class="glyphicon glyphicon-home"></span> Home</a> + </li> + <li> + <a href="https://devcenter.heroku.com/articles/how-heroku-works"><span class="glyphicon glyphicon-user"></span> How Heroku Works</a> + </li> + <li class="dropdown"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><span class="glyphicon glyphicon-info-sign"></span> Getting Started Guides <span class="caret"></span></a> + <ul class="dropdown-menu" role="menu"> + <li><a href="https://devcenter.heroku.com/articles/getting-started-with-ruby">Getting Started with Ruby on Heroku</a></li> + <li><a href="https://devcenter.heroku.com/articles/getting-started-with-nodejs">Getting Started with Node on Heroku</a></li> + <li><a href="https://devcenter.heroku.com/articles/getting-started-with-php">Getting Started with PHP on Heroku</a></li> + <li><a href="https://devcenter.heroku.com/articles/getting-started-with-python">Getting Started with Python on Heroku</a></li> + <li><a href="https://devcenter.heroku.com/articles/getting-started-with-java">Getting Started with Java on Heroku</a></li> + <li><a href="https://devcenter.heroku.com/articles/getting-started-with-clojure">Getting Started with Clojure on Heroku</a></li> + <li><a href="https://devcenter.heroku.com/articles/getting-started-with-scala">Getting Started with Scala on Heroku</a></li> + <li class="divider"></li> + <li><a href="https://devcenter.heroku.com/articles/getting-started-with-heroku-and-connect-without-local-dev">Getting Started on Heroku with Heroku Connect</a></li> + <li><a href="https://devcenter.heroku.com/articles/getting-started-with-jruby">Getting Started with Ruby on Heroku (Microsoft Windows)</a></li> + </ul> + </li> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li class="navbar-right"> + <a href="https://devcenter.heroku.com"><span class="glyphicon glyphicon-book"></span> Heroku Dev Center</a> + </li> + </ul> + </div> +</nav> + +{% block content %}{% endblock %} + +</body> +</html> diff --git a/test/fixtures/collectstatic/hello/templates/db.html b/test/fixtures/collectstatic/hello/templates/db.html new file mode 100644 index 00000000..e0e03d4c --- /dev/null +++ b/test/fixtures/collectstatic/hello/templates/db.html @@ -0,0 +1,21 @@ +{% extends "base.html" %} +{% load staticfiles %} + +{% block content %} + <div class="container"> + + +<h2>Page View Report</h2> + + +<ul> + +{% for greeting in greetings %} + <li>{{ greeting.when }}</li> +{% endfor %} + +</ul> + +</div> + +{% endblock %} \ No newline at end of file diff --git a/test/fixtures/collectstatic/hello/templates/index.html b/test/fixtures/collectstatic/hello/templates/index.html new file mode 100644 index 00000000..8af29028 --- /dev/null +++ b/test/fixtures/collectstatic/hello/templates/index.html @@ -0,0 +1,58 @@ +{% extends "base.html" %} +{% load staticfiles %} + +{% block content %} + +<div class="jumbotron text-center"> + <div class="container"> + <a href="/" class="lang-logo"> + <img src="{% static 'lang-logo.png'%}"> + </a> + <h1>Getting Started with Python on Heroku</h1> + <p>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.</p> + <a type="button" class="btn btn-lg btn-default" href="https://devcenter.heroku.com/articles/getting-started-with-python"><span class="glyphicon glyphicon-flash"></span> Getting Started with Python</a> + <a type="button" class="btn btn-lg btn-primary" href="https://github.com/heroku/python-getting-started"><span class="glyphicon glyphicon-download"></span> Source on GitHub</a> + </div> +</div> +<div class="container"> + <div class="alert alert-info text-center" role="alert"> + To deploy your own copy, and learn the fundamentals of the Heroku platform, head over to the <a href="https://devcenter.heroku.com/articles/getting-started-with-python" class="alert-link">Getting Started with Python on Heroku</a> tutorial. + </div> + <hr> + <div class="row"> + <div class="col-md-6"> + <h3><span class="glyphicon glyphicon-info-sign"></span> How this sample app works</h3> + <ul> + <li>This app was deployed to Heroku, either using Git or by using <a href="https://github.com/heroku/python-getting-started">Heroku Button</a> on the repository.</li> + + <li>When Heroku received the source code, it fetched all the dependencies in the <a href="https://github.com/heroku/python-getting-started/blob/master/Pipfile">Pipfile</a>, creating a deployable slug.</li> + <li>The platform then spins up a dyno, a lightweight container that provides an isolated environment in which the slug can be mounted and executed.</li> + <li>You can scale your app, manage it, and deploy over <a href="https://addons.heroku.com/">150 add-on services</a>, from the Dashboard or CLI.</li> + </ul> + </div> + <div class="col-md-6"> + <h3><span class="glyphicon glyphicon-link"></span> Next Steps</h3> + <ul> + <li>If you are following the <a href="https://devcenter.heroku.com/articles/getting-started-with-python">Getting Started</a> guide, then please head back to the tutorial and follow the next steps!</li> + <li>If you deployed this app by deploying the Heroku Button, then in a command line shell, run:</li> + <ul> + <li><code>git clone https://github.com/heroku/python-getting-started.git</code> - this will create a local copy of the source code for the app</li> + <li><code>cd python-getting-started</code> - change directory into the local source code repository</li> + <li><code>heroku git:remote -a <your-app-name></code> - associate the Heroku app with the repository</li> + <li>You'll now be set up to run the app locally, or <a href="https://devcenter.heroku.com/articles/getting-started-with-python#push-local-changes">deploy changes</a> to Heroku</li> + </ul> + </ul> + <h3><span class="glyphicon glyphicon-link"></span> Helpful Links</h3> + <ul> + <li><a href="https://www.heroku.com/home">Heroku</a></li> + <li><a href="https://devcenter.heroku.com/">Heroku Dev Center</a></li> + <li><a href="https://devcenter.heroku.com/articles/getting-started-with-python">Getting Started with Python on Heroku</a></li> + <li><a href="https://devcenter.heroku.com/articles/django-app-configuration">Configuring Django Apps for Heroku</a></li> + </ul> + </div> + </div> <!-- row --> + <div class="alert alert-info text-center" role="alert"> + Please do work through the Getting Started guide, even if you do know how to build such an application. The guide covers the basics of working with Heroku, and will familiarize you with all the concepts you need in order to build and deploy your own apps. + </div> +</div> +{% endblock %} diff --git a/test/fixtures/collectstatic/hello/tests.py b/test/fixtures/collectstatic/hello/tests.py new file mode 100644 index 00000000..1d69113f --- /dev/null +++ b/test/fixtures/collectstatic/hello/tests.py @@ -0,0 +1,18 @@ +from django.contrib.auth.models import AnonymousUser, User +from django.test import TestCase, RequestFactory + +from .views import index + +class SimpleTest(TestCase): + def setUp(self): + # Every test needs access to the request factory. + self.factory = RequestFactory() + + def test_details(self): + # Create an instance of a GET request. + request = self.factory.get('/') + request.user = AnonymousUser() + + # Test my_view() as if it were deployed at /customer/details + response = index(request) + self.assertEqual(response.status_code, 200) \ No newline at end of file diff --git a/test/fixtures/collectstatic/hello/views.py b/test/fixtures/collectstatic/hello/views.py new file mode 100644 index 00000000..8558d845 --- /dev/null +++ b/test/fixtures/collectstatic/hello/views.py @@ -0,0 +1,20 @@ +from django.shortcuts import render +from django.http import HttpResponse + +from .models import Greeting + +# Create your views here. +def index(request): + # return HttpResponse('Hello from Python!') + return render(request, 'index.html') + + +def db(request): + + greeting = Greeting() + greeting.save() + + greetings = Greeting.objects.all() + + return render(request, 'db.html', {'greetings': greetings}) + diff --git a/test/fixtures/collectstatic/manage.py b/test/fixtures/collectstatic/manage.py new file mode 100755 index 00000000..eb3ab8af --- /dev/null +++ b/test/fixtures/collectstatic/manage.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python +import os +import sys + +if __name__ == "__main__": + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "gettingstarted.settings") + + from django.core.management import execute_from_command_line + + execute_from_command_line(sys.argv) diff --git a/test/run b/test/run index 62e902f4..82baf795 100755 --- a/test/run +++ b/test/run @@ -27,6 +27,11 @@ testNoRequirements() { assertCapturedError } +testCollectstatic() { + compile "collectstatic" + assertCaptured "collectstatic" +} + testGEOS() { BUILD_WITH_GEO_LIBRARIES=1 compile "geos" assertCaptured "geos" -- GitLab