001/*
002 * Copyright (c) 2012-2018 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 org.eclipse.golo.cli.command.spi.CliCommand;
017import org.eclipse.golo.compiler.GoloCompilationException;
018import org.eclipse.golo.compiler.GoloCompiler;
019
020import java.io.File;
021import java.io.FileInputStream;
022import java.io.FileOutputStream;
023import java.io.IOException;
024import java.util.LinkedList;
025import java.util.List;
026import java.util.jar.Attributes;
027import java.util.jar.JarOutputStream;
028import java.util.jar.Manifest;
029
030import static gololang.Messages.*;
031
032@Parameters(commandNames = {"compile"}, resourceBundle = "commands", commandDescriptionKey = "compile")
033public class CompilerCommand implements CliCommand {
034
035  @Parameter(names = "--output", descriptionKey = "compile.output")
036  String output = ".";
037
038  @Parameter(descriptionKey = "source_files")
039  List<String> sources = new LinkedList<>();
040
041  @ParametersDelegate
042  ClasspathOption classpath = new ClasspathOption();
043
044  @Override
045  public void execute() throws Throwable {
046    // TODO: recurse into directories
047    GoloCompiler compiler = classpath.initGoloClassLoader().getCompiler();
048    final boolean compilingToJar = this.output.endsWith(".jar");
049    File outputDir = compilingToJar ? null : new File(this.output);
050    JarOutputStream jarOutputStream = compilingToJar ? new JarOutputStream(new FileOutputStream(new File(this.output)), manifest()) : null;
051    for (String source : this.sources) {
052      File file = new File(source);
053      try (FileInputStream in = new FileInputStream(file)) {
054        if (compilingToJar) {
055          compiler.compileToJar(file.getName(), in, jarOutputStream);
056        } else {
057          compiler.compileTo(file.getName(), in, outputDir);
058        }
059      } catch (IOException e) {
060        error(message("file_not_found", source));
061        return;
062      } catch (GoloCompilationException e) {
063        handleCompilationException(e);
064      }
065    }
066    if (compilingToJar) {
067      jarOutputStream.close();
068    }
069  }
070
071  private Manifest manifest() {
072    Manifest manifest = new Manifest();
073    Attributes attributes = manifest.getMainAttributes();
074    attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0");
075    attributes.put(new Attributes.Name("Created-By"), "Eclipse Golo " + Metadata.VERSION);
076    return manifest;
077  }
078}