001/* 002 * Copyright (c) 2012-2021 Institut National des Sciences Appliquées de Lyon (INSA Lyon) and others 003 * 004 * This program and the accompanying materials are made available under the 005 * terms of the Eclipse Public License 2.0 which is available at 006 * http://www.eclipse.org/legal/epl-2.0. 007 * 008 * SPDX-License-Identifier: EPL-2.0 009 */ 010 011package org.eclipse.golo.cli.command; 012 013import com.beust.jcommander.Parameter; 014import com.beust.jcommander.Parameters; 015import com.beust.jcommander.ParametersDelegate; 016import com.beust.jcommander.converters.FileConverter; 017 018import org.eclipse.golo.cli.GoloFilesManager; 019import org.eclipse.golo.cli.command.spi.CliCommand; 020import org.eclipse.golo.compiler.GoloClassLoader; 021import org.eclipse.golo.compiler.GoloCompiler; 022 023import java.io.File; 024import java.util.Collection; 025import java.util.LinkedList; 026import java.util.List; 027import java.util.Objects; 028 029import static gololang.Messages.*; 030 031@Parameters(commandNames = "golo", resourceBundle = "commands", commandDescriptionKey = "golo") 032public final class GoloGoloCommand implements CliCommand { 033 034 @Parameter(names = "--files", variableArity = true, descriptionKey = "golo.files", required = true, converter = FileConverter.class) 035 List<File> files = new LinkedList<>(); 036 037 @Parameter(names = "--module", descriptionKey = "main_module") 038 String module; 039 040 @Parameter(names = "--args", variableArity = true, descriptionKey = "arguments") 041 List<String> arguments = new LinkedList<>(); 042 043 @ParametersDelegate 044 ClasspathOption classpath = new ClasspathOption(); 045 046 @Parameter(names = "--verbose", descriptionKey = "verbose") 047 boolean verbose = false; 048 049 @Override 050 public boolean verbose() { 051 return this.verbose; 052 } 053 054 @Override 055 public void execute() throws Throwable { 056 GoloClassLoader loader = classpath.initGoloClassLoader(); 057 GoloCompiler compiler = loader.getCompiler(); 058 Class<?> lastClass = GoloFilesManager.goloFiles(this.files) 059 .filter(this::canRead) 060 .map(wrappedTreatment(compiler::parse)) 061 .map(wrappedTreatment(compiler::transform)) 062 .sorted(CliCommand.MODULE_COMPARATOR) 063 .map(wrappedTreatment(compiler::expand)) 064 .map(wrappedTreatment(compiler::refine)) 065 .map(wrappedTreatment(compiler::generate)) 066 .filter(Objects::nonNull) 067 .flatMap(Collection::stream) 068 .map(displayInfo("Loading %s")) 069 .map(loader::load) 070 .reduce(null, this::selectMainModule); 071 072 if (lastClass == null && this.module != null) { 073 error(message("module_not_found", this.module)); 074 return; 075 } 076 if (lastClass == null) { 077 return; 078 } 079 try { 080 callRun(lastClass, this.arguments.toArray(new String[this.arguments.size()])); 081 } catch (NoMainMethodException e) { 082 error(message("module_no_main", lastClass.getName())); 083 } 084 } 085 086 private Class<?> selectMainModule(Class<?> old, Class<?> loaded) { 087 if (this.module == null || this.module.equals(loaded.getCanonicalName())) { 088 return loaded; 089 } 090 return old; 091 } 092}