PageRenderTime 44ms CodeModel.GetById 16ms app.highlight 21ms RepoModel.GetById 2ms app.codeStats 1ms

/archetypes/scalate-archetypes-itests/src/main/scala/org/fusesource/scalate/tooling/ArchetypeTestSupport.scala

http://github.com/scalate/scalate
Scala | 321 lines | 228 code | 51 blank | 42 comment | 26 complexity | d8a7b0fb5a8b0cc46f3072dd6b0212ed MD5 | raw file
  1/**
  2 * Copyright (C) 2009-2010 the original author or authors.
  3 * See the notice.md file distributed with this work for additional
  4 * information regarding copyright ownership.
  5 *
  6 * Licensed under the Apache License, Version 2.0 (the "License");
  7 * you may not use this file except in compliance with the License.
  8 * You may obtain a copy of the License at
  9 *
 10 *     http://www.apache.org/licenses/LICENSE-2.0
 11 *
 12 * Unless required by applicable law or agreed to in writing, software
 13 * distributed under the License is distributed on an "AS IS" BASIS,
 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15 * See the License for the specific language governing permissions and
 16 * limitations under the License.
 17 */
 18
 19package org.fusesource.scalate.tooling
 20
 21import java.io.File
 22import java.util.Collections
 23import java.util.{List => JList}
 24import java.util.LinkedHashMap
 25import java.util.Map
 26import java.util.Properties
 27
 28import scala.collection.JavaConversions._
 29
 30import org.apache.maven.Maven
 31import org.apache.maven.exception.DefaultExceptionHandler
 32import org.apache.maven.exception.ExceptionHandler
 33import org.apache.maven.exception.ExceptionSummary
 34import org.apache.maven.execution.DefaultMavenExecutionRequest
 35import org.apache.maven.execution.MavenExecutionRequest
 36import org.apache.maven.execution.MavenExecutionRequestPopulator
 37import org.apache.maven.execution.MavenExecutionResult
 38import org.apache.maven.lifecycle.LifecycleExecutionException
 39import org.apache.maven.project.{DefaultProjectBuildingRequest, ProjectBuilder, MavenProject}
 40import org.apache.maven.repository.RepositorySystem
 41import org.apache.maven.settings.building.DefaultSettingsBuildingRequest
 42import org.apache.maven.settings.building.SettingsBuilder
 43import org.apache.maven.settings.building.SettingsBuildingRequest
 44import org.apache.maven.settings.building.SettingsBuildingResult
 45
 46import org.codehaus.plexus.{DefaultContainerConfiguration, ContainerConfiguration, DefaultPlexusContainer}
 47import org.codehaus.plexus.util.FileUtils
 48
 49import org.fusesource.scalate.util.IOUtil._
 50
 51import org.junit.{After, Before, Assert}
 52
 53import org.slf4j.LoggerFactory
 54
 55/**
 56 * A base class for testing out archetypes
 57 */
 58class ArchetypeTestSupport {
 59  protected val logger = LoggerFactory.getLogger(getClass)
 60  protected var baseDir = new File(System.getProperty("basedir", ".")).getAbsoluteFile
 61  protected var container: DefaultPlexusContainer = null
 62
 63  // TODO discover this from the pom!
 64  protected var version: String = _
 65
 66  protected var newProjectDir: File = _
 67
 68  protected def testScalateArchetype(artifactId: String, testConsole: Boolean = false): Unit = {
 69    // lets try resolve the current project version
 70    version = findCurrentPomVersion
 71    logger.info("Looked up version from current pom: " + version)
 72
 73    testScalateArchetype("org.fusesource.scalate.tooling", artifactId, version, testConsole)
 74  }
 75
 76  protected def testScalateArchetype(groupId: String, artifactId: String, version: String, testConsole: Boolean): Unit = {
 77    logger.info("Attempting to create archetype: " + artifactId + " using version: " + version)
 78
 79    // create a temp directory to run the archetype in
 80    var targetDir: File = new File(baseDir, "target/archetypes/" + artifactId)
 81    FileUtils.deleteDirectory(targetDir)
 82    targetDir.mkdirs
 83    //val createdArtifactId: String = UUID.randomUUID.toString
 84    val createdArtifactId: String = "myArtifact"
 85
 86    var props: Properties = new Properties
 87    props.setProperty("archetypeGroupId", groupId)
 88    props.setProperty("archetypeArtifactId", artifactId)
 89    props.setProperty("archetypeVersion", version)
 90    props.setProperty("groupId", "sample")
 91    props.setProperty("artifactId", createdArtifactId)
 92    props.setProperty("user.dir", targetDir.getAbsolutePath)
 93    props.setProperty("basedir", targetDir.getAbsolutePath)
 94
 95    /*val localRepo = "file://" + (new File(System.getProperty("user.home", ".") + "/.m2/repository").getCanonicalFile)
 96    println("Using archetype repo: " + localRepo)
 97    props.setProperty("archetypeRepository", localRepo)
 98    */
 99    props.setProperty("archetypeCatalog", "local")
100
101    var request: DefaultMavenExecutionRequest = new DefaultMavenExecutionRequest
102
103    request.setSystemProperties(System.getProperties.clone.asInstanceOf[Properties])
104    request.setUserProperties(props)
105    request.setGoals(Collections.singletonList("archetype:generate"))
106    request.setBaseDirectory(targetDir)
107    request.setProjectPresent(false)
108    runMaven(request)
109
110
111    newProjectDir = new File(targetDir, createdArtifactId)
112    logger.info("Now building created archetype in: " + newProjectDir)
113
114    runMaven(mavenRequest(Collections.singletonList("install")))
115    /*
116        request = new DefaultMavenExecutionRequest
117        request.setSystemProperties(System.getProperties.clone.asInstanceOf[Properties])
118        request.setGoals(Collections.singletonList("install"))
119        request.setBaseDirectory(newProjectDir)
120        request.setProjectPresent(true)
121        request.setPom(new File(newProjectDir, "pom.xml"))
122        runMaven(request)
123    */
124
125
126    if (testConsole) {
127      // lets copy the ConsoleTest
128      copyFile(baseDir.getParentFile.getParentFile.getPath +
129              "/scalate-war/src/test/scala/org/fusesource/scalate/console/ConsoleTest.scala",
130        newProjectDir.getPath + "/src/test/scala/org/fusesource/scalate/console/ConsoleTest.scala")
131
132      // lets copy the TestGeneratedConsoleFiles
133      copyFile(baseDir.getPath + "/src/test/scala/org/fusesource/scalate/console/TestGeneratedConsoleFiles.scala",
134        newProjectDir.getPath + "/src/test/scala/org/fusesource/scalate/console/TestGeneratedConsoleFiles.scala")
135
136      System.setProperty("scalate.package.resources", "sample.resources")
137      System.setProperty("scalate.generate.src", new File(newProjectDir, "src").getPath)
138      mavenTest("ConsoleTest")
139      mavenTest("TestGeneratedConsoleFiles")
140    }
141  }
142
143
144  def copyFile(fromFileName: String, toFileName: String): File = {
145    val from = new File(fromFileName)
146    val to = new File(toFileName)
147    println("copying from: " + from + " to: " + to)
148    copy(from, to)
149    to
150  }
151
152  def mavenTest(test: String): Unit = {
153    val request = mavenRequest(Collections.singletonList("install"))
154    val properties = new Properties()
155    properties.put("test", test)
156    request.setUserProperties(properties)
157    runMaven(request)
158  }
159
160  def mavenRequest(goals: JList[String]): DefaultMavenExecutionRequest = {
161    val request = new DefaultMavenExecutionRequest
162    request.setSystemProperties(System.getProperties.clone.asInstanceOf[Properties])
163    request.setGoals(goals)
164    request.setBaseDirectory(newProjectDir)
165    request.setProjectPresent(true)
166    request.setPom(new File(newProjectDir, "pom.xml"))
167    request
168  }
169
170
171  @Before
172  def setUp: Unit = {
173    container = createContainer
174  }
175
176  @After
177  def tearDown: Unit = {
178    if (container != null) {
179      container.dispose
180    }
181    container = null
182  }
183
184
185  /**
186   * Uses the current pom.xml to find the version
187   */
188  protected def findCurrentPomVersion: String = {
189    val builder = container.lookup(classOf[ProjectBuilder])
190    assert(builder != null)
191
192    val buildingRequest = new DefaultProjectBuildingRequest
193    buildingRequest.setOffline(false)
194
195    var rsys = container.lookup(classOf[RepositorySystem])
196    buildingRequest.setLocalRepository(rsys.createDefaultLocalRepository)
197    buildingRequest.setRemoteRepositories(Collections.singletonList(rsys.createDefaultRemoteRepository))
198
199    val buildingResult = builder.build(new File(baseDir, "pom.xml"), buildingRequest)
200    assert(buildingResult != null)
201    val answer = buildingResult.getProject.getVersion
202    println("Found archetype version: " + answer)
203    answer
204  }
205
206  protected def runMaven(request: MavenExecutionRequest): MavenExecutionResult = {
207    assert(container != null)
208    var maven = container.lookup(classOf[Maven])
209    Assert.assertNotNull("Should have a maven!", maven)
210    configureRequest(request)
211    var result: MavenExecutionResult = null
212    try {
213      result = maven.execute(request)
214    }
215    finally {
216      container.release(maven)
217    }
218    if (result.hasExceptions) {
219      var handler: ExceptionHandler = new DefaultExceptionHandler
220      var references: Map[String, String] = new LinkedHashMap[String, String]
221      var project: MavenProject = null
222
223      for (exception <- result.getExceptions) {
224        var summary: ExceptionSummary = handler.handleException(exception)
225        logSummary(summary, references, "", request.isShowErrors)
226        if (project == null && exception.isInstanceOf[LifecycleExecutionException]) {
227          project = (exception.asInstanceOf[LifecycleExecutionException]).getProject
228        }
229      }
230      Assert.fail("Failed to invoke maven goals: " + request.getGoals + " due to exceptions: " + result.getExceptions)
231    }
232    return result
233  }
234
235
236  protected def configureRequest(request: MavenExecutionRequest): Unit = {
237    assert(request != null)
238
239    var settingsRequest: SettingsBuildingRequest = new DefaultSettingsBuildingRequest
240    settingsRequest.setSystemProperties(request.getSystemProperties)
241    settingsRequest.setUserProperties(request.getUserProperties)
242
243    var settingsResult: SettingsBuildingResult = null
244    val settingsBuilder = container.lookup(classOf[SettingsBuilder])
245    try {
246      settingsResult = settingsBuilder.build(settingsRequest)
247    }
248    finally {
249      container.release(settingsBuilder)
250    }
251    val populator = container.lookup(classOf[MavenExecutionRequestPopulator])
252    try {
253      populator.populateFromSettings(request, settingsResult.getEffectiveSettings)
254    }
255    finally {
256      container.release(populator)
257    }
258    val rsys = container.lookup(classOf[RepositorySystem])
259    request.setLocalRepository(rsys.createDefaultLocalRepository)
260    request.setRemoteRepositories(Collections.singletonList(rsys.createDefaultRemoteRepository))
261    if (!settingsResult.getProblems.isEmpty && logger.isWarnEnabled) {
262      logger.warn("")
263      logger.warn("Some problems were encountered while building the effective settings")
264      for (problem <- settingsResult.getProblems) {
265        logger.warn(problem.getMessage + " @ " + problem.getLocation)
266      }
267      logger.warn("")
268    }
269    request.setShowErrors(true)
270    request.setOffline(false)
271    request.setInteractiveMode(false)
272    request.setLoggingLevel(MavenExecutionRequest.LOGGING_LEVEL_DEBUG)
273  }
274
275
276  private def createContainer: DefaultPlexusContainer = {
277    var cc: ContainerConfiguration = new DefaultContainerConfiguration
278    cc.setName("maven")
279
280    var c: DefaultPlexusContainer = new DefaultPlexusContainer(cc)
281    configureContainer(c)
282    return c
283  }
284
285
286  protected def configureContainer(c: DefaultPlexusContainer): Unit = {
287    assert(c != null)
288  }
289
290
291  private def logSummary(summary: ExceptionSummary, references: Map[String, String], indent: String, showErrors: Boolean): Unit = {
292    assert(summary != null)
293    var referenceKey: String = ""
294    if (org.codehaus.plexus.util.StringUtils.isNotEmpty(summary.getReference)) {
295      referenceKey = references.get(summary.getReference)
296      if (referenceKey == null) {
297        referenceKey = "[Help " + (references.size + 1) + "]"
298        references.put(summary.getReference, referenceKey)
299      }
300    }
301    var msg: String = indent + summary.getMessage
302    if (org.codehaus.plexus.util.StringUtils.isNotEmpty(referenceKey)) {
303      if (msg.indexOf('\n') < 0) {
304        msg += " -> " + referenceKey
305      }
306      else {
307        msg += '\n' + indent + "-> " + referenceKey
308      }
309    }
310    if (showErrors) {
311      logger.error(msg, summary.getException)
312    }
313    else {
314      logger.error(msg)
315    }
316    val childIndent = indent + "  "
317    for (child <- summary.getChildren) {
318      logSummary(child, references, childIndent, showErrors)
319    }
320  }
321}