MavenCli - stdout,stderr

时间:2016-06-14 18:32:08

标签: scala maven maven-embedder

我一直在尝试使用MavenCli,将ByteArrayOutpurStream - s设为stdoutstderr。 我有测试验证一些记录写入这些流。 只要我有一个测试,一切都没问题。 但是,如果我引入另一个测试,它会失败,因为没有任何内容写入stdout。

这是一个片段(Scala):

class MyIT extends SpecWithJUnit {

  sequential

  trait Ctx extends Scope {
    val outStream = new ByteArrayOutpurStream()
    val errStream = new ByteArrayOutpurStream()
    val pomDir = Files.createTempDirectory("test_pom_").toFile
    val mavenCli = new MavenCli()

    def haveWrote(str: String): Matcher[Int] = {
      contain(str) ^^ { (_: Int) => 
          new String(outStream.toByteArray, "UTF-8") aka "written records" }
    }

    def maven(pom: Elem, goals: String*): Int = {
      val pomFile = new File(pomDir, "pom.xml")

      XML.save(pomFile.getCanonicalPath, pom)

      System.setProperty(
          "maven.multiModuleProjectDirectory", 
          pomDir.getCanonicalPath)

      mavenCli.doMain(
          goals.toArray,
          pomDir.getCanonicalPath, 
          new PrintStream(outStream), 
          new PrintStream(errStream))
    }
  }


  "test 1" should {
    "write something" in new Ctx {
      val pomXml =
        <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xmlns="http://maven.apache.org/POM/4.0.0">
          <modelVersion>4.0.0</modelVersion>

          <groupId>com.company</groupId>
          <artifactId>some-artifact-id</artifactId>
          <version>1.0.0-SNAPSHOT</version>
          <description>some meaningful description</description>
          <name>some catchy name</name>
          ...
        </project>

      maven(pomXml, "clean" "validate") must haveWrote("something")
    }

    "write something else" in new Ctx {
      val pomXml =
        <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xmlns="http://maven.apache.org/POM/4.0.0">
          <modelVersion>4.0.0</modelVersion>

          <groupId>com.company</groupId>
          <artifactId>some-artifact-id</artifactId>
          <version>1.0.0-SNAPSHOT</version>
          <description>some meaningful description</description>
          <name>some catchy name</name>
          ... (different than the "write something" test)
        </project>

      maven(pomXml, "clean" "validate") must haveWrote("something else")
    }
  }
}

如果我评论"write something"测试,则"write something else"通过。

如果我评论"write something else"测试(并取消注释"write something"),则会"write something"通过。

如果两者都被取消注释并执行,则会失败("write something else",因为它是连续的)。

在maven执行后添加println -s outStream,原因似乎是outStream为空......

我无法弄清楚为什么,或者更重要的是,如何解决方法。

任何想法?...

提前致谢, 辖

1 个答案:

答案 0 :(得分:0)

好的,我放弃了MavenCli方法,转而支持Maven.execute(MavenExecutionRequest)。这本身并没有解决问题,但我能够引入自己的ExecutionListener,而不是默认的ExecutionEventLogger。我的执行监听器直接记录记录,而不使用任何记录框架,这似乎解决了这个问题。

代码现在看起来像:

class MyIT extends SpecWithJUnit {

  sequential

  def plexusContainer = {
    val containerConfig = new DefaultContainerConfiguration()
      .setClassPathScanning(PlexusConstants.SCANNING_INDEX)
      .setAutoWiring(true)
      .setName("maven")
    val container = new DefaultPlexusContainer(containerConfig)

    container
  }

  def buildMavenRequest(pomFile: Path,
                        executionListener: ExecutionListener,
                        goals: String*): MavenExecutionRequest = {
    val userProperties = new Properties()
    val executionRequestPopulator = plexusContainer.lookup(classOf[MavenExecutionRequestPopulator])
    val req = new DefaultMavenExecutionRequest()
      .setPom(pomFile.toFile)
      .setBaseDirectory(pomFile.getParent.toFile)
      .setGoals(goals)
      .setInteractiveMode(false)
      .setExecutionListener(executionListener)
      .setUserProperties(userProperties)

    executionRequestPopulator.populateDefaults(req)
  }

  def maven(pomFile: Path,
            executionListener: ExecutionListener,
            goals: String*): MavenExecutionResult = {
    val mavenRequest = buildMavenRequest(pomFile, executionListener, goals: _*)
    val mvn = plexusContainer.lookup(classOf[Maven])

    mvn.execute(mavenRequest)
  }

  def readFile(filename: Path): Seq[String] = {
    Source.fromFile(filename.toString).getLines().foldLeft(Seq.empty[String]){ _ :+ _ }
  }


  trait Ctx extends Scope {
    val pomDir = Files.createTempDirectory("test_pom_").toFile
    val logFile = pomDir.resolve("test_log.log")
    val myExecutionListener = new MyExecutionListener(logFile)

    def haveWrote(str: String): Matcher[MavenExecutionResult] = {
      contain(str) ^^ { (_: MavenExecutionResult) => 
        readFile(logFile) aka "written records" }
    }
  }


  "test 1" should {
    "write something" in new Ctx {
      val pomXml =
        <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xmlns="http://maven.apache.org/POM/4.0.0">
          <modelVersion>4.0.0</modelVersion>

          <groupId>com.company</groupId>
          <artifactId>some-artifact-id</artifactId>
          <version>1.0.0-SNAPSHOT</version>
          <description>some meaningful description</description>
          <name>some catchy name</name>
          ...
        </project>

      maven(pomXml, "clean" "validate") must haveWrote("something")
    }

    "write something else" in new Ctx {
      val pomXml =
        <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xmlns="http://maven.apache.org/POM/4.0.0">
          <modelVersion>4.0.0</modelVersion>

          <groupId>com.company</groupId>
          <artifactId>some-artifact-id</artifactId>
          <version>1.0.0-SNAPSHOT</version>
          <description>some meaningful description</description>
          <name>some catchy name</name>
          ... (different than the "write something" test)
        </project>

      maven(pomXml, "clean" "validate") must haveWrote("something else")
    }
  }
}