Ant build.xml creator first cut

This commit is contained in:
Bruce Eckel 2015-04-27 14:31:25 -07:00
parent b459197cf3
commit 3f4a3cae7a
34 changed files with 268 additions and 3 deletions

View File

@ -1,4 +1,4 @@
<project basedir="." name="Thinking in Java Director's Cut by Bruce Eckel">
<project basedir=".">
<property name="chapter" value="CHAPTER?"/>
@ -24,6 +24,22 @@
</sequential>
</macrodef>
<macrodef name="jrunp">
<attribute name="cls" default="NOT SET"/>
<attribute name="dirpath" default="NOT SET"/>
<sequential>
<echo>Running: @{cls}</echo>
<java
classname="@{cls}"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="@{dirpath}"
failonerror="true"
fork="true"/>
<echo>Finished: @{cls}</echo>
<echo>--------------------------------</echo>
</sequential>
</macrodef>
<condition property="version1.8">
<equals arg1="1.8" arg2="${ant.java.version}"/>
</condition>
@ -46,6 +62,7 @@
<javac includeantruntime="false"
classpath="${java.class.path};${basedir};${basedir}/.."
debug="true"
excludes="${excludedfiles}"
srcdir="${basedir}">
<compilerarg value="-Xmaxerrs"/>
<compilerarg value="10"/>

View File

@ -1,10 +1,10 @@
<?xml version="1.0" ?>
<project basedir="." default="run" name="Thinking in Java, 4th Edition (Refreshed) by Bruce Eckel">
<project basedir="." default="run" name="Thinking in Java Director's Cut by Bruce Eckel">
<description>
Main build.xml for the source code for
Thinking in Java, 4th Edition (Refreshed) by Bruce Eckel
Thinking in Java Director's Cut by Bruce Eckel
Code available at http://www.MindView.net
See installation instructions in README.md
See copyright notice in CopyRight.txt
@ -43,6 +43,15 @@
concurrency/build.xml
gui/build.xml
swt/build.xml
patterns/build.xml
references/build.xml
assertions/build.xml
database/build.xml
unittesting/build.xml
debugging/build.xml
logging/build.xml
network/build.xml
remote/build.xml
"/>
<target name="run" description="Compiles and runs all examples">

239
tools/Examples.py Normal file
View File

