Skip to content

Only generate files automatically when binding source is managed #164

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

Merged
merged 1 commit into from
Aug 15, 2018
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
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ object ScalaNativeBindgenPlugin extends AutoPlugin {
val NativeBinding = BindingOptions
val ScalaNativeBindgen = config("scala-native-bindgen").hide
val nativeBindgenPath =
taskKey[File]("Path to the scala-native-bindgen executable")
settingKey[Option[File]]("Path to the scala-native-bindgen executable")
val nativeBindgenResolvedPath =
taskKey[File]("Resolved path to the scala-native-bindgen executable")
val nativeBindings =
settingKey[Seq[NativeBinding]]("Configuration for each bindings")
val nativeBindgen = taskKey[Seq[File]]("Generate Scala Native bindings")
Expand All @@ -69,40 +71,52 @@ object ScalaNativeBindgenPlugin extends AutoPlugin {
Def.settings(
ivyConfigurations += ScalaNativeBindgen,
version in nativeBindgen := BuildInfo.version,
nativeBindgenPath := None,
libraryDependencies ++= {
artifactName.map { name =>
val bindgenVersion = (version in nativeBindgen).value
val url =
s"${BuildInfo.projectUrl}/releases/download/v$bindgenVersion/$name"
(nativeBindgenPath.value, artifactName) match {
case (None, Some(name)) =>
val bindgenVersion = (version in nativeBindgen).value
val url =
s"${BuildInfo.projectUrl}/releases/download/v$bindgenVersion/$name"

BuildInfo.organization % name % bindgenVersion % ScalaNativeBindgen from (url)
}.toSeq
Seq(
BuildInfo.organization % name % bindgenVersion % ScalaNativeBindgen from (url))
case _ =>
Seq.empty
}
},
nativeBindgenPath := {
val scalaNativeBindgenUpdate = (update in ScalaNativeBindgen).value

val artifactFile = artifactName match {
nativeBindgenResolvedPath := Def.taskDyn {
nativeBindgenPath.value match {
case Some(path) => Def.task { path }
case None =>
sys.error(
"No downloadable binaries available for your OS, " +
"please provide path via `nativeBindgenPath`")
case Some(name) =>
scalaNativeBindgenUpdate
.select(artifact = artifactFilter(name = name))
.head
}
Def.task {
val scalaNativeBindgenUpdate =
(update in ScalaNativeBindgen).value

// Set the executable bit on the expected path to fail if it doesn't exist
for (view <- Option(
Files.getFileAttributeView(artifactFile.toPath,
classOf[PosixFileAttributeView]))) {
val permissions = view.readAttributes.permissions
if (permissions.add(PosixFilePermission.OWNER_EXECUTE))
view.setPermissions(permissions)
}
val artifactFile = artifactName match {
case None =>
sys.error(
"No downloadable binaries available for your OS, " +
"please provide path via `nativeBindgenPath`")
case Some(name) =>
scalaNativeBindgenUpdate
.select(artifact = artifactFilter(name = name))
.head
}

artifactFile
}
// Set the executable bit on the expected path to fail if it doesn't exist
for (view <- Option(Files.getFileAttributeView(
artifactFile.toPath,
classOf[PosixFileAttributeView]))) {
val permissions = view.readAttributes.permissions
if (permissions.add(PosixFilePermission.OWNER_EXECUTE))
view.setPermissions(permissions)
}

artifactFile
}
}
}.value
)

private val artifactName =
Expand All @@ -115,10 +129,19 @@ object ScalaNativeBindgenPlugin extends AutoPlugin {
inConfig(conf)(
Def.settings(
nativeBindings := Seq.empty,
sourceGenerators += Def.task { nativeBindgen.value },
target in nativeBindgen := sourceManaged.value / "sbt-scala-native-bindgen",
sourceGenerators += Def.taskDyn {
val nativeBindgenTarget = (target in nativeBindgen).value.toPath
val managedSource = sourceManaged.value.toPath

if (nativeBindgenTarget.startsWith(managedSource)) {
Def.task { nativeBindgen.value }
} else {
Def.task { Seq.empty[File] }
}
},
nativeBindgen := {
val bindgen = Bindgen(nativeBindgenPath.value)
val bindgen = Bindgen(nativeBindgenResolvedPath.value)
val optionsList = nativeBindings.value
val outputDirectory = (target in nativeBindgen).value
val logger = streams.value.log
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,13 @@ enablePlugins(ScalaNativeBindgenPlugin)

//#example
scalaVersion := "2.11.12"
nativeBindgenPath := Some(file(System.getProperty("bindgen.path")))

//#example
inConfig(Compile)(
Def.settings(
//#example
nativeBindgenPath := file(System.getProperty("bindgen.path")),
//#example
nativeBindings += {
NativeBinding((resourceDirectory in Compile).value / "stdlib.h")
NativeBinding(resourceDirectory.value / "stdlib.h")
.name("stdlib")
.packageName("org.example.app.stdlib")
.excludePrefix("__")
Expand Down
13 changes: 13 additions & 0 deletions sbt-scala-native-bindgen/src/sbt-test/bindgen/generate/test
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
# Generate bindings in managed source mode
> sources
$ must-mirror target/scala-2.11/src_managed/main/sbt-scala-native-bindgen/stdlib.scala expected/stdlib.scala

# Generate bindings when nativeBindgen is explicitly run
> clean
> nativeBindgen
$ must-mirror target/scala-2.11/src_managed/main/sbt-scala-native-bindgen/stdlib.scala expected/stdlib.scala

# Not generate bindings when not in managed source mode
> clean
> set target in (Compile, nativeBindgen) := nativeBindgenCustomTarget.value
> sources
$ absent src/main/scala/org/example/stdlib.scala

# Support custom output path
> clean
> nativeBindgen
$ must-mirror src/main/scala/org/example/stdlib.scala expected/stdlib.scala

# Support multiple bindings
> clean
> set nativeBindings in Compile += nativeBindgenCoreBinding.value
> nativeBindgen
Expand Down