3 # Hans-Martin von Gaudecker, 2012
6 Run a R script in the directory specified by **ctx.bldnode**.
8 For error-catching purposes, keep an own log-file that is destroyed if the
9 task finished without error. If not, it will show up as rscript_[index].log
10 in the bldnode directory.
14 ctx(features='run_r_script',
15 source='some_script.r',
16 target=['some_table.tex', 'some_figure.eps'],
22 from waflib
import Task
, TaskGen
, Logs
24 R_COMMANDS
= ['RTerm', 'R', 'r']
27 ctx
.find_program(R_COMMANDS
, var
='RCMD', errmsg
= """\n
28 No R executable found!\n\n
30 1) Check the settings of your system path.
31 2) Note we are looking for R executables called: %s
32 If yours has a different name, please report to hmgaudecker [at] gmail\n
34 Do not load the 'run_r_script' tool in the main wscript.\n\n""" % R_COMMANDS
)
35 ctx
.env
.RFLAGS
= 'CMD BATCH --slave'
37 class run_r_script_base(Task
.Task
):
39 run_str
= '"${RCMD}" ${RFLAGS} "${SRC[0].abspath()}" "${LOGFILEPATH}"'
42 class run_r_script(run_r_script_base
):
43 """Erase the R overall log file if everything went okay, else raise an
44 error and print its 10 last lines.
47 ret
= run_r_script_base
.run(self
)
48 logfile
= self
.env
.LOGFILEPATH
51 if sys
.version_info
.major
>= 3:
53 with
open(logfile
, mode
=mode
) as f
:
54 tail
= f
.readlines()[-10:]
55 Logs
.error("""Running R on %r returned the error %r\n\nCheck the log file %s, last 10 lines\n\n%s\n\n\n""",
56 self
.inputs
[0], ret
, logfile
, '\n'.join(tail
))
62 @TaskGen.feature('run_r_script')
63 @TaskGen.before_method('process_source')
64 def apply_run_r_script(tg
):
65 """Task generator customising the options etc. to call R in batch
66 mode for running a R script.
69 # Convert sources and targets to nodes
70 src_node
= tg
.path
.find_resource(tg
.source
)
71 tgt_nodes
= [tg
.path
.find_or_declare(t
) for t
in tg
.to_list(tg
.target
)]
73 tsk
= tg
.create_task('run_r_script', src
=src_node
, tgt
=tgt_nodes
)
74 tsk
.env
.LOGFILEPATH
= os
.path
.join(tg
.bld
.bldnode
.abspath(), '%s_%d.log' % (os
.path
.splitext(src_node
.name
)[0], tg
.idx
))
76 # dependencies (if the attribute 'deps' changes, trigger a recompilation)
77 for x
in tg
.to_list(getattr(tg
, 'deps', [])):
78 node
= tg
.path
.find_resource(x
)
80 tg
.bld
.fatal('Could not find dependency %r for running %r' % (x
, src_node
.abspath()))
81 tsk
.dep_nodes
.append(node
)
82 Logs
.debug('deps: found dependencies %r for running %r', tsk
.dep_nodes
, src_node
.abspath())
84 # Bypass the execution of process_source by setting the source to an empty list