001/*
002 * Copyright (c) 2012-2017 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 */
009
010package org.eclipse.golo.cli.command;
011
012import com.beust.jcommander.Parameter;
013import com.beust.jcommander.Parameters;
014import com.beust.jcommander.ParametersDelegate;
015import org.eclipse.golo.cli.command.spi.CliCommand;
016import org.eclipse.golo.compiler.GoloCompilationException;
017import org.eclipse.golo.compiler.GoloCompiler;
018
019import java.io.File;
020import java.io.FileInputStream;
021import java.io.FileOutputStream;
022import java.io.IOException;
023import java.util.LinkedList;
024import java.util.List;
025import java.util.jar.Attributes;
026import java.util.jar.JarOutputStream;
027import java.util.jar.Manifest;
028
029import static gololang.Messages.*;
030
031@Parameters(commandNames = {"compile"}, resourceBundle = "commands", commandDescriptionKey = "compile")
032public class CompilerCommand implements CliCommand {
033
034  @Parameter(names = "--output", descriptionKey = "compile.output")
035  String output = ".";
036
037  @Parameter(descriptionKey = "source_files")
038  List<String> sources = new LinkedList<>();
039
040  @ParametersDelegate
041  ClasspathOption classpath = new ClasspathOption();
042
043  @Override
044  public void execute() throws Throwable {
045    // TODO: recurse into directories
046    classpath.initGoloClassLoader();
047    GoloCompiler compiler = new GoloCompiler();
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}