Have cache busting hashes be generated as part of the build process.
This commit is contained in:
parent
5f431e966e
commit
09a10b6153
4 changed files with 52 additions and 17 deletions
|
@ -3,6 +3,7 @@ import urlparse
|
||||||
import json
|
import json
|
||||||
import string
|
import string
|
||||||
import datetime
|
import datetime
|
||||||
|
import os
|
||||||
|
|
||||||
# Register the various exceptions via decorators.
|
# Register the various exceptions via decorators.
|
||||||
import endpoints.decorated
|
import endpoints.decorated
|
||||||
|
@ -32,6 +33,23 @@ profile = logging.getLogger('application.profiler')
|
||||||
|
|
||||||
route_data = None
|
route_data = None
|
||||||
|
|
||||||
|
CACHE_BUSTERS_JSON = 'static/dist/cachebusters.json'
|
||||||
|
CACHE_BUSTERS = None
|
||||||
|
|
||||||
|
def get_cache_busters():
|
||||||
|
""" Retrieves the cache busters hashes. """
|
||||||
|
global CACHE_BUSTERS
|
||||||
|
if CACHE_BUSTERS is not None:
|
||||||
|
return CACHE_BUSTERS
|
||||||
|
|
||||||
|
if not os.path.exists(CACHE_BUSTERS_JSON):
|
||||||
|
return {}
|
||||||
|
|
||||||
|
with open(CACHE_BUSTERS_JSON, 'r') as f:
|
||||||
|
CACHE_BUSTERS = json.loads(f.read())
|
||||||
|
return CACHE_BUSTERS
|
||||||
|
|
||||||
|
|
||||||
class RepoPathConverter(BaseConverter):
|
class RepoPathConverter(BaseConverter):
|
||||||
regex = '[\.a-zA-Z0-9_\-]+/[\.a-zA-Z0-9_\-]+'
|
regex = '[\.a-zA-Z0-9_\-]+/[\.a-zA-Z0-9_\-]+'
|
||||||
weight = 200
|
weight = 200
|
||||||
|
@ -113,17 +131,15 @@ def list_files(path, extension):
|
||||||
filepath = 'static/' + path
|
filepath = 'static/' + path
|
||||||
return [join_path(dp, f) for dp, dn, files in os.walk(filepath) for f in files if matches(f)]
|
return [join_path(dp, f) for dp, dn, files in os.walk(filepath) for f in files if matches(f)]
|
||||||
|
|
||||||
SAVED_CACHE_STRING = random_string()
|
|
||||||
|
|
||||||
def render_page_template(name, **kwargs):
|
def render_page_template(name, **kwargs):
|
||||||
if app.config.get('DEBUGGING', False):
|
debugging = app.config.get('DEBUGGING', False)
|
||||||
|
if debugging:
|
||||||
# If DEBUGGING is enabled, then we load the full set of individual JS and CSS files
|
# If DEBUGGING is enabled, then we load the full set of individual JS and CSS files
|
||||||
# from the file system.
|
# from the file system.
|
||||||
library_styles = list_files('lib', 'css')
|
library_styles = list_files('lib', 'css')
|
||||||
main_styles = list_files('css', 'css')
|
main_styles = list_files('css', 'css')
|
||||||
library_scripts = list_files('lib', 'js')
|
library_scripts = list_files('lib', 'js')
|
||||||
main_scripts = list_files('js', 'js')
|
main_scripts = list_files('js', 'js')
|
||||||
cache_buster = 'debugging'
|
|
||||||
|
|
||||||
file_lists = [library_styles, main_styles, library_scripts, main_scripts]
|
file_lists = [library_styles, main_styles, library_scripts, main_scripts]
|
||||||
for file_list in file_lists:
|
for file_list in file_lists:
|
||||||
|
@ -133,7 +149,6 @@ def render_page_template(name, **kwargs):
|
||||||
main_styles = ['dist/quay-frontend.css']
|
main_styles = ['dist/quay-frontend.css']
|
||||||
library_scripts = []
|
library_scripts = []
|
||||||
main_scripts = ['dist/quay-frontend.min.js']
|
main_scripts = ['dist/quay-frontend.min.js']
|
||||||
cache_buster = SAVED_CACHE_STRING
|
|
||||||
|
|
||||||
use_cdn = app.config.get('USE_CDN', True)
|
use_cdn = app.config.get('USE_CDN', True)
|
||||||
if request.args.get('use_cdn') is not None:
|
if request.args.get('use_cdn') is not None:
|
||||||
|
@ -142,6 +157,12 @@ def render_page_template(name, **kwargs):
|
||||||
external_styles = get_external_css(local=not use_cdn)
|
external_styles = get_external_css(local=not use_cdn)
|
||||||
external_scripts = get_external_javascript(local=not use_cdn)
|
external_scripts = get_external_javascript(local=not use_cdn)
|
||||||
|
|
||||||
|
def add_cachebusters(filenames):
|
||||||
|
cachebusters = get_cache_busters()
|
||||||
|
for filename in filenames:
|
||||||
|
cache_buster = cachebusters.get(filename, random_string()) if not debugging else 'debugging'
|
||||||
|
yield (filename, cache_buster)
|
||||||
|
|
||||||
def get_oauth_config():
|
def get_oauth_config():
|
||||||
oauth_config = {}
|
oauth_config = {}
|
||||||
for oauth_app in oauth_apps:
|
for oauth_app in oauth_apps:
|
||||||
|
@ -153,13 +174,14 @@ def render_page_template(name, **kwargs):
|
||||||
if len(app.config.get('CONTACT_INFO', [])) == 1:
|
if len(app.config.get('CONTACT_INFO', [])) == 1:
|
||||||
contact_href = app.config['CONTACT_INFO'][0]
|
contact_href = app.config['CONTACT_INFO'][0]
|
||||||
|
|
||||||
resp = make_response(render_template(name, route_data=json.dumps(get_route_data()),
|
resp = make_response(render_template(name,
|
||||||
|
route_data=json.dumps(get_route_data()),
|
||||||
external_styles=external_styles,
|
external_styles=external_styles,
|
||||||
external_scripts=external_scripts,
|
external_scripts=external_scripts,
|
||||||
main_styles=main_styles,
|
main_styles=add_cachebusters(main_styles),
|
||||||
library_styles=library_styles,
|
library_styles=add_cachebusters(library_styles),
|
||||||
main_scripts=main_scripts,
|
main_scripts=add_cachebusters(main_scripts),
|
||||||
library_scripts=library_scripts,
|
library_scripts=add_cachebusters(library_scripts),
|
||||||
feature_set=json.dumps(features.get_features()),
|
feature_set=json.dumps(features.get_features()),
|
||||||
config_set=json.dumps(getFrontendVisibleConfig(app.config)),
|
config_set=json.dumps(getFrontendVisibleConfig(app.config)),
|
||||||
oauth_set=json.dumps(get_oauth_config()),
|
oauth_set=json.dumps(get_oauth_config()),
|
||||||
|
@ -169,7 +191,6 @@ def render_page_template(name, **kwargs):
|
||||||
sentry_public_dsn=app.config.get('SENTRY_PUBLIC_DSN', ''),
|
sentry_public_dsn=app.config.get('SENTRY_PUBLIC_DSN', ''),
|
||||||
is_debug=str(app.config.get('DEBUGGING', False)).lower(),
|
is_debug=str(app.config.get('DEBUGGING', False)).lower(),
|
||||||
show_chat=features.OLARK_CHAT,
|
show_chat=features.OLARK_CHAT,
|
||||||
cache_buster=cache_buster,
|
|
||||||
has_billing=features.BILLING,
|
has_billing=features.BILLING,
|
||||||
contact_href=contact_href,
|
contact_href=contact_href,
|
||||||
hostname=app.config['SERVER_HOSTNAME'],
|
hostname=app.config['SERVER_HOSTNAME'],
|
||||||
|
|
|
@ -68,6 +68,18 @@ module.exports = function(grunt) {
|
||||||
src: ['../static/partials/*.html', '../static/directives/*.html'],
|
src: ['../static/partials/*.html', '../static/directives/*.html'],
|
||||||
dest: '../static/dist/template-cache.js'
|
dest: '../static/dist/template-cache.js'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
cachebuster: {
|
||||||
|
build: {
|
||||||
|
options: {
|
||||||
|
format: 'json',
|
||||||
|
basedir: '../static/'
|
||||||
|
},
|
||||||
|
src: [ '../static/dist/template-cache.js', '../static/dist/<%= pkg.name %>.min.js',
|
||||||
|
'../static/dist/<%= pkg.name %>.css' ],
|
||||||
|
dest: '../static/dist/cachebusters.json'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -75,7 +87,8 @@ module.exports = function(grunt) {
|
||||||
grunt.loadNpmTasks('grunt-contrib-concat');
|
grunt.loadNpmTasks('grunt-contrib-concat');
|
||||||
grunt.loadNpmTasks('grunt-contrib-cssmin');
|
grunt.loadNpmTasks('grunt-contrib-cssmin');
|
||||||
grunt.loadNpmTasks('grunt-angular-templates');
|
grunt.loadNpmTasks('grunt-angular-templates');
|
||||||
|
grunt.loadNpmTasks('grunt-cachebuster');
|
||||||
|
|
||||||
// Default task(s).
|
// Default task(s).
|
||||||
grunt.registerTask('default', ['ngtemplates', 'concat', 'cssmin', 'uglify']);
|
grunt.registerTask('default', ['ngtemplates', 'concat', 'cssmin', 'uglify', 'cachebuster']);
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
"grunt-contrib-concat": "~0.4.0",
|
"grunt-contrib-concat": "~0.4.0",
|
||||||
"grunt-contrib-cssmin": "~0.9.0",
|
"grunt-contrib-cssmin": "~0.9.0",
|
||||||
"grunt-angular-templates": "~0.5.4",
|
"grunt-angular-templates": "~0.5.4",
|
||||||
"grunt-contrib-uglify": "~0.4.0"
|
"grunt-contrib-uglify": "~0.4.0",
|
||||||
|
"grunt-cachebuster": "~0.1.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,11 +28,11 @@
|
||||||
<link rel="apple-touch-icon" sizes="152x152" href="/static/img/apple-touch-icon-152x152.png" />
|
<link rel="apple-touch-icon" sizes="152x152" href="/static/img/apple-touch-icon-152x152.png" />
|
||||||
<!-- /Icons -->
|
<!-- /Icons -->
|
||||||
|
|
||||||
{% for style_path in main_styles %}
|
{% for style_path, cache_buster in main_styles %}
|
||||||
<link rel="stylesheet" href="/static/{{ style_path }}?v={{ cache_buster }}" type="text/css">
|
<link rel="stylesheet" href="/static/{{ style_path }}?v={{ cache_buster }}" type="text/css">
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{% for style_path in library_styles %}
|
{% for style_path, cache_buster in library_styles %}
|
||||||
<link rel="stylesheet" href="/static/{{ style_path }}?v={{ cache_buster }}" type="text/css">
|
<link rel="stylesheet" href="/static/{{ style_path }}?v={{ cache_buster }}" type="text/css">
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
<script src="{{ script_url }}"></script>
|
<script src="{{ script_url }}"></script>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{% for script_path in library_scripts %}
|
{% for script_path, cache_buster in library_scripts %}
|
||||||
<script src="/static/{{ script_path }}?v={{ cache_buster }}"></script>
|
<script src="/static/{{ script_path }}?v={{ cache_buster }}"></script>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% for script_path in main_scripts %}
|
{% for script_path, cache_buster in main_scripts %}
|
||||||
<script src="/static/{{ script_path }}?v={{ cache_buster }}"></script>
|
<script src="/static/{{ script_path }}?v={{ cache_buster }}"></script>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
|
Reference in a new issue