1
0
Fork 0
arangodb/Documentation/Scripts/generateExamples.py

394 lines
13 KiB
Python

################################################################################
### @brief creates examples from documentation files
###
### @file
###
### DISCLAIMER
###
### Copyright by triAGENS GmbH - All rights reserved.
###
### The Programs (which include both the software and documentation)
### contain proprietary information of triAGENS GmbH; they are
### provided under a license agreement containing restrictions on use and
### disclosure and are also protected by copyright, patent and other
### intellectual and industrial property laws. Reverse engineering,
### disassembly or decompilation of the Programs, except to the extent
### required to obtain interoperability with other independently created
### software or as specified by law, is prohibited.
###
### The Programs are not intended for use in any nuclear, aviation, mass
### transit, medical, or other inherently dangerous applications. It shall
### be the licensee's responsibility to take all appropriate fail-safe,
### backup, redundancy, and other measures to ensure the safe use of such
### applications if the Programs are used for such purposes, and triAGENS
### GmbH disclaims liability for any damages caused by such use of
### the Programs.
###
### This software is the confidential and proprietary information of
### triAGENS GmbH. You shall not disclose such confidential and
### proprietary information and shall use it only in accordance with the
### terms of the license agreement you entered into with triAGENS GmbH.
###
### Copyright holder is triAGENS GmbH, Cologne, Germany
###
### @author Dr. Frank Celler
### @author Copyright 2011-2014, triagens GmbH, Cologne, Germany
################################################################################
import re, sys, string, os
argv = sys.argv
argv.pop(0)
################################################################################
### @brief enable debug output
################################################################################
DEBUG = False
################################################################################
### @brief enable debug output in JavaScript
################################################################################
JS_DEBUG = False
################################################################################
### @brief output directory
################################################################################
OutputDir = "/tmp/"
################################################################################
### @brief arangosh output
###
### A list of commands that are executed in order to produce the output. The
### commands and there output is logged.
################################################################################
ArangoshOutput = {}
################################################################################
### @brief arangosh run
###
### A list of commands that are executed in order to produce the output. This
### is mostly used for HTTP request examples.
################################################################################
ArangoshRun = {}
################################################################################
### @brief arangosh output files
################################################################################
ArangoshFiles = {}
################################################################################
### @brief arangosh examples, in some deterministic order
################################################################################
ArangoshCases = [ ]
################################################################################
### @brief global setup for arangosh
################################################################################
ArangoshSetup = ""
################################################################################
### @brief states
################################################################################
STATE_BEGIN = 0
STATE_ARANGOSH_OUTPUT = 1
STATE_ARANGOSH_RUN = 2
state = STATE_BEGIN
################################################################################
### @brief option states
################################################################################
OPTION_NORMAL = 0
OPTION_ARANGOSH_SETUP = 1
OPTION_OUTPUT_DIR = 2
fstate = OPTION_NORMAL
################################################################################
### @brief append input
################################################################################
def appendInput (partialCmd, cmd, addNL):
nl = ""
if addNL:
nl = "\\n"
if partialCmd == "":
return "arangosh> " + cmd + nl
else:
return partialCmd + "........> " + cmd + nl
################################################################################
### @brief get file names
################################################################################
filenames = []
for filename in argv:
if filename == "--arangosh-setup":
fstate = OPTION_ARANGOSH_SETUP
continue
if filename == "--output-dir":
fstate = OPTION_OUTPUT_DIR
continue
if fstate == OPTION_NORMAL:
if os.path.isdir(filename):
for root, dirs, files in os.walk(filename):
for file in files:
if (file.endswith(".mdpp") or file.endswith(".js") or file.endswith(".cpp")) and not file.endswith("ahuacatl.js"):
filenames.append(os.path.join(root, file))
else:
filenames.append(filename)
elif fstate == OPTION_ARANGOSH_SETUP:
fstate = OPTION_NORMAL
f = open(filename, "r")
for line in f:
line = line.rstrip('\n')
ArangoshSetup += line + "\n"
f.close()
elif fstate == OPTION_OUTPUT_DIR:
fstate = OPTION_NORMAL
OutputDir = filename
################################################################################
### @brief loop over input files
################################################################################
r1 = re.compile(r'^(/// )?@EXAMPLE_ARANGOSH_OUTPUT{([^}]*)}')
r2 = re.compile(r'^(/// )?@EXAMPLE_ARANGOSH_RUN{([^}]*)}')
r3 = re.compile(r'^@END_EXAMPLE_')
r4 = re.compile(r'^ +')
strip = None
name = ""
partialCmd = ""
partialLine = ""
for filename in filenames:
f = open(filename, "r")
state = STATE_BEGIN
for line in f:
if strip is None:
strip = ""
line = line.rstrip('\n')
# read the start line and remember the prefix which must be skipped
if state == STATE_BEGIN:
m = r1.match(line)
if m:
strip = m.group(1)
name = m.group(2)
if name in ArangoshFiles:
print >> sys.stderr, "%s\nduplicate file name '%s'\n%s\n" % ('#' * 80, name, '#' * 80)
ArangoshFiles[name] = True
ArangoshOutput[name] = []
state = STATE_ARANGOSH_OUTPUT
continue
m = r2.match(line)
if m:
strip = m.group(1)
name = m.group(2)
if name in ArangoshFiles:
print >> sys.stderr, "%s\nduplicate file name '%s'\n%s\n" % ('#' * 80, name, '#' * 80)
ArangoshCases.append(name)
ArangoshFiles[name] = True
ArangoshRun[name] = ""
state = STATE_ARANGOSH_RUN
continue
continue
# we are within a example
line = line[len(strip):]
showCmd = True
# end-example test
m = r3.match(line)
if m:
name = ""
partialLine = ""
partialCmd = ""
state = STATE_BEGIN
continue
# fix special characters
cmd = line.replace("\\", "\\\\").replace("'", "\\'")
# handle any continued line magic
if line != "":
if line[0] == "|":
if line.startswith("| "):
line = line[2:]
cmd = cmd[2:]
else:
line = line[1:]
cmd = cmd[1:]
partialLine = partialLine + line + "\n"
partialCmd = appendInput(partialCmd, cmd, True)
continue
if line[0] == "~":
if line.startswith("~ "):
line = line[2:]
else:
line = line[1:]
showCmd = False
elif line.startswith(" "):
line = line[2:]
cmd = cmd[2:]
line = partialLine + line
partialLine = ""
if showCmd:
cmd = appendInput(partialCmd, cmd, False)
partialCmd = ""
else:
cmd = None
if state == STATE_ARANGOSH_OUTPUT:
ArangoshOutput[name].append([line, cmd])
elif state == STATE_ARANGOSH_RUN:
ArangoshRun[name] += line + "\n"
f.close()
################################################################################
### @brief generate arangosh example
################################################################################
gr1 = re.compile(r'^[ \n]*(while|if|var|throw|for) ')
def generateArangoshOutput():
print "var internal = require('internal');"
print "var fs = require('fs');"
print "var ArangoshOutput = {};"
print "internal.startPrettyPrint(true);"
print "internal.stopColorPrint(true);"
if JS_DEBUG:
print "internal.output('%s\\n');" % ('=' * 80)
print "internal.output('ARANGOSH EXAMPLE\\n');"
print "internal.output('%s\\n');" % ('=' * 80)
print
print "(function () {\n%s}());" % ArangoshSetup
print
for key in ArangoshOutput:
value = ArangoshOutput[key]
print "(function() {"
print "internal.startCaptureMode();";
for l in value:
print "try {"
print " var XXX;"
m = gr1.match(l[0])
if l[1]:
print "print('%s');" % l[1]
if m:
print "%s" % l[0]
else:
print "XXX = %s" % l[0]
if l[1]:
print "if (XXX !== undefined) {print(XXX);}"
print "} catch (err) { print(err); }"
print "var output = internal.stopCaptureMode();"
print "ArangoshOutput['%s'] = output;" % key
if JS_DEBUG:
print "internal.output('%s', ':\\n', output, '\\n%s\\n');" % (key, '-' * 80)
print "}());"
for key in ArangoshOutput:
print "fs.write('%s/%s.generated', ArangoshOutput['%s']);" % (OutputDir, key, key)
################################################################################
### @brief generate arangosh run
################################################################################
def generateArangoshRun():
print "var internal = require('internal');"
print "var fs = require('fs');"
print "var ArangoshRun = {};"
print "internal.startPrettyPrint(true);"
print "internal.stopColorPrint(true);"
if JS_DEBUG:
print "internal.output('%s\\n');" % ('=' * 80)
print "internal.output('ARANGOSH RUN\\n');"
print "internal.output('%s\\n');" % ('=' * 80)
print
print "(function () {\n%s}());" % ArangoshSetup
print
for key in ArangoshCases:
value = ArangoshRun[key]
print "(function() {"
print "internal.output('RUN STARTING: %s\\n');" % key
print "var output = '';"
print "var appender = function(text) { output += text; };"
print "var log = function (a) { internal.startCaptureMode(); print(a); appender(internal.stopCaptureMode()); };"
print "var logCurlRequestRaw = internal.appendCurlRequest(appender);"
print "var logCurlRequest = function () { var r = logCurlRequestRaw.apply(logCurlRequestRaw, arguments); db._collections(); return r; };"
print "var curlRequestRaw = internal.appendCurlRequest(function (text) {});"
print "var curlRequest = function () { return curlRequestRaw.apply(curlRequestRaw, arguments); };"
print "var logJsonResponse = internal.appendJsonResponse(appender);"
print "var logRawResponse = internal.appendRawResponse(appender);"
print "var assert = function(a) { if (! a) { internal.output('%s\\nASSERTION FAILED: %s\\n%s\\n'); throw new Error('assertion failed'); } };" % ('#' * 80, key, '#' * 80)
print "try { %s internal.output('RUN SUCCEEDED: %s\\n'); } catch (err) { print('%s\\nRUN FAILED: %s, ', err, '\\n%s\\n'); }" % (value, key, '#' * 80, key, '#' * 80)
print "ArangoshRun['%s'] = output;" % key
if JS_DEBUG:
print "internal.output('%s', ':\\n', output, '\\n%s\\n');" % (key, '-' * 80)
print "fs.write('%s/%s.generated', ArangoshRun['%s']);" % (OutputDir, key, key)
print "}());"
################################################################################
### @brief main
################################################################################
generateArangoshOutput()
generateArangoshRun()