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.IParameterValidator;
013import com.beust.jcommander.Parameter;
014import com.beust.jcommander.Parameters;
015import com.beust.jcommander.ParameterException;
016import org.eclipse.golo.cli.command.spi.CliCommand;
017
018import java.io.*;
019import java.nio.file.*;
020import java.util.*;
021import java.util.function.Supplier;
022
023import static gololang.Messages.message;
024import static gololang.Messages.info;
025
026@Parameters(commandNames = {"new"}, resourceBundle = "commands", commandDescriptionKey = "new")
027public class InitCommand implements CliCommand {
028
029  @Parameter(names = "--path", descriptionKey = "new.path")
030  String path = ".";
031
032  @Parameter(names = "--type", descriptionKey = "new.type", validateWith = ProjectTypeValidator.class)
033  String type = System.getProperty("golo.new.type", ProjectTypeValidator.DEFAULT);
034
035  @Parameter(names = "--vcs", descriptionKey = "new.vcs", validateWith = VcsValidator.class)
036  String vcs = System.getProperty("golo.new.vcs", VcsValidator.DEFAULT);
037
038  @Parameter(names = "--profile", descriptionKey = "new.profile", validateWith = ProfileValidator.class)
039  String profile = System.getProperty("golo.new.profile", ProfileValidator.DEFAULT);
040
041  @Parameter(descriptionKey = "new.names")
042  List<String> names = new LinkedList<>();
043
044  private static final Map<String, Profile> PROFILES = new LinkedHashMap<>();
045  static {
046    PROFILES.put("app", new Profile()
047        .defaultFileName("main.golo")
048        .label("application")
049        .runnable());
050    PROFILES.put("lib", new Profile()
051        .defaultFileName("lib.golo")
052        .label("library")
053        .directories(
054          Paths.get("samples")));
055  }
056
057  private static final Map<String, VCS> VERSION_SYSTEMS = new LinkedHashMap<>();
058  static {
059    VERSION_SYSTEMS.put("none", null);
060    VERSION_SYSTEMS.put("git", new VCS()
061        .command("git", "init")
062        .ignoreFilename(".gitignore")
063        .ignore("*.class"));
064    VERSION_SYSTEMS.put("hg", new VCS()
065        .command("hg", "init")
066        .ignoreFilename(".hgignore")
067        .ignore("syntax: glob", "*.class"));
068  }
069
070  private static final Map<String, Supplier<ProjectInitializer>> TYPES = new LinkedHashMap<>();
071  static {
072    TYPES.put("simple", () -> new ProjectInitializer()
073        .directories(
074          Paths.get("imports"),
075          Paths.get("jars"))
076        .runCommand("golo golo --files *.golo"));
077
078    TYPES.put("gradle", () -> new ProjectInitializer()
079        .manager("gradle")
080        .projectFileName("build.gradle")
081        .sourcesDir(Paths.get("src", "main", "golo"))
082        .directories(
083          Paths.get("src", "main", "resources"),
084          Paths.get("src", "test", "golo"))
085        .withFile(Paths.get("README.md"), "README.md")
086        .ignore("build/", ".gradle/")
087        .runCommand("gradle -q run"));
088
089    TYPES.put("maven", () -> new ProjectInitializer()
090        .manager("maven")
091        .projectFileName("pom.xml")
092        .sourcesDir(Paths.get("src", "main", "golo"))
093        .directories(
094          Paths.get("src", "main", "resources"),
095          Paths.get("src", "test", "golo"))
096        .withFile(Paths.get("README.md"), "README.md")
097        .ignore("target/")
098        .runCommand("mvn -q package && mvn -q exec:java"));
099  }
100
101  public static class ProjectTypeValidator implements IParameterValidator {
102    public static final String DEFAULT = "simple";
103    @Override
104    public void validate(String name, String value) {
105      if (!TYPES.containsKey(value)) {
106        throw new ParameterException(message("project_type_error", TYPES.keySet().toString()));
107      }
108    }
109  }
110
111  public static class VcsValidator implements IParameterValidator {
112    public static final String DEFAULT = "none";
113    @Override
114    public void validate(String name, String value) {
115      if (!VERSION_SYSTEMS.containsKey(value)) {
116        throw new ParameterException(message("vcs_type_error", VERSION_SYSTEMS.keySet().toString()));
117      }
118    }
119  }
120
121  public static class ProfileValidator implements IParameterValidator {
122    public static final String DEFAULT = "app";
123    @Override
124    public void validate(String name, String value) {
125      if (!PROFILES.containsKey(value)) {
126        throw new ParameterException(message("profile_type_error", PROFILES.keySet().toString()));
127      }
128    }
129  }
130
131  @Override
132  public void execute() throws Throwable {
133    if (this.names.isEmpty()) {
134      this.names.add("Golo");
135    }
136    ProjectInitializer init = TYPES.get(this.type).get();
137    init.setRootPath(this.path);
138    init.setVCS(VERSION_SYSTEMS.get(this.vcs));
139    init.setProfile(PROFILES.get(this.profile));
140    for (String name : this.names) {
141      try {
142        info(message("project_generation", this.type, name));
143        init.init(name);
144      } catch (Exception e) {
145        handleThrowable(e, false, false);
146      }
147    }
148  }
149}