Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added exportContents target #5

Merged
merged 3 commits into from
Jan 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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