# this can do multipage
#go5:
#	dot -Tps server.dot > server.ps
#	evince server.ps

#backshift_filesystem.py
#fses.py
#hardlinks.py
#test_backshift_filesystem.py
modules=varblock_mod.py

pylint_files= \
	backshift \
	backshift_file_mod.py  \
	base255.py \
	bloom_filter_mod.py  \
	bufsock.py  \
	cacher_mod.py \
	chunk_mod_traditional.py \
	compressed_file_mod.py \
	compressed_string_mod.py \
	constants_mod.py \
	dohdbm.py \
	dirops_mod.py \
	escape_mod.py \
	expire_mod.py \
	hardlinks_mod.py \
	main.py \
	metadata_mod.py \
	modunits.py \
	py_treap_node.py \
	py_treap.py \
	readline0.py \
	repo_mod.py \
	rolling_checksum_py_mod.py \
	saveset_files_mod.py \
	saveset_summary_mod.py \
	try_psyco.py \
	xz_mod.py

# These are all files with things that pylint hates, even with the weird workarounds I've tried - keep'em small!
# Why?  Mostly because of the module renames from Python 2.x to 3.x.
no_pylint_files= \
	adbm.py \
	chunk_mod.py \
	db_mod.py \
	python2x3.py \
	rolling_checksum_mod.py \
	stringio.py \
	treap.py

all_py_files=$(pylint_files) $(no_pylint_files)

first-rule: prep static-analysis unit-tests system-tests
	echo first-rule done

prep: treap.py rolling_checksum_py_mod.py tags
	true

treap.py py_treap.py py_treap_node.py: treap/m4_treap.m4
	cd treap; make py_treap.py py_treap_node.py; cp treap.py py_treap.py py_treap_node.py ..

unit-tests: \
	test-compressed_string_mod.2.uto \
	test-compressed_string_mod.3.uto \
	test-cacher_mod.uto \
	test-compressed_file_mod.2.uto \
	test-compressed_file_mod.3.uto \
	test-dohdbm.uto \
	test-escape_mod.2.uto \
	test-escape_mod.3.uto \
	test-rolling_checksum_py_mod.uto
	true

pick:
	./this-pylint pick-rolling_checksum
	./pick-rolling_checksum

tags: $(all_py_files)
	ctags-exuberant $(all_py_files) || true

static-analysis: $(pylint_files)
	./this-pylint $(pylint_files)
	./this-pep8 $(pylint_files)

system-tests: $(all_py_files)
	cd tests; make

rcm-input-data:
	./gen-rcm-input-data > rcm-input-data

test-compressed_file_mod.2.uto: test-compressed_file_mod compressed_file_mod.py
	./this-pylint test-compressed_file_mod compressed_file_mod.py
	bash -c 'set -o pipefail > /dev/null 2>&1 || true; ./this-interpreter --variety minimal-a --args test-compressed_file_mod 2>&1 | tee test-compressed_file_mod.2.uto'

test-compressed_file_mod.3.uto: test-compressed_file_mod compressed_file_mod.py
	./this-pylint test-compressed_file_mod compressed_file_mod.py
	bash -c 'set -o pipefail > /dev/null 2>&1 || true; ./this-interpreter --variety minimal-b --args test-compressed_file_mod 2>&1 | tee test-compressed_file_mod.3.uto'

test-compressed_string_mod.2.uto: test-compressed_string_mod compressed_string_mod.py
	./this-pylint test-compressed_string_mod compressed_string_mod.py
	bash -c 'set -o pipefail > /dev/null 2>&1 || true; ./this-interpreter --variety minimal-a --args test-compressed_string_mod 2>&1 | tee test-compressed_string_mod.2.uto'

test-compressed_string_mod.3.uto: test-compressed_string_mod compressed_string_mod.py
	./this-pylint test-compressed_string_mod compressed_string_mod.py
	bash -c 'set -o pipefail > /dev/null 2>&1 || true; ./this-interpreter --variety minimal-b --args test-compressed_string_mod 2>&1 | tee test-compressed_string_mod.3.uto'

test-rolling_checksum_py_mod.uto: rcm-input-data test-rolling_checksum_mod rolling_checksum_py_mod.py
	./this-pylint test-rolling_checksum_mod rolling_checksum_py_mod.py
	bash -c 'set -o pipefail > /dev/null 2>&1 || true; ./this-interpreter --variety fast --args test-rolling_checksum_mod py 2>&1 3>&2 | tee test-rolling_checksum_py_mod.uto'

test-rolling_checksum_pyx_mod.2.uto: rcm-input-data test-rolling_checksum_mod rolling_checksum_py_mod.py
	./this-pylint test-rolling_checksum_mod rolling_checksum_py_mod.py
	bash -c 'set -o pipefail > /dev/null 2>&1 || true; ./this-interpreter --variety minimal-a --args test-rolling_checksum_mod pyx 2>&1 3>&2 | tee test-rolling_checksum_pyx_mod.2.uto'

test-rolling_checksum_pyx_mod.3.uto: rcm-input-data test-rolling_checksum_mod rolling_checksum_py_mod.py
	./this-pylint test-rolling_checksum_mod rolling_checksum_py_mod.py
	bash -c 'set -o pipefail > /dev/null 2>&1 || true; ./this-interpreter --variety minimal-b --args test-rolling_checksum_mod pyx 2>&1 3>&2 | tee test-rolling_checksum_pyx_mod.3.uto'

test-cacher_mod.uto: test-cacher_mod cacher_mod.py
	./this-pylint test-cacher_mod cacher_mod.py
	./run-ut cacher_mod
	rm -f *.doh

test-dohdbm.uto: test-dohdbm dohdbm.py
	./this-pylint test-dohdbm dohdbm.py
	./run-ut dohdbm
	rm -f *.doh

test-escape_mod.2.uto: test-escape_mod escape_mod.py
	./this-pylint test-escape_mod escape_mod.py
	if ! ./this-interpreter --variety minimal-a --args test-escape_mod > test-escape_mod.2.uto 2>&1; then cat test-escape_mod.2.uto; exit 1; fi

test-escape_mod.3.uto: test-escape_mod escape_mod.py
	./this-pylint test-escape_mod escape_mod.py
	if ! ./this-interpreter --variety minimal-b --args test-escape_mod > test-escape_mod.3.uto 2>&1; then cat test-escape_mod.3.uto; exit 1; fi

rcms: test-rolling_checksum_py_mod.uto rolling_checksum_pyx_mod.pyx
	set -xeu; \
	for cpython in $$(set -eu; \
		./this-interpreter --variety all-cpythons | cut -f 2 -d '%'); \
	do \
		if ./build-one-rcm --python "$${cpython}" --install-to-site-packages; \
		then \
			"$${cpython}" ./test-rolling_checksum_mod pyx; \
		fi; \
	done
	rm -f rolling_checksum_pyx_mod.so rolling_checksum_pyx_mod.o
	touch rcms

rolling_checksum_py_mod.py: rolling_checksum_mod.m4
	m4 -Dpy=1 rolling_checksum_mod.m4 > rolling_checksum_py_mod.py

rolling_checksum_pyx_mod.pyx: rolling_checksum_mod.m4
	m4 -Dpyx=1 rolling_checksum_mod.m4 > rolling_checksum_pyx_mod.pyx

publish: documentation
	[ `hostname` = server ] || exit 1
	rsync -apl --delete doc/. ~/public_html/backshift/documentation/.
	#(cd doc && tar cflS - .) | (cd ~/public_html/backshift/documentation && tar xfp -)

documentation: $(all_py_files) rolling_checksum_pyx_mod.pyx doc/profile-rcm.pdf
	# snakefood for an import graph
	sfood ${all_py_files} | sfood-graph > doc/imports.dot
	dot -Tpdf doc/imports.dot > doc/imports.pdf
	# pyreverse for package and class diagrams
	PYTHONPATH=$$(pwd) pyreverse -f ALL -a1 -s1 -p backshift ${all_py_files}
	mv packages_backshift.dot doc/.
	mv classes_backshift.dot doc/.
	dot -Tpdf doc/packages_backshift.dot > doc/packages_backshift.pdf
	dot -Tpdf doc/classes_backshift.dot > doc/classes_backshift.pdf
	epydoc --graph all --docformat=plaintext ${all_py_files}
	rm -rf doc/html
	mv html doc/.
	./this-interpreter --variety just-a-cython --args -a rolling_checksum_pyx_mod.pyx
	mv rolling_checksum_pyx_mod.html doc/.
	cd doc/comparison && make
	./doc/give-cc $(all_py_files) > doc/cyclo.html

doc/profile-rcm.pdf: rcm-input-data rolling_checksum_py_mod.py profile-rcm
	./this-pylint profile-rcm rolling_checksum_py_mod.py
	./this-interpreter --variety minimal-a --args profile-rcm
	gprof2dot -f pstats profile-rcm.pstats | dot -Tpdf -o doc/profile-rcm.pdf || true
	
tarball: clean prep
	d=$$(date +%Y-%m-%d-%H-%M); find . -name .svn -prune -o -print0 | tar --null --files-from - --create --file - | ./mtee "bzip2 > /tmp/backshift-$$d.tar.bz2" "xz > /tmp/backshift-$$d.tar.xz"

install: prep
	./perform-install ${all_py_files}

clean:
	rm -f *.pdf input-file output-file *.o *.so *.pyc *-pylint.html tags *.class *.uto treap.py py_treap.py py_treap_node.py
	rm -f *\$$py.class # for Jython
	cd tests; make clean
	cd treap; make veryclean
	rm -rf __pycache__
	rm -f rcms
	rm -f rcm-input-data
	# these are automatically generated from a _mod.m4 file
	rm -f *_py_mod.py
	rm -f rolling_checksum_pyx_mod.pyx
	rm -f rolling_checksum_pyx_mod.c
	rm -f *.dot *.ps *.pdf doc/*.dot doc/*.ps doc/*.pdf
	rm -f doc/comparison/index.html
	rm -rf html doc/html
	rm -f backshiftc
	rm -f doc/rolling_checksum_pyx_mod.html
	rm -f test-file.rm-me
	rm -f *.doh
	rm -f @testfile
	chmod +rwx readonly-directory 2> /dev/null || true; rm -rf readonly-directory
	rm -f *.pstats
	rm -rf install-variables
	rm -f doc/cyclo.html