def _intellij_native_projects(s, module_files_only, declared_modules, modulesXml): for p in s.projects_recursive() + mx._mx_suite.projects_recursive(): if not p.isNativeProject(): continue mx.ensure_dir_exists(p.dir) moduleXml = mx.XMLDoc() moduleXml.open('module', attributes={'type': 'CPP_MODULE'}) moduleXml.open('component', attributes={'name': 'NewModuleRootManager', 'inherit-compiler-output': 'false'}) moduleXml.open('content', attributes={'url': 'file://$MODULE_DIR$'}) for src in p.srcDirs: srcDir = join(p.dir, src) mx.ensure_dir_exists(srcDir) moduleXml.element('sourceFolder', attributes={'url': 'file://$MODULE_DIR$/' + src, 'isTestSource': str(p.is_test_project())}) moduleXml.close('content') moduleXml.element('orderEntry', attributes={'type': 'sourceFolder', 'forTests': 'false'}) moduleXml.close('component') moduleXml.close('module') moduleFile = join(p.dir, p.name + '.iml') mx.update_file(moduleFile, moduleXml.xml(indent=' ', newl='\n')) if not module_files_only: declared_modules.add(p.name) moduleFilePath = "$PROJECT_DIR$/" + os.path.relpath(moduleFile, s.dir) modulesXml.element('module', attributes={'fileurl': 'file://' + moduleFilePath, 'filepath': moduleFilePath})
def make_library(name, path, source_path, suite_dir): libraryXml = mx.XMLDoc() libraryXml.open('component', attributes={'name': 'libraryTable'}) libraryXml.open('library', attributes={'name': name}) libraryXml.open('CLASSES') pathX = mx.relpath_or_absolute(path, suite_dir, prefix='$PROJECT_DIR$') libraryXml.element('root', attributes={'url': 'jar://' + pathX + '!/'}) libraryXml.close('CLASSES') libraryXml.element('JAVADOC') if sourcePath: libraryXml.open('SOURCES') if os.path.isdir(sourcePath): sourcePathX = mx.relpath_or_absolute(sourcePath, suite_dir, prefix='$PROJECT_DIR$') libraryXml.element('root', attributes={'url': 'file://' + sourcePathX}) else: source_pathX = mx.relpath_or_absolute(source_path, suite_dir, prefix='$PROJECT_DIR$') libraryXml.element('root', attributes={'url': 'jar://' + source_pathX + '!/'}) libraryXml.close('SOURCES') else: libraryXml.element('SOURCES') libraryXml.close('library') libraryXml.close('component') libraryFile = join(librariesDirectory, _intellij_library_file_name(name, unique_library_file_names)) return mx.update_file(libraryFile, libraryXml.xml(indent=' ', newl='\n'))
def intellijinit(args, refreshOnly=False, doFsckProjects=True, mx_python_modules=True, java_modules=True, generate_external_projects=True, native_projects=False): # In a multiple suite context, the .idea directory in each suite # has to be complete and contain information that is repeated # in dependent suites. declared_modules = set() referenced_modules = set() sdks = intellij_read_sdks() for suite in mx.suites(True) + ([mx._mx_suite] if mx_python_modules else []): _intellij_suite(args, suite, declared_modules, referenced_modules, sdks, refreshOnly, mx_python_modules, generate_external_projects, java_modules and not suite.isBinarySuite(), suite != mx.primary_suite(), generate_native_projects=native_projects) if len(referenced_modules - declared_modules) != 0: mx.abort('Some referenced modules are missing from modules.xml: {}'.format(referenced_modules - declared_modules)) if mx_python_modules: # mx module moduleXml = mx.XMLDoc() moduleXml.open('module', attributes={'type': 'PYTHON_MODULE', 'version': '4'}) moduleXml.open('component', attributes={'name': 'NewModuleRootManager', 'inherit-compiler-output': 'true'}) moduleXml.element('exclude-output') moduleXml.open('content', attributes={'url': 'file://$MODULE_DIR$'}) moduleXml.element('sourceFolder', attributes={'url': 'file://$MODULE_DIR$', 'isTestSource': 'false'}) for d in set((p.subDir for p in mx._mx_suite.projects if p.subDir)): moduleXml.element('excludeFolder', attributes={'url': 'file://$MODULE_DIR$/' + d}) if dirname(mx._mx_suite.get_output_root()) == mx._mx_suite.dir: moduleXml.element('excludeFolder', attributes={'url': 'file://$MODULE_DIR$/' + basename(mx._mx_suite.get_output_root())}) moduleXml.close('content') moduleXml.element('orderEntry', attributes={'type': 'jdk', 'jdkType': intellij_python_sdk_type, 'jdkName': intellij_get_python_sdk_name(sdks)}) moduleXml.element('orderEntry', attributes={'type': 'sourceFolder', 'forTests': 'false'}) moduleXml.close('component') moduleXml.close('module') mxModuleFile = join(mx._mx_suite.dir, basename(mx._mx_suite.dir) + '.iml') mx.update_file(mxModuleFile, moduleXml.xml(indent=' ', newl='\n')) if doFsckProjects and not refreshOnly: mx_ideconfig.fsckprojects([])
def _eclipseinit(self, files=None, libFiles=None): """ Generates an Eclipse project for each HotSpot build configuration. """ roots = ['cpu', 'os', 'os_cpu', 'share'] for jvmVariant in _jdkJvmVariants: for debugLevel in _jdkDebugLevels: name = jvmVariant + '-' + debugLevel eclProjectDir = join(self.dir, 'eclipse', name) mx.ensure_dir_exists(eclProjectDir) out = mx.XMLDoc() out.open('projectDescription') out.element('name', data='hotspot:' + name) out.element('comment', data='') out.element('projects', data='') out.open('buildSpec') out.open('buildCommand') out.element( 'name', data= 'org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder') out.element('triggers', data='full,incremental') out.element('arguments', data='') out.close('buildCommand') out.close('buildSpec') out.open('natures') out.element('nature', data='org.eclipse.cdt.core.cnature') out.element('nature', data='org.eclipse.cdt.core.ccnature') out.element( 'nature', data= 'org.eclipse.cdt.managedbuilder.core.managedBuildNature') out.element( 'nature', data= 'org.eclipse.cdt.managedbuilder.core.ScannerConfigNature') out.close('natures') if roots: out.open('linkedResources') for r in roots: f = join(_suite.dir, r) out.open('link') out.element('name', data=r) out.element('type', data='2' if isdir(f) else '1') out.element( 'locationURI', data=mx.get_eclipse_project_rel_locationURI( f, eclProjectDir)) out.close('link') out.open('link') out.element('name', data='gensrc') out.element('type', data='2') generated = join( _get_hotspot_build_dir(jvmVariant, debugLevel), 'gensrc') out.element('locationURI', data=mx.get_eclipse_project_rel_locationURI( generated, eclProjectDir)) out.close('link') out.close('linkedResources') out.close('projectDescription') projectFile = join(eclProjectDir, '.project') mx.update_file(projectFile, out.xml(indent='\t', newl='\n')) if files: files.append(projectFile) cprojectTemplate = join(self.dir, 'templates', 'eclipse', 'cproject') cprojectFile = join(eclProjectDir, '.cproject') with open(cprojectTemplate) as f: content = f.read() mx.update_file(cprojectFile, content) if files: files.append(cprojectFile) settingsDir = join(eclProjectDir, ".settings") mx.ensure_dir_exists(settingsDir) for name, source in self._get_eclipse_settings_sources( ).iteritems(): out = StringIO.StringIO() print >> out, '# GENERATED -- DO NOT EDIT' print >> out, '# Source:', source with open(source) as f: print >> out, f.read() content = out.getvalue() mx.update_file(join(settingsDir, name), content) if files: files.append(join(settingsDir, name))
def _netbeansinit_project(p, jdks=None, files=None, libFiles=None, dists=None): dists = [] if dists is None else dists nb_dir = mx.ensure_dir_exists(join(p.dir)) nbproject_dir = mx.ensure_dir_exists(join(nb_dir, 'nbproject')) jdk = mx.get_jdk(p.javaCompliance) assert jdk if jdks is not None: jdks.add(jdk) execDir = mx.primary_suite().dir out = mx.XMLDoc() out.open('project', {'name' : p.name, 'default' : 'default', 'basedir' : '.'}) out.element('description', data='Builds, tests, and runs the project ' + p.name + '.') out.element('available', {'file' : 'nbproject/build-impl.xml', 'property' : 'build.impl.exists'}) out.element('import', {'file' : 'nbproject/build-impl.xml', 'optional' : 'true'}) out.element('extension-point', {'name' : '-mx-init'}) out.element('available', {'file' : 'nbproject/build-impl.xml', 'property' : 'mx.init.targets', 'value' : 'init'}) out.element('property', {'name' : 'mx.init.targets', 'value' : ''}) out.element('bindtargets', {'extensionPoint' : '-mx-init', 'targets' : '${mx.init.targets}'}) out.open('target', {'name' : '-post-init'}) out.open('pathconvert', {'property' : 'comma.javac.classpath', 'pathsep' : ','}) out.element('path', {'path' : '${javac.classpath}'}) out.close('pathconvert') out.open('restrict', {'id' : 'missing.javac.classpath'}) out.element('filelist', {'dir' : '${basedir}', 'files' : '${comma.javac.classpath}'}) out.open('not') out.element('exists') out.close('not') out.close('restrict') out.element('property', {'name' : 'missing.javac.classpath', 'refid' : 'missing.javac.classpath'}) out.open('condition', {'property' : 'no.dependencies', 'value' : 'true'}) out.element('equals', {'arg1' : '${missing.javac.classpath}', 'arg2' : ''}) out.close('condition') out.element('property', {'name' : 'no.dependencies', 'value' : 'false'}) out.open('condition', {'property' : 'no.deps'}) out.element('equals', {'arg1' : '${no.dependencies}', 'arg2' : 'true'}) out.close('condition') out.close('target') out.open('target', {'name' : 'clean'}) out.open('exec', {'executable' : sys.executable, 'failonerror' : 'true', 'dir' : execDir}) out.element('env', {'key' : 'JAVA_HOME', 'value' : jdk.home}) out.element('arg', {'value' : os.path.abspath(__file__)}) out.element('arg', {'value' : 'clean'}) out.element('arg', {'value' : '--projects'}) out.element('arg', {'value' : p.name}) out.close('exec') out.close('target') out.open('target', {'name' : 'compile'}) out.open('exec', {'executable' : sys.executable, 'failonerror' : 'true', 'dir' : execDir}) out.element('env', {'key' : 'JAVA_HOME', 'value' : jdk.home}) out.element('arg', {'value' : os.path.abspath(__file__)}) out.element('arg', {'value' : 'build'}) dependsOn = p.name for d in dists: dependsOn = dependsOn + ',' + d.name out.element('arg', {'value' : '--only'}) out.element('arg', {'value' : dependsOn}) out.element('arg', {'value' : '--force-javac'}) out.element('arg', {'value' : '--no-native'}) out.element('arg', {'value' : '--no-daemon'}) out.close('exec') out.close('target') out.open('target', {'name' : 'package', 'if' : 'build.impl.exists'}) out.element('antcall', {'target': '-package', 'inheritall': 'true', 'inheritrefs': 'true'}) out.close('target') out.open('target', {'name' : '-package', 'depends' : '-mx-init'}) out.element('loadfile', {'srcFile' : join(p.suite.get_output_root(), 'netbeans.log'), 'property' : 'netbeans.log', 'failonerror' : 'false'}) out.element('echo', {'message' : '...truncated...${line.separator}', 'output' : join(p.suite.get_output_root(), 'netbeans.log')}) out.element('echo', {'message' : '${netbeans.log}'}) for d in dists: if d.isDistribution(): out.element('touch', {'file' : '${java.io.tmpdir}/' + d.name}) out.element('echo', {'message' : d.name + ' set to now${line.separator}', 'append' : 'true', 'output' : join(p.suite.get_output_root(), 'netbeans.log')}) out.open('copy', {'todir' : '${build.classes.dir}', 'overwrite' : 'true'}) out.element('resources', {'refid' : 'changed.files'}) out.close('copy') if len(p.annotation_processors()) > 0: out.open('copy', {'todir' : '${src.ap-source-output.dir}'}) out.open('fileset', {'dir': '${cos.src.dir.internal}/../sources/'}) out.element('include', {'name': '**/*.java'}) out.close('fileset') out.close('copy') out.open('exec', {'executable' : '${ant.home}/bin/ant', 'spawn' : 'true'}) out.element('arg', {'value' : '-f'}) out.element('arg', {'value' : '${ant.file}'}) out.element('arg', {'value' : 'packagelater'}) out.close('exec') out.close('target') for d in dists: if d.isDistribution(): out.open('target', {'name' : 'checkpackage-' + d.name}) out.open('tstamp') out.element('format', {'pattern' : 'S', 'unit' : 'millisecond', 'property' : 'at.' + d.name}) out.close('tstamp') out.element('touch', {'file' : '${java.io.tmpdir}/' + d.name, 'millis' : '${at.' + d.name + '}0000'}) out.element('echo', {'message' : d.name + ' touched to ${at.' + d.name + '}0000${line.separator}', 'append' : 'true', 'output' : join(p.suite.get_output_root(), 'netbeans.log')}) out.element('sleep', {'seconds' : '3'}) out.open('condition', {'property' : 'mx.' + d.name, 'value' : sys.executable}) out.open('islastmodified', {'millis' : '${at.' + d.name + '}0000', 'mode' : 'equals'}) out.element('file', {'file' : '${java.io.tmpdir}/' + d.name}) out.close('islastmodified') out.close('condition') out.element('echo', {'message' : d.name + ' defined as ' + '${mx.' + d.name + '}${line.separator}', 'append' : 'true', 'output' : join(p.suite.get_output_root(), 'netbeans.log')}) out.close('target') out.open('target', {'name' : 'packagelater-' + d.name, 'depends' : 'checkpackage-' + d.name, 'if' : 'mx.' + d.name}) out.open('exec', {'executable' : '${mx.' + d.name + '}', 'failonerror' : 'true', 'dir' : execDir, 'output' : join(p.suite.get_output_root(), 'netbeans.log'), 'append' : 'true'}) out.element('env', {'key' : 'JAVA_HOME', 'value' : jdk.home}) out.element('arg', {'value' : os.path.abspath(__file__)}) out.element('arg', {'value' : 'build'}) out.element('arg', {'value' : '-f'}) out.element('arg', {'value' : '--only'}) out.element('arg', {'value' : d.name}) out.element('arg', {'value' : '--force-javac'}) out.element('arg', {'value' : '--no-native'}) out.element('arg', {'value' : '--no-daemon'}) out.close('exec') out.close('target') dependsOn = '' sep = '' for d in dists: dependsOn = dependsOn + sep + 'packagelater-' + d.name sep = ',' out.open('target', {'name' : 'packagelater', 'depends' : dependsOn}) out.close('target') out.open('target', {'name' : 'jar', 'depends' : 'compile'}) out.close('target') out.element('target', {'name' : 'test', 'depends' : 'run'}) out.element('target', {'name' : 'test-single', 'depends' : 'run'}) out.open('target', {'name' : 'run'}) out.element('property', {'name' : 'test.class', 'value' : p.name}) out.open('exec', {'executable' : sys.executable, 'failonerror' : 'true', 'dir' : execDir}) out.element('env', {'key' : 'JAVA_HOME', 'value' : jdk.home}) out.element('arg', {'value' : os.path.abspath(__file__)}) out.element('arg', {'value' : 'unittest'}) out.element('arg', {'value' : '${test.class}'}) out.close('exec') out.close('target') out.element('target', {'name' : 'debug-test', 'depends' : 'debug'}) out.open('target', {'name' : 'debug', 'depends' : '-mx-init'}) out.element('property', {'name' : 'test.class', 'value' : p.name}) out.open('nbjpdastart', {'addressproperty' : 'jpda.address', 'name' : p.name}) out.open('classpath') out.open('fileset', {'dir' : '..'}) out.element('include', {'name' : '*/bin/'}) out.close('fileset') out.close('classpath') out.open('sourcepath') out.element('pathelement', {'location' : 'src'}) out.close('sourcepath') out.close('nbjpdastart') out.open('exec', {'executable' : sys.executable, 'failonerror' : 'true', 'dir' : execDir}) out.element('env', {'key' : 'JAVA_HOME', 'value' : jdk.home}) out.element('arg', {'value' : os.path.abspath(__file__)}) out.element('arg', {'value' : '-d'}) out.element('arg', {'value' : '--attach'}) out.element('arg', {'value' : '${jpda.address}'}) out.element('arg', {'value' : 'unittest'}) out.element('arg', {'value' : '${test.class}'}) out.close('exec') out.close('target') out.open('target', {'name' : 'javadoc'}) out.open('exec', {'executable' : sys.executable, 'failonerror' : 'true', 'dir' : execDir}) out.element('env', {'key' : 'JAVA_HOME', 'value' : jdk.home}) out.element('arg', {'value' : os.path.abspath(__file__)}) out.element('arg', {'value' : 'javadoc'}) out.element('arg', {'value' : '--projects'}) out.element('arg', {'value' : p.name}) out.element('arg', {'value' : '--force'}) out.close('exec') out.element('nbbrowse', {'file' : 'javadoc/index.html'}) out.close('target') out.close('project') mx.update_file(join(nb_dir, 'build.xml'), out.xml(indent='\t', newl='\n')) if files is not None: files.append(join(nb_dir, 'build.xml')) out = mx.XMLDoc() out.open('project', {'xmlns' : 'http://www.netbeans.org/ns/project/1'}) out.element('type', data='org.netbeans.modules.java.j2seproject') out.open('configuration') out.open('data', {'xmlns' : 'http://www.netbeans.org/ns/j2se-project/3'}) out.element('name', data=p.name) out.element('explicit-platform', {'explicit-source-supported' : 'true'}) out.open('source-roots') out.element('root', {'id' : 'src.dir'}) if len(p.annotation_processors()) > 0: out.element('root', {'id' : 'src.ap-source-output.dir', 'name' : 'Generated Packages'}) out.close('source-roots') out.open('test-roots') out.close('test-roots') out.close('data') firstDep = [] def processDep(dep, edge): if dep is p: return if dep.isProject(): n = dep.name.replace('.', '_') if not firstDep: out.open('references', {'xmlns' : 'http://www.netbeans.org/ns/ant-project-references/1'}) firstDep.append(dep) out.open('reference') out.element('foreign-project', data=n) out.element('artifact-type', data='jar') out.element('script', data='build.xml') out.element('target', data='jar') out.element('clean-target', data='clean') out.element('id', data='jar') out.close('reference') #pylint: disable=too-many-function-args p.walk_deps(visit=processDep, ignoredEdges=[mx.DEP_EXCLUDED]) if firstDep: out.close('references') out.close('configuration') out.close('project') mx.update_file(join(nbproject_dir, 'project.xml'), out.xml(indent=' ', newl='\n')) if files is not None: files.append(join(nbproject_dir, 'project.xml')) out = StringIO() jdkPlatform = 'JDK_' + str(jdk.version) annotationProcessorEnabled = "false" annotationProcessorSrcFolder = "" annotationProcessorSrcFolderRef = "" if len(p.annotation_processors()) > 0: annotationProcessorEnabled = "true" mx.ensure_dir_exists(p.source_gen_dir()) annotationProcessorSrcFolder = os.path.relpath(p.source_gen_dir(), nb_dir) annotationProcessorSrcFolder = annotationProcessorSrcFolder.replace('\\', '\\\\') annotationProcessorSrcFolderRef = "src.ap-source-output.dir=" + annotationProcessorSrcFolder canSymlink = not (mx.is_windows() or mx.is_cygwin()) and 'symlink' in dir(os) if canSymlink: nbBuildDir = join(nbproject_dir, 'build') apSourceOutRef = "annotation.processing.source.output=" + annotationProcessorSrcFolder if os.path.lexists(nbBuildDir): os.unlink(nbBuildDir) os.symlink(p.output_dir(), nbBuildDir) else: nbBuildDir = p.output_dir() apSourceOutRef = "" mx.ensure_dir_exists(p.output_dir()) mx_ide_eclipse._copy_eclipse_settings(nb_dir, p) content = """ annotation.processing.enabled=""" + annotationProcessorEnabled + """ annotation.processing.enabled.in.editor=""" + annotationProcessorEnabled + """ """ + apSourceOutRef + """ annotation.processing.processors.list= annotation.processing.run.all.processors=true application.title=""" + p.name + """ application.vendor=mx auxiliary.de-markiewb-netbeans-plugins-eclipse-formatter.eclipseFormatterActiveProfile= auxiliary.de-markiewb-netbeans-plugins-eclipse-formatter.eclipseFormatterEnabled=true auxiliary.de-markiewb-netbeans-plugins-eclipse-formatter.eclipseFormatterLocation= auxiliary.de-markiewb-netbeans-plugins-eclipse-formatter.enableFormatAsSaveAction=true auxiliary.de-markiewb-netbeans-plugins-eclipse-formatter.linefeed= auxiliary.de-markiewb-netbeans-plugins-eclipse-formatter.preserveBreakPoints=true auxiliary.de-markiewb-netbeans-plugins-eclipse-formatter.SaveActionModifiedLinesOnly=false auxiliary.de-markiewb-netbeans-plugins-eclipse-formatter.showNotifications=false auxiliary.de-markiewb-netbeans-plugins-eclipse-formatter.sourcelevel= auxiliary.de-markiewb-netbeans-plugins-eclipse-formatter.useProjectPref=true auxiliary.de-markiewb-netbeans-plugins-eclipse-formatter.useProjectSettings=true auxiliary.de-markiewb-netbeans-plugins-eclipse-formatter.eclipseFormatterActiveProfile= auxiliary.org-netbeans-spi-editor-hints-projects.perProjectHintSettingsEnabled=true auxiliary.org-netbeans-spi-editor-hints-projects.perProjectHintSettingsFile=nbproject/cfg_hints.xml build.classes.dir=${build.dir} build.classes.excludes=**/*.java,**/*.form # This directory is removed when the project is cleaned: build.dir=""" + nbBuildDir + """ $cos.update=package $cos.update.resources=changed.files compile.on.save=true build.generated.sources.dir=${build.dir}/generated-sources # Only compile against the classpath explicitly listed here: build.sysclasspath=ignore build.test.classes.dir=${build.dir}/test/classes build.test.results.dir=${build.dir}/test/results # Uncomment to specify the preferred debugger connection transport: #debug.transport=dt_socket debug.classpath=\\ ${run.classpath} debug.test.classpath=\\ ${run.test.classpath} # This directory is removed when the project is cleaned: dist.dir=dist dist.jar=${dist.dir}/""" + p.name + """.jar dist.javadoc.dir=${dist.dir}/javadoc endorsed.classpath= excludes= includes=** jar.compress=false java.main.action=test # Space-separated list of extra javac options javac.compilerargs=-XDignore.symbol.file javac.deprecation=false javac.source=""" + str(p.javaCompliance) + """ javac.target=""" + str(p.javaCompliance) + """ javac.test.classpath=\\ ${javac.classpath}:\\ ${build.classes.dir} javadoc.additionalparam= javadoc.author=false javadoc.encoding=${source.encoding} javadoc.noindex=false javadoc.nonavbar=false javadoc.notree=false javadoc.private=false javadoc.splitindex=true javadoc.use=true javadoc.version=false javadoc.windowtitle= manifest.file=manifest.mf meta.inf.dir=${src.dir}/META-INF mkdist.disabled=false platforms.""" + jdkPlatform + """.home=""" + jdk.home + """ platform.active=""" + jdkPlatform + """ run.classpath=\\ ${javac.classpath}:\\ ${build.classes.dir} # Space-separated list of JVM arguments used when running the project # (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value # or test-sys-prop.name=value to set system properties for unit tests): run.jvmargs= run.test.classpath=\\ ${javac.test.classpath}:\\ ${build.test.classes.dir} test.src.dir=./test """ + annotationProcessorSrcFolderRef + """ source.encoding=UTF-8""".replace(':', os.pathsep).replace('/', os.sep) print(content, file=out) # Workaround for NetBeans "too clever" behavior. If you want to be # able to press F6 or Ctrl-F5 in NetBeans and run/debug unit tests # then the project must have its main.class property set to an # existing class with a properly defined main method. Until this # behavior is remedied, we specify a well known Truffle class # that will be on the class path for most Truffle projects. # This can be overridden by defining a netbeans.project.properties # attribute for a project in suite.py (see below). print("main.class=com.oracle.truffle.api.impl.Accessor", file=out) # Add extra properties specified in suite.py for this project if hasattr(p, 'netbeans.project.properties'): properties = getattr(p, 'netbeans.project.properties') for prop in [properties] if isinstance(properties, str) else properties: print(prop, file=out) mainSrc = True for src in p.srcDirs: srcDir = mx.ensure_dir_exists(join(p.dir, src)) ref = 'file.reference.' + p.name + '-' + src print(ref + '=' + os.path.relpath(srcDir, nb_dir), file=out) if mainSrc: print('src.dir=${' + ref + '}', file=out) mainSrc = False else: print('src.' + src + '.dir=${' + ref + '}', file=out) javacClasspath = [] def newDepsCollector(into): return lambda dep, edge: into.append(dep) if dep.isLibrary() or dep.isJdkLibrary() or dep.isProject() or dep.isClasspathDependency() else None deps = [] p.walk_deps(visit=newDepsCollector(deps)) annotationProcessorOnlyDeps = [] if len(p.annotation_processors()) > 0: for apDep in p.annotation_processors(): resolvedApDeps = [] apDep.walk_deps(visit=newDepsCollector(resolvedApDeps)) for resolvedApDep in resolvedApDeps: if not resolvedApDep in deps: deps.append(resolvedApDep) annotationProcessorOnlyDeps.append(resolvedApDep) annotationProcessorReferences = [] for dep in deps: if dep == p: continue if dep.isLibrary() or dep.isJdkLibrary(): if dep.isLibrary(): path = dep.get_path(resolve=True) sourcePath = dep.get_source_path(resolve=True) else: path = dep.classpath_repr(jdk, resolve=True) sourcePath = dep.get_source_path(jdk) if path: if os.sep == '\\': path = path.replace('\\', '\\\\') ref = 'file.reference.' + dep.name + '-bin' print(ref + '=' + path, file=out) if libFiles: libFiles.append(path) if sourcePath: if os.sep == '\\': sourcePath = sourcePath.replace('\\', '\\\\') print('source.reference.' + dep.name + '-bin=' + sourcePath, file=out) elif dep.isMavenProject(): path = dep.get_path(resolve=False) if path: if os.sep == '\\': path = path.replace('\\', '\\\\') ref = 'file.reference.' + dep.name + '-bin' print(ref + '=' + path, file=out) elif dep.isProject(): n = dep.name.replace('.', '_') relDepPath = os.path.relpath(dep.dir, nb_dir).replace(os.sep, '/') if canSymlink: depBuildPath = join('nbproject', 'build') else: depBuildPath = 'dist/' + dep.name + '.jar' ref = 'reference.' + n + '.jar' print('project.' + n + '=' + relDepPath, file=out) print(ref + '=${project.' + n + '}/' + depBuildPath, file=out) elif dep.isJreLibrary(): continue elif dep.isClasspathDependency(): extra = [di for di in dep.deps if di not in deps] if dep.isDistribution() and dep.deps and not extra: # ignore distribution classpath dependencies that only contain other explicit depedencies continue path = dep.classpath_repr(resolve=True) sourcePath = dep.get_source_path(jdk) if hasattr(dep, 'get_source_path') else None if path: if os.sep == '\\': path = path.replace('\\', '\\\\') ref = 'file.reference.' + dep.name + '-bin' print(ref + '=' + path, file=out) if libFiles: libFiles.append(path) if sourcePath: if os.sep == '\\': sourcePath = sourcePath.replace('\\', '\\\\') print('source.reference.' + dep.name + '-bin=' + sourcePath, file=out) if not dep in annotationProcessorOnlyDeps: javacClasspath.append('${' + ref + '}') else: annotationProcessorReferences.append('${' + ref + '}') print('javac.classpath=\\\n ' + (os.pathsep + '\\\n ').join(javacClasspath), file=out) print('javac.processorpath=' + (os.pathsep + '\\\n ').join(['${javac.classpath}'] + annotationProcessorReferences), file=out) print('javac.test.processorpath=' + (os.pathsep + '\\\n ').join(['${javac.test.classpath}'] + annotationProcessorReferences), file=out) mx.update_file(join(nbproject_dir, 'project.properties'), out.getvalue()) out.close() if files is not None: files.append(join(nbproject_dir, 'project.properties')) for source in p.suite.netbeans_settings_sources().get('cfg_hints.xml'): with open(source) as fp: content = fp.read() mx.update_file(join(nbproject_dir, 'cfg_hints.xml'), content) if files is not None: files.append(join(p.dir, 'nbproject', 'cfg_hints.xml'))
def findbugs(args, fbArgs=None, suite=None, projects=None): """run FindBugs against non-test Java projects""" findBugsHome = mx.get_env('FINDBUGS_HOME', None) if suite is None: suite = mx.primary_suite() if findBugsHome: findbugsJar = join(findBugsHome, 'lib', 'findbugs.jar') else: findbugsLib = join(mx._mx_suite.get_output_root(), 'findbugs-3.0.0') if not exists(findbugsLib): tmp = tempfile.mkdtemp(prefix='findbugs-download-tmp', dir=mx._mx_suite.dir) try: findbugsDist = mx.library('FINDBUGS_DIST').get_path(resolve=True) with zipfile.ZipFile(findbugsDist) as zf: candidates = [e for e in zf.namelist() if e.endswith('/lib/findbugs.jar')] assert len(candidates) == 1, candidates libDirInZip = os.path.dirname(candidates[0]) zf.extractall(tmp) shutil.copytree(join(tmp, libDirInZip), findbugsLib) finally: shutil.rmtree(tmp) findbugsJar = join(findbugsLib, 'findbugs.jar') assert exists(findbugsJar) projectsToTest = [p for p in mx.projects() if _should_test_project(p)] if not projectsToTest: return 0 ignoredClasses = set() for p in projectsToTest: ignore = getattr(p, 'findbugsIgnoresGenerated', False) if not isinstance(ignore, bool): mx.abort('Value of attribute "findbugsIgnoresGenerated" must be True or False', context=p) if ignore is True: sourceDir = p.source_gen_dir() for root, _, files in os.walk(sourceDir): for name in files: if name.endswith('.java') and '-info' not in name: pkg = root[len(sourceDir) + 1:].replace(os.sep, '.') cls = pkg + '.' + name[:-len('.java')] ignoredClasses.add(cls) with tempfile.NamedTemporaryFile(suffix='.xml', prefix='findbugs_exclude_filter.', mode='w', delete=False) as fp: findbugsExcludeFilterFile = fp.name xmlDoc = mx.XMLDoc() xmlDoc.open('FindBugsFilter') # Javac from JDK11 might have been used to compile the classes so # disable the check for redundant null tests since FindBugs does # not (yet) detect and suppress warnings about patterns generated by # this version of javac. This will be removed once # https://github.com/spotbugs/spotbugs/issues/600 is resolved. xmlDoc.open('Match') xmlDoc.element('Bug', attributes={'pattern' : 'RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE'}) xmlDoc.close('Match') for cls in ignoredClasses: xmlDoc.open('Match') xmlDoc.element('Class', attributes={'name' : '~' + cls + '.*'}) xmlDoc.close('Match') xmlDoc.close('FindBugsFilter') xml = xmlDoc.xml(indent=' ', newl='\n') print >> fp, xml outputDirs = map(mx._cygpathU2W, [p.output_dir() for p in projectsToTest]) javaCompliance = max([p.javaCompliance for p in projectsToTest]) jdk = mx.get_jdk(javaCompliance) if jdk.javaCompliance >= '9': mx.log('FindBugs does not yet support JDK9 - skipping') return 0 findbugsResults = join(suite.dir, 'findbugs.results') if fbArgs is None: fbArgs = defaultFindbugsArgs() cmd = ['-jar', mx._cygpathU2W(findbugsJar)] + fbArgs cmd = cmd + ['-exclude', findbugsExcludeFilterFile] cmd = cmd + ['-auxclasspath', mx._separatedCygpathU2W(mx.classpath([p.name for p in projectsToTest], jdk=jdk)), '-output', mx._cygpathU2W(findbugsResults), '-exitcode'] + args + outputDirs try: exitcode = mx.run_java(cmd, nonZeroIsFatal=False, jdk=jdk) finally: os.unlink(findbugsExcludeFilterFile) if exitcode != 0: with open(findbugsResults) as fp: mx.log(fp.read()) os.unlink(findbugsResults) return exitcode
def _intellij_external_project(externalProjects, sdks, host): if externalProjects: for project_name, project_definition in externalProjects.items(): if not project_definition.get('path', None): mx.abort("external project {} is missing path attribute".format(project_name)) if not project_definition.get('type', None): mx.abort("external project {} is missing type attribute".format(project_name)) supported = ['path', 'type', 'source', 'test', 'excluded', 'load_path'] unknown = set(project_definition.keys()) - frozenset(supported) if unknown: mx.abort("There are unsupported {} keys in {} external project".format(unknown, project_name)) path = os.path.realpath(join(host.dir, project_definition["path"])) module_type = project_definition["type"] moduleXml = mx.XMLDoc() moduleXml.open('module', attributes={'type': {'ruby': 'RUBY_MODULE', 'python': 'PYTHON_MODULE', 'web': 'WEB_MODULE'}.get(module_type, 'UKNOWN_MODULE'), 'version': '4'}) moduleXml.open('component', attributes={'name': 'NewModuleRootManager', 'inherit-compiler-output': 'true'}) moduleXml.element('exclude-output') moduleXml.open('content', attributes={'url': 'file://$MODULE_DIR$'}) for name in project_definition.get('source', []): moduleXml.element('sourceFolder', attributes={'url':'file://$MODULE_DIR$/' + name, 'isTestSource': str(False)}) for name in project_definition.get('test', []): moduleXml.element('sourceFolder', attributes={'url':'file://$MODULE_DIR$/' + name, 'isTestSource': str(True)}) for name in project_definition.get('excluded', []): _intellij_exclude_if_exists(moduleXml, type('', (object,), {"dir": path})(), name) moduleXml.close('content') if module_type == "ruby": moduleXml.element('orderEntry', attributes={'type': 'jdk', 'jdkType': intellij_ruby_sdk_type, 'jdkName': intellij_get_ruby_sdk_name(sdks)}) elif module_type == "python": moduleXml.element('orderEntry', attributes={'type': 'jdk', 'jdkType': intellij_python_sdk_type, 'jdkName': intellij_get_python_sdk_name(sdks)}) elif module_type == "web": # nothing to do pass else: mx.abort("External project type {} not supported".format(module_type)) moduleXml.element('orderEntry', attributes={'type': 'sourceFolder', 'forTests': 'false'}) moduleXml.close('component') load_paths = project_definition.get('load_path', []) if load_paths: if not module_type == "ruby": mx.abort("load_path is supported only for ruby type external project") moduleXml.open('component', attributes={'name': 'RModuleSettingsStorage'}) load_paths_attributes = {} load_paths_attributes['number'] = str(len(load_paths)) for i, name in enumerate(load_paths): load_paths_attributes["string" + str(i)] = "$MODULE_DIR$/" + name moduleXml.element('LOAD_PATH', load_paths_attributes) moduleXml.close('component') moduleXml.close('module') moduleFile = join(path, project_name + '.iml') mx.update_file(moduleFile, moduleXml.xml(indent=' ', newl='\n')) if not module_files_only: declared_modules.add(project_name) moduleFilePath = "$PROJECT_DIR$/" + os.path.relpath(moduleFile, s.dir) modulesXml.element('module', attributes={'fileurl': 'file://' + moduleFilePath, 'filepath': moduleFilePath})
def _intellij_suite(args, s, declared_modules, referenced_modules, sdks, refreshOnly=False, mx_python_modules=False, generate_external_projects=True, java_modules=True, module_files_only=False, generate_native_projects=False): libraries = set() jdk_libraries = set() project_dir = s.dir ideaProjectDirectory = join(project_dir, '.idea') modulesXml = mx.XMLDoc() if not module_files_only and not s.isBinarySuite(): mx.ensure_dir_exists(ideaProjectDirectory) nameFile = join(ideaProjectDirectory, '.name') mx.update_file(nameFile, s.name) modulesXml.open('project', attributes={'version': '4'}) modulesXml.open('component', attributes={'name': 'ProjectModuleManager'}) modulesXml.open('modules') def _intellij_exclude_if_exists(xml, p, name, output=False): root = p.get_output_root() if output else p.dir path = join(root, name) if exists(path): excludeRoot = p.get_output_root() if output else '$MODULE_DIR$' excludePath = join(excludeRoot, name) xml.element('excludeFolder', attributes={'url':'file://' + excludePath}) annotationProcessorProfiles = {} def _complianceToIntellijLanguageLevel(compliance): # they changed the name format starting with JDK_10 if compliance.value >= 10: # Lastest Idea 2018.2 only understands JDK_11 so clamp at that value return 'JDK_' + str(min(compliance.value, 11)) return 'JDK_1_' + str(compliance.value) def _intellij_external_project(externalProjects, sdks, host): if externalProjects: for project_name, project_definition in externalProjects.items(): if not project_definition.get('path', None): mx.abort("external project {} is missing path attribute".format(project_name)) if not project_definition.get('type', None): mx.abort("external project {} is missing type attribute".format(project_name)) supported = ['path', 'type', 'source', 'test', 'excluded', 'load_path'] unknown = set(project_definition.keys()) - frozenset(supported) if unknown: mx.abort("There are unsupported {} keys in {} external project".format(unknown, project_name)) path = os.path.realpath(join(host.dir, project_definition["path"])) module_type = project_definition["type"] moduleXml = mx.XMLDoc() moduleXml.open('module', attributes={'type': {'ruby': 'RUBY_MODULE', 'python': 'PYTHON_MODULE', 'web': 'WEB_MODULE'}.get(module_type, 'UKNOWN_MODULE'), 'version': '4'}) moduleXml.open('component', attributes={'name': 'NewModuleRootManager', 'inherit-compiler-output': 'true'}) moduleXml.element('exclude-output') moduleXml.open('content', attributes={'url': 'file://$MODULE_DIR$'}) for name in project_definition.get('source', []): moduleXml.element('sourceFolder', attributes={'url':'file://$MODULE_DIR$/' + name, 'isTestSource': str(False)}) for name in project_definition.get('test', []): moduleXml.element('sourceFolder', attributes={'url':'file://$MODULE_DIR$/' + name, 'isTestSource': str(True)}) for name in project_definition.get('excluded', []): _intellij_exclude_if_exists(moduleXml, type('', (object,), {"dir": path})(), name) moduleXml.close('content') if module_type == "ruby": moduleXml.element('orderEntry', attributes={'type': 'jdk', 'jdkType': intellij_ruby_sdk_type, 'jdkName': intellij_get_ruby_sdk_name(sdks)}) elif module_type == "python": moduleXml.element('orderEntry', attributes={'type': 'jdk', 'jdkType': intellij_python_sdk_type, 'jdkName': intellij_get_python_sdk_name(sdks)}) elif module_type == "web": # nothing to do pass else: mx.abort("External project type {} not supported".format(module_type)) moduleXml.element('orderEntry', attributes={'type': 'sourceFolder', 'forTests': 'false'}) moduleXml.close('component') load_paths = project_definition.get('load_path', []) if load_paths: if not module_type == "ruby": mx.abort("load_path is supported only for ruby type external project") moduleXml.open('component', attributes={'name': 'RModuleSettingsStorage'}) load_paths_attributes = {} load_paths_attributes['number'] = str(len(load_paths)) for i, name in enumerate(load_paths): load_paths_attributes["string" + str(i)] = "$MODULE_DIR$/" + name moduleXml.element('LOAD_PATH', load_paths_attributes) moduleXml.close('component') moduleXml.close('module') moduleFile = join(path, project_name + '.iml') mx.update_file(moduleFile, moduleXml.xml(indent=' ', newl='\n')) if not module_files_only: declared_modules.add(project_name) moduleFilePath = "$PROJECT_DIR$/" + os.path.relpath(moduleFile, s.dir) modulesXml.element('module', attributes={'fileurl': 'file://' + moduleFilePath, 'filepath': moduleFilePath}) if generate_external_projects: for p in s.projects_recursive() + mx._mx_suite.projects_recursive(): _intellij_external_project(getattr(p, 'externalProjects', None), sdks, p) max_checkstyle_version = None compilerXml = None if java_modules: if not module_files_only: compilerXml = mx.XMLDoc() compilerXml.open('project', attributes={'version': '4'}) # The IntelliJ parser seems to mishandle empty ADDITIONAL_OPTIONS_OVERRIDE elements # so only emit the section if there will be something in it. additionalOptionsOverrides = False assert not s.isBinarySuite() # create the modules (1 IntelliJ module = 1 mx project/distribution) for p in s.projects_recursive() + mx._mx_suite.projects_recursive(): if not p.isJavaProject(): continue jdk = mx.get_jdk(p.javaCompliance) assert jdk # Value of the $MODULE_DIR$ IntelliJ variable and parent directory of the .iml file. module_dir = mx.ensure_dir_exists(p.dir) processors = p.annotation_processors() if processors: annotationProcessorProfiles.setdefault((p.source_gen_dir_name(),) + tuple(processors), []).append(p) intellijLanguageLevel = _complianceToIntellijLanguageLevel(p.javaCompliance) moduleXml = mx.XMLDoc() moduleXml.open('module', attributes={'type': 'JAVA_MODULE', 'version': '4'}) moduleXml.open('component', attributes={'name': 'NewModuleRootManager', 'LANGUAGE_LEVEL': intellijLanguageLevel, 'inherit-compiler-output': 'false'}) moduleXml.element('output', attributes={'url': 'file://$MODULE_DIR$/' + os.path.relpath(p.output_dir(), module_dir)}) moduleXml.open('content', attributes={'url': 'file://$MODULE_DIR$'}) for src in p.srcDirs: srcDir = mx.ensure_dir_exists(join(p.dir, src)) moduleXml.element('sourceFolder', attributes={'url':'file://$MODULE_DIR$/' + os.path.relpath(srcDir, module_dir), 'isTestSource': str(p.is_test_project())}) for name in ['.externalToolBuilders', '.settings', 'nbproject']: _intellij_exclude_if_exists(moduleXml, p, name) moduleXml.close('content') if processors: moduleXml.open('content', attributes={'url': 'file://' + p.get_output_root()}) genDir = p.source_gen_dir() mx.ensure_dir_exists(genDir) moduleXml.element('sourceFolder', attributes={'url':'file://' + p.source_gen_dir(), 'isTestSource': str(p.is_test_project()), 'generated': 'true'}) for name in [basename(p.output_dir())]: _intellij_exclude_if_exists(moduleXml, p, name, output=True) moduleXml.close('content') moduleXml.element('orderEntry', attributes={'type': 'sourceFolder', 'forTests': 'false'}) proj = p dependencies_project_packages = set() def should_process_dep(dep, edge): if dep.isTARDistribution() or dep.isNativeProject() or dep.isArchivableProject() or dep.isResourceLibrary(): mx.logv("Ignoring dependency from {} to {}".format(proj.name, dep.name)) return False return True def process_dep(dep, edge): if dep is proj: return if dep.isLibrary() or dep.isJARDistribution() or dep.isMavenProject(): libraries.add(dep) moduleXml.element('orderEntry', attributes={'type': 'library', 'name': dep.name, 'level': 'project'}) elif dep.isJavaProject(): dependencies_project_packages.update(dep.defined_java_packages()) referenced_modules.add(dep.name) moduleXml.element('orderEntry', attributes={'type': 'module', 'module-name': dep.name}) elif dep.isJdkLibrary(): jdk_libraries.add(dep) if jdk.javaCompliance < dep.jdkStandardizedSince: moduleXml.element('orderEntry', attributes={'type': 'library', 'name': dep.name, 'level': 'project'}) else: mx.logv("{} skipping {} for {}".format(p, dep, jdk)) #pylint: disable=undefined-loop-variable elif dep.isJreLibrary(): pass elif dep.isClasspathDependency(): moduleXml.element('orderEntry', attributes={'type': 'library', 'name': dep.name, 'level': 'project'}) else: mx.abort("Dependency not supported: {0} ({1})".format(dep, dep.__class__.__name__)) p.walk_deps(preVisit=should_process_dep, visit=process_dep, ignoredEdges=[mx.DEP_EXCLUDED]) moduleXml.element('orderEntry', attributes={'type': 'jdk', 'jdkType': intellij_java_sdk_type, 'jdkName': intellij_get_java_sdk_name(sdks, jdk)}) moduleXml.close('component') if compilerXml and jdk.javaCompliance >= '9': moduleDeps = p.get_concealed_imported_packages(jdk=jdk) if moduleDeps: exports = sorted([(m, pkgs) for m, pkgs in moduleDeps.items() if dependencies_project_packages.isdisjoint(pkgs)]) if exports: args = [] exported_modules = set() for m, pkgs in exports: args += ['--add-exports={}/{}=ALL-UNNAMED'.format(m, pkg) for pkg in pkgs] exported_modules.add(m) roots = set(jdk.get_root_modules()) observable_modules = jdk.get_modules() default_module_graph = mx_javamodules.get_transitive_closure(roots, observable_modules) module_graph = mx_javamodules.get_transitive_closure(roots | exported_modules, observable_modules) extra_modules = module_graph - default_module_graph if extra_modules: args.append('--add-modules=' + ','.join((m.name for m in extra_modules))) if not additionalOptionsOverrides: additionalOptionsOverrides = True compilerXml.open('component', {'name': 'JavacSettings'}) compilerXml.open('option', {'name': 'ADDITIONAL_OPTIONS_OVERRIDE'}) compilerXml.element('module', {'name': p.name, 'options': ' '.join(args)}) # Checkstyle csConfig, checkstyleVersion, checkstyleProj = p.get_checkstyle_config() if csConfig: max_checkstyle_version = max(max_checkstyle_version, mx.VersionSpec(checkstyleVersion)) if max_checkstyle_version else mx.VersionSpec(checkstyleVersion) moduleXml.open('component', attributes={'name': 'CheckStyle-IDEA-Module'}) moduleXml.open('option', attributes={'name': 'configuration'}) moduleXml.open('map') moduleXml.element('entry', attributes={'key': "checkstyle-version", 'value': checkstyleVersion}) moduleXml.element('entry', attributes={'key': "active-configuration", 'value': "PROJECT_RELATIVE:" + join(checkstyleProj.dir, ".checkstyle_checks.xml") + ":" + checkstyleProj.name}) moduleXml.close('map') moduleXml.close('option') moduleXml.close('component') moduleXml.close('module') moduleFile = join(module_dir, p.name + '.iml') mx.update_file(moduleFile, moduleXml.xml(indent=' ', newl='\n').rstrip()) if not module_files_only: declared_modules.add(p.name) moduleFilePath = "$PROJECT_DIR$/" + os.path.relpath(moduleFile, project_dir) modulesXml.element('module', attributes={'fileurl': 'file://' + moduleFilePath, 'filepath': moduleFilePath}) if additionalOptionsOverrides: compilerXml.close('option') compilerXml.close('component') if mx_python_modules: def _python_module(suite): """ Gets a tuple describing the IntelliJ module for the python sources of `suite`. The tuple consists of the module name, module directory and the name of the .iml in the module directory. """ name = basename(suite.mxDir) module_dir = suite.mxDir return name, mx.ensure_dir_exists(module_dir), name + '.iml' def _add_declared_module(suite): if not module_files_only: name, module_dir, iml_file = _python_module(suite) declared_modules.add(name) moduleFilePath = "$PROJECT_DIR$/" + os.path.relpath(join(module_dir, iml_file), project_dir) modulesXml.element('module', attributes={'fileurl': 'file://' + moduleFilePath, 'filepath': moduleFilePath}) # mx.<suite> python module: _, module_dir, iml_file = _python_module(s) moduleXml = mx.XMLDoc() moduleXml.open('module', attributes={'type': 'PYTHON_MODULE', 'version': '4'}) moduleXml.open('component', attributes={'name': 'NewModuleRootManager', 'inherit-compiler-output': 'true'}) moduleXml.element('exclude-output') if s.name == 'mx': # MX itself is special. Python sources are also in the parent folder. moduleXml.open('content', attributes={'url': 'file://$MODULE_DIR$/..'}) moduleXml.element('sourceFolder', attributes={'url': 'file://$MODULE_DIR$/..', 'isTestSource': 'false'}) else: moduleXml.open('content', attributes={'url': 'file://$MODULE_DIR$'}) moduleXml.element('sourceFolder', attributes={'url': 'file://$MODULE_DIR$/' + os.path.relpath(s.mxDir, module_dir), 'isTestSource': 'false'}) for d in os.listdir(s.mxDir): directory = join(s.mxDir, d) if isdir(directory) and mx.dir_contains_files_recursively(directory, r".*\.java"): moduleXml.element('excludeFolder', attributes={'url': 'file://$MODULE_DIR$/' + os.path.relpath(directory, module_dir)}) moduleXml.close('content') moduleXml.element('orderEntry', attributes={'type': 'jdk', 'jdkType': intellij_python_sdk_type, 'jdkName': intellij_get_python_sdk_name(sdks)}) moduleXml.element('orderEntry', attributes={'type': 'sourceFolder', 'forTests': 'false'}) processed_suites = {s.name} def _mx_projects_suite(visited_suite, suite_import): if suite_import.name in processed_suites: return processed_suites.add(suite_import.name) dep_suite = mx.suite(suite_import.name) dep_module_name, _, _ = _python_module(dep_suite) moduleXml.element('orderEntry', attributes={'type': 'module', 'module-name': dep_module_name}) _add_declared_module(dep_suite) dep_suite.visit_imports(_mx_projects_suite) s.visit_imports(_mx_projects_suite) if s.name != 'mx': moduleXml.element('orderEntry', attributes={'type': 'module', 'module-name': 'mx.mx'}) moduleXml.close('component') moduleXml.close('module') moduleFile = join(module_dir, iml_file) mx.update_file(moduleFile, moduleXml.xml(indent=' ', newl='\n')) _add_declared_module(s) _add_declared_module(mx._mx_suite) if generate_native_projects: _intellij_native_projects(s, module_files_only, declared_modules, modulesXml) if generate_external_projects: _intellij_external_project(s.suiteDict.get('externalProjects', None), sdks, s) if not module_files_only: modulesXml.close('modules') modulesXml.close('component') modulesXml.close('project') moduleXmlFile = join(ideaProjectDirectory, 'modules.xml') mx.update_file(moduleXmlFile, modulesXml.xml(indent=' ', newl='\n')) if java_modules and not module_files_only: unique_library_file_names = set() librariesDirectory = mx.ensure_dir_exists(join(ideaProjectDirectory, 'libraries')) mx.ensure_dir_exists(librariesDirectory) def make_library(name, path, source_path, suite_dir): libraryXml = mx.XMLDoc() libraryXml.open('component', attributes={'name': 'libraryTable'}) libraryXml.open('library', attributes={'name': name}) libraryXml.open('CLASSES') pathX = mx.relpath_or_absolute(path, suite_dir, prefix='$PROJECT_DIR$') libraryXml.element('root', attributes={'url': 'jar://' + pathX + '!/'}) libraryXml.close('CLASSES') libraryXml.element('JAVADOC') if sourcePath: libraryXml.open('SOURCES') if os.path.isdir(sourcePath): sourcePathX = mx.relpath_or_absolute(sourcePath, suite_dir, prefix='$PROJECT_DIR$') libraryXml.element('root', attributes={'url': 'file://' + sourcePathX}) else: source_pathX = mx.relpath_or_absolute(source_path, suite_dir, prefix='$PROJECT_DIR$') libraryXml.element('root', attributes={'url': 'jar://' + source_pathX + '!/'}) libraryXml.close('SOURCES') else: libraryXml.element('SOURCES') libraryXml.close('library') libraryXml.close('component') libraryFile = join(librariesDirectory, _intellij_library_file_name(name, unique_library_file_names)) return mx.update_file(libraryFile, libraryXml.xml(indent=' ', newl='\n')) # Setup the libraries that were used above for library in libraries: sourcePath = None if library.isLibrary(): path = library.get_path(True) if library.sourcePath: sourcePath = library.get_source_path(True) elif library.isMavenProject(): path = library.get_path(True) sourcePath = library.get_source_path(True) elif library.isJARDistribution(): path = library.path if library.sourcesPath: sourcePath = library.sourcesPath elif library.isClasspathDependency(): path = library.classpath_repr() else: mx.abort('Dependency not supported: {} ({})'.format(library.name, library.__class__.__name__)) make_library(library.name, path, sourcePath, s.dir) jdk = mx.get_jdk() updated = False for library in jdk_libraries: if library.classpath_repr(jdk) is not None: if make_library(library.name, library.classpath_repr(jdk), library.get_source_path(jdk), s.dir): updated = True if jdk_libraries and updated: mx.log("Setting up JDK libraries using {0}".format(jdk)) # Set annotation processor profiles up, and link them to modules in compiler.xml compilerXml.open('component', attributes={'name': 'CompilerConfiguration'}) compilerXml.element('option', attributes={'name': "DEFAULT_COMPILER", 'value': 'Javac'}) # using the --release option with javac interferes with using --add-modules which is required for some projects compilerXml.element('option', attributes={'name': "USE_RELEASE_OPTION", 'value': 'false'}) compilerXml.element('resourceExtensions') compilerXml.open('wildcardResourcePatterns') compilerXml.element('entry', attributes={'name': '!?*.java'}) compilerXml.close('wildcardResourcePatterns') if annotationProcessorProfiles: compilerXml.open('annotationProcessing') for t, modules in sorted(annotationProcessorProfiles.items()): source_gen_dir = t[0] processors = t[1:] compilerXml.open('profile', attributes={'default': 'false', 'name': '-'.join([ap.name for ap in processors]) + "-" + source_gen_dir, 'enabled': 'true'}) compilerXml.element('sourceOutputDir', attributes={'name': join(os.pardir, source_gen_dir)}) compilerXml.element('sourceTestOutputDir', attributes={'name': join(os.pardir, source_gen_dir)}) compilerXml.open('processorPath', attributes={'useClasspath': 'false'}) # IntelliJ supports both directories and jars on the annotation processor path whereas # Eclipse only supports jars. for apDep in processors: def processApDep(dep, edge): if dep.isLibrary() or dep.isJARDistribution(): compilerXml.element('entry', attributes={'name': mx.relpath_or_absolute(dep.path, s.dir, prefix='$PROJECT_DIR$')}) elif dep.isProject(): compilerXml.element('entry', attributes={'name': mx.relpath_or_absolute(dep.output_dir(), s.dir, prefix='$PROJECT_DIR$')}) apDep.walk_deps(visit=processApDep) compilerXml.close('processorPath') for module in modules: compilerXml.element('module', attributes={'name': module.name}) compilerXml.close('profile') compilerXml.close('annotationProcessing') compilerXml.close('component') if compilerXml: compilerXml.close('project') compilerFile = join(ideaProjectDirectory, 'compiler.xml') mx.update_file(compilerFile, compilerXml.xml(indent=' ', newl='\n')) if not module_files_only: # Write misc.xml for global JDK config miscXml = mx.XMLDoc() miscXml.open('project', attributes={'version' : '4'}) if java_modules: mainJdk = mx.get_jdk() miscXml.open('component', attributes={'name' : 'ProjectRootManager', 'version': '2', 'languageLevel': _complianceToIntellijLanguageLevel(mainJdk.javaCompliance), 'project-jdk-name': intellij_get_java_sdk_name(sdks, mainJdk), 'project-jdk-type': intellij_java_sdk_type}) miscXml.element('output', attributes={'url' : 'file://$PROJECT_DIR$/' + os.path.relpath(s.get_output_root(), s.dir)}) miscXml.close('component') else: miscXml.element('component', attributes={'name' : 'ProjectRootManager', 'version': '2', 'project-jdk-name': intellij_get_python_sdk_name(sdks), 'project-jdk-type': intellij_python_sdk_type}) miscXml.close('project') miscFile = join(ideaProjectDirectory, 'misc.xml') mx.update_file(miscFile, miscXml.xml(indent=' ', newl='\n')) # Generate a default configuration for debugging Graal runConfig = mx.XMLDoc() runConfig.open('component', attributes={'name' : 'ProjectRunConfigurationManager'}) runConfig.open('configuration', attributes={'default' :'false', 'name' : 'GraalDebug', 'type' : 'Remote', 'factoryName': 'Remote'}) runConfig.element('option', attributes={'name' : 'USE_SOCKET_TRANSPORT', 'value' : 'true'}) runConfig.element('option', attributes={'name' : 'SERVER_MODE', 'value' : 'false'}) runConfig.element('option', attributes={'name' : 'SHMEM_ADDRESS', 'value' : 'javadebug'}) runConfig.element('option', attributes={'name' : 'HOST', 'value' : 'localhost'}) runConfig.element('option', attributes={'name' : 'PORT', 'value' : '8000'}) runConfig.open('RunnerSettings', attributes={'RunnerId' : 'Debug'}) runConfig.element('option', attributes={'name' : 'DEBUG_PORT', 'value' : '8000'}) runConfig.element('option', attributes={'name' : 'LOCAL', 'value' : 'false'}) runConfig.close('RunnerSettings') runConfig.element('method') runConfig.close('configuration') runConfig.close('component') runConfigFile = join(ideaProjectDirectory, 'runConfigurations', 'GraalDebug.xml') mx.ensure_dir_exists(join(ideaProjectDirectory, 'runConfigurations')) mx.update_file(runConfigFile, runConfig.xml(indent=' ', newl='\n')) if java_modules: # Eclipse formatter config corePrefsSources = s.eclipse_settings_sources().get('org.eclipse.jdt.core.prefs') uiPrefsSources = s.eclipse_settings_sources().get('org.eclipse.jdt.ui.prefs') if corePrefsSources: miscXml = mx.XMLDoc() miscXml.open('project', attributes={'version' : '4'}) out = StringIO() print('# GENERATED -- DO NOT EDIT', file=out) for source in corePrefsSources: print('# Source:', source, file=out) with open(source) as fileName: for line in fileName: if line.startswith('org.eclipse.jdt.core.formatter.'): print(line.strip(), file=out) formatterConfigFile = join(ideaProjectDirectory, 'EclipseCodeFormatter.prefs') mx.update_file(formatterConfigFile, out.getvalue()) importConfigFile = None if uiPrefsSources: out = StringIO() print('# GENERATED -- DO NOT EDIT', file=out) for source in uiPrefsSources: print('# Source:', source, file=out) with open(source) as fileName: for line in fileName: if line.startswith('org.eclipse.jdt.ui.importorder') \ or line.startswith('org.eclipse.jdt.ui.ondemandthreshold') \ or line.startswith('org.eclipse.jdt.ui.staticondemandthreshold'): print(line.strip(), file=out) importConfigFile = join(ideaProjectDirectory, 'EclipseImports.prefs') mx.update_file(importConfigFile, out.getvalue()) miscXml.open('component', attributes={'name' : 'EclipseCodeFormatterProjectSettings'}) miscXml.open('option', attributes={'name' : 'projectSpecificProfile'}) miscXml.open('ProjectSpecificProfile') miscXml.element('option', attributes={'name' : 'formatter', 'value' : 'ECLIPSE'}) custom_eclipse_exe = mx.get_env('ECLIPSE_EXE') if custom_eclipse_exe: custom_eclipse = dirname(custom_eclipse_exe) if mx.is_darwin(): custom_eclipse = join(dirname(custom_eclipse), 'Eclipse') if not exists(custom_eclipse_exe): mx.abort('Custom eclipse "{}" does not exist'.format(custom_eclipse_exe)) miscXml.element('option', attributes={'name' : 'eclipseVersion', 'value' : 'CUSTOM'}) miscXml.element('option', attributes={'name' : 'pathToEclipse', 'value' : custom_eclipse}) miscXml.element('option', attributes={'name' : 'pathToConfigFileJava', 'value' : '$PROJECT_DIR$/.idea/' + basename(formatterConfigFile)}) if importConfigFile: miscXml.element('option', attributes={'name' : 'importOrderConfigFilePath', 'value' : '$PROJECT_DIR$/.idea/' + basename(importConfigFile)}) miscXml.element('option', attributes={'name' : 'importOrderFromFile', 'value' : 'true'}) miscXml.close('ProjectSpecificProfile') miscXml.close('option') miscXml.close('component') miscXml.close('project') miscFile = join(ideaProjectDirectory, 'eclipseCodeFormatter.xml') mx.update_file(miscFile, miscXml.xml(indent=' ', newl='\n')) if java_modules: # Write codestyle settings mx.ensure_dir_exists(join(ideaProjectDirectory, 'codeStyles')) codeStyleConfigXml = mx.XMLDoc() codeStyleConfigXml.open('component', attributes={'name': 'ProjectCodeStyleConfiguration'}) codeStyleConfigXml.open('state') codeStyleConfigXml.element('option', attributes={'name': 'USE_PER_PROJECT_SETTINGS', 'value': 'true'}) codeStyleConfigXml.close('state') codeStyleConfigXml.close('component') codeStyleConfigFile = join(ideaProjectDirectory, 'codeStyles', 'codeStyleConfig.xml') mx.update_file(codeStyleConfigFile, codeStyleConfigXml.xml(indent=' ', newl='\n')) codeStyleProjectXml = mx.XMLDoc() codeStyleProjectXml.open('component', attributes={'name': 'ProjectCodeStyleConfiguration'}) codeStyleProjectXml.open('code_scheme', attributes={'name': 'Project', 'version': '173'}) codeStyleProjectXml.open('JavaCodeStyleSettings') # We cannot entirely disable wildcards import, but we can set the threshold to an insane number. codeStyleProjectXml.element('option', attributes={'name': 'CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND', 'value': '65536'}) codeStyleProjectXml.element('option', attributes={'name': 'NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND', 'value': '65536'}) codeStyleProjectXml.close('JavaCodeStyleSettings') codeStyleProjectXml.close('code_scheme') codeStyleProjectXml.close('component') codeStyleProjectFile = join(ideaProjectDirectory, 'codeStyles', 'Project.xml') mx.update_file(codeStyleProjectFile, codeStyleProjectXml.xml(indent=' ', newl='\n')) # Write checkstyle-idea.xml for the CheckStyle-IDEA checkstyleXml = mx.XMLDoc() checkstyleXml.open('project', attributes={'version': '4'}) checkstyleXml.open('component', attributes={'name': 'CheckStyle-IDEA'}) checkstyleXml.open('option', attributes={'name' : "configuration"}) checkstyleXml.open('map') if max_checkstyle_version: checkstyleXml.element('entry', attributes={'key': "checkstyle-version", 'value': str(max_checkstyle_version)}) # Initialize an entry for each style that is used checkstyleConfigs = set([]) for p in s.projects_recursive(): if not p.isJavaProject(): continue csConfig, checkstyleVersion, checkstyleProj = p.get_checkstyle_config() if not csConfig or csConfig in checkstyleConfigs: continue checkstyleConfigs.add(csConfig) checkstyleXml.element('entry', attributes={'key' : "location-" + str(len(checkstyleConfigs)), 'value': "PROJECT_RELATIVE:" + join(checkstyleProj.dir, ".checkstyle_checks.xml") + ":" + checkstyleProj.name}) checkstyleXml.close('map') checkstyleXml.close('option') checkstyleXml.close('component') checkstyleXml.close('project') checkstyleFile = join(ideaProjectDirectory, 'checkstyle-idea.xml') mx.update_file(checkstyleFile, checkstyleXml.xml(indent=' ', newl='\n')) # mx integration def antTargetName(dist): return 'archive_' + dist.name def artifactFileName(dist): return dist.name.replace('.', '_').replace('-', '_') + '.xml' validDistributions = [dist for dist in mx.sorted_dists() if not dist.suite.isBinarySuite() and not dist.isTARDistribution()] # 1) Make an ant file for archiving the distributions. antXml = mx.XMLDoc() antXml.open('project', attributes={'name': s.name, 'default': 'archive'}) for dist in validDistributions: antXml.open('target', attributes={'name': antTargetName(dist)}) antXml.open('exec', attributes={'executable': sys.executable}) antXml.element('arg', attributes={'value': join(mx._mx_home, 'mx.py')}) antXml.element('arg', attributes={'value': 'archive'}) antXml.element('arg', attributes={'value': '@' + dist.name}) antXml.close('exec') antXml.close('target') antXml.close('project') antFile = join(ideaProjectDirectory, 'ant-mx-archive.xml') mx.update_file(antFile, antXml.xml(indent=' ', newl='\n')) # 2) Tell IDEA that there is an ant-build. ant_mx_archive_xml = 'file://$PROJECT_DIR$/.idea/ant-mx-archive.xml' metaAntXml = mx.XMLDoc() metaAntXml.open('project', attributes={'version': '4'}) metaAntXml.open('component', attributes={'name': 'AntConfiguration'}) metaAntXml.open('buildFile', attributes={'url': ant_mx_archive_xml}) metaAntXml.close('buildFile') metaAntXml.close('component') metaAntXml.close('project') metaAntFile = join(ideaProjectDirectory, 'ant.xml') mx.update_file(metaAntFile, metaAntXml.xml(indent=' ', newl='\n')) # 3) Make an artifact for every distribution validArtifactNames = {artifactFileName(dist) for dist in validDistributions} artifactsDir = join(ideaProjectDirectory, 'artifacts') mx.ensure_dir_exists(artifactsDir) for fileName in os.listdir(artifactsDir): filePath = join(artifactsDir, fileName) if os.path.isfile(filePath) and fileName not in validArtifactNames: os.remove(filePath) for dist in validDistributions: artifactXML = mx.XMLDoc() artifactXML.open('component', attributes={'name': 'ArtifactManager'}) artifactXML.open('artifact', attributes={'build-on-make': 'true', 'name': dist.name}) artifactXML.open('output-path', data='$PROJECT_DIR$/mxbuild/artifacts/' + dist.name) artifactXML.close('output-path') artifactXML.open('properties', attributes={'id': 'ant-postprocessing'}) artifactXML.open('options', attributes={'enabled': 'true'}) artifactXML.open('file', data=ant_mx_archive_xml) artifactXML.close('file') artifactXML.open('target', data=antTargetName(dist)) artifactXML.close('target') artifactXML.close('options') artifactXML.close('properties') artifactXML.open('root', attributes={'id': 'root'}) for javaProject in [dep for dep in dist.archived_deps() if dep.isJavaProject()]: artifactXML.element('element', attributes={'id': 'module-output', 'name': javaProject.name}) for javaProject in [dep for dep in dist.deps if dep.isLibrary() or dep.isDistribution()]: artifactXML.element('element', attributes={'id': 'artifact', 'artifact-name': javaProject.name}) artifactXML.close('root') artifactXML.close('artifact') artifactXML.close('component') artifactFile = join(artifactsDir, artifactFileName(dist)) mx.update_file(artifactFile, artifactXML.xml(indent=' ', newl='\n')) def intellij_scm_name(vc_kind): if vc_kind == 'git': return 'Git' elif vc_kind == 'hg': return 'hg4idea' vcsXml = mx.XMLDoc() vcsXml.open('project', attributes={'version': '4'}) vcsXml.open('component', attributes={'name': 'VcsDirectoryMappings'}) suites_for_vcs = mx.suites() + ([mx._mx_suite] if mx_python_modules else []) sourceSuitesWithVCS = [vc_suite for vc_suite in suites_for_vcs if vc_suite.isSourceSuite() and vc_suite.vc is not None] uniqueSuitesVCS = {(vc_suite.vc_dir, vc_suite.vc.kind) for vc_suite in sourceSuitesWithVCS} for vcs_dir, kind in uniqueSuitesVCS: vcsXml.element('mapping', attributes={'directory': vcs_dir, 'vcs': intellij_scm_name(kind)}) vcsXml.close('component') vcsXml.close('project') vcsFile = join(ideaProjectDirectory, 'vcs.xml') mx.update_file(vcsFile, vcsXml.xml(indent=' ', newl='\n'))