-
Notifications
You must be signed in to change notification settings - Fork 1
/
pipeR.mk
229 lines (182 loc) · 5.89 KB
/
pipeR.mk
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
pdfcheck = perl -wf makestuff/wrapR/pdfcheck.pl
rvan = R --vanilla
noMakeFlags = env -u MAKELEVEL -u MAKEFLAGS
stanVan = $(noMakeFlags) $(rvan)
rrun ?= $(rvan)
define makeArgs
@echo "rpcall(\"$@ $*.pipestar $^\")" >> $@.args
@echo >> $@.args
endef
## Potential infelicity if a script used to produce a file
## but now runs successfully without producing it
## file can still be used downstream
## awkwardly delete known target types; or make all known targets start with full target name?
define pipeR
@-$(RM) $@ $@.*
@$(makeArgs)
@echo pipeR: Making $@ using $^
@(($(rrun) --args $@ shellpipes $*.pipestar $^ < $(word 1, $(filter %.R, $^)) > $@) 2> $(@:%.Rout=%.Rlog) && cat $(@:%.Rout=%.Rlog)) || (sleep 1 && touch $(word 1, $(filter %.R, $^)) && cat $(@:%.Rout=%.Rlog) && false)
endef
## Make the rpcall first so that we don't outdate things
define pipeRcall
perl -wf makestuff/pipeRcall.pl $@ $^
$(pipeR)
endef
## Back-compatility
makeR=$(pipeR)
## This stuff should be refactored, and also reconciled with a _bunch_ of other stuff:
## rmd, rmdweb, pandoc ...
define render
-$(RM) $@ $@.*
$(makeArgs)
$(rrun) -e 'library("rmarkdown"); render("$<", output_file="$@")' shellpipes $*.pipestar $^
endef
define render_rmd
-$(RM) $@ $@.*
$(makeArgs)
Rscript --vanilla -e 'library("rmarkdown"); render("$(word 1, $(filter %.rmd %.Rmd, $^))", output_file="$@")' shellpipes $*.pipestar $^
endef
define knitpdf
-$(RM) $@ $@.*
$(makeArgs)
Rscript --vanilla -e 'library("rmarkdown"); render("$(word 1, $(filter %.rmd %.Rmd, $^))", output_format="pdf_document", output_file="$@")' shellpipes $*.pipestar $^
endef
define knitmd
-$(RM) $@ $@.*
$(makeArgs)
Rscript --vanilla -e 'library("rmarkdown"); render("$(word 1, $(filter %.rmd %.Rmd, $^))", md_document(preserve_yaml=TRUE, variant="markdown"), output_file="$@")' shellpipes $*.pipestar $^
endef
define knithtml
-$(RM) $@ $@.*
$(makeArgs)
Rscript --vanilla -e 'library("rmarkdown"); render("$(word 1, $(filter %.rmd %.Rmd, $^))", output_format="html_document", output_file="$@")' shellpipes $*.pipestar $^
endef
define wrapR
-$(RM) $@ $@.*
(($(rrun) --args $@ $^ shellpipes < makestuff/wrappipeR.R > $(@:%.Rout=%.rtmp)) 2> $(@:%.Rout=%.Rlog) && cat $(@:%.Rout=%.Rlog)) || (cat $(@:%.Rout=%.Rlog) && false)
$(MVF) $(@:%.Rout=%.rtmp) $@
endef
run-R = $(wrapR)
define scriptR
cd $(dir $<) && $(rrun) < $(notdir $<) > $(notdir $@)
endef
## Legacy
ifdef autowrapR
.PRECIOUS: %.Rout
%.Rout: %.R
$(wrapR)
endif
## autopipeR seems like a reasonable default
ifdef autopipeR
.PRECIOUS: %.Rout
%.Rout: %.R
$(pipeR)
endif
## More aggressive autopiping
ifdef alwayspipeR
.PRECIOUS: %.Rout
%.Rout:
$(pipeR)
endif
ifdef autopipeRcall
.PRECIOUS: %.Rout
%.Rout: %.R
$(pipeRcall)
endif
ifdef alwayspipeRcall
.PRECIOUS: %.Rout
%.Rout:
$(pipeRcall)
endif
%.Routput: %.Rout
perl -f makestuff/wrapR/Rcalc.pl $< > $@
######################################################################
ifdef autoknit
%.html: %.Rmd
$(knithtml)
%.pdf: %.Rmd
$(knitpdf)
endif
## If no recipe, then this doesn't work
## If there is a recipe, it never resolves
## Use sparingly (or only for development)
%.manual: %
touch $@
.PRECIOUS: %.rda %.rdata %.RData
%.rda %.rdata %.RData: %.Rout
$(lstouch)
.PRECIOUS: %.rds %.Rds
%.rds %.Rds: %.Rout
$(lstouch)
.PRECIOUS: %.Rout.tsv
%.Rout.tsv: %.Rout
$(lstouch)
.PRECIOUS: %.Rout.csv
%.Rout.csv: %.Rout
$(lstouch)
## ggp.png is more necessary than it should be (pngDesc not working)
## .pdf.tmp is a pure intermediate; you should require .pdf, not .pdf.tmp
%.Rout.pdf.tmp %.Rout.png %.ggp.png %.Rout.jpeg %.ggp.pdf %.Rout.tikz: %.Rout
$(lstouch)
.PRECIOUS: %.Rout.pdf
%.Rout.pdf: %.Rout
$(lstouch) || ($(pdfcheck) $@.tmp && $(MVF) $@.tmp $@) || (ls Rplots.pdf && echo WARNING: Trying an orphaned Rplots file && mv Rplots.pdf $@) || (echo ERROR: Failed to find, make or rescue $@ && false)
Ignore += .Rhistory .RData
Ignore += *.RData *.Rlog *.rdata *.rda *.rtmp
Ignore += *.Rout*
Ignore += *.html.args *.pdf.args
Ignore += *.Rds *.rds
Ignore += Rplots.pdf
Ignore += *.ggp.*
######################################################################
## Eval rules for implicit dependencies
## These are necessary so that we can chain through .rda and other products
## but specify dependencies centrally through .Rout
define impdep_r
%.$(1).rda: %.$(1).Rout ; $(impcheck)
%.$(1).rds: %.$(1).Rout ; $(impcheck)
%.$(1).rdata: %.$(1).Rout ; $(impcheck)
%.$(1).Rdata: %.$(1).Rout ; $(impcheck)
.PRECIOUS: %.$(1).Rdata %.$(1).rdata %.$(1).rda %.$(1).rds %.$(1).Rout
endef
impmakeR += $(pipeRimplicit)
$(foreach stem,$(impmakeR),$(eval $(call impdep_r,$(stem))))
## Eval rules for "described" pdf files
define pipedesc_r
$(1).%.pdf: $(1).Rout ; $(impcheck)
Ignore += $(1).*.pdf
endef
pipeRdesc += $(pdfDesc)
$(foreach stem,$(pipeRdesc),$(eval $(call pipedesc_r,$(stem))))
## STILL haven't found a reliable description about competing make rules
## Eval rules for "described" pdf files (Rout only)
define pipedesc_rout_r
$(1).%.Rout.pdf: $(1).Rout ; $(impcheck)
Ignore += $(1).*.Rout.pdf
endef
$(foreach stem,$(pipeRoutdesc),$(eval $(call pipedesc_rout_r,$(stem))))
define pngDesc_r
$(1).%.png: $(1).Rout ; $(impcheck)
Ignore += $(1).*.png
endef
$(foreach stem,$(pngDesc),$(eval $(call pngDesc_r,$(stem))))
######################################################################
## Scripts
## Disentangle how things work, and empower people who don't use make
## Won't work in directories that need non-automatic setup
%.pipeR.script:
$(MAKE) dotdir.mslink
$(MAKE) dotdir.localdir
$(MAKE) dotdir.testsetup
cd dotdir && $(MAKE) -n $*.Rout > make.log
perl -wf makestuff/pipeRscript.pl dotdir/make.log > $@
Ignore += $(wildcard *.pipeR.script)
%.Rscript: %.pipeR.script makestuff/allR.pl
$(PUSH)
Ignore += $(wildcard *.allR)
%.allR: %.Rscript
$(rrun) < $< | tee $@
######################################################################
## Legacy cleaning
wrapclean wrapClean:
rm -fr *.wrapR* .*.wrapR*