comparison mxtool/mx.py @ 10061:b6dfe12478ff

[GRAAL-308] pre-defined working sets for Eclipse
author Michael Haupt <michael.haupt@oracle.com>
date Mon, 17 Jun 2013 08:30:03 +0200
parents 193d5163a94a
children 36b75ddac55e
comparison
equal deleted inserted replaced
10060:193d5163a94a 10061:b6dfe12478ff
123 "true" if the project is native. 123 "true" if the project is native.
124 124
125 javaCompliance 125 javaCompliance
126 The minimum JDK version (format: x.y) to which the project's 126 The minimum JDK version (format: x.y) to which the project's
127 sources comply (required for non-native projects). 127 sources comply (required for non-native projects).
128
129 workingSets
130 A comma separated list of working set names. The project belongs
131 to the given working sets, for which the eclipseinit command
132 will generate Eclipse configurations.
128 133
129 Other properties can be specified for projects and libraries for use 134 Other properties can be specified for projects and libraries for use
130 by extension commands. 135 by extension commands.
131 136
132 Property values can use environment variables with Bash syntax (e.g. ${HOME}). 137 Property values can use environment variables with Bash syntax (e.g. ${HOME}).
196 201
197 def isLibrary(self): 202 def isLibrary(self):
198 return isinstance(self, Library) 203 return isinstance(self, Library)
199 204
200 class Project(Dependency): 205 class Project(Dependency):
201 def __init__(self, suite, name, srcDirs, deps, javaCompliance, d): 206 def __init__(self, suite, name, srcDirs, deps, javaCompliance, workingSets, d):
202 Dependency.__init__(self, suite, name) 207 Dependency.__init__(self, suite, name)
203 self.srcDirs = srcDirs 208 self.srcDirs = srcDirs
204 self.deps = deps 209 self.deps = deps
205 self.checkstyleProj = name 210 self.checkstyleProj = name
206 self.javaCompliance = JavaCompliance(javaCompliance) if javaCompliance is not None else None 211 self.javaCompliance = JavaCompliance(javaCompliance) if javaCompliance is not None else None
207 self.native = False 212 self.native = False
213 self.workingSets = workingSets
208 self.dir = d 214 self.dir = d
209 215
210 # Create directories for projects that don't yet exist 216 # Create directories for projects that don't yet exist
211 if not exists(d): 217 if not exists(d):
212 os.mkdir(d) 218 os.mkdir(d)
528 srcDirs = pop_list(attrs, 'sourceDirs') 534 srcDirs = pop_list(attrs, 'sourceDirs')
529 deps = pop_list(attrs, 'dependencies') 535 deps = pop_list(attrs, 'dependencies')
530 ap = pop_list(attrs, 'annotationProcessors') 536 ap = pop_list(attrs, 'annotationProcessors')
531 #deps += ap 537 #deps += ap
532 javaCompliance = attrs.pop('javaCompliance', None) 538 javaCompliance = attrs.pop('javaCompliance', None)
533 subDir = attrs.pop('subDir', None); 539 subDir = attrs.pop('subDir', None)
534 if subDir is None: 540 if subDir is None:
535 d = join(self.dir, name) 541 d = join(self.dir, name)
536 else: 542 else:
537 d = join(self.dir, subDir, name) 543 d = join(self.dir, subDir, name)
538 p = Project(self, name, srcDirs, deps, javaCompliance, d) 544 workingSets = attrs.pop('workingSets', None)
545 p = Project(self, name, srcDirs, deps, javaCompliance, workingSets, d)
539 p.checkstyleProj = attrs.pop('checkstyle', name) 546 p.checkstyleProj = attrs.pop('checkstyle', name)
540 p.native = attrs.pop('native', '') == 'true' 547 p.native = attrs.pop('native', '') == 'true'
541 if not p.native and p.javaCompliance is None: 548 if not p.native and p.javaCompliance is None:
542 abort('javaCompliance property required for non-native project ' + name) 549 abort('javaCompliance property required for non-native project ' + name)
543 if len(ap) > 0: 550 if len(ap) > 0:
2177 if not exists(eclipseLaunches): 2184 if not exists(eclipseLaunches):
2178 os.makedirs(eclipseLaunches) 2185 os.makedirs(eclipseLaunches)
2179 return update_file(join(eclipseLaunches, name + '.launch'), launch) 2186 return update_file(join(eclipseLaunches, name + '.launch'), launch)
2180 2187
2181 def eclipseinit(args, suite=None, buildProcessorJars=True): 2188 def eclipseinit(args, suite=None, buildProcessorJars=True):
2182 """(re)generate Eclipse project configurations""" 2189 """(re)generate Eclipse project configurations and working sets"""
2183 2190
2184 if suite is None: 2191 if suite is None:
2185 suite = _mainSuite 2192 suite = _mainSuite
2186 2193
2187 if buildProcessorJars: 2194 if buildProcessorJars:
2365 out.element('factorypathentry', {'kind' : 'WKSPJAR', 'id' : '/' + dep.name + '/' + dep.name + '.jar', 'enabled' : 'true', 'runInBatchMode' : 'false'}) 2372 out.element('factorypathentry', {'kind' : 'WKSPJAR', 'id' : '/' + dep.name + '/' + dep.name + '.jar', 'enabled' : 'true', 'runInBatchMode' : 'false'})
2366 out.close('factorypath') 2373 out.close('factorypath')
2367 update_file(join(p.dir, '.factorypath'), out.xml(indent='\t', newl='\n')) 2374 update_file(join(p.dir, '.factorypath'), out.xml(indent='\t', newl='\n'))
2368 2375
2369 make_eclipse_attach('localhost', '8000', deps=projects()) 2376 make_eclipse_attach('localhost', '8000', deps=projects())
2377 generate_eclipse_workingsets(suite)
2370 2378
2371 2379
2372 def _isAnnotationProcessorDependency(p): 2380 def _isAnnotationProcessorDependency(p):
2373 """ 2381 """
2374 Determines if a given project is part of an annotation processor. 2382 Determines if a given project is part of an annotation processor.
2421 dotProjectDoc.element('key', data = 'incclean') 2429 dotProjectDoc.element('key', data = 'incclean')
2422 dotProjectDoc.element('value', data = 'true') 2430 dotProjectDoc.element('value', data = 'true')
2423 dotProjectDoc.close('dictionary') 2431 dotProjectDoc.close('dictionary')
2424 dotProjectDoc.close('arguments') 2432 dotProjectDoc.close('arguments')
2425 dotProjectDoc.close('buildCommand') 2433 dotProjectDoc.close('buildCommand')
2434
2435 def generate_eclipse_workingsets(suite):
2436 """
2437 Populate the workspace's working set configuration with working sets generated from project data.
2438 If the workspace already contains working set definitions, the existing ones will be retained and extended.
2439 In case mx/env does not contain a WORKSPACE definition pointing to the workspace root directory, the Graal project root directory will be assumed.
2440 If no workspace root directory can be identified, the Graal project root directory is used and the user has to place the workingsets.xml file by hand.
2441 """
2442
2443 # identify the location where to look for workingsets.xml
2444 wsfilename = 'workingsets.xml'
2445 wsroot = suite.dir
2446 if os.environ.has_key('WORKSPACE'):
2447 wsroot = os.environ['WORKSPACE']
2448 wsdir = join(wsroot, '.metadata/.plugins/org.eclipse.ui.workbench')
2449 if not exists(wsdir):
2450 wsdir = wsroot
2451 wspath = join(wsdir, wsfilename)
2452
2453 # gather working set info from project data
2454 workingSets = dict()
2455 for p in projects():
2456 if p.workingSets is None:
2457 continue
2458 for w in p.workingSets.split(","):
2459 if not workingSets.has_key(w):
2460 workingSets[w] = [p.name]
2461 else:
2462 workingSets[w].append(p.name)
2463
2464 if exists(wspath):
2465 wsdoc = _copy_workingset_xml(wspath, workingSets)
2466 else:
2467 wsdoc = _make_workingset_xml(workingSets)
2468
2469 update_file(wspath, wsdoc.xml(newl='\n'))
2470
2471 def _make_workingset_xml(workingSets):
2472 wsdoc = XMLDoc()
2473 wsdoc.open('workingSetManager')
2474
2475 for w in sorted(workingSets.keys()):
2476 _workingset_open(wsdoc, w)
2477 for p in workingSets[w]:
2478 _workingset_element(wsdoc, p)
2479 wsdoc.close('workingSet')
2480
2481 wsdoc.close('workingSetManager')
2482 return wsdoc
2483
2484 def _copy_workingset_xml(wspath, workingSets):
2485 target = XMLDoc()
2486 target.open('workingSetManager')
2487
2488 parser = xml.parsers.expat.ParserCreate()
2489
2490 class ParserState(object):
2491 def __init__(self):
2492 self.current_ws_name = 'none yet'
2493 self.current_ws = None
2494 self.seen_ws = list()
2495 self.seen_projects = list()
2496
2497 ps = ParserState()
2498
2499 # parsing logic
2500 def _ws_start(name, attributes):
2501 if name == 'workingSet':
2502 ps.current_ws_name = attributes['name']
2503 if workingSets.has_key(ps.current_ws_name):
2504 ps.current_ws = workingSets[ps.current_ws_name]
2505 ps.seen_ws.append(ps.current_ws_name)
2506 ps.seen_projects = list()
2507 else:
2508 ps.current_ws = None
2509 target.open(name, attributes)
2510 parser.StartElementHandler = _ws_item
2511
2512 def _ws_end(name):
2513 if name == 'workingSet':
2514 if not ps.current_ws is None:
2515 for p in ps.current_ws:
2516 if not p in ps.seen_projects:
2517 _workingset_element(target, p)
2518 target.close('workingSet')
2519 parser.StartElementHandler = _ws_start
2520 elif name == 'workingSetManager':
2521 # process all working sets that are new to the file
2522 for w in sorted(workingSets.keys()):
2523 if not w in ps.seen_ws:
2524 _workingset_open(target, w)
2525 for p in workingSets[w]:
2526 _workingset_element(target, p)
2527 target.close('workingSet')
2528
2529 def _ws_item(name, attributes):
2530 if name == 'item':
2531 if ps.current_ws is None:
2532 target.element(name, attributes)
2533 else:
2534 p_name = attributes['elementID'][1:] # strip off the leading '='
2535 _workingset_element(target, p_name)
2536 ps.seen_projects.append(p_name)
2537
2538 # process document
2539 parser.StartElementHandler = _ws_start
2540 parser.EndElementHandler = _ws_end
2541 with open(wspath, 'r') as wsfile:
2542 parser.ParseFile(wsfile)
2543
2544 target.close('workingSetManager')
2545 return target
2546
2547 def _workingset_open(wsdoc, ws):
2548 wsdoc.open('workingSet', {'editPageID': 'org.eclipse.jdt.ui.JavaWorkingSetPage', 'factoryID': 'org.eclipse.ui.internal.WorkingSetFactory', 'id': 'wsid_' + ws, 'label': ws, 'name': ws})
2549
2550 def _workingset_element(wsdoc, p):
2551 wsdoc.element('item', {'elementID': '=' + p, 'factoryID': 'org.eclipse.jdt.ui.PersistableJavaElementFactory'})
2426 2552
2427 def netbeansinit(args, suite=None): 2553 def netbeansinit(args, suite=None):
2428 """(re)generate NetBeans project configurations""" 2554 """(re)generate NetBeans project configurations"""
2429 2555
2430 if suite is None: 2556 if suite is None: