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