All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scala_maven.ScalaContinuousCompileMojo Maven / Gradle / Ivy

/*
 * This is free and unencumbered software released into the public domain.
 * See UNLICENSE.
 */
package scala_maven;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import scala_maven_dependency.Context;
import scala_maven_executions.JavaMainCaller;
import util.FileUtils;

/**
 * Compile the main and test scala source directory in continuous (infinite loop). !! This is an
 * util goal for commandline usage only (Do not use or call it in a pom) !!!
 */
@Mojo(name = "cc", requiresDependencyResolution = ResolutionScope.TEST)
public class ScalaContinuousCompileMojo extends ScalaCompilerSupport {

  /** The output directory for compilation. */
  @Parameter(property = "project.build.outputDirectory")
  protected File mainOutputDir;

  /**
   * The main directory containing scala source for compilation
   *
   * 

Note: Allows extending for 3rd-party usages */ @Parameter(defaultValue = "${project.build.sourceDirectory}/../scala") protected File mainSourceDir; /** * The directory to place test compilation output in * *

Note: Allows extending for 3rd-party usages */ @Parameter(defaultValue = "${project.build.testOutputDirectory}") protected File testOutputDir; /** * The directory containing test source for compilation * *

Note: Allows extending for 3rd-party usages */ @Parameter(defaultValue = "${project.build.testSourceDirectory}/../scala") protected File testSourceDir; /** * Analysis cache file for incremental recompilation. * *

Note: Allows extending for 3rd-party usages */ @Parameter( property = "analysisCacheFile", defaultValue = "${project.build.directory}/analysis/compile") protected File analysisCacheFile; /** * Analysis cache file for incremental recompilation. * *

Note: Allows extending for 3rd-party usages */ @Parameter( property = "testAnalysisCacheFile", defaultValue = "${project.build.directory}/analysis/test-compile") protected File testAnalysisCacheFile; /** * Define if fsc should be used, else scalac is used. fsc => scala.tools.nsc.CompileClient, scalac * => scala.tools.nsc.Main. * *

Note: Allows extending for 3rd-party usages */ @Parameter(property = "fsc", defaultValue = "true") protected boolean useFsc; /** * Define if cc should run once or in infinite loop. (useful for test or working with editor) * *

Note: Allows extending for 3rd-party usages */ @Parameter(property = "once", defaultValue = "false") protected boolean once; /** * Turns verbose output on. * *

Note: Allows extending for 3rd-party usages */ @Parameter(property = "verbose", defaultValue = "false") protected boolean verbose; @Override protected Set getClasspathElements() { throw new UnsupportedOperationException("USELESS"); } @Override protected File getOutputDir() { throw new UnsupportedOperationException("USELESS"); } @Override protected List getSourceDirectories() { throw new UnsupportedOperationException("USELESS"); } @Override protected File getAnalysisCacheFile() { throw new UnsupportedOperationException("USELESS"); } @Override protected JavaMainCaller getScalaCommand() throws Exception { Context sc = findScalaContext(); JavaMainCaller jcmd = getScalaCommand(fork, sc.compilerMainClassName(scalaClassName, useFsc)); if (useFsc && verbose) { jcmd.addOption("-verbose", true); } return jcmd; } @Override protected final void doExecute() throws Exception { mainOutputDir = FileUtils.fileOf(mainOutputDir, useCanonicalPath); if (!mainOutputDir.exists()) { mainOutputDir.mkdirs(); } List mainSources = new ArrayList<>(project.getCompileSourceRoots()); mainSources.add(FileUtils.pathOf(mainSourceDir, useCanonicalPath)); List mainSourceDirs = normalize(mainSources); testOutputDir = FileUtils.fileOf(testOutputDir, useCanonicalPath); if (!testOutputDir.exists()) { testOutputDir.mkdirs(); } List testSources = new ArrayList<>(project.getTestCompileSourceRoots()); testSources.add(FileUtils.pathOf(testSourceDir, useCanonicalPath)); List testSourceDirs = normalize(testSources); analysisCacheFile = FileUtils.fileOf(analysisCacheFile, useCanonicalPath); testAnalysisCacheFile = FileUtils.fileOf(testAnalysisCacheFile, useCanonicalPath); if (useFsc && recompileMode != RecompileMode.incremental) { getLog().info("use fsc for compilation"); if (!once) { StopServer stopServer = new StopServer(); stopServer.run(); startNewCompileServer(); Runtime.getRuntime().addShutdownHook(stopServer); } else { startNewCompileServer(); } } getLog().info("wait for files to compile..."); do { clearCompileErrors(); int nbFile = 0; if (!mainSourceDirs.isEmpty()) { nbFile = compile( mainSourceDirs, mainOutputDir, analysisCacheFile, FileUtils.fromStrings(project.getCompileClasspathElements()), true); // If there are no source files, the compile method returns -1. Thus, to make // sure we // still run the tests if there are test sources, reset nbFile to zero. if (nbFile == -1) nbFile = 0; } if (!testSourceDirs.isEmpty()) { nbFile += compile( testSourceDirs, testOutputDir, testAnalysisCacheFile, FileUtils.fromStrings(project.getTestClasspathElements()), true); } if (nbFile > 0) { if (!hasCompileErrors()) { postCompileActions(); } else { getLog().info("Not running test cases due to compile error"); } } if (!once) { if (nbFile > 0) { getLog().info("wait for files to compile..."); Thread.sleep(5000); } else { Thread.sleep(3000); } } else if (hasCompileErrors()) { throw new MojoFailureException("scala compilation failed"); } } while (!once); } /** * Allows derived Mojos to do things after a compile has succesfully completed such as run test * cases */ protected void postCompileActions() throws Exception {} private void startNewCompileServer() throws Exception { File serverTagFile = new File(mainOutputDir + ".server"); if (serverTagFile.exists()) { return; } getLog().info("start server..."); JavaMainCaller jcmd = getEmptyScalaCommand("scala.tools.nsc.MainGenericRunner"); jcmd.addArgs("scala.tools.nsc.CompileServer"); jcmd.addJvmArgs(jvmArgs); jcmd.addArgs(args); jcmd.spawn(displayCmd); FileUtils.fileWrite(serverTagFile.getAbsolutePath(), "."); Thread.sleep(1000); // HACK To wait startup time of server (avoid first fsc command to failed to // contact server) } private class StopServer extends Thread { @Override public void run() { try { getLog().info("stop server(s)..."); JavaMainCaller jcmd = getScalaCommand(); jcmd.addArgs("-shutdown"); jcmd.run(displayCmd, false); File serverTagFile = new File(mainOutputDir + ".server"); if (serverTagFile.exists()) { serverTagFile.delete(); } } catch (Exception exc) { // getLog().warn(exc); } } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy