This commit is contained in:
Bruce Eckel 2015-06-06 15:07:33 -07:00
parent c3259b13a6
commit 534743f196
3 changed files with 221 additions and 106 deletions

View File

@ -3,18 +3,17 @@
Append output and error files to Java files Append output and error files to Java files
""" """
TODO = """ TODO = """
- Add:
} /* Output: (None) *///:~ - Display all files with less than 100% match (rather than putting percentage and "Sample" in)
To files that produce no output. Rely on visual inspection of non-matching file?
Have a list of files to exclude normally, and inspect ocasionally
- Test to make sure that None files indeed have no output - Test to make sure that None files indeed have no output
- Ambitious: Allow edits of "AttachedResults.txt" which are - Ambitious: Allow edits of "AttachedResults.txt" which are
then pulled back into the source files. then pulled back into the source files.
- 1st and last 10 lines, with ... in between? {OutputFirstAndLast: 10 Lines}
} /* Same output as RoShamBo2.java *///:~ } /* Same output as RoShamBo2.java *///:~
} /* Output: (Same as RoShamBo2.java) *///:~ } /* Output: (Same as RoShamBo2.java) *///:~
@ -28,85 +27,108 @@ from betools import CmdLine, visitDir, ruler, head
maxlinewidth = 59 maxlinewidth = 59
examplePath = Path(r"C:\Users\Bruce\Dropbox\__TIJ4-ebook\ExtractedExamples") examplePath = Path(r"C:\Users\Bruce\Dropbox\__TIJ4-ebook\ExtractedExamples")
maindef = re.compile("public\s+static\s+void\s+main")
class JFile:
class JavaMain:
maindef = re.compile("public\s+static\s+void\s+main")
ellipses = ["[...]".center(maxlinewidth, '_')]
class JFile:
"""Could just manipulate this, then write it at the end"""
@staticmethod
def with_main(javaFilePath):
with javaFilePath.open() as doc:
code = doc.read()
if JavaMain.maindef.search(code):
return JavaMain.JFile(javaFilePath, code)
return None
def __init__(self, javaFilePath, code):
self.javaFilePath = javaFilePath
self.code = code
self.lines = self.code.splitlines()
self.output_line = None
for line in self.lines:
if "} /* Output:" in line:
self.output_line = line
self.newcode = ""
@staticmethod @staticmethod
def with_main(javaFilePath): def create(javaFilePath):
with javaFilePath.open() as doc: j_file = JavaMain.JFile.with_main(javaFilePath)
code = doc.read() if j_file is None:
if maindef.search(code): return None
return JFile(code) if "{ValidateByHand}" in j_file.code:
return None
if "/* Output: (None) */" in j_file.code:
return None
outfile = javaFilePath.with_name(javaFilePath.stem + "-output.txt")
errfile = javaFilePath.with_name(javaFilePath.stem + "-erroroutput.txt")
if outfile.exists() or errfile.exists():
return JavaMain(javaFilePath, j_file, outfile, errfile)
return None return None
def __init__(self, code): def __init__(self, javaFilePath, j_file, outfile, errfile):
self.code = code self.javaFilePath = javaFilePath
self.lines = self.code.splitlines() self.j_file = j_file
self.outfile = outfile
self.errfile = errfile
self.first_and_last = None
self.first_lines = None
def has_output(self): ol = self.j_file.output_line
return "} /* Output:" in self.code if ol:
if "(First and last" in ol:
self.first_and_last = int(ol.partition("(First and last")[2].split()[0])
elif "(First" in ol:
self.first_lines = int(ol.partition("(First")[2].split()[0])
def output_line(self): result =""
for line in self.lines: if outfile.exists():
if "} /* Output:" in line: with outfile.open() as f:
return line out = f.read().strip()
if out:
if self.first_and_last:
lines = out.splitlines()
out = "\n".join(lines[:self.first_and_last] + JavaMain.ellipses + lines[-self.first_and_last:])
elif self.first_lines:
lines = out.splitlines()
out = "\n".join(lines[:self.first_lines] + JavaMain.ellipses)
result += out + "\n"
if errfile.exists(): # Always include all of errfile
with errfile.open() as f:
err = f.read().strip()
if err:
result += "___[ Error Output ]___\n"
result += err
self.result = JavaMain.wrapOutput(result) + "\n"
for line in self.j_file.lines:
if line.startswith("} ///:~"):
self.j_file.newcode += "} /* Output:\n"
self.j_file.newcode += self.result + "*///:~\n"
break
if line.startswith("} /* Output:"):
line = line.partition("*///:~")[0]
self.j_file.newcode += line + "\n"
self.j_file.newcode += self.result + "*///:~\n"
break
else:
self.j_file.newcode += line + "\n"
def new_code(self):
return self.j_file.newcode
@staticmethod
def wrapOutput(output):
lines = output.splitlines()
result = []
for line in lines:
result += textwrap.wrap(line.rstrip(), width=maxlinewidth)
return "\n".join(result)
def wrapOutput(output):
lines = output.splitlines()
result = []
for line in lines:
result += textwrap.wrap(line.rstrip(), width=maxlinewidth)
return "\n".join(result)
def newOutput(javaFilePath):
outfile = javaFilePath.with_name(javaFilePath.stem + "-output.txt")
errfile = javaFilePath.with_name(javaFilePath.stem + "-erroroutput.txt")
result =""
if outfile.exists():
with outfile.open() as f:
out = f.read().strip()
if out:
result += out + "\n"
if errfile.exists():
with errfile.open() as f:
err = f.read().strip()
if err:
result += "--[ Error Output ]--\n"
result += err
result = wrapOutput(result)
if result:
return result + "\n"
return None
def appendOutputFiles(javaFilePath):
jfile = JFile.with_main(javaFilePath)
if jfile is None:
return
output = newOutput(javaFilePath)
if not output:
return
if not self.output_tags.has_output: # no /* Output: at all
with self.javaFilePath.open() as jf:
code = jf.read()
lines = code.splitlines()
while lines[-1].strip() is "":
lines.pop()
assert lines[-1].rstrip() == "} ///:~"
lines[-1] = "} /* Output:"
lines.append(self.new_output)
lines.append("*///:~")
result = "\n".join(lines) + "\n"
with self.javaFilePath.open("w") as jf:
jf.write(result)
return result
else:
print("{} already has Output!".format(self.javaFilePath))
sys.exit()
@CmdLine('o') @CmdLine('o')
def allOutputTagLines(): def allOutputTagLines():
"""Shows all lines starting with } /*""" """Shows all lines starting with } /*"""
@ -126,64 +148,126 @@ def outputTagTypes():
types = set() types = set()
os.chdir(str(examplePath)) os.chdir(str(examplePath))
for jfp in Path(".").rglob("*.java"): for jfp in Path(".").rglob("*.java"):
jf = JFile.with_main(jfp) jf = JavaMain.JFile.with_main(jfp)
if jf is None: if jf is None:
continue continue
if jf.has_output(): if jf.output_line:
types.add(jf.output_line()) types.add(jf.output_line)
pprint.pprint(types) pprint.pprint(types)
@CmdLine('e') @CmdLine('e')
def extractResults(): def extractResults():
"""Test extraction of all results""" """Test extraction of all results"""
os.chdir(str(examplePath)) os.chdir(str(examplePath))
with Path("AttachedResults.txt").open('w') as results: with Path("AttachedResults.txt").open('w') as results:
for jfp in Path(".").rglob("*.java"): for jfp in Path(".").rglob("*.java"):
output = newOutput(jfp) j_main = JavaMain.create(jfp)
if output: if j_main:
results.write(ruler(jfp)) results.write(ruler(jfp))
jf = JFile.with_main(jfp) outline = j_main.j_file.output_line
if jf is None:
continue
outline = jf.output_line()
if outline: if outline:
results.write(outline + "\n") results.write(outline + "\n")
results.write(output) results.write(j_main.result)
else: # else:
results.write("[ No output for {} ]\n".format(jfp)) # results.write("[ No output for {} ]\n".format(jfp))
os.system("subl AttachedResults.txt")
@CmdLine('n') @CmdLine('n')
def noOutputFixup(): def noOutputFixup():
"""Attach no output lines to empty output files""" """Attach "Output: (None)" lines to empty output files"""
# Exclude gui and swt directories!
os.chdir(str(examplePath)) os.chdir(str(examplePath))
test = open("test.txt", 'w') # test = open("test.txt", 'w')
for jfp in Path(".").rglob("*.java"): for jfp in Path(".").rglob("*.java"):
jf = JFile.with_main(jfp) if "gui" in jfp.parts or "swt" in jfp.parts:
continue
jf = JavaMain.JFile.with_main(jfp)
if jf is None: if jf is None:
continue continue
if not jf.has_output(): if "{ValidateByHand}" in jf.code:
continue
if not jf.output_line:
if JavaMain.create(jfp):
continue
newcode = "" newcode = ""
for line in jf.lines: for line in jf.lines:
if line.startswith("} ///:~"): if line.startswith("} ///:~"):
newcode += "} /* Output: (None) *///:~\n" newcode += "} /* Output: (None) *///:~\n"
else: else:
newcode += line + "\n" newcode += line + "\n"
test.write(ruler(jfp)) with jfp.open('w') as f:
test.write(newcode) f.write(newcode)
os.system("subl {}".format(jfp))
# test.write(ruler(jfp))
# test.write(newcode)
@CmdLine('a') @CmdLine('a')
def attachFiles(): def attachFiles():
"""Attach standard and error output to all files""" """Attach standard and error output to all files"""
os.chdir(str(examplePath)) os.chdir(str(examplePath))
test = open("test.txt", 'w')
for jfp in Path(".").rglob("*.java"): for jfp in Path(".").rglob("*.java"):
jf = JFile.with_main(jfp) if "gui" in jfp.parts or "swt" in jfp.parts:
if jf is None:
continue continue
if jf.has_output(): j_main = JavaMain.create(jfp)
head(jfp) if j_main is None:
print("\t{}".format(jf.output_line())) continue
test.write(ruler())
test.write(j_main.new_code())
os.system("subl test.txt")
if __name__ == '__main__': CmdLine.run() if __name__ == '__main__': CmdLine.run()
# def newOutput(javaFilePath):
# outfile = javaFilePath.with_name(javaFilePath.stem + "-output.txt")
# errfile = javaFilePath.with_name(javaFilePath.stem + "-erroroutput.txt")
# result =""
# if outfile.exists():
# with outfile.open() as f:
# out = f.read().strip()
# if out:
# result += out + "\n"
# if errfile.exists():
# with errfile.open() as f:
# err = f.read().strip()
# if err:
# result += "___[ Error Output ]___\n"
# result += err
# result = wrapOutput(result)
# if result:
# return result + "\n"
# return None
# def appendOutputFiles(javaFilePath):
# jfile = JFile.with_main(javaFilePath)
# if jfile is None:
# return
# output = newOutput(javaFilePath)
# if not output:
# return
# if not self.output_tags.has_output: # no /* Output: at all
# with self.javaFilePath.open() as jf:
# code = jf.read()
# lines = code.splitlines()
# while lines[-1].strip() is "":
# lines.pop()
# assert lines[-1].rstrip() == "} ///:~"
# lines[-1] = "} /* Output:"
# lines.append(self.new_output)
# lines.append("*///:~")
# result = "\n".join(lines) + "\n"
# with self.javaFilePath.open("w") as jf:
# jf.write(result)
# return result
# else:
# print("{} already has Output!".format(self.javaFilePath))
# sys.exit()

View File

@ -3,6 +3,9 @@
Extract code examples from TIJ Director's Cut plain text file. Extract code examples from TIJ Director's Cut plain text file.
Creates Ant build.xml file for each subdirectory. Creates Ant build.xml file for each subdirectory.
""" """
TODO = """
incorporate exec_command into build.xml
"""
from pathlib import Path from pathlib import Path
import sys, os import sys, os
import re import re
@ -187,7 +190,6 @@ class CodeFileOptions(object):
self.continue_on_error = True self.continue_on_error = True
self.msg = "* Exception was Expected *" self.msg = "* Exception was Expected *"
self.alternatemainclass = None self.alternatemainclass = None
if "{main: " in self.codeFile.code: if "{main: " in self.codeFile.code:
for line in self.codeFile.lines: for line in self.codeFile.lines:
@ -195,6 +197,14 @@ class CodeFileOptions(object):
self.alternatemainclass = line.split("{main:")[1].strip() self.alternatemainclass = line.split("{main:")[1].strip()
self.alternatemainclass = self.alternatemainclass.rsplit("}", 1)[0] self.alternatemainclass = self.alternatemainclass.rsplit("}", 1)[0]
self.exec_command = None
if "{Exec:" in self.codeFile.code:
for line in self.codeFile.lines:
if "{Exec:" in line:
self.exec_command = line.split("{Exec:")[1].strip()
self.exec_command = self.exec_command.rsplit("}", 1)[0]
self.exec_command = self.exec_command.strip()
self.timeout = None self.timeout = None
if "{TimeOut:" in self.codeFile.code: if "{TimeOut:" in self.codeFile.code:
for line in self.codeFile.lines: for line in self.codeFile.lines:

View File

@ -28,6 +28,7 @@ maindef = re.compile("public\s+static\s+void\s+main")
############################################################################### ###############################################################################
# Powershell: https://gist.github.com/diyan/2850866 # Powershell: https://gist.github.com/diyan/2850866
# http://marxsoftware.blogspot.com/2008/02/windows-powershell-and-java.html # http://marxsoftware.blogspot.com/2008/02/windows-powershell-and-java.html
allflags = dict()
class Flags: class Flags:
discard = ["{Requires:"] discard = ["{Requires:"]
@ -48,8 +49,11 @@ class Flags:
fl = fl.strip() fl = fl.strip()
arg = arg.strip() arg = arg.strip()
self.flags[fl] = arg self.flags[fl] = arg
allflags[fl] = arg
else: else:
self.flags[flag] = None # Make an entry, but no arg self.flags[flag] = None # Make an entry, but no arg
allflags[flag] = None
# allflags.add(flag)
def __contains__(self, elt): def __contains__(self, elt):
return elt in self.flags return elt in self.flags
@ -125,7 +129,7 @@ class RunFiles:
for java in RunFiles.base.rglob("*.java"): for java in RunFiles.base.rglob("*.java"):
with java.open() as code: with java.open() as code:
body = code.read() body = code.read()
if maindef.search(body): if maindef.search(body) or "{Exec:" in body:
self.runFiles.append(RunnableFile(java, body)) self.runFiles.append(RunnableFile(java, body))
allMains = set(self.runFiles) allMains = set(self.runFiles)
self.runFiles = [f for f in self.runFiles if not [nr for nr in self.not_runnable if nr in f]] self.runFiles = [f for f in self.runFiles if not [nr for nr in self.not_runnable if nr in f]]
@ -180,10 +184,25 @@ def createPowershellScript():
-RedirectStandardOutput {}-output.txt -RedirectStandardOutput {}-output.txt
-RedirectStandardError {}-erroroutput.txt -RedirectStandardError {}-erroroutput.txt
""".format(argquote, rf.javaArguments(), argquote, rf.name, rf.name) """.format(argquote, rf.javaArguments(), argquote, rf.name, rf.name)
if "Exec" in rf:
print("Exec found in {}".format(rf.name))
pprint.pprint(rf.flags.flags)
command = rf.flags.flags["Exec"].split()
pprint.pprint(command)
pstext = """\
Start-Process
-FilePath "{}"
-ArgumentList {}{}{}
-NoNewWindow
-RedirectStandardOutput {}-output.txt
-RedirectStandardError {}-erroroutput.txt
""".format(command[0] ,argquote, " ".join(command[1:]), argquote, rf.name, rf.name)
pstext = textwrap.dedent(pstext).replace('\n', ' ') pstext = textwrap.dedent(pstext).replace('\n', ' ')
if "ThrowsException" in rf: if "ThrowsException" in rf:
pstext += " -Wait\n" pstext += " -Wait\n"
pstext += "Add-Content {}-erroroutput.txt '---[ Exception is Expected ]---'".format(rf.name) pstext += "Add-Content {}-erroroutput.txt '___[ Exception is Expected ]___'".format(rf.name)
ps.write("cd {}\n".format(os.getcwd())) ps.write("cd {}\n".format(os.getcwd()))
ps.write(pstext + "\n") ps.write(pstext + "\n")
ps.write('Write-Host [{}] {}\n'.format(rf.relative, rf.name)) ps.write('Write-Host [{}] {}\n'.format(rf.relative, rf.name))
@ -276,7 +295,7 @@ class Result:
with self.errFilePath.open() as f: with self.errFilePath.open() as f:
err = f.read().strip() err = f.read().strip()
if err: if err:
result += "--[ Error Output ]--\n" result += "___[ Error Output ]___\n"
result += err result += err
return textwrap.wrap(result, width=maxlinewidth) return textwrap.wrap(result, width=maxlinewidth)
@ -386,7 +405,7 @@ def showProblemErrors():
continue continue
if "LoggingException" in err: if "LoggingException" in err:
continue continue
if "---[ Exception is Expected ]---" in err: if "___[ Exception is Expected ]___" in err:
continue continue
print(err) print(err)
@ -503,4 +522,6 @@ def clean_files():
w.write(code) w.write(code)
if __name__ == '__main__': CmdLine.run() if __name__ == '__main__':
CmdLine.run()
pprint.pprint(allflags)