aboutsummaryrefslogtreecommitdiff
path: root/Makefile
blob: d64412ac0fa35bdafdd48c94465de59af5d8e384 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
VERSION?=$(shell grep '^[Vv]ersion:' pandoc.cabal | awk '{print $$2;}')
PANDOC_CLI_VERSION?=$(shell grep '^[Vv]ersion:' pandoc-cli/pandoc-cli.cabal | awk '{print $$2;}')
SOURCEFILES?=$(shell git ls-tree -r main --name-only src pandoc-cli pandoc-server pandoc-lua-engine | grep "\.hs$$")
PANDOCSOURCEFILES?=$(shell git ls-tree -r main --name-only src | grep "\.hs$$")
DOCKERIMAGE=quay.io/benz0li/ghc-musl:9.10
TIMESTAMP=$(shell date "+%Y%m%d_%H%M")
LATESTBENCH=$(word 1,$(shell ls -t bench_*.csv 2>/dev/null))
BASELINE?=$(LATESTBENCH)
ROOT?=Text.Pandoc
ifeq ($(BASELINE),)
BASELINECMD=
else
BASELINECMD=--baseline $(BASELINE)
endif
CABALOPTS?=--disable-optimization -f-export-dynamic --ghc-option=-fwrite-ide-info --ghc-option=-fdiagnostics-color=always --ghc-option=-j
WEBSITE=../../web/pandoc.org
REVISION?=1
BENCHARGS?=--csv bench_$(TIMESTAMP).csv $(BASELINECMD) --timeout=6 +RTS -T --nonmoving-gc -RTS $(if $(PATTERN),--pattern "$(PATTERN)",)
pandoc=$(shell cabal list-bin $(CABALOPTS) pandoc-cli)
OPTIMIZE_WASM?=1

all: build test binpath ## build executable and run tests
.PHONY: all

build: ## build executable
	cabal build \
	  $(CABALOPTS) pandoc-cli
.PHONY: build

prof: ## build with profiling and optimizations
	cabal build --enable-profiling all
.PHONY: prof

binpath: ## print path of built pandoc executable
	@cabal list-bin -v0 $(CABALOPTS) pandoc-cli
.PHONY: binpath

ghcid: ## run ghcid
	ghcid -c 'cabal repl pandoc'
.PHONY: ghcid

repl:  ## run cabal repl
	cabal repl $(CABALOPTS) pandoc
.PHONY: repl

linecounts: ## print line counts for each module
	@wc -l $(SOURCEFILES) | sort -n
.PHONY: linecounts

# Note:  to accept current results of golden tests,
# make test TESTARGS='--accept'
test:  ## unoptimized build and run tests with cabal
	cabal test \
	  $(CABALOPTS) \
	  --test-options="--hide-successes --ansi-tricks=false $(TESTARGS)" all
.PHONY: test

quick-stack: ## unoptimized build and tests with stack
	stack install \
	  --system-ghc --flag 'pandoc:embed_data_files' \
	  --fast \
	  --test \
	  --test-arguments='-j4 --hide-successes --ansi-tricks=false $(TESTARGS)'
.PHONY: quick-stack

prerelease: validate-epub README.md fix_spacing check-cabal check-stack checkdocs man check-version-sync check-changelog check-manversion uncommitted_changes ## prerelease checks
.PHONY: prerelease

uncommitted_changes:
	! git diff | grep '.'
.PHONY: uncommitted_changes

authors:  ## prints unique authors since last released version
	git log --pretty=format:"%an" $$(git tag -l | grep '[^0-9]' | sort | tail -1)..HEAD | sort | uniq | while read -r; do grep -i -q "^- $$REPLY" AUTHORS.md || echo $$REPLY ; done

check-stack:
	$$HOME/.local/bin/stack-lint-extra-deps # check that stack.yaml dependencies are up to date
	! grep 'git:' stack.yaml # use only released versions
.PHONY: check-stack

check-cabal: git-files.txt sdist-files.txt
	@echo "Checking to see if all committed test/data files are in sdist."
	diff -u $^
	@for pkg in . pandoc-lua-engine pandoc-server pandoc-cli; \
	do \
	     pushd $$pkg ; \
	     cabal check --ignore=missing-upper-bounds ; \
	     cabal outdated ; \
	     popd ; \
	done
	! grep 'git:' cabal.project # use only released versions

.PHONY: check-cabal

check-version-sync:
	@echo "Checking for match between pandoc and pandoc-cli versions"
	[ $(VERSION) == $(PANDOC_CLI_VERSION) ]
	@echo "Checking that pandoc-cli depends on this version of pandoc"
	grep 'pandoc == $(VERSION)' pandoc-cli/pandoc-cli.cabal
.PHONY: check-version-sync

check-changelog:
	@echo "Checking for changelog entry for this version"
	rg '## pandoc $(VERSION) \(\d\d\d\d-\d\d-\d\d\)' changelog.md
.PHONY: check-changelog

check-manversion:
	@echo "Checking version number in man pages"
	grep '"pandoc $(VERSION)"' "pandoc-cli/man/pandoc.1"
	grep '"pandoc $(VERSION)"' "pandoc-cli/man/pandoc-server.1"
	grep '"pandoc $(VERSION)"' "pandoc-cli/man/pandoc-lua.1"
.PHONY: check-manversion

checkdocs:
	@echo "Checking for tabs in manual."
	! rg -n -e '\t' \
	   MANUAL.txt changelog.md doc/pandoc-server.md doc/pandoc-lua.md
.PHONY: checkdocs

bench: ## build and run benchmarks
	cabal bench --benchmark-options='$(BENCHARGS)' 2>&1 | tee "bench_$(TIMESTAMP).txt"
.PHONY: bench

reformat: ## reformat with stylish-haskell
	for f in $(SOURCEFILES); do echo $$f; stylish-haskell -i $$f ; done
.PHONY: reformat

lint: ## run hlint
	hlint --report=hlint.html $(SOURCEFILES) || open hlint.html
.PHONY: lint

fix_spacing: ## fix trailing newlines and spaces
	@ERRORS=0; echo "Checking for spacing errors..." && for f in $(SOURCEFILES); do printf '%s\n' "`cat $$f`" | sed -e 's/  *$$//' > $$f.tmp; diff -u $$f $$f.tmp || ERRORS=1; mv $$f.tmp $$f; done; [ $$ERRORS -eq 0 ] || echo "Spacing errors have been fixed; please commit the changes."; exit $$ERRORS
.PHONY: fix_spacing

changes_github: ## copy this release's changes in gfm
	@$(pandoc) --lua-filter tools/extract-changes.lua changelog.md -t gfm --wrap=none --template tools/changes_template.html | sed -e 's/\\#/#/g'
.PHONY: changes_github

man: pandoc-cli/man/pandoc.1 pandoc-cli/man/pandoc-server.1 pandoc-cli/man/pandoc-lua.1 ## build man pages
.PHONY: man

latex-package-dependencies: ## print packages used by default latex template
	$(pandoc) lua tools/latex-package-dependencies.lua
.PHONY: latex-package-dependencies

coverage: ## code coverage information
	cabal test \
	  --ghc-option=-fhpc \
	  $(CABALOPTS) \
	  --test-options="--hide-successes --ansi-tricks=false $(TESTARGS)"
	hpc markup --destdir=coverage test/test-pandoc.tix
	open coverage/hpc_index.html
.PHONY: coverage

weeder: ## run weeder to find dead code
	weeder
.PHONY: weeder

transitive-deps: ## print transitive dependencies
	cabal-plan topo | sort | sed -e 's/-[0-9]\..*//'
.PHONY: transitive-deps

