blob: 5f3cb4f0729454e0935270fd54e0bb3314ef4078 [file] [log] [blame]
# Copyright 2014 the Melange authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# all targets are PHONY because they don't actually generate a file with the
# name of the target.
.PHONY: setup test pylint lint localserver gitclean help
.PHONY: pyunit functionaltest jstest _ptests ptest
help:
@echo
@echo Common Commands:
@echo local-docker - build and run a local docker container
@echo docker - enter the docker container
@echo setup - setup environment
@echo css - rebuild css
@echo docs - build the python and javascript documentation
@echo localserver - run local development server
@echo gitclean - reset to clean checkout
@echo lint - run lint and safety checks
@echo test - run all tests
@echo ptest - run all tests in parallel
@echo functionaltest - run functional tests
@echo do-release - make production release
@echo do-dev-release APP=foo - make dev release
@echo
@echo To make a release...
@echo " make gitclean && make setup && make ptest && make do-release"
@echo
# try and avoid downloading things more than once.
DOWNLOAD_CACHE=/var/tmp/melange-download-cache-$(USER)
ifdef DOWNLOAD_CACHE
DOWNLOAD_CACHE_SENTINEL=$(DOWNLOAD_CACHE)/.sentinel
# where should bootstrap store its download cache?
DOWNLOAD_CACHE_ARG=download-cache=$(DOWNLOAD_CACHE)
# where should PIP store its download cache?
export PIP_DOWNLOAD_CACHE=$(DOWNLOAD_CACHE)/pip
export npm_config_cache=$(DOWNLOAD_CACHE)/npm
endif
# bootstrap gets unhappy if the directory doesn't exist
$(DOWNLOAD_CACHE_SENTINEL):
ifdef DOWNLOAD_CACHE_SENTINEL
mkdir -p $(DOWNLOAD_CACHE)
touch $(DOWNLOAD_CACHE_SENTINEL)
endif
# initial setup for the development environment
initial-setup: .initial-setup
.initial-setup: $(DOWNLOAD_CACHE_SENTINEL)
virtualenv venv
venv/bin/pip install -U setuptools
venv/bin/python -c 'import lxml' || venv/bin/pip install -U lxml
venv/bin/python bootstrap.py $(DOWNLOAD_CACHE_ARG) bootstrap
touch $@
# run buildout
buildout: .buildout
.buildout: $(DOWNLOAD_CACHE_SENTINEL) buildout.cfg setup.py
bin/buildout $(DOWNLOAD_CACHE_ARG)
touch $@
# clear the sentinel files that prevent buildout and initial-setup from
# running again unless a dependency has changed.
clean-setup:
rm -f .buildout .initial-setup
@echo now re-run 'make setup'
# build and run a local copy of the melange docker container
local-docker:
docker build -t $(USER)/melange .
docker run -ti --rm -v $(PWD):/workspace -p 8080:8080 $(USER)/melange
# enter the docker container
docker:
@echo You are now working in a docker container.
@echo Type 'exit' to leave the container
@docker run -ti --rm -v $(PWD):/workspace -p 8080:8080 melange/melange-dev
# setup target sets up the basics of the development environment
setup: APP=local-devel
setup: initial-setup buildout
bin/gen-app-yaml -f $(APP)
bin/paver build --skip-docs
# force all setup dependencies to run again
force-setup: clean-setup setup
# update python and js generated docs
docs:
bin/paver build_docs
bin/grunt documentation
# run all the tests
test:
bin/run-tests
# which directories and paths should we run pylint on
PYLINT_PATHS:=app/codein app/melange app/soc app/summerofcode
PYLINT_PATHS+=app/settings.py app/urls.py app/main.py
PYLINT_PATHS+=scripts tests
PYLINT_PATHS+=configuration/buildbot/*.py configuration/buildbot/*.cfg
PYLINT_PATHS+=pavement.py setup.py
PYLINT_FLAGS:=
# how much parallelism for pylint?
# (pylint doesn't parallelize on Melange very well, so there's not a
# lot of improvement once you get much past 2.)
PYLINT_JOBS:=4
# run pylint
pylint:
bin/pylint --jobs=$(PYLINT_JOBS) --rcfile=$(PWD)/pylintrc \
$(PYLINT_FLAGS) $(PYLINT_PATHS)
# *** pylint-verbose enables more checks
# In the rcfile(pylintrc) errors-only option is
# set. PYLINT_VERBOSE_FLAGS defines other errors that we might want to
# turn on.
# Include fancier output:
PYLINT_VERBOSE_FLAGS+=--reports=yes
# R and C modules are just too chatty, we can however turn a few of
# the more useful ones on explicitly:
PYLINT_VERBOSE_FLAGS:=--enable=W,F
# We may want to enable these in the future:
PYLINT_VERBOSE_FLAGS+=--disable=protected-access,attribute-defined-outside-init
# TODO(nathaniel): fix all occurences and enable this:
PYLINT_VERBOSE_FLAGS+=--disable=abstract-method
# These are just plain useless, we don't ever want to these:
PYLINT_VERBOSE_FLAGS+=--disable=fixme,unused-argument,star-args,bad-builtin,locally-disabled
# These are somewhat debatable, but not realistic for Melange:
PYLINT_VERBOSE_FLAGS+=--disable=no-init,super-init-not-called
# TODO(nathaniel): fix all occurences and move this to pylintrc file:
PYLINT_VERBOSE_FLAGS+=--enable=line-too-long
pylint-verbose: PYLINT_FLAGS=$(PYLINT_VERBOSE_FLAGS)
pylint-verbose: pylint
lint: pylint
# run only the pyunit tests
pyunit: PROCESSES=$(if $(PTESTS),4,-1)
pyunit:
bin/run-tests -t pyunit --processes=$(PROCESSES)
functionaltest:
bin/run-tests -t functional
jstest:
bin/run-tests -t js
# helper target for ptest target (specifies which tests to run)
_ptests: PTESTS=1
_ptests: functionaltest pyunit pylint jstest
@echo
# run tests in parallel (note, output will be interleaved)
ptest:
make -j _ptests
# build less files into css
css:
bin/grunt less
# some files (like css) are generated dynamically, group them all in
# one target
generated: css
# start a local instance. defaults to port 8080 for the app and 8000
# for the appengine console
localserver:
thirdparty/google_appengine/dev_appserver.py build
# return to a pristine git checkout. *DELETES EVERYTHING WITHOUT PROMPTING*
gitclean:
git clean -xdf
# Targets related to making a release ---
.PHONY: update-template-version commit-release push-release-to-appengine
.PHONY: do-release
# define an string equality function. call with $(call eq,1,2)
eq = $(and $(findstring $(1),$(2)),$(findstring $(2),$(1)))
BRANCH=$(shell git rev-parse --abbrev-ref HEAD)
BRANCH_CLEAN=$(shell echo $(BRANCH) \
| tr 'A-Z' 'a-z' \
| sed -r 's/[^a-z0-9-]/-/g' \
| cut -c 1-34)
VERSION_SUFFIX=$(if $(call eq,$(BRANCH),master),,-$(BRANCH_CLEAN))
# Sets the version in app.yaml.template to the version as specified by
# the current day.
# If you need to specify a patchlevel (i.e. -1, -2), you must specify
# the whole VERSION on the make command line.
# For development versions, use the output of git describe --tags
_update_app_yaml_template:
sed -i -r 's/^(version: )[^ \t]+/\1$(VERSION)/' app/app.yaml.template
# only updates the version in app.yaml
_update_app_yaml:
sed -i -r 's/^(version: )[^ \t]+/\1$(VERSION)/' app/app.yaml
update-version: VERSION=2-1-$(shell date +%Y%m%d)$(VERSION_SUFFIX)
update-version: _update_app_yaml_template
# update-dev-version only updates the version in
# app/app.yaml, not in the template.
update-dev-version: VERSION=$(shell git describe --tags | cut -c2-)$(VERSION_SUFFIX)
update-dev-version: _update_app_yaml
commit-release: VERSION=$(shell awk '/^version: / { print $$2 }' app/app.yaml.template)
commit-release:
git commit -e -m "Set new Melange version number to $(VERSION)." app/app.yaml.template
git tag v$(VERSION) HEAD
gen-app-yaml: app/app.yaml
app/app.yaml: app/app.yaml.template scripts/gen_app_yaml.py
bin/gen-app-yaml -f $(APP)
# TODO(robert): set the default value of APP to local-devel?
push-release-to-appengine:
thirdparty/google_appengine/appcfg.py \
--application=$(APP) \
--noauth_local_webserver \
--oauth2 update build
do-dev-release: APP=YOU_MUST_SPECIFY_A_VALID_APP
do-dev-release: generated update-dev-version push-release-to-appengine
@echo
@echo ==========================================================
@echo Melange dev release $(VERSION) pushed successfully!
@echo *. go to the App Engine control panel and send it traffic
@echo https://appengine.google.com/deployment?app_id=s~$(APP)
do-release: APP=google-melange
do-release: generated update-version gen-app-yaml \
commit-release push-release-to-appengine
@echo
@echo ==========================================================
@echo Melange release $(VERSION) pushed successfully!
@echo 1. push the release commit to the repository
@echo git push --tags origin master
@echo 2. go to the App Engine control panel and send it traffic
@echo https://appengine.google.com/deployment?app_id=s~$(APP)