Skip to content

Commit

Permalink
Merge pull request #5 from lefou/export-contents
Browse files Browse the repository at this point in the history
Added exportContents target
  • Loading branch information
lefou committed Jan 19, 2020
2 parents 835452c + 15982eb commit ecf23a2
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 6 deletions.
6 changes: 6 additions & 0 deletions core/src/de/tobiasroeser/mill/osgi/OsgiBundleModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ trait OsgiBundleModule extends JavaModule {
.map(dir => dir.path.toIO.getAbsolutePath())
}

def exportContents: T[Seq[String]] = T {
Seq[String]()
}

// TODO: do we want support default Mill Jar headers?

/**
Expand Down Expand Up @@ -212,6 +216,8 @@ trait OsgiBundleModule extends JavaModule {
mergeSeqProps(builder, Constants.INCLUDERESOURCE, Seq("@" + jar.path.toIO.getAbsolutePath()))
}

mergeSeqProps(builder, Constants.EXPORT_CONTENTS, exportContents())

builder.addProperties(osgiHeaders().toProperties)

builder.addProperties(additionalHeaders().asJava)
Expand Down
88 changes: 88 additions & 0 deletions itest/src/03-WrapContents/build.sc
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import mill._
import mill.scalalib._
import $exec.plugins
import de.tobiasroeser.mill.osgi._
import mill.api.Loose
import mill.define.Target

def verify() = T.command {
import de.tobiasroeser.mill.osgi.testsupport.TestSupport._

// withManifest(hello.jar().path) { manifest =>
// checkExact(manifest, "Manifest-Version", "1.0")
// checkExact(manifest, "Bundle-SymbolicName", "hello_2.12")
// checkExact(manifest, "Bundle-Version", "0.0.0")
// checkSlices(manifest, "Private-Package", Seq("example"))
// }

val origEntries = jarFileEntries(akkaHttpCore.originalJar().path)
val osgiEntries = jarFileEntries(akkaHttpCore.osgiBundle().path)

val missingEntries = origEntries.filterNot(e => osgiEntries.contains(e))
assert("Wrapped jar has no missing entries", missingEntries.isEmpty, s"\nMissing entries:\n ${missingEntries.mkString(",\n ")}")

val addedEntries = osgiEntries.filterNot(e => origEntries.contains(e))
assert("Wrapped jar has no additional entries", addedEntries.isEmpty, s"\nAdded entries:\n ${addedEntries.mkString(",\n ")}")

assert(
"Wrapped jar contains the same entries",
origEntries.sorted == osgiEntries.sorted,
s"Different entries: ${origEntries} vs. ${osgiEntries}"
)

}

object akkaHttpCore extends ScalaModule with OsgiBundleModule {
def orig = ivy"com.typesafe.akka::akka-http-core:10.1.11"

override def scalaVersion: T[String] = "2.12.10"

override def compileIvyDeps: Target[Loose.Agg[Dep]] = T {
Agg(orig)
}

def originalJar: T[PathRef] = T {
resolveDeps(T.task {
Agg(orig.exclude("*" -> "*"))
})().toSeq.head
}

override def includeResource: T[Seq[String]] = T {
val includeFromJar = Seq(
"reference.conf",
"akka-http-version.conf",
"akka/http/ccompat/CompatImpl.class",
"akka/http/ccompat/package$.class",
"akka/http/ccompat/MapHelpers$.class",
"akka/http/ccompat/CompatImpl$.class",
"akka/http/ccompat/Builder.class",
"akka/http/ccompat/package.class",
"akka/http/ccompat/QuerySeqOptimized.class",
"akka/http/ccompat/CompatImpl$$anon$1.class",
"akka/http/ccompat/MapHelpers.class"
)
super.includeResource() ++ includeFromJar.map { f =>
s"@${originalJar().path.toIO.getAbsolutePath()}!/$f"
}
}

override def exportContents = T {
Seq(
"akka.http.ccompat"
)
}

override def osgiHeaders: T[OsgiHeaders] = T {
super.osgiHeaders().copy(
`Export-Package` = Seq(
"akka.http",
// "akka.http.ccompat",
"akka.http.ccompat.imm",
"akka.http.impl.*",
"akka.http.javadsl.*",
"akka.http.scaladsl.*",
)
)
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package de.tobiasroeser.mill.osgi.testsupport

import java.io.IOException
import java.util.jar.Manifest
import java.util.jar.{JarEntry, JarInputStream, Manifest}
import java.util.zip.ZipFile

import os.Path
Expand All @@ -23,18 +23,47 @@ trait TestSupport {

def checkSlices(manifest: Manifest, header: String, expectedSlices: Seq[String]) = {
val value = manifest.getMainAttributes().getValue(header)
if (!expectedSlices.forall(s => value.containsSlice(s))) {
sys.error(s"""Expected '${header}' header with slices ${expectedSlices.mkString("'", "' and '", "'")}! But was '${value}'""")
}
assert(
expectedSlices.forall(s => value.containsSlice(s)),
s"""Expected '${header}' header with slices ${expectedSlices.mkString("'", "' and '", "'")}! But was '${value}'"""
)
}

def checkExact(manifest: Manifest, header: String, expectedValue: String) = {
val value = manifest.getMainAttributes().getValue(header)
if (expectedValue != value) {
sys.error(s"""Expected '${header}' header with value '${expectedValue}'! But was '${value}'""")
assert(
expectedValue == value,
s"""Expected '${header}' header with value '${expectedValue}'! But was '${value}'"""
)
}

def jarFileEntries(file: os.Path): Seq[String] = {
val ois = new JarInputStream(file.getInputStream)
try {
var entry: JarEntry = ois.getNextJarEntry()
var entries: Seq[String] = Seq()
while (entry != null) {
if (!entry.isDirectory()) entries = entries ++ Seq(entry.getName())
entry = ois.getNextJarEntry()
}
entries
} finally {
ois.close()
}
}

def assert(condition: Boolean, hint: => String): Unit = {
if (!condition) {
throw new AssertionError(hint)
}
}

def assert(check: String, condition: Boolean, hint: => String): Unit = {
if(condition) println(s"Checked: ${check}")
else println(s"FAILED: ${check}")
assert(condition, hint)
}

}

object TestSupport extends TestSupport

0 comments on commit ecf23a2

Please sign in to comment.