Reorganize makefile and scripts.

This commit is contained in:
Bob Nystrom
2014-01-23 23:29:50 -08:00
parent a4162a2eb3
commit 96d728cc5d
12 changed files with 237 additions and 44 deletions
+31
View File
@@ -0,0 +1,31 @@
#!/usr/bin/python
import re
with open("corelib.wren", "r") as f:
lines = f.readlines()
# Remove the comment from the top.
lines.pop(0)
lines.pop(0)
corelib = ""
for line in lines:
line = line.replace('"', "\\\"")
line = line.replace("\n", "\\n\"")
if corelib: corelib += "\n"
corelib += '"' + line
with open("src/wren_core.c", "r") as f:
wren_core = f.read()
# re.sub() will unescape escape sequences, but we want them to stay as escapes
# in the C string literal.
corelib = corelib.replace('\\', '\\\\')
corelib = "coreLibSource =\n" + corelib + ";"
PATTERN = re.compile(r'coreLibSource =\n("(.|[\n])*?);')
wren_core = PATTERN.sub(corelib, wren_core)
with open("src/wren_core.c", "w") as f:
f.write(wren_core)
+87
View File
@@ -0,0 +1,87 @@
#!/usr/bin/python
import glob
import markdown
import os
import shutil
import sys
import time
from datetime import datetime
def format_file(path, skip_up_to_date):
basename = os.path.basename(path)
basename = basename.split('.')[0]
out_path = "build/site/" + basename + ".html"
# See if it's up to date.
source_mod = os.path.getmtime(path)
source_mod = max(source_mod, os.path.getmtime('doc/site/template.html'))
dest_mod = 0
if os.path.exists(out_path):
dest_mod = os.path.getmtime(out_path)
if skip_up_to_date and source_mod < dest_mod:
return
title = ""
# Read the markdown file and preprocess it.
contents = ""
with open(path, "r") as input:
# Read each line, preprocessing the special codes.
for line in input:
stripped = line.lstrip()
indentation = line[:len(line) - len(stripped)]
if stripped.startswith("^"):
command,_,args = stripped.rstrip("\n").lstrip("^").partition(" ")
args = args.strip()
if command == "title":
title = args
else:
print "UNKNOWN COMMAND:", command, args
else:
contents = contents + line
html = markdown.markdown(contents, ['def_list', 'codehilite'])
modified = datetime.fromtimestamp(os.path.getmtime(path))
mod_str = modified.strftime('%B %d, %Y')
fields = {'title': title, 'html': html, 'mod': mod_str}
with open("doc/site/template.html") as f:
template = f.read()
# Write the html output.
with open(out_path, 'w') as out:
out.write(template.format(**fields))
print "converted", basename
def format_files(skip_up_to_date):
for f in glob.iglob("doc/site/*.markdown"):
format_file(f, skip_up_to_date)
# Clean the output directory.
if os.path.exists("build/site"):
shutil.rmtree("build/site")
os.mkdir("build/site")
# Process each markdown file.
format_files(False)
# Copy the CSS file.
shutil.copyfile("doc/site/style.css", "build/site/style.css")
# TODO(bob): Check for CSS modification.
if len(sys.argv) == 2 and sys.argv[1] == '--watch':
while True:
format_files(True)
time.sleep(0.3)
Executable
+232
View File
@@ -0,0 +1,232 @@
#!/usr/bin/python
from collections import defaultdict
from os import listdir
from os.path import abspath, dirname, isdir, isfile, join, realpath, relpath, splitext
import re
from subprocess import Popen, PIPE
import sys
# Runs the tests.
WREN_DIR = dirname(dirname(realpath(__file__)))
TEST_DIR = join(WREN_DIR, 'test')
WREN_APP = join(WREN_DIR, 'wrend')
EXPECT_PATTERN = re.compile(r'// expect: (.*)')
EXPECT_ERROR_PATTERN = re.compile(r'// expect error')
EXPECT_ERROR_LINE_PATTERN = re.compile(r'// expect error line (\d+)')
EXPECT_RUNTIME_ERROR_PATTERN = re.compile(r'// expect runtime error: (.+)')
ERROR_PATTERN = re.compile(r'\[.* line (\d+)\] Error')
STACK_TRACE_PATTERN = re.compile(r'\[.* line (\d+)\] in \(script\)')
SKIP_PATTERN = re.compile(r'// skip: (.*)')
NONTEST_PATTERN = re.compile(r'// nontest')
if sys.platform == 'win32':
class color:
GREEN = ''
RED = ''
DEFAULT = ''
PINK = ''
YELLOW = ''
else:
class color:
GREEN = '\033[32m'
RED = '\033[31m'
DEFAULT = '\033[0m'
PINK = '\033[91m'
YELLOW = '\033[33m'
passed = 0
failed = 0
skipped = defaultdict(int)
num_skipped = 0;
def walk(dir, callback):
""" Walks [dir], and executes [callback] on each file. """
dir = abspath(dir)
for file in [file for file in listdir(dir) if not file in [".",".."]]:
nfile = join(dir, file)
if isdir(nfile):
walk(nfile, callback)
else:
callback(nfile)
def print_line(line=None):
# Erase the line.
print '\033[2K',
# Move the cursor to the beginning.
print '\r',
if line:
print line,
sys.stdout.flush()
def run_test(path):
global passed
global failed
global skipped
global num_skipped
if (splitext(path)[1] != '.wren'):
return
# Check if we are just running a subset of the tests.
if len(sys.argv) == 2:
this_test = relpath(path, join(WREN_DIR, 'test'))
if not this_test.startswith(sys.argv[1]):
return
# Make a nice short path relative to the working directory.
path = relpath(path)
# Read the test and parse out the expectations.
expect_output = []
expect_error = []
expect_runtime_error_line = 0
expect_runtime_error = None
expect_return = 0
print_line('Passed: ' + color.GREEN + str(passed) + color.DEFAULT +
' Failed: ' + color.RED + str(failed) + color.DEFAULT +
' Skipped: ' + color.YELLOW + str(num_skipped) + color.DEFAULT)
line_num = 1
with open(path, 'r') as file:
for line in file:
match = EXPECT_PATTERN.search(line)
if match:
expect_output.append((match.group(1), line_num))
match = EXPECT_ERROR_PATTERN.search(line)
if match:
expect_error.append(line_num)
# If we expect compile errors, it should exit with EX_DATAERR.
expect_return = 65
match = EXPECT_ERROR_LINE_PATTERN.search(line)
if match:
expect_error.append(int(match.group(1)))
# If we expect compile errors, it should exit with EX_DATAERR.
expect_return = 65
match = EXPECT_RUNTIME_ERROR_PATTERN.search(line)
if match:
expect_runtime_error_line = line_num
expect_runtime_error = match.group(1)
# If we expect a runtime error, it should exit with EX_SOFTWARE.
expect_return = 70
match = SKIP_PATTERN.search(line)
if match:
num_skipped += 1
skipped[match.group(1)] += 1
return
match = NONTEST_PATTERN.search(line)
if match:
# Not a test file at all, so ignore it.
return
line_num += 1
# Invoke wren and run the test.
proc = Popen([WREN_APP, path], stdout=PIPE, stderr=PIPE)
(out, err) = proc.communicate()
(out, err) = out.replace('\r\n', '\n'), err.replace('\r\n', '\n')
fails = []
# Validate that no unexpected errors occurred.
if expect_return != 0 and err != '':
lines = err.split('\n')
if expect_runtime_error:
# Make sure we got the right error.
if lines[0] != expect_runtime_error:
fails.append('Expected runtime error "' + expect_runtime_error +
'" and got:')
fails.append(lines[0])
# Make sure the stack trace has the right line.
match = STACK_TRACE_PATTERN.search(lines[1])
if not match:
fails.append('Expected stack trace and got:')
fails.append(lines[1])
else:
stack_line = int(match.group(1))
if stack_line != expect_runtime_error_line:
fails.append('Expected runtime error on line ' +
str(expect_runtime_error_line) + ' but was on line ' +
str(stack_line))
else:
lines = err.split('\n')
while len(lines) > 0:
line = lines.pop(0)
match = ERROR_PATTERN.search(line)
if match:
if float(match.group(1)) not in expect_error:
fails.append('Unexpected error:')
fails.append(line)
elif line != '':
fails.append('Unexpected output on stderr:')
fails.append(line)
else:
for line in expect_error:
fails.append('Expected error on line ' + str(line) + ' and got none.')
if expect_runtime_error:
fails.append('Expected runtime error "' + expect_runtime_error +
'" and got none.')
# Validate the exit code.
if proc.returncode != expect_return:
fails.append('Expected return code {0} and got {1}.'
.format(expect_return, proc.returncode))
else:
# Validate the output.
expect_index = 0
# Remove the trailing last empty line.
out_lines = out.split('\n')
if out_lines[-1] == '':
del out_lines[-1]
for line in out_lines:
if expect_index >= len(expect_output):
fails.append('Got output "{0}" when none was expected.'.format(line))
elif expect_output[expect_index][0] != line:
fails.append('Expected output "{0}" on line {1} and got "{2}".'.
format(expect_output[expect_index][0],
expect_output[expect_index][1], line))
expect_index += 1
while expect_index < len(expect_output):
fails.append('Missing expected output "{0}" on line {1}.'.
format(expect_output[expect_index][0],
expect_output[expect_index][1]))
expect_index += 1
# Display the results.
if len(fails) == 0:
passed += 1
#print color.GREEN + 'PASS' + color.DEFAULT + ': ' + path
else:
failed += 1
print_line(color.RED + 'FAIL' + color.DEFAULT + ': ' + path)
print
for fail in fails:
print ' ', color.PINK + fail + color.DEFAULT
print
walk(TEST_DIR, run_test)
print_line()
if failed == 0:
print 'All ' + color.GREEN + str(passed) + color.DEFAULT + ' tests passed.'
else:
print (color.GREEN + str(passed) + color.DEFAULT + ' tests passed. ' +
color.RED + str(failed) + color.DEFAULT + ' tests failed.')
for key in sorted(skipped.keys()):
print ('Skipped ' + color.YELLOW + str(skipped[key]) + color.DEFAULT +
' tests: ' + key)