def test(args): """run some or all of the Maxine tests The Maxine sources include a variety of tests that can be run by a special launcher. These include JUnit tests, VM micro tests, certain benchmark suites and output comparison tests, amongst others. Use "mx test -help" to see what other options this command accepts.""" maxineTesterDir = join(_maxine_home, 'maxine-tester') if isdir(maxineTesterDir): for root, _, files in os.walk(maxineTesterDir): for name in files: if name.rsplit(', ', 1) in ['stdout', 'stderr', 'passed', 'failed', 'command']: os.remove(join(root, name)) else: os.mkdir(maxineTesterDir) class Tee: def __init__(self, f): self.f = f def eat(self, line): mx.log(line.rstrip()) self.f.write(line) console = join(maxineTesterDir, 'console') with open(console, 'w', 0) as f: tee = Tee(f) java = mx.java() mx.run_java(['-cp', sanitized_classpath(), 'test.com.sun.max.vm.MaxineTester', '-output-dir=maxine-tester', '-graal-jar=' + mx.distribution('GRAAL').path, '-refvm=' + java.java, '-refvm-args=' + ' '.join(java.java_args)] + args, out=tee.eat, err=subprocess.STDOUT)
def _configs(): class Configs: def __init__(self): self.configs = dict() def eat(self, line): (k, v) = line.split('#') self.configs[k] = v.rstrip() c = Configs() mx.run([mx.java().java, '-client', '-Xmx40m', '-Xms40m', '-XX:NewSize=30m', '-cp', mx.classpath(resolve=False), 'test.com.sun.max.vm.MaxineTesterConfiguration'], out=c.eat) return c.configs
def makejdk(args): """create a JDK directory based on the Maxine VM Create a JDK directory by replicating the file structure of $JAVA_HOME and replacing the 'java' executable with the Maxine VM executable. This produces a Maxine VM based JDK for applications (such as NetBeans) which expect a certain directory structure and executable names in a JDK installation.""" if mx.os == 'darwin': mx.log('mx makejdk is not supported on Darwin') mx.abort(1) if len(args) == 0: maxjdk = join(_maxine_home, 'maxjdk') else: maxjdk = args[0] if maxjdk[0] != '/': maxjdk = join(os.getcwd(), maxjdk) if exists(maxjdk): mx.log('The destination directory already exists -- it will be deleted') shutil.rmtree(maxjdk) jdk = mx.java().jdk if not isdir(jdk): mx.log(jdk + " does not exist or is not a directory") mx.abort(1) mx.log('Replicating ' + jdk + ' in ' + maxjdk + '...') shutil.copytree(jdk, maxjdk, symlinks=True) jreExists = exists(join(maxjdk, 'jre')) for f in os.listdir(_vmdir): fpath = join(_vmdir, f) if isfile(fpath): shutil.copy(fpath, join(maxjdk, 'bin')) if jreExists: shutil.copy(fpath, join(maxjdk, 'jre', 'bin')) os.unlink(join(maxjdk, 'bin', 'java')) if jreExists: os.unlink(join(maxjdk, 'jre', 'bin', 'java')) if (mx.os == 'windows'): shutil.copy(join(maxjdk, 'bin', 'maxvm'), join(maxjdk, 'bin', 'java')) shutil.copy(join(maxjdk, 'jre', 'bin', 'maxvm'), join(maxjdk, 'jre', 'bin', 'java')) else: os.symlink(join(maxjdk, 'bin', 'maxvm'), join(maxjdk, 'bin', 'java')) if jreExists: os.symlink(join(maxjdk, 'jre', 'bin', 'maxvm'), join(maxjdk, 'jre', 'bin', 'java')) mx.log('Created Maxine based JDK in ' + maxjdk)
def inspectoragent(args): """launch the Inspector agent Launch the Inspector agent. The agent listens on a given port for an incoming connection from a remote Inspector process.""" cmd = mx.java().format_cmd(['-cp', mx.classpath(), 'com.sun.max.tele.channel.agent.InspectorAgent'] + args) if mx.get_os() == 'darwin': # The -E option propagates the environment variables into the sudo process mx.run(['sudo', '-E', '-p', 'Debugging is a privileged operation on Mac OS X.\nPlease enter your "sudo" password:'] + cmd) else: mx.run(cmd)
def _configs(): class Configs: def __init__(self): self.configs = dict() def eat(self, line): (k, v) = line.split('#') self.configs[k] = v.rstrip() c = Configs() mx.run([ mx.java().java, '-client', '-Xmx40m', '-Xms40m', '-XX:NewSize=30m', '-cp', mx.classpath(resolve=False), 'test.com.sun.max.vm.MaxineTesterConfiguration' ], out=c.eat) return c.configs
def vm(args): """launch the Maxine VM Run the Maxine VM with the given options and arguments. A class path component with a '@' prefix is expanded to be the class path of the project named after the '@'. The expansion of the MAXVM_OPTIONS environment variable is inserted before any other VM options specified on the command line. Use "mx vm -help" to see what other options this command accepts.""" mx.expand_project_in_args(args) maxvmOptions = os.getenv('MAXVM_OPTIONS', '').split() debug_port = mx.java().debug_port if debug_port is not None: maxvmOptions += ['-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(debug_port)] mx.run([join(_vmdir, 'maxvm')] + maxvmOptions + args)
def test(args): """run some or all of the Maxine tests The Maxine sources include a variety of tests that can be run by a special launcher. These include JUnit tests, VM micro tests, certain benchmark suites and output comparison tests, amongst others. Use "mx test -help" to see what other options this command accepts.""" maxineTesterDir = join(_maxine_home, 'maxine-tester') if isdir(maxineTesterDir): for root, _, files in os.walk(maxineTesterDir): for name in files: if name.rsplit(', ', 1) in [ 'stdout', 'stderr', 'passed', 'failed', 'command' ]: os.remove(join(root, name)) else: os.mkdir(maxineTesterDir) class Tee: def __init__(self, f): self.f = f def eat(self, line): mx.log(line.rstrip()) self.f.write(line) console = join(maxineTesterDir, 'console') with open(console, 'w', 0) as f: tee = Tee(f) java = mx.java() mx.run_java([ '-cp', sanitized_classpath(), 'test.com.sun.max.vm.MaxineTester', '-output-dir=maxine-tester', '-graal-jar=' + mx.distribution('GRAAL').path, '-refvm=' + java.java, '-refvm-args=' + ' '.join(java.java_args) ] + args, out=tee.eat, err=subprocess.STDOUT)
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.dir, 'lib', '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) nonTestProjects = [p for p in mx.projects() if not p.name.endswith('.test') and not p.name.endswith('.jtt')] outputDirs = map(mx._cygpathU2W, [p.output_dir() for p in nonTestProjects]) javaCompliance = max([p.javaCompliance for p in nonTestProjects]) findbugsResults = join(suite.dir, 'findbugs.results') if fbArgs is None: fbArgs = defaultFindbugsArgs() cmd = ['-jar', mx._cygpathU2W(findbugsJar)] + fbArgs cmd = cmd + ['-auxclasspath', mx._separatedCygpathU2W(mx.classpath([p.name for p in nonTestProjects])), '-output', mx._cygpathU2W(findbugsResults), '-exitcode'] + args + outputDirs exitcode = mx.run_java(cmd, nonZeroIsFatal=False, javaConfig=mx.java(javaCompliance)) if exitcode != 0: with open(findbugsResults) as fp: mx.log(fp.read()) os.unlink(findbugsResults) return exitcode
def vm(args): """launch the Maxine VM Run the Maxine VM with the given options and arguments. A class path component with a '@' prefix is expanded to be the class path of the project named after the '@'. The expansion of the MAXVM_OPTIONS environment variable is inserted before any other VM options specified on the command line. Use "mx vm -help" to see what other options this command accepts.""" cwdArgs = check_cwd_change(args) cwd = cwdArgs[0] vmArgs = cwdArgs[1] mx.expand_project_in_args(vmArgs) maxvmOptions = os.getenv('MAXVM_OPTIONS', '').split() debug_port = mx.java().debug_port if debug_port is not None: maxvmOptions += ['-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(debug_port)] mx.run([join(_vmdir, 'maxvm')] + maxvmOptions + vmArgs, cwd=cwd)
def _run_tests(args, harness, vmLauncher, annotations, testfile, blacklist, whitelist, regex): vmArgs, tests = mx.extract_VM_args(args) for t in tests: if t.startswith('-'): mx.abort('VM option ' + t + ' must precede ' + tests[0]) candidates = {} for p in mx.projects_opt_limit_to_suites(): if mx.java().javaCompliance < p.javaCompliance: continue for c in _find_classes_with_annotations(p, None, annotations).keys(): candidates[c] = p classes = [] if len(tests) == 0: classes = candidates.keys() projectsCp = mx.classpath([pcp.name for pcp in mx.projects_opt_limit_to_suites() if pcp.javaCompliance <= mx.java().javaCompliance]) else: projs = set() found = False if len(tests) == 1 and '#' in tests[0]: words = tests[0].split('#') if len(words) != 2: mx.abort("Method specification is class#method: " + tests[0]) t, method = words for c, p in candidates.iteritems(): # prefer exact matches first if t == c: found = True classes.append(c) projs.add(p.name) if not found: for c, p in candidates.iteritems(): if t in c: found = True classes.append(c) projs.add(p.name) if not found: mx.log('warning: no tests matched by substring "' + t) elif len(classes) != 1: mx.abort('More than one test matches substring {0} {1}'.format(t, classes)) classes = [c + "#" + method for c in classes] else: for t in tests: if '#' in t: mx.abort('Method specifications can only be used in a single test: ' + t) for c, p in candidates.iteritems(): if t in c: found = True classes.append(c) projs.add(p.name) if not found: mx.log('warning: no tests matched by substring "' + t) projectsCp = mx.classpath(projs) if blacklist: classes = [c for c in classes if not any((glob.match(c) for glob in blacklist))] if whitelist: classes = [c for c in classes if any((glob.match(c) for glob in whitelist))] if regex: classes = [c for c in classes if re.search(regex, c)] if len(classes) != 0: f_testfile = open(testfile, 'w') for c in classes: f_testfile.write(c + '\n') f_testfile.close() harness(projectsCp, vmLauncher, vmArgs)
def inspect(args): """launch a given program under the Inspector Run Maxine under the Inspector. The arguments accepted by this command are those accepted by the 'mx vm' command plus the Inspector specific options. To debug a program in the Inspector, simply replace 'vm' on the command line that launches the program with 'inspect'. Use "mx inspect --help" to see what the Inspector options are. These options must be specified with a '--' prefix so that they can be distinguished from the VM options. The inspect command also accepts the same system property related options as the 'image' command except that a '--' prefix must be used (e.g. '--os Darwin --bits 32'). Use "mx help image" for more detail. Use "mx vm -help" to see what the VM options are.""" saveClassDir = join(_vmdir, 'inspected_classes') maxvmOptions = os.getenv('MAXVM_OPTIONS', '').split() vmArgs = ['-XX:SaveClassDir=' + saveClassDir, '-XX:+TrapOnError'] + maxvmOptions insArgs = ['-vmdir=' + _vmdir] if not isdir(saveClassDir): os.makedirs(saveClassDir) sysProps = [] insCP = [] i = 0 remote = False while i < len(args): arg = args[i] if arg.startswith('-XX:LogFile='): logFile = arg.split('=', 1)[1] vmArgs += [arg] os.environ['TELE_LOG_FILE'] = 'tele-' + logFile elif arg in ['-cp', '-classpath']: vmArgs += [arg, args[i + 1]] insCP += [mx.expand_project_in_class_path_arg(args[i + 1])] i += 1 elif arg == '-jar': vmArgs += ['-jar', args[i + 1]] insCP += [args[i + 1]] i += 1 elif arg == '--remote': remote = True elif arg in ['--platform', '--cpu', '--isa', '--os', '--endianness', '--bits', '--page', '--nsig']: name = arg.lstrip('-') i += 1 value = args[i] sysProps += ['-Dmax.' + name + '=' + value] elif arg.startswith('--cp='): insCP += [arg[len('--cp='):]] elif arg.startswith('--'): # chomp leading '-' insArgs += [arg[1:]] elif arg.startswith('-XX:SaveClassDir='): vmArgs += [arg] saveClassDir = arg.split('=', 1)[1] if not isdir(saveClassDir): os.makedirs(saveClassDir) elif arg.startswith('-'): vmArgs += [arg] else: # This is the main class argument; copy it and any following # arguments to the VM verbatim vmArgs += args[i:] break i += 1 insCP += [saveClassDir] insCP = pathsep.join(insCP) insArgs += ['-cp=' + insCP] mx.expand_project_in_args(vmArgs) cmd = mx.java().format_cmd(sysProps + ['-cp', mx.classpath() + pathsep + insCP, 'com.sun.max.ins.MaxineInspector'] + insArgs + ['-a=' + ' '.join(vmArgs)]) if mx.get_os() == 'darwin' and not remote: # The -E option propagates the environment variables into the sudo process mx.run(['sudo', '-E', '-p', 'Debugging is a privileged operation on Mac OS X.\nPlease enter your "sudo" password:'] + cmd) else: mx.run(cmd)
def inspect(args): """launch a given program under the Inspector Run Maxine under the Inspector. The arguments accepted by this command are those accepted by the 'mx vm' command plus the Inspector specific options. To debug a program in the Inspector, simply replace 'vm' on the command line that launches the program with 'inspect'. Use "mx inspect --help" to see what the Inspector options are. These options must be specified with a '--' prefix so that they can be distinguished from the VM options. The inspect command also accepts the same system property related options as the 'image' command except that a '--' prefix must be used (e.g. '--os Darwin --bits 32'). Use "mx help image" for more detail. Use "mx vm -help" to see what the VM options are.""" saveClassDir = join(_vmdir, 'inspected_classes') maxvmOptions = os.getenv('MAXVM_OPTIONS', '').split() vmArgs = ['-XX:SaveClassDir=' + saveClassDir, '-XX:+TrapOnError'] + maxvmOptions insArgs = ['-vmdir=' + _vmdir] if not isdir(saveClassDir): os.makedirs(saveClassDir) sysProps = [] sysProps += ['-Xbootclasspath/a:' + mx.distribution('GRAAL').path] insCP = [] cwdArgs = check_cwd_change(args) cwd = cwdArgs[0] args = cwdArgs[1] i = 0 remote = False while i < len(args): arg = args[i] if arg.startswith('-XX:LogFile='): logFile = arg.split('=', 1)[1] vmArgs += [arg] os.environ['TELE_LOG_FILE'] = 'tele-' + logFile elif arg in ['-cp', '-classpath']: vmArgs += [arg, args[i + 1]] insCP += [mx.expand_project_in_class_path_arg(args[i + 1])] i += 1 elif arg == '-jar': vmArgs += ['-jar', args[i + 1]] insCP += [args[i + 1]] i += 1 elif arg == '--remote': remote = True elif arg in ['--platform', '--cpu', '--isa', '--os', '--endianness', '--bits', '--page', '--nsig']: name = arg.lstrip('-') i += 1 value = args[i] sysProps += ['-Dmax.' + name + '=' + value] elif arg.startswith('--cp='): insCP += [arg[len('--cp='):]] elif arg.startswith('--'): # chomp leading '-' insArgs += [arg[1:]] elif arg.startswith('-XX:SaveClassDir='): vmArgs += [arg] saveClassDir = arg.split('=', 1)[1] if not isdir(saveClassDir): os.makedirs(saveClassDir) elif arg.startswith('-'): vmArgs += [arg] else: # This is the main class argument; copy it and any following # arguments to the VM verbatim vmArgs += args[i:] break i += 1 insCP += [saveClassDir] insCP = pathsep.join(insCP) insArgs += ['-cp=' + insCP] mx.expand_project_in_args(vmArgs) cmd = mx.java().format_cmd(sysProps + ['-cp', sanitized_classpath() + pathsep + insCP, 'com.sun.max.ins.MaxineInspector'] + insArgs + ['-a=' + ' '.join(vmArgs)]) if mx.get_os() == 'darwin' and not remote: # The -E option propagates the environment variables into the sudo process mx.run(['sudo', '-E', '-p', 'Debugging is a privileged operation on Mac OS X.\nPlease enter your "sudo" password:'] + cmd, cwd=cwd) else: mx.run(cmd, cwd=cwd)
def do_build_makefile(mf, selectedDists): java = mx.java() bootClassPath = java.bootclasspath() bootClassPath = bootClassPath.replace(os.path.realpath(java.jdk), "$(ABS_BOOTDIR)") jdkBootClassPathVariableName = "JDK_BOOTCLASSPATH" mf.add_definition("""# This Makefile is generated automatically, do not edit TARGET=. # Bootstrap JDK to be used (for javac and jar) ABS_BOOTDIR= JAVAC=$(ABS_BOOTDIR)/bin/javac -g -target """ + str(java.javaCompliance) + """ JAR=$(ABS_BOOTDIR)/bin/jar HS_COMMON_SRC=. # Directories, where the generated property-files reside within the JAR files PROVIDERS_INF=/META-INF/jvmci.providers SERVICES_INF=/META-INF/jvmci.services OPTIONS_INF=/META-INF/jvmci.options JARS = $(foreach dist,$(DISTRIBUTIONS),$($(dist)_JAR)) ifeq ($(ABS_BOOTDIR),) $(error Variable ABS_BOOTDIR must be set to a JDK installation.) endif ifeq ($(MAKE_VERBOSE),) QUIETLY=@ endif # Required to construct a whitespace for use with subst space := space += # Takes the provider files created by ServiceProviderProcessor (the processor # for the @ServiceProvider annotation) and merges them into a single file. # Arguments: # 1: directory with contents of the JAR file define process_providers $(eval providers := $(1)/$(PROVIDERS_INF)) $(eval services := $(1)/$(SERVICES_INF)) $(QUIETLY) test -d $(services) || mkdir -p $(services) $(QUIETLY) test ! -d $(providers) || (cd $(providers) && for i in $$(ls); do c=$$(cat $$i); echo $$i >> $(abspath $(services))/$$c; rm $$i; done) @# Since all projects are built together with one javac call we cannot determine @# which project contains HotSpotVMConfig.inline.hpp so we hardcode it. $(eval vmconfig := $(1)/hotspot/HotSpotVMConfig.inline.hpp) $(eval vmconfigDest := $(HS_COMMON_SRC)/../jvmci/jdk.internal.jvmci.hotspot/src_gen/hotspot) $(QUIETLY) test ! -f $(vmconfig) || (mkdir -p $(vmconfigDest) && cp $(vmconfig) $(vmconfigDest)) endef # Reads the files in jvmci.options/ created by OptionProcessor (the processor for the @Option annotation) # and appends to services/jdk.internal.jvmci.options.Options entries for the providers # also created by the same processor. # Arguments: # 1: directory with contents of the JAR file define process_options $(eval options := $(1)/$(OPTIONS_INF)) $(eval services := $(1)/META-INF/services) $(QUIETLY) test -d $(services) || mkdir -p $(services) $(QUIETLY) test ! -d $(options) || (cd $(options) && for i in $$(ls); do echo $${i}_Options >> $(abspath $(services))/jdk.internal.jvmci.options.Options; done) endef # Extracts META-INF/jvmci.services and META-INF/jvmci.options of a JAR file into a given directory # Arguments: # 1: JAR file to extract # 2: target directory (which already exists) define extract $(eval TMP := $(shell mktemp -d $(TARGET)/tmp_XXXXX)) $(QUIETLY) cd $(TMP) && $(JAR) xf $(abspath $(1)) && \\ ((test ! -d .$(SERVICES_INF) || cp -r .$(SERVICES_INF) $(abspath $(2))) && \\ (test ! -d .$(OPTIONS_INF) || cp -r .$(OPTIONS_INF) $(abspath $(2)))); $(QUIETLY) rm -r $(TMP); $(QUIETLY) cp $(1) $(2) endef # Calls $(JAVAC) with the boot class path $(JDK_BOOTCLASSPATH) and sources taken from the automatic variable $^ # Arguments: # 1: processorpath # 2: classpath # 3: resources to copy # 4: target JAR file define build_and_jar $(info Building $(4)) $(eval TMP := $(shell mkdir -p $(TARGET) && mktemp -d $(TARGET)/tmp_XXXXX)) $(QUIETLY) $(JAVAC) -d $(TMP) -processorpath :$(1) -bootclasspath $(JDK_BOOTCLASSPATH) -cp :$(2) $(filter %.java,$^) $(QUIETLY) test "$(3)" = "" || cp -r $(3) $(TMP) $(QUIETLY) $(call process_options,$(TMP)) $(QUIETLY) $(call process_providers,$(TMP)) $(QUIETLY) mkdir -p $(shell dirname $(4)) $(QUIETLY) $(JAR) -0cf $(4) -C $(TMP) . $(QUIETLY) rm -r $(TMP) endef # Verifies that make/defs.make contains an appropriate line for each JVMCI service or option # and that only existing JVMCI services and options are exported. # Arguments: # 1: list of service or option files # 2: variable name for directory of service or option files define verify_defs_make $(eval defs := make/defs.make) $(eval uncondPattern := EXPORT_LIST += $$$$($(2))/) $(eval condPattern := CONDITIONAL_EXPORT_LIST += $$$$($(2))/) $(eval unconditionalExports := $(shell grep '^EXPORT_LIST += $$($2)' make/defs.make | sed 's:.*($(2))/::g')) $(eval conditionalExports := $(shell grep '^CONDITIONAL_EXPORT_LIST += $$($2)' make/defs.make | sed 's:.*($(2))/::g')) $(eval allExports := $(unconditionalExports) $(conditionalExports)) $(foreach file,$(1),$(if $(findstring $(file),$(allExports)), ,$(error "Line matching '$(uncondPattern)$(file)' or '$(condPattern)$(file)' not found in $(defs)"))) $(foreach export,$(unconditionalExports),$(if $(findstring $(export),$(1)), ,$(error "The line '$(uncondPattern)$(export)' should not be in $(defs)"))) endef all: default \t$(info Put $(EXPORTED_FILES) into SHARED_DIR $(SHARED_DIR)) \t$(shell mkdir -p $(SHARED_DIR)) \t$(foreach export,$(EXPORTED_FILES),$(call extract,$(export),$(SHARED_DIR))) export: all \t$(call verify_defs_make,$(notdir $(wildcard $(SHARED_DIR)/jvmci.services/*)),EXPORT_JRE_LIB_JVMCI_SERVICES_DIR) \t$(call verify_defs_make,$(notdir $(wildcard $(SHARED_DIR)/jvmci.options/*)),EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR) .PHONY: export clean: \t$(QUIETLY) rm $(JARS) 2> /dev/null || true \t$(QUIETLY) rmdir -p $(dir $(JARS)) 2> /dev/null || true .PHONY: export clean """) s = mx.suite("graal") dists = [] ap = [] projects = [] for d in s.dists: if d.name in selectedDists: update_list(dists, d.get_dist_deps(True, True)) update_list(projects, d.sorted_deps(includeLibs=False, transitive=True)) for p in projects: deps = p.all_deps([], False, includeSelf=True, includeJreLibs=False, includeAnnotationProcessors=True) for d in deps: if d.definedAnnotationProcessorsDist is not None: apd = d.definedAnnotationProcessorsDist update_list(ap, [apd]) if len(dists) > 0: mf.add_definition(jdkBootClassPathVariableName + " = " + bootClassPath) for d in ap: make_dist_rule(d, mf) for d in dists: make_dist_rule(d, mf) mf.add_definition("DISTRIBUTIONS = " + " ".join([short_dist_name(d.name) for d in dists+ap])) mf.add_rule("default: $({}_JAR)\n.PHONY: default\n".format("_JAR) $(".join([short_dist_name(d.name) for d in dists]))) return True else: for d in dists: selectedDists.remove(d.name) print "Distribution(s) '" + "', '".join(selectedDists) + "' does not exist."