debpkg: ## create linux package
	docker run -v `pwd`:/mnt \
                   -v `pwd`/linux/artifacts:/artifacts \
		   --user $(id -u):$(id -g) \
		   -e REVISION=$(REVISION) \
       -e CABALOPTS="-f-export-dynamic -fembed_data_files -fserver -flua --enable-executable-static -j4 --ghc-option=-j4 --ghc-option=-split-sections --ghc-option=-optc-Os --ghc-option=-optl=-pthread" \
		   -w /mnt \
		   --memory=0 \
		   --rm \
		   $(DOCKERIMAGE) \
		   bash \
		   /mnt/linux/make_artifacts.sh
.PHONY: debpkg

pandoc-cli/man/pandoc.1: MANUAL.txt man/pandoc.1.before man/pandoc.1.after pandoc.cabal
	$(pandoc) $< -f markdown -t man -s \
		--lua-filter man/manfilter.lua \
		--include-before-body man/pandoc.1.before \
		--include-after-body man/pandoc.1.after \
		--metadata author="" \
    --variable section="1" \
    --variable title="pandoc" \
    --variable header='Pandoc User\[cq]s Guide' \
		--variable footer="pandoc $(VERSION)" \
		-o $@

pandoc-cli/man/%.1: doc/%.md pandoc.cabal
	$(pandoc) $< -f markdown -t man -s \
		--lua-filter man/manfilter.lua \
		--metadata author="" \
    --variable section="1" \
    --variable title="$(basename $(notdir $@))" \
    --variable header='Pandoc User\[cq]s Guide' \
		--variable footer="pandoc $(VERSION)" \
    --include-after-body man/pandoc.1.after \
		-o $@


README.md: README.template MANUAL.txt tools/update-readme.lua
	$(pandoc) --lua-filter tools/update-readme.lua \
	      --reference-location=section -t gfm $< -o $@

doc/lua-filters.md: tools/update-lua-module-docs.lua  ## update lua-filters.md module docs
	cabal run pandoc-cli -- \
		--standalone \
		--reference-links \
		--columns=66 \
		--from=$< \
		--output=$@ \
		$@
.PHONY: doc/lua-filters.md

download_stats: ## print download stats from GitHub releases
	curl https://api.github.com/repos/jgm/pandoc/releases | \
		jq -r '.[] | .assets | .[] | "\(.download_count)\t\(.name)"'
.PHONY: download_stats

pandoc-templates: ## update pandoc-templates repo
	rm ../pandoc-templates/default.* ; \
	cp data/templates/* ../pandoc-templates/ ; \
	pushd ../pandoc-templates/ && \
	git add * && \
	git commit -m "Updated templates for pandoc $(VERSION)" && \
	popd
.PHONY: pandoc-templates

update-website: ## update website and upload
	make -C $(WEBSITE) update
	make -C $(WEBSITE)
	make -C $(WEBSITE) upload
.PHONY: update-website

update-translations: ## update data/translations from Babel and Polyglossia
	python3 tools/update-translations.py
.PHONY: update-translations

validate-docx-golden-tests: ## validate docx golden tests against schema
	which xmllint || ("xmllint is required" && exit 1)
	test -d ./docx-validator || \
		(git clone https://github.com/devoidfury/docx-validator && \
		cd docx-validator && patch -p1 <../wml.xsd.patch)
	sh ./tools/validate-docx.sh test/docx/golden/*.docx
.PHONY: validate-docx-golden-tests

validate-docx-golden-tests2: ## validate docx golden tests using OOXMLValidator
	which dotnet || ("dotnet is required" && exit 1)
	which jq || ("jq is required" && exit 1)
	test -d ./OOXML-Validator || \
		(git clone https://github.com/mikeebowen/OOXML-Validator.git \
		&& cd OOXML-Validator && dotnet build --configuration=Release)
	sh ./tools/validate-docx2.sh test/docx/golden/
.PHONY: validate-docx-golden-tests2

node_modules/.bin/ace:
	npm install @daisy/ace

validate-epub: node_modules/.bin/ace ## generate an epub and validate it with epubcheck and ace
	which epubcheck || exit 1
	tmp=$$(mktemp -d) && \
  for epubver in 2 3; do \
    file=$$tmp/ver$$epubver.epub ; \
	  $(pandoc) test/epub/wasteland.epub --epub-cover=test/lalune.jpg -Mtitle="The Wasteland" --resource-path test/epub -t epub$$epubver -o $$file --number-sections --toc --quiet && \
	  echo $$file && \
	  epubcheck $$file || exit 1 ; \
  done && \
	./node_modules/.bin/ace $$tmp/ver3.epub -o ace-report-v2 --force

modules.csv: $(PANDOCSOURCEFILES)
	@rg '^import.*Text\.Pandoc\.' --with-filename $^ \
		| rg -v 'Text\.Pandoc\.(Definition|Builder|Walk|Generic)' \
		| sort \
		| uniq \
		| sed -e 's/src\///' \
	        | sed -e 's/\//\./g' \
		| sed -e 's/\.hs:import *\(qualified *\)*\([^ ]*\).*/,\2/' \
		> $@

modules.dot: modules.csv
	@echo "digraph G {" > $@
	@echo "overlap=\"scale\"" >> $@
	@sed -e 's/\([^,]*\),\(.*\)/  "\1" -> "\2";/' $< >> $@
	@echo "}" >> $@

# To get the module dependencies of Text.Pandoc.Parsing:
# make modules.pdf ROOT=Text.Pandoc.Parsing
modules.pdf: modules.dot
	gvpr -f tools/cliptree.gvpr -a '"$(ROOT)"' $< | dot -Tpdf > $@

# make moduledeps ROOT=Text.Pandoc.Parsing
moduledeps: modules.csv  ## Print transitive dependencies of a module ROOT
	@echo "$(ROOT)"
	@$(pandoc) lua tools/moduledeps.lua transitive $(ROOT) | sort
.PHONY: moduledeps

clean: ## clean up
	cabal clean
.PHONY: clean

.PHONY: .FORCE

sdist-files.txt: .FORCE
	cabal sdist --list-only | sed 's/\.\///' | grep '^\(test\|data\)/' | sort > $@

git-files.txt: .FORCE
	git ls-tree -r --name-only HEAD | grep '^\(test\|data\)/' | sort > $@

help: ## display this help
	@echo "Targets:"
	@grep -E '^[ a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "%-16s %s\n", $$1, $$2}'
	@echo
	@echo "Environment variables with default values:"
	@printf "%-16s%s\n" "CABALOPTS" "$(CABALOPTS)"
	@printf "%-16s%s\n" "TESTARGS" "$(TESTARGS)"
	@printf "%-16s%s\n" "BASELINE" "$(BASELINE)"
	@printf "%-16s%s\n" "REVISION" "$(REVISION)"
.PHONY: help

release-checklist: release-checklist-$(VERSION).org
.PHONY: release-checklist

release-checklist-$(VERSION).org: RELEASE-CHECKLIST-TEMPLATE.org
	sed -e 's/RELEASE_VERSION/$(VERSION)/g' $< > $@

hie.yaml: ## regenerate hie.yaml
	gen-hie > $@
.PHONY: hie.yaml

pandoc.wasm:
	-rm $@
	wasm32-wasi-cabal build pandoc-cli
ifeq ($(OPTIMIZE_WASM),1)
	echo "Optimizing (this may take a long time, to avoid, set OPTIMIZE_WASM=0)..."
	wasm-opt --low-memory-unused --converge --gufa --flatten --rereloop -Oz $$(wasm32-wasi-cabal list-bin pandoc-cli | tail -1) -o $@
else
	echo "Copying unoptimized pandoc.wasm..."
	cp "$$(wasm32-wasi-cabal list-bin pandoc-cli | tail -1)" "$@"
endif
.PHONY: pandoc.wasm