@@ -3,6 +3,9 @@ package org.scalanative.bindgen.sbt
3
3
import sbt ._
4
4
import sbt .Keys ._
5
5
6
+ import java .nio .file .Files
7
+ import java .nio .file .attribute .{PosixFileAttributeView , PosixFilePermission }
8
+
6
9
import org .scalanative .bindgen .Bindgen
7
10
8
11
/**
@@ -42,8 +45,9 @@ import org.scalanative.bindgen.Bindgen
42
45
object ScalaNativeBindgenPlugin extends AutoPlugin {
43
46
44
47
object autoImport {
48
+ val ScalaNativeBindgen = config(" scala-native-bindgen" ).hide
45
49
val nativeBindgenPath =
46
- taskKey[Option [ File ] ](" Path to the scala-native-bindgen executable" )
50
+ taskKey[File ](" Path to the scala-native-bindgen executable" )
47
51
val nativeBindgenHeader = taskKey[File ](" C header file" )
48
52
val nativeBindgenPackage =
49
53
settingKey[Option [String ]](" Package for the generated code" )
@@ -57,7 +61,46 @@ object ScalaNativeBindgenPlugin extends AutoPlugin {
57
61
override def requires = plugins.JvmPlugin
58
62
59
63
override def projectSettings : Seq [Setting [_]] =
60
- nativeBindgenScopedSettings(Compile )
64
+ inConfig(ScalaNativeBindgen )(Defaults .configSettings) ++
65
+ nativeBindgenScopedSettings(Compile ) ++
66
+ Def .settings(
67
+ ivyConfigurations += ScalaNativeBindgen ,
68
+ version in nativeBindgen := BuildInfo .version,
69
+ libraryDependencies ++= {
70
+ artifactName.map { name =>
71
+ val bindgenVersion = (version in nativeBindgen).value
72
+ val url =
73
+ s " ${BuildInfo .projectUrl}/releases/download/v $bindgenVersion/ $name"
74
+
75
+ BuildInfo .organization % name % bindgenVersion % ScalaNativeBindgen from (url)
76
+ }.toSeq
77
+ },
78
+ nativeBindgenPath := {
79
+ val scalaNativeBindgenUpdate = (update in ScalaNativeBindgen ).value
80
+
81
+ val artifactFile = artifactName match {
82
+ case None =>
83
+ sys.error(
84
+ " No downloadable binaries available for your OS, " +
85
+ " please provide path via `nativeBindgenPath`" )
86
+ case Some (name) =>
87
+ scalaNativeBindgenUpdate
88
+ .select(artifact = artifactFilter(name = name))
89
+ .head
90
+ }
91
+
92
+ // Set the executable bit on the expected path to fail if it doesn't exist
93
+ for (view <- Option (
94
+ Files .getFileAttributeView(artifactFile.toPath,
95
+ classOf [PosixFileAttributeView ]))) {
96
+ val permissions = view.readAttributes.permissions
97
+ if (permissions.add(PosixFilePermission .OWNER_EXECUTE ))
98
+ view.setPermissions(permissions)
99
+ }
100
+
101
+ artifactFile
102
+ }
103
+ )
61
104
62
105
private implicit class BindgenOps (val bindgen : Bindgen ) extends AnyVal {
63
106
def maybe [T ](opt : Option [T ], f : Bindgen => T => Bindgen ): Bindgen =
@@ -67,23 +110,28 @@ object ScalaNativeBindgenPlugin extends AutoPlugin {
67
110
}
68
111
}
69
112
113
+ private val artifactName =
114
+ Option (System .getProperty(" os.name" )).collect {
115
+ case " Mac OS X" => " scala-native-bindgen-darwin"
116
+ case " Linux" => " scala-native-bindgen-linux"
117
+ }
118
+
70
119
def nativeBindgenScopedSettings (conf : Configuration ): Seq [Setting [_]] =
71
120
inConfig(conf)(
72
- Seq (
121
+ Def .settings (
73
122
nativeBindgenHeader := {
74
123
sys.error(" nativeBindgenHeader not configured" )
75
124
},
76
- nativeBindgenPath := None ,
77
125
nativeBindgenPackage := None ,
78
126
nativeBindgenExclude := None ,
79
127
resourceDirectories in nativeBindgen := resourceDirectories.value,
80
128
sourceGenerators += Def .task { Seq (nativeBindgen.value) },
81
129
name in nativeBindgen := " ScalaNativeBindgen" ,
82
130
nativeBindgen := {
83
- val output = sourceManaged.value / " sbt-scala-native-bindgen" / " nativeBindgen .scala"
131
+ val output = sourceManaged.value / " sbt-scala-native-bindgen" / " ScalaNativeBindgen .scala"
84
132
85
133
Bindgen ()
86
- .bindgenExecutable(nativeBindgenPath.value.get )
134
+ .bindgenExecutable(nativeBindgenPath.value)
87
135
.header(nativeBindgenHeader.value)
88
136
.name((name in nativeBindgen).value)
89
137
.maybe(nativeBindgenLink.value, _.link)
0 commit comments