@ -0,0 +1,239 @@
#! py -3
"""
Extract code examples from TIJ4 Refreshed. Extracts from plain text file
"""
from pathlib import Path
import sys, os
import re
import argparse
import shutil
import pprint
destination = Path('.') / "ExtractedExamples"
sourceText = Path('.') / "TIJDirectorsCut.txt"
github = Path(r'C:\Users\Bruce\Documents\GitHub\TIJ-Directors-Cut')
startBuild = """\
<?xml version="1.0" ?>
<project default="run">
<property name="chapter" value="%s"/>
<property name="excludedfiles" value="%s"/>
<import file="../Ant-Common.xml"/>
<target
depends="build"
description="Compile and run"
name="run">
<touch file="failures"/>
"""
endBuild = """\
<delete file="failures"/>
</target>
</project>
"""
parser = argparse.ArgumentParser()
parser.add_argument("-e", "--extract", action='store_true',
help="Extract examples from TIJDirectorsCut.txt")
parser.add_argument("-x", "--clean", action='store_true',
help="Remove ExtractedExamples directory")
parser.add_argument("-c", "--compare", action='store_true',
help="Compare files from Github repository to extracted examples")
parser.add_argument("-a", "--ant", action='store_true',
help="Copy ant build files from Github repository to extracted examples")
parser.add_argument("-m", "--makeant", action='store_true',
help="Make ant files that don't exist")
def extractExamples():
if not destination.exists():
destination.mkdir()
if not sourceText.exists():
print("Cannot find", sourceText)
sys.exit()
with sourceText.open("rb") as book:
text = book.read().decode("utf-8", "ignore")
for listing in re.findall("^//:.*?///:~", text, re.DOTALL | re.MULTILINE):
title = listing.splitlines()[0]
if "//: as a special marker" in title:
continue
title = title.split()[1]
print(title)
target = destination / Path(title)
if not target.parent.exists():
target.parent.mkdir(parents=True)
with target.open("w", newline='') as codeListing:
codeListing.writelines(listing)
def clean():
print("clean")
if destination.exists():
shutil.rmtree(str(destination))
def compareWithGithub():
leader = len(str(github)) + 1
githubfiles = [str(file)[leader:] for file in github.glob("**/*")]
githubfiles = [ghf for ghf in githubfiles if not ghf.startswith(".git")]
duplicates = { ghf for ghf in githubfiles if githubfiles.count(ghf) > 1 }
print("duplicates = ", duplicates)
leader2 = len(str(destination)) + 1
destfiles = [str(file)[leader2:] for file in destination.glob("**/*")]
duplicates = { ghf for ghf in destfiles if destfiles.count(ghf) > 1 }
print("duplicates = ", duplicates)
githubfiles = set(githubfiles)
destfiles = set(destfiles)
print("in githubfiles but not destfiles:")
for f in githubfiles.difference(destfiles):
print("\t", f)
print("#" * 80)
print("in destfiles but not githubfiles:")
for f in destfiles.difference(githubfiles):
print("\t", f)
def githubDirs():
leader = len(str(github)) + 1
buildfiles = [str(file)[leader:] for file in github.glob("**/build.xml")]
return {str((github / f).parent)[leader:] for f in buildfiles}
def destDirs(pattern="**"):
leader = len(str(destination)) + 1
return {str(file)[leader:] for file in destination.glob(pattern)}
def copyAntBuildFiles():
for common in githubDirs().intersection(destDirs()):
print("->", common)
build = github / common / "build.xml"
# print (str(build), build.exists())
target = destination / common
# print (str(target), target.exists())
shutil.copy(str(build), str(target))
shutil.copy(str(github / "Ant-Common.xml"), str(destination))
class CodeFile:
def __init__(self, javaFile):
with javaFile.open() as j:
self.code = j.read()
self.lines = self.code.splitlines()
self.main = None
if "public static void main" in self.code:
self.main = True
self.package = None
if "package " in self.code:
for line in self.lines:
if line.startswith("package ") and line.strip().endswith(";"):
self.package = line
break
self.tagLine = self.lines[0][4:]
self.relpath = '../' + '/'.join(self.tagLine.split('/')[:-1])
self.name = javaFile.name.split('.')[0]
def __repr__(self):
result = self.tagLine
if self.package:
result += "\n" + self.package
result += "\n"
return result
# return "\n".join(self.lines)
def packageName(self):
return self.package.split()[1][:-1]
def checkPackage(self):
if not self.package:
return True
path = '.'.join(self.tagLine.split('/')[:-1])
packagePath = self.packageName()
return path == packagePath
class Chapter:
def __init__(self, dir):
self.dir = dir
self.code_files = [CodeFile(javaFile) for javaFile in dir.glob("**/*.java")]
self.excludes = [cf.name + ".java" for cf in self.code_files if "{CompileTimeError}" in cf.code]
def __repr__(self):
result = "-" * 80
result += "\n" + str(self.dir) + "\n"
result += "-" * 80
result += "\n"
for cf in self.code_files:
result += str(cf.name) + "\n"
return result
def checkPackages(self):
for cf in self.code_files:
if not cf.checkPackage():
print("BAD PACKAGE")
print("\t", cf.tagLine)
print("\t", cf.package)
print("\n".join(cf.lines))
def makeBuildFile(self):
buildFile = startBuild % (self.dir.name, " ".join(self.excludes))
for cf in self.code_files:
if cf.name + ".java" in self.excludes:
continue
print(cf.name)
if cf.main:
if not cf.package:
buildFile += ' <jrun cls="%s"/>\n' % cf.name
else:
buildFile += ' <jrunp cls ="%s" dirpath="%s"/>\n' % (cf.packageName() + '.' + cf.name, cf.relpath)
buildFile += endBuild
# print(buildFile)
with (self.dir / "build.xml").open("w") as buildxml:
buildxml.write(buildFile)
def createAntFiles():
chapters = [Chapter(fd) for fd in destination.glob("*") if fd.is_dir() if not (fd / "build.xml").exists()]
# chapters = [Chapter(fd) for fd in destination.glob("*") if fd.is_dir()]
for chapter in chapters:
print(chapter)
chapter.checkPackages()
chapter.makeBuildFile()
def default():
clean()
extractExamples()
copyAntBuildFiles()
createAntFiles()
os.chdir("ExtractedExamples")
if __name__ == '__main__':
args = parser.parse_args()
if not any(vars(args).values()): default()
if args.extract:
extractExamples()
copyAntBuildFiles()
createAntFiles()
if args.compare:
compareWithGithub()
if args.ant:
copyAntBuildFiles()
if args.makeant:
createAntFiles()
if args.clean:
clean()