comparison mxtool/mx.py @ 4269:ffd5ce8fc736

Moved IDE project configuration into mx.py. Added capability for generating NetBeans project configurations.
author Doug Simon <doug.simon@oracle.com>
date Wed, 11 Jan 2012 15:14:45 +0100
parents 8d2c14f722ac
children 2158e26b50cf
comparison
equal deleted inserted replaced
4258:8d2c14f722ac 4269:ffd5ce8fc736
87 import sys, os, errno, time, subprocess, shlex, types, urllib2, contextlib, StringIO, zipfile, signal 87 import sys, os, errno, time, subprocess, shlex, types, urllib2, contextlib, StringIO, zipfile, signal
88 import shutil, fnmatch, re, xml.dom.minidom 88 import shutil, fnmatch, re, xml.dom.minidom
89 from collections import Callable 89 from collections import Callable
90 from threading import Thread 90 from threading import Thread
91 from argparse import ArgumentParser, REMAINDER 91 from argparse import ArgumentParser, REMAINDER
92 from os.path import join, dirname, exists, getmtime, isabs, expandvars, isdir 92 from os.path import join, dirname, exists, getmtime, isabs, expandvars, isdir, isfile
93 93
94 DEFAULT_JAVA_ARGS = '-ea -Xss2m -Xmx1g' 94 DEFAULT_JAVA_ARGS = '-ea -Xss2m -Xmx1g'
95 95
96 _projects = dict() 96 _projects = dict()
97 _libs = dict() 97 _libs = dict()
98 _suites = dict() 98 _suites = dict()
99 _mainSuite = None
99 _opts = None 100 _opts = None
100 _java = None 101 _java = None
101 102
102 """ 103 """
103 A dependency is a library or project specified in a suite. 104 A dependency is a library or project specified in a suite.
363 abort('Unknown operating system ' + sys.platform) 364 abort('Unknown operating system ' + sys.platform)
364 365
365 def _loadSuite(dir, primary=False): 366 def _loadSuite(dir, primary=False):
366 mxDir = join(dir, 'mx') 367 mxDir = join(dir, 'mx')
367 if not exists(mxDir) or not isdir(mxDir): 368 if not exists(mxDir) or not isdir(mxDir):
368 return 369 return None
369 if not _suites.has_key(dir): 370 if not _suites.has_key(dir):
370 suite = Suite(dir, primary) 371 suite = Suite(dir, primary)
371 _suites[dir] = suite 372 _suites[dir] = suite
373 return suite
372 374
373 def suites(): 375 def suites():
374 """ 376 """
375 Get the list of all loaded suites. 377 Get the list of all loaded suites.
376 """ 378 """
908 for dep in p.all_deps([], False): 910 for dep in p.all_deps([], False):
909 if dep.name in built: 911 if dep.name in built:
910 mustBuild = True 912 mustBuild = True
911 913
912 javafilelist = [] 914 javafilelist = []
913 nonjavafilelistdst = []
914 for sourceDir in sourceDirs: 915 for sourceDir in sourceDirs:
915 for root, _, files in os.walk(sourceDir): 916 for root, _, files in os.walk(sourceDir):
916 javafiles = [join(root, name) for name in files if name.endswith('.java') and name != 'package-info.java'] 917 javafiles = [join(root, name) for name in files if name.endswith('.java') and name != 'package-info.java']
917 javafilelist += javafiles 918 javafilelist += javafiles
918 919
1183 fmtArgs += [str(d)] 1184 fmtArgs += [str(d)]
1184 doc = doc.format(*fmtArgs) 1185 doc = doc.format(*fmtArgs)
1185 print 'mx {0} {1}\n\n{2}\n'.format(name, usage, doc) 1186 print 'mx {0} {1}\n\n{2}\n'.format(name, usage, doc)
1186 1187
1187 1188
1188 # Commands are in alphabetical order in this file. 1189 def eclipseinit(args, suite=None):
1190 """(re)generate Eclipse project configurations"""
1191
1192 if suite is None:
1193 suite = _mainSuite
1194
1195 def println(out, obj):
1196 out.write(str(obj) + '\n')
1197
1198 for p in projects():
1199 if p.native:
1200 continue
1201
1202 if not exists(p.dir):
1203 os.makedirs(p.dir)
1204
1205 out = StringIO.StringIO()
1206
1207 println(out, '<?xml version="1.0" encoding="UTF-8"?>')
1208 println(out, '<classpath>')
1209 for src in p.srcDirs:
1210 srcDir = join(p.dir, src)
1211 if not exists(srcDir):
1212 os.mkdir(srcDir)
1213 println(out, '\t<classpathentry kind="src" path="' + src + '"/>')
1214
1215 # Every Java program depends on the JRE
1216 println(out, '\t<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>')
1217
1218 for dep in p.all_deps([], True):
1219 if dep == p:
1220 continue;
1221
1222 if dep.isLibrary():
1223 if hasattr(dep, 'eclipse.container'):
1224 println(out, '\t<classpathentry exported="true" kind="con" path="' + getattr(dep, 'eclipse.container') + '"/>')
1225 elif hasattr(dep, 'eclipse.project'):
1226 println(out, '\t<classpathentry combineaccessrules="false" exported="true" kind="src" path="/' + getattr(dep, 'eclipse.project') + '"/>')
1227 else:
1228 path = dep.path
1229 if dep.mustExist:
1230 dep.get_path(resolve=True)
1231 if isabs(path):
1232 println(out, '\t<classpathentry exported="true" kind="lib" path="' + path + '"/>')
1233 else:
1234 println(out, '\t<classpathentry exported="true" kind="lib" path="' + join(suite.dir, path) + '"/>')
1235 else:
1236 println(out, '\t<classpathentry combineaccessrules="false" exported="true" kind="src" path="/' + dep.name + '"/>')
1237
1238 println(out, '\t<classpathentry kind="output" path="' + getattr(p, 'eclipse.output', 'bin') + '"/>')
1239 println(out, '</classpath>')
1240 update_file(join(p.dir, '.classpath'), out.getvalue())
1241 out.close()
1242
1243 csConfig = join(project(p.checkstyleProj).dir, '.checkstyle_checks.xml')
1244 if exists(csConfig):
1245 out = StringIO.StringIO()
1246
1247 dotCheckstyle = join(p.dir, ".checkstyle")
1248 checkstyleConfigPath = '/' + p.checkstyleProj + '/.checkstyle_checks.xml'
1249 println(out, '<?xml version="1.0" encoding="UTF-8"?>')
1250 println(out, '<fileset-config file-format-version="1.2.0" simple-config="true">')
1251 println(out, '\t<local-check-config name="Checks" location="' + checkstyleConfigPath + '" type="project" description="">')
1252 println(out, '\t\t<additional-data name="protect-config-file" value="false"/>')
1253 println(out, '\t</local-check-config>')
1254 println(out, '\t<fileset name="all" enabled="true" check-config-name="Checks" local="true">')
1255 println(out, '\t\t<file-match-pattern match-pattern="." include-pattern="true"/>')
1256 println(out, '\t</fileset>')
1257 println(out, '\t<filter name="FileTypesFilter" enabled="true">')
1258 println(out, '\t\t<filter-data value="java"/>')
1259 println(out, '\t</filter>')
1260
1261 exclude = join(p.dir, '.checkstyle.exclude')
1262 if exists(exclude):
1263 println(out, '\t<filter name="FilesFromPackage" enabled="true">')
1264 with open(exclude) as f:
1265 for line in f:
1266 if not line.startswith('#'):
1267 line = line.strip()
1268 exclDir = join(p.dir, line)
1269 assert isdir(exclDir), 'excluded source directory listed in ' + exclude + ' does not exist or is not a directory: ' + exclDir
1270 println(out, '\t\t<filter-data value="' + line + '"/>')
1271 println(out, '\t</filter>')
1272
1273 println(out, '</fileset-config>')
1274 update_file(dotCheckstyle, out.getvalue())
1275 out.close()
1276
1277
1278 out = StringIO.StringIO()
1279
1280 println(out, '<?xml version="1.0" encoding="UTF-8"?>')
1281 println(out, '<projectDescription>')
1282 println(out, '\t<name>' + p.name + '</name>')
1283 println(out, '\t<comment></comment>')
1284 println(out, '\t<projects>')
1285 println(out, '\t</projects>')
1286 println(out, '\t<buildSpec>')
1287 println(out, '\t\t<buildCommand>')
1288 println(out, '\t\t\t<name>org.eclipse.jdt.core.javabuilder</name>')
1289 println(out, '\t\t\t<arguments>')
1290 println(out, '\t\t\t</arguments>')
1291 println(out, '\t\t</buildCommand>')
1292 if exists(csConfig):
1293 println(out, '\t\t<buildCommand>')
1294 println(out, '\t\t\t<name>net.sf.eclipsecs.core.CheckstyleBuilder</name>')
1295 println(out, '\t\t\t<arguments>')
1296 println(out, '\t\t\t</arguments>')
1297 println(out, '\t\t</buildCommand>')
1298 println(out, '\t</buildSpec>')
1299 println(out, '\t<natures>')
1300 println(out, '\t\t<nature>org.eclipse.jdt.core.javanature</nature>')
1301 if exists(csConfig):
1302 println(out, '\t\t<nature>net.sf.eclipsecs.core.CheckstyleNature</nature>')
1303 println(out, '\t</natures>')
1304 println(out, '</projectDescription>')
1305 update_file(join(p.dir, '.project'), out.getvalue())
1306 out.close()
1307
1308 out = StringIO.StringIO()
1309 settingsDir = join(p.dir, ".settings")
1310 if not exists(settingsDir):
1311 os.mkdir(settingsDir)
1312
1313 eclipseSettingsDir = join(suite.dir, 'mx', 'eclipse-settings')
1314 if exists(eclipseSettingsDir):
1315 for name in os.listdir(eclipseSettingsDir):
1316 path = join(eclipseSettingsDir, name)
1317 if isfile(path):
1318 with open(join(eclipseSettingsDir, name)) as f:
1319 content = f.read()
1320 update_file(path, content)
1321
1322 def netbeansinit(args, suite=None):
1323 """(re)generate NetBeans project configurations"""
1324
1325 if suite is None:
1326 suite = _mainSuite
1327
1328 def println(out, obj):
1329 out.write(str(obj) + '\n')
1330
1331 updated = False
1332 for p in projects():
1333 if p.native:
1334 continue
1335
1336 if not exists(join(p.dir, 'nbproject')):
1337 os.makedirs(join(p.dir, 'nbproject'))
1338
1339 out = StringIO.StringIO()
1340
1341 println(out, '<?xml version="1.0" encoding="UTF-8"?>')
1342 println(out, '<project name="' + p.name + '" default="default" basedir=".">')
1343 println(out, '\t<description>Builds, tests, and runs the project ' + p.name + '.</description>')
1344 println(out, '\t<import file="nbproject/build-impl.xml"/>')
1345 println(out, '</project>')
1346 updated = update_file(join(p.dir, 'build.xml'), out.getvalue()) or updated
1347 out.close()
1348
1349 out = StringIO.StringIO()
1350 println(out, '<?xml version="1.0" encoding="UTF-8"?>')
1351 println(out, '<project xmlns="http://www.netbeans.org/ns/project/1">')
1352 println(out, '\t<type>org.netbeans.modules.java.j2seproject</type>')
1353 println(out, '\t<configuration>')
1354 println(out, '\t\t<data xmlns="http://www.netbeans.org/ns/j2se-project/3">')
1355 println(out, '\t\t\t<name>' + p.name + '</name>')
1356 println(out, '\t\t\t<explicit-platform explicit-source-supported="true"/>')
1357 println(out, '\t\t\t<source-roots>')
1358 println(out, '\t\t\t\t<root id="src.dir"/>')
1359 println(out, '\t\t\t</source-roots>')
1360 println(out, '\t\t\t<test-roots>')
1361 println(out, '\t\t\t\t<root id="test.src.dir"/>')
1362 println(out, '\t\t\t</test-roots>')
1363 println(out, '\t\t</data>')
1364 println(out, '\t</configuration>')
1365 println(out, '</project>')
1366 updated = update_file(join(p.dir, 'nbproject', 'project.xml'), out.getvalue()) or updated
1367 out.close()
1368
1369 out = StringIO.StringIO()
1370
1371 jdkPlatform = 'JDK_' + java().version
1372
1373 content = """
1374 annotation.processing.enabled=false
1375 annotation.processing.enabled.in.editor=false
1376 annotation.processing.processors.list=
1377 annotation.processing.run.all.processors=true
1378 annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
1379 application.title=""" + p.name + """
1380 application.vendor=mx
1381 build.classes.dir=${build.dir}
1382 build.classes.excludes=**/*.java,**/*.form
1383 # This directory is removed when the project is cleaned:
1384 build.dir=bin
1385 build.generated.dir=${build.dir}/generated
1386 build.generated.sources.dir=${build.dir}/generated-sources
1387 # Only compile against the classpath explicitly listed here:
1388 build.sysclasspath=ignore
1389 build.test.classes.dir=${build.dir}/test/classes
1390 build.test.results.dir=${build.dir}/test/results
1391 # Uncomment to specify the preferred debugger connection transport:
1392 #debug.transport=dt_socket
1393 debug.classpath=\\
1394 ${run.classpath}
1395 debug.test.classpath=\\
1396 ${run.test.classpath}
1397 # This directory is removed when the project is cleaned:
1398 dist.dir=dist
1399 dist.jar=${dist.dir}/""" + p.name + """.jar
1400 dist.javadoc.dir=${dist.dir}/javadoc
1401 endorsed.classpath=
1402 excludes=
1403 includes=**
1404 jar.compress=false
1405 # Space-separated list of extra javac options
1406 javac.compilerargs=
1407 javac.deprecation=false
1408 javac.processorpath=\\
1409 ${javac.classpath}
1410 javac.source=1.7
1411 javac.target=1.7
1412 javac.test.classpath=\\
1413 ${javac.classpath}:\\
1414 ${build.classes.dir}
1415 javac.test.processorpath=\\
1416 ${javac.test.classpath}
1417 javadoc.additionalparam=
1418 javadoc.author=false
1419 javadoc.encoding=${source.encoding}
1420 javadoc.noindex=false
1421 javadoc.nonavbar=false
1422 javadoc.notree=false
1423 javadoc.private=false
1424 javadoc.splitindex=true
1425 javadoc.use=true
1426 javadoc.version=false
1427 javadoc.windowtitle=
1428 main.class=
1429 manifest.file=manifest.mf
1430 meta.inf.dir=${src.dir}/META-INF
1431 mkdist.disabled=true
1432 platforms.""" + jdkPlatform + """.home=""" + java().jdk + """
1433 platform.active=""" + jdkPlatform + """
1434 run.classpath=\\
1435 ${javac.classpath}:\\
1436 ${build.classes.dir}
1437 # Space-separated list of JVM arguments used when running the project
1438 # (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
1439 # or test-sys-prop.name=value to set system properties for unit tests):
1440 run.jvmargs=
1441 run.test.classpath=\\
1442 ${javac.test.classpath}:\\
1443 ${build.test.classes.dir}
1444 test.src.dir=
1445 source.encoding=UTF-8""".replace(':', os.pathsep).replace('/', os.sep)
1446 println(out, content)
1447
1448 mainSrc = True
1449 for src in p.srcDirs:
1450 srcDir = join(p.dir, src)
1451 if not exists(srcDir):
1452 os.mkdir(srcDir)
1453 ref = 'file.reference.' + p.name + '-' + src
1454 println(out, ref + '=' + src)
1455 if mainSrc:
1456 println(out, 'src.dir=${' + ref + '}')
1457 mainSrc = False
1458 else:
1459 println(out, 'src.' + src + '.dir=${' + ref + '}')
1460
1461 javacClasspath = []
1462 for dep in p.all_deps([], True):
1463 if dep == p:
1464 continue;
1465
1466 if dep.isLibrary():
1467 path = dep.path
1468 if dep.mustExist:
1469 dep.get_path(resolve=True)
1470 if not isabs(path):
1471 path = join(suite.dir, path)
1472
1473 else:
1474 path = dep.output_dir()
1475
1476 ref = 'file.reference.' + dep.name + '-bin'
1477 println(out, ref + '=' + path)
1478 javacClasspath.append('${' + ref + '}')
1479
1480 println(out, 'javac.classpath=\\\n ' + (os.pathsep + '\\\n ').join(javacClasspath))
1481
1482
1483 updated = update_file(join(p.dir, 'nbproject', 'project.properties'), out.getvalue()) or updated
1484 out.close()
1485
1486 if updated:
1487 log('If using NetBeans, ensure that a platform name ' + jdkPlatform + ' is defined (Tools -> Java Platforms)')
1488
1489 def ideinit(args, suite=None):
1490 """(re)generate Eclipse and NetBeans project configurations"""
1491 eclipseinit(args, suite)
1492 netbeansinit(args, suite)
1189 1493
1190 def javap(args): 1494 def javap(args):
1191 """launch javap with a -classpath option denoting all available classes 1495 """launch javap with a -classpath option denoting all available classes
1192 1496
1193 Run the JDK javap class file disassembler with the following prepended options: 1497 Run the JDK javap class file disassembler with the following prepended options:
1224 commands = { 1528 commands = {
1225 'build': [build, '[options]'], 1529 'build': [build, '[options]'],
1226 'checkstyle': [checkstyle, ''], 1530 'checkstyle': [checkstyle, ''],
1227 'canonicalizeprojects': [canonicalizeprojects, ''], 1531 'canonicalizeprojects': [canonicalizeprojects, ''],
1228 'clean': [clean, ''], 1532 'clean': [clean, ''],
1533 'eclipseinit': [eclipseinit, ''],
1229 'help': [help_, '[command]'], 1534 'help': [help_, '[command]'],
1535 'ideinit': [ideinit, ''],
1230 'javap': [javap, ''], 1536 'javap': [javap, ''],
1231 'projects': [show_projects, ''], 1537 'projects': [show_projects, ''],
1232 } 1538 }
1233 1539
1234 _argParser = ArgParser() 1540 _argParser = ArgParser()
1235 1541
1236 def main(): 1542 def main():
1237 cwdMxDir = join(os.getcwd(), 'mx') 1543 cwdMxDir = join(os.getcwd(), 'mx')
1238 if exists(cwdMxDir) and isdir(cwdMxDir): 1544 if exists(cwdMxDir) and isdir(cwdMxDir):
1239 _loadSuite(os.getcwd(), True) 1545 global _mainSuite
1546 _mainSuite = _loadSuite(os.getcwd(), True)
1240 1547
1241 opts, commandAndArgs = _argParser._parse_cmd_line() 1548 opts, commandAndArgs = _argParser._parse_cmd_line()
1242 1549
1243 global _opts, _java 1550 global _opts, _java
1244 _opts = opts 1551 _opts = opts