Skip to content

Commit

Permalink
feat: support additional entry points for other operating systems (i.…
Browse files Browse the repository at this point in the history
…e. requiring a .bat file for Windows)
  • Loading branch information
uglyog committed Oct 11, 2021
1 parent b72772f commit 0f93dd2
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 4 deletions.
2 changes: 1 addition & 1 deletion docs/content-matcher-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ For a content matcher or generator, the entries need to be:

#### Entry Type

The entry type must be set to `CONTENT_MATCHER` or `CONTENT_GENERATOR`.
The entry type must be set to `CONTENT_MATCHER` or `CONTENT_GENERATOR`.

#### Entry Key

Expand Down
1 change: 1 addition & 0 deletions docs/plugin-driver-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ The plugin manifest file describes what the plugin provides and how to load it.
| executableType | Executable type of the plugin. Supported types are: exec (executable binary) |
| minimumRequiredVersion | Minimum required version of the runtime/interpreter to run the plugin |
| entryPoint | The main executable for the plugin |
| entryPoints | Optional map of additional entry points. This allows additional entry points for other operating systems (i.e. requiring a .bat file for Windows) |
| dependencies | List of system dependencies or plugins required to be able to execute this plugin |

Example of a manifest for a plugin written in Ruby that provides matching CSV files:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,24 +48,69 @@ import java.util.concurrent.TimeUnit
import javax.json.Json
import javax.json.JsonObject

/**
* Type of plugin dependency
*/
enum class PluginDependencyType {
OSPackage, Plugin, Library, Executable
}

/**
* Details of a plugin dependency
*/
data class PluginDependency(
val name: String,
val version: String?,
val type: PluginDependencyType
)

/**
* Manifest entry that describes a plugin
*/
interface PactPluginManifest {
/**
* Directory where the manifest file is
*/
val pluginDir: File

/**
* Plugin interface version
*/
val pluginInterfaceVersion: Int

/**
* Plugin name
*/
val name: String

/**
* Plugin version
*/
val version: String

/**
* Executable type. Supported types are: exec (executable binary)
*/
val executableType: String

/**
* Minimum required version of the runtime/interpreter to run the plugin
*/
val minimumRequiredVersion: String?

/**
* The main executable for the plugin
*/
val entryPoint: String

/**
* Additional entry points for other operating systems (i.e. requiring a .bat file for Windows)
*/
val entryPoints: Map<String, String?>

/**
* List of system dependencies or plugins required to be able to execute this plugin
*/
val dependencies: List<PluginDependency>
}

Expand All @@ -77,6 +122,7 @@ data class DefaultPactPluginManifest(
override val executableType: String,
override val minimumRequiredVersion: String?,
override val entryPoint: String,
override val entryPoints: Map<String, String?>,
override val dependencies: List<PluginDependency>
): PactPluginManifest {

Expand All @@ -89,9 +135,15 @@ data class DefaultPactPluginManifest(
"executableType" to executableType,
"entryPoint" to entryPoint
)

if (!minimumRequiredVersion.isNullOrEmpty()) {
map["minimumRequiredVersion"] = minimumRequiredVersion
}

if (entryPoints.isNotEmpty()) {
map["entryPoints"] = entryPoints
}

if (dependencies.isNotEmpty()) {
map["dependencies"] = dependencies.map {
mapOf(
Expand All @@ -101,12 +153,25 @@ data class DefaultPactPluginManifest(
)
}
}

return map
}

companion object {
companion object : KLogging() {
@JvmStatic
fun fromJson(pluginDir: File, pluginJson: JsonObject): PactPluginManifest {
val entryPoints = if (pluginJson.containsKey("entryPoints")) {
when (val ep = pluginJson["entryPoints"]) {
is JsonObject -> ep.entries.associate { it.key to toString(it.value) }
else -> {
logger.warn { "entryPoints field in plugin manifest is invalid" }
emptyMap()
}
}
} else {
emptyMap()
}

return DefaultPactPluginManifest(
pluginDir,
toInteger(pluginJson["pluginInterfaceVersion"]) ?: 1,
Expand All @@ -115,6 +180,7 @@ data class DefaultPactPluginManifest(
toString(pluginJson["executableType"])!!,
toString(pluginJson["minimumRequiredVersion"]),
toString(pluginJson["entryPoint"])!!,
entryPoints,
listOf()
)
}
Expand Down Expand Up @@ -544,8 +610,13 @@ object DefaultPluginManager: KLogging(), PluginManager {
val pb = if (command.isNotEmpty()) {
ProcessBuilder(command.asList() + manifest.pluginDir.resolve(manifest.entryPoint).toString())
} else {
ProcessBuilder(manifest.pluginDir.resolve(manifest.entryPoint).toString())
}.directory(manifest.pluginDir)
val osName = System.getProperty("os.name")?.lowercase()
if (manifest.entryPoints.containsKey(osName)) {
ProcessBuilder(manifest.pluginDir.resolve(manifest.entryPoints[osName]!!).toString())
} else {
ProcessBuilder(manifest.pluginDir.resolve(manifest.entryPoint).toString())
}.directory(manifest.pluginDir)
}

val logLevel = logLevel()
pb.environment()["LOG_LEVEL"] = logLevel
Expand Down

0 comments on commit 0f93dd2

Please sign in to comment.