aboutsummaryrefslogtreecommitdiffstats
path: root/waflib/extras/erlang.py
diff options
context:
space:
mode:
Diffstat (limited to 'waflib/extras/erlang.py')
-rw-r--r--waflib/extras/erlang.py110
1 files changed, 110 insertions, 0 deletions
diff --git a/waflib/extras/erlang.py b/waflib/extras/erlang.py
new file mode 100644
index 00000000..0b93d9a4
--- /dev/null
+++ b/waflib/extras/erlang.py
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+# encoding: utf-8
+# Thomas Nagy, 2010 (ita)
+# Przemyslaw Rzepecki, 2016
+
+"""
+Erlang support
+"""
+
+import re
+from waflib import Task, TaskGen
+from waflib.TaskGen import feature, after_method, before_method
+# to load the method "to_incnodes" below
+from waflib.Tools import ccroot
+
+# Those flags are required by the Erlang VM to execute/evaluate code in
+# non-interactive mode. It is used in this tool to create Erlang modules
+# documentation and run unit tests. The user can pass additional arguments to the
+# 'erl' command with ERL_FLAGS environment variable.
+EXEC_NON_INTERACTIVE = ['-noshell', '-noinput', '-eval']
+
+def configure(conf):
+ conf.find_program('erlc', var='ERLC')
+ conf.find_program('erl', var='ERL')
+ conf.add_os_flags('ERLC_FLAGS')
+ conf.add_os_flags('ERL_FLAGS')
+ conf.env.ERLC_DEF_PATTERN = '-D%s'
+ conf.env.ERLC_INC_PATTERN = '-I%s'
+
+@TaskGen.extension('.erl')
+def process_erl_node(self, node):
+ tsk = self.create_task('erl', node, node.change_ext('.beam'))
+ tsk.erlc_incnodes = [tsk.outputs[0].parent] + self.to_incnodes(self.includes)
+ tsk.env.append_value('ERLC_INCPATHS', [x.abspath() for x in tsk.erlc_incnodes])
+ tsk.env.append_value('ERLC_DEFINES', self.to_list(getattr(self, 'defines', [])))
+ tsk.env.append_value('ERLC_FLAGS', self.to_list(getattr(self, 'flags', [])))
+ tsk.cwd = tsk.outputs[0].parent
+
+class erl(Task.Task):
+ color = 'GREEN'
+ run_str = '${ERLC} ${ERL_FLAGS} ${ERLC_INC_PATTERN:ERLC_INCPATHS} ${ERLC_DEF_PATTERN:ERLC_DEFINES} ${SRC}'
+
+ def scan(task):
+ node = task.inputs[0]
+
+ deps = []
+ scanned = set([])
+ nodes_to_scan = [node]
+
+ for n in nodes_to_scan:
+ if n.abspath() in scanned:
+ continue
+
+ for i in re.findall(r'-include\("(.*)"\)\.', n.read()):
+ for d in task.erlc_incnodes:
+ r = d.find_node(i)
+ if r:
+ deps.append(r)
+ nodes_to_scan.append(r)
+ break
+ scanned.add(n.abspath())
+
+ return (deps, [])
+
+@TaskGen.extension('.beam')
+def process(self, node):
+ pass
+
+
+class erl_test(Task.Task):
+ color = 'BLUE'
+ run_str = '${ERL} ${ERL_FLAGS} ${ERL_TEST_FLAGS}'
+
+@feature('eunit')
+@after_method('process_source')
+def add_erl_test_run(self):
+ test_modules = [t.outputs[0] for t in self.tasks]
+ test_task = self.create_task('erl_test')
+ test_task.set_inputs(self.source + test_modules)
+ test_task.cwd = test_modules[0].parent
+
+ test_task.env.append_value('ERL_FLAGS', self.to_list(getattr(self, 'flags', [])))
+
+ test_list = ", ".join([m.change_ext("").path_from(test_task.cwd)+":test()" for m in test_modules])
+ test_flag = 'halt(case lists:all(fun(Elem) -> Elem == ok end, [%s]) of true -> 0; false -> 1 end).' % test_list
+ test_task.env.append_value('ERL_TEST_FLAGS', EXEC_NON_INTERACTIVE)
+ test_task.env.append_value('ERL_TEST_FLAGS', test_flag)
+
+
+class edoc(Task.Task):
+ color = 'BLUE'
+ run_str = "${ERL} ${ERL_FLAGS} ${ERL_DOC_FLAGS}"
+ def keyword(self):
+ return 'Generating edoc'
+
+@feature('edoc')
+@before_method('process_source')
+def add_edoc_task(self):
+ # do not process source, it would create double erl->beam task
+ self.meths.remove('process_source')
+ e = self.path.find_resource(self.source)
+ t = e.change_ext('.html')
+ png = t.parent.make_node('erlang.png')
+ css = t.parent.make_node('stylesheet.css')
+ tsk = self.create_task('edoc', e, [t, png, css])
+ tsk.cwd = tsk.outputs[0].parent
+ tsk.env.append_value('ERL_DOC_FLAGS', EXEC_NON_INTERACTIVE)
+ tsk.env.append_value('ERL_DOC_FLAGS', 'edoc:files(["%s"]), halt(0).' % tsk.inputs[0].abspath())
+ # TODO the above can break if a file path contains '"'
+