blob: 184141cdb1e42603c91f315591ee2c196dc869e0 [file] [log] [blame]
# == Makefile for Trac related tasks (beyond those supported by setuptools) ==
#
# Automating testing, i18n tasks, documentation generation, ... see HELP below
# ----------------------------------------------------------------------------
#
# Note about customization:
# No changes to the present Makefile should be necessary,
# rather copy Makefile.cfg.sample to Makefile.cfg and adapt it
# to match your local environment.
#
# Note that this is a GNU Makefile, nmake and other abominations are
# not supported.
#
# ============================================================================
define HELP
Please use `make <target>' where <target> is one of:
clean delete all compiled files
status show which Python is used and other infos
[python=...] variable for selecting Python version
---------------- Testing tasks
unit-test run unit tests
functional-test run functional tests
test-wiki shortcut for running all wiki unit tests
test run all tests
coverage run all tests, under coverage
figleaf run all tests, under figleaf
[db=...] variable for selecting database backend
[test=...] variable for selecting a single test file
[testopts=...] variable containing extra options for running tests
[coverageopts=...] variable containing extra options for coverage
---------------- Code checking tasks
pylint check code with pylint
---------------- Standalone test server
server start tracd
[port=...] variable for selecting the port
[auth=...] variable for specifying authentication
[env=...] variable for the trac environment or parent dir
[tracdopts=...] variable containing extra options for tracd
---------------- L10N tasks
init-xy create catalogs for given xy locale
extraction regenerate the catalog templates
update update all the catalog files from the templates
update-xy update the catalogs for the xy locale only
compile compile all the catalog files
compile-xy compile the catalogs for the xy locale only
check verify all the catalog files
check-xy verify the catalogs for the xy locale only
stats detailed translation statistics for all catalogs
stats-pot total messages in the catalog templates
stats-xy translated, fuzzy, untranslated for the xy locale only
summary display percent translated for all catalogs
summary-xy display percent translated for the xy locale only
(suitable for a commit message)
diff show relevant changes after an update for all catalogs
diff-xy show relevant changes after an update for the xy locale
[locale=...] variable for selecting a set of locales
---------------- Documentation tasks
apidoc|sphinx generate the Sphinx documentation (all specified formats)
apidoc-html generate the Sphinx documentation in HTML format
apidoc-pdf generate the Sphinx documentation in PDF format
apiref|epydoc generate the full API reference using Epydoc
[sphinxformat=...] list of formats for generated documentation
[sphinxopts=...] variable containing extra options for Sphinx
[sphinxopts-html=...] variable containing extra options used for html format
[epydocopts=...] variable containing extra options for Epydoc
[dotpath=/.../dot] path to Graphviz' dot program (not used yet)
endef
export HELP
# ` (keep emacs font-lock happy)
define HELP_CFG
It looks like you don't have a Makefile.cfg file yet.
You can get started by doing `cp Makefile.cfg.sample Makefile.cfg'
and then adapt it to your environment.
endef
export HELP_CFG
# ============================================================================
# ----------------------------------------------------------------------------
#
# Main targets
#
# ----------------------------------------------------------------------------
.PHONY: all help status clean clean-bytecode clean-mo
ifdef test
all: status
python $(test) $(testopts)
else
all: help
endif
help: Makefile.cfg
@echo "$$HELP"
Makefile.cfg:
@echo "$$HELP_CFG"
status:
@echo -n "Python version: "
@python -V
@echo -n "figleaf: "
@-which figleaf 2>/dev/null || echo
@echo -n "coverage: "
@-which coverage 2>/dev/null || echo
@echo "PYTHONPATH=$$PYTHONPATH"
@echo "TRAC_TEST_DB_URI=$$TRAC_TEST_DB_URI"
@echo "server-options=$(server-options)"
Trac.egg-info: status
python setup.py egg_info
clean: clean-bytecode clean-figleaf clean-coverage clean-doc
clean-bytecode:
find -name \*.py[co] -exec rm {} \;
Makefile: ;
# ----------------------------------------------------------------------------
#
-include Makefile.cfg
#
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
#
# L10N related tasks
#
# ----------------------------------------------------------------------------
catalogs = messages messages-js tracini
ifdef locale
locales = $(locale)
else
locales = $(wildcard trac/locale/*/LC_MESSAGES/messages.po)
locales := $(subst trac/locale/,,$(locales))
locales := $(subst /LC_MESSAGES/messages.po,,$(locales))
locales := $(sort $(locales))
endif
# Note: variables only valid within a $(foreach catalog,...) evaluation
catalog.po = trac/locale/$(*)/LC_MESSAGES/$(catalog).po
catalog.pot = trac/locale/$(catalog).pot
catalog_stripped = $(subst messages,,$(subst -,,$(catalog)))
_catalog = $(if $(catalog_stripped),_)$(catalog_stripped)
.PHONY: extract extraction update compile check stats summary diff
init-%:
@$(foreach catalog,$(catalogs), \
[ -e $(catalog.po) ] \
&& echo "$(catalog.po) already exists" \
|| python setup.py init_catalog$(_catalog) -l $(*);)
extract extraction:
python setup.py $(foreach catalog,$(catalogs),\
extract_messages$(_catalog))
update-%:
python setup.py $(foreach catalog,$(catalogs), \
update_catalog$(_catalog) -l $(*))
ifdef locale
update: $(addprefix update-,$(locale))
else
update:
python setup.py $(foreach catalog,$(catalogs), \
update_catalog$(_catalog))
endif
compile-%:
python setup.py $(foreach catalog,$(catalogs), \
compile_catalog$(_catalog) -l $(*)) \
generate_messages_js -l $(*)
ifdef locale
compile: $(addprefix compile-,$(locale))
else
compile:
python setup.py $(foreach catalog,$(catalogs), \
compile_catalog$(_catalog))
endif
check: pre-check $(addprefix check-,$(locales))
@echo "All catalogs checked are OK"
pre-check:
@echo "checking catalogs for $(locales)..."
check-%:
@echo -n "$(@): "
@$(foreach catalog,$(catalogs), \
msgfmt --check $(catalog.po) &&) echo OK
@rm -f messages.mo
stats: pre-stats $(addprefix stats-,$(locales))
pre-stats: stats-pot
@echo "translation statistics for $(locales)..."
stats-pot:
@echo "translation statistics for catalog templates:"
@$(foreach catalog,$(catalogs), \
echo -n "$(catalog.pot): "; \
msgfmt --statistics $(catalog.pot);)
@rm -f messages.mo
stats-%:
@$(foreach catalog,$(catalogs), \
[ -e $(catalog.po) ] \
&& echo -n "$(catalog.po): "; \
msgfmt --statistics $(catalog.po) \
|| echo "$(catalog.po) doesn't exist (make init-$(*))";)
@rm -f messages.mo
summary: $(addprefix summary-,$(locales))
define untranslated-sh
LC_ALL=C msgfmt --statistics $(catalog.pot) 2>&1 \
| tail -1 \
| sed -e 's/0 translated messages, \([0-9]*\) un.*/\1/'
endef
define translated-sh
{ LC_ALL=C msgfmt --statistics $(catalog.po) 2>&1 || echo 0; } \
| tail -1 \
| sed -e 's/[^0-9]*\([0-9]*\) translated.*/\1/'
endef
MESSAGES_TOTAL = \
$(eval MESSAGES_TOTAL := ($(foreach catalog,$(catalogs), \
$(shell $(untranslated-sh)) + ) 0)) \
$(MESSAGES_TOTAL)
summary-%:
@python -c "print 'l10n/$(*): translations updated (%d%%)' \
% (($(foreach catalog,$(catalogs), \
$(shell $(translated-sh)) + ) 0) * 100.0 \
/ $(MESSAGES_TOTAL))"
@rm -f messages.mo
diff: $(addprefix diff-,$(locales))
diff-%:
@svn diff trac/locale/$(*) \
| grep -Ev '^([-+]#:|[@ ])' | grep -E '^[-+@]' || true
clean-mo:
find trac/locale -name \*.mo -exec rm {} \;
find trac/htdocs/js/messages -name \*.js -exec rm {} \;
# ----------------------------------------------------------------------------
#
# Testing related tasks
#
# ----------------------------------------------------------------------------
.PHONY: test unit-test functional-test test-wiki
test: unit-test functional-test
unit-test: Trac.egg-info
python ./trac/test.py --skip-functional-tests $(testopts)
functional-test: Trac.egg-info
python trac/tests/functional/__init__.py -v $(testopts)
test-wiki:
python trac/tests/allwiki.py $(testopts)
# ----------------------------------------------------------------------------
#
# Code checking tasks
#
# ----------------------------------------------------------------------------
.PHONY: pylint
pylint:
pylint \
--include-ids=y --persistent=n --comment=n --init-import=y \
--disable=E0102,E0211,E0213,E0602,E0611,E1002,E1101,E1102,E1103 \
--disable=F0401 \
--disable=W0102,W0141,W0142,W0201,W0212,W0221,W0223,W0231,W0232, \
--disable=W0401,W0511,W0603,W0613,W0614,W0621,W0622,W0703 \
--disable=C0103,C0111 \
trac tracopt
# ----------------------------------------------------------------------------
#
# Coverage related tasks
#
# (see http://nedbatchelder.com/code/coverage/)
#
# ----------------------------------------------------------------------------
.PHONY: coverage clean-coverage show-coverage
coverage: clean-coverage test-coverage show-coverage
clean-coverage:
coverage erase
@rm -fr htmlcov
ifdef test
test-coverage:
coverage run $(test) $(testopts)
else
test-coverage: unit-test-coverage functional-test-coverage
endif
unit-test-coverage:
coverage run -a $(coverageopts) trac/test.py --skip-functional-tests
functional-test-coverage:
FIGLEAF='coverage run -a $(coverageopts)' python \
trac/tests/functional/testcases.py -v
show-coverage: htmlcov/index.html
#coverage report
htmlcov/index.html:
coverage html \
--omit=$(subst $(space),$(comma),$(wildcard trac/*/templates)),trac/templates
# ----------------------------------------------------------------------------
#
# Figleaf based coverage tasks
#
# (see http://darcs.idyll.org/~t/projects/figleaf/doc/)
#
# ** NOTE: there are still several issues with this **
# - as soon as a DocTestSuite is run, figleaf gets confused
# - functional-test-figleaf is broken (no .figleaf generated)
#
# ----------------------------------------------------------------------------
.PHONY: figleaf clean-figleaf show-figleaf
figleaf: clean-figleaf test-figleaf show-figleaf
clean-figleaf:
rm -f .figleaf* *.figleaf
rm -fr figleaf
show-figleaf: figleaf/index.html
figleaf/index.html: $(wildcard *.figleaf)
figleaf2html \
--output-directory=figleaf \
--exclude-patterns=trac/tests/figleaf-exclude \
*.figleaf
.PHONY: test-figleaf unit-test-figleaf functional-test-figleaf
test-figleaf: unit-test-figleaf functional-test-figleaf
unit-test-figleaf: unit-test.figleaf
functional-test-figleaf: functional-test.figleaf
functional-test.figleaf: Trac.egg-info
rm -f .figleaf
FIGLEAF=figleaf python trac/tests/functional/testcases.py -v
@mv .figleaf $(@)
unit-test.figleaf: Trac.egg-info
rm -f .figleaf
figleaf trac/test.py --skip-functional-tests
@mv .figleaf $(@)
# ----------------------------------------------------------------------------
#
# Tracd related tasks
#
# ----------------------------------------------------------------------------
port ?= 8000
tracdopts ?= -r
define server-options
$(if $(port),-p $(port))\
$(if $(auth),-a '$(auth)')\
$(tracdopts)\
$(if $(wildcard $(env)/VERSION),$(env),-e $(env))
endef
.PHONY: server
server: Trac.egg-info
ifdef env
python trac/web/standalone.py $(server-options)
else
@echo "\`env' variable was not specified. See \`make help'."
endif
# ----------------------------------------------------------------------------
#
# Documentation related tasks
#
# ----------------------------------------------------------------------------
.PHONY: apidoc sphinx apiref epydoc clean-doc
# We also try to honor the "conventional" environment variables used by Sphinx
sphinxopts ?= $(SPHINXOPTS)
SPHINXBUILD ?= sphinx-build
BUILDDIR ?= build/doc
PAPER ?= a4
sphinxopts-latex ?= -D latex_paper_size=$(PAPER)
sphinxformat = html
sphinx: apidoc
apidoc: $(addprefix apidoc-,$(sphinxformat))
apidoc-%:
@$(SPHINXBUILD) -b $(*) \
$(sphinxopts) $(sphinxopts-$(*)) \
-d build/doc/doctree \
doc $(BUILDDIR)/$(*)
epydoc: apiref
apiref: doc-images
@python doc/utils/runepydoc.py --config=doc/utils/epydoc.conf \
$(epydocopts) $(if $(dotpath),--dotpath=$(dotpath))
doc-images: $(addprefix build/,$(wildcard doc/images/*.png))
build/doc/images/%: doc/images/% | build/doc/images
@cp $(<) $(@)
build/doc/images:
@mkdir -p $(@)
clean-doc:
rm -fr build/doc
# ============================================================================
#
# Setup environment variables
python-home := $(python.$(if $(python),$(python),$($(db).python)))
ifeq "$(OS)" "Windows_NT"
ifndef python-home
# Detect location of current python
python-exe := $(shell python -c 'import sys; print sys.executable')
python-home := $(subst \python.exe,,$(python-exe))
endif
SEP = ;
python-bin = $(python-home)$(SEP)$(python-home)/Scripts
else
SEP = :
endif
ifdef python-bin
export PATH := $(python-bin)$(SEP)$(PATH)
endif
export PYTHONPATH := .$(SEP)$(PYTHONPATH)
export TRAC_TEST_DB_URI = $($(db).uri)
# Misc.
space = $(empty) $(empty)
comma = ,
# ----------------------------------------------------------------------------