diff --git a/src/main/kotlin/net/thauvin/erik/kobalt/plugin/versioneye/VersionEyePlugin.kt b/src/main/kotlin/net/thauvin/erik/kobalt/plugin/versioneye/VersionEyePlugin.kt index e19e980..8bcc717 100644 --- a/src/main/kotlin/net/thauvin/erik/kobalt/plugin/versioneye/VersionEyePlugin.kt +++ b/src/main/kotlin/net/thauvin/erik/kobalt/plugin/versioneye/VersionEyePlugin.kt @@ -36,6 +36,7 @@ import com.beust.kobalt.TaskResult import com.beust.kobalt.api.* import com.beust.kobalt.api.annotation.Directive import com.beust.kobalt.api.annotation.Task +import com.beust.kobalt.misc.KobaltLogger import com.beust.kobalt.misc.log import com.beust.kobalt.misc.warn import com.google.gson.GsonBuilder @@ -43,7 +44,6 @@ import com.google.gson.JsonObject import com.google.inject.Inject import com.google.inject.Singleton import okhttp3.* -import java.io.File import java.io.FileOutputStream import java.nio.file.Files import java.nio.file.Paths @@ -55,8 +55,11 @@ class VersionEyePlugin @Inject constructor(val configActor: ConfigActor by configActor { private val API_KEY_PROPERTY = "versioneye.apiKey" private val PROJECT_KEY_PROPERTY = "versioneye.projectKey" + private val COLORS_PROPERTY = "ve.colors" + private val VERBOSE_PROPERTY = "ve.verbose" + private val QUIET_PROPERTY = "ve.quiet" - private val debug = System.getProperty("debug", "false").toBoolean() + private val debug = System.getProperty("ve.debug", "false").toBoolean() private val httpClient = OkHttpClient() // ITaskContributor @@ -86,11 +89,13 @@ class VersionEyePlugin @Inject constructor(val configActor: ConfigActor if (config.baseUrl.isBlank()) { warn("Please specify a valid VersionEye base URL.") return TaskResult() } else { + // Load properties val projectKey = System.getProperty(PROJECT_KEY_PROPERTY) var apiKey = System.getProperty(API_KEY_PROPERTY) val p = Properties() @@ -102,7 +107,7 @@ class VersionEyePlugin @Inject constructor(val configActor: ConfigActor p.store(output, "") } @@ -132,28 +146,36 @@ class VersionEyePlugin @Inject constructor(val configActor: ConfigActor $curVer", out_number, isFailDeps, + config.colors)) + } + + // Parse licenses + var whitelisted: Int = 0 + var unknowns: Int = 0 + val licenses = dep.get("licenses").asJsonArray + if (licenses.size() > 0) { + licenses.forEach { + val license = it.asJsonObject + val onWhitelist = license.get("on_whitelist") + val onCwl = license.get("on_cwl") + if (!onWhitelist.isJsonNull) { + if (onWhitelist.asString.equals("false")) { + if (onCwl.isJsonNull) { + whitelisted++ + } else if (!onCwl.toString().equals("true")) { + whitelisted++ + } + } + } + } + } else { + unknowns++ + } + + // Whitelisted + if (whitelisted > 0) { + if (licensesInfo.isNotEmpty()) { + licensesInfo.append(lf) + } + licensesInfo.append(Utils.redLight(" - $depName: $whitelisted whitelist " + + Utils.plural("violation", whitelisted, "s"), whitelisted, isFailLicense, config.colors)) + } + + // Unknowns + if (unknowns > 0) { + if (licensesInfo.isNotEmpty()) { + licensesInfo.append(lf) + } + licensesInfo.append(Utils.redLight(" - $depName: $unknowns " + + Utils.plural("unknown license", unknowns, "s"), unknowns, isFailUnknown, config.colors)) + } + + // Security vulnerabilities + val security = dep.get("security_vulnerabilities") + if (!security.isJsonNull) { + if (securityInfo.length > 0) { + securityInfo.append(lf) + } + val count = security.asJsonArray.size() + + securityInfo.append(Utils.redLight(" - $depName: $count " + + Utils.plural("known issue", count, "s"), count, isFailSecurity, config.colors)) + } + } + + // Non-verbose failure + val verbose = (KobaltLogger.LOG_LEVEL > 1 || config.verbose) + val alt = " [FAILED]" + + // Log dependencies check results + log(1, " Dependencies: " + + Utils.redLight(out_number, isFailDeps, config.colors) + " outdated of $dep_number total" + + if (isFailDeps && !config.colors) alt else "") + Utils.log(depsInfo, verbose) + + // Log licenses check results + log(1, " Licenses: " + + Utils.redLight(licenses_red, isFailLicense, config.colors) + + " whitelist, " + + Utils.redLight(licenses_unknown, isFailUnknown, config.colors) + + Utils.plural(" unknown", licenses_unknown, "s") + + if ((isFailLicense || isFailUnknown) && !config.colors) alt else "") + Utils.log(licensesInfo, verbose) + + // Log security check results + log(1, " Security: " + + Utils.redLight(sv_count, isFailSecurity, config.colors) + + ' ' + + Utils.plural("vulnerabilit", sv_count, "ies", "y") + + if (isFailSecurity && !config.colors) alt else "") + Utils.log(securityInfo, verbose) + } + + // Show project url + if (!config.quiet) { + val baseUrl = if (config.baseUrl.endsWith('/')) config.baseUrl else config.baseUrl + '/' + log(1, " View more at: ${baseUrl}user/projects/$projectKey") + } + + // Task failure + if (out_number > 0 && isFailDeps + || licenses_red > 0 && isFailLicense + || licenses_unknown > 0 && isFailUnknown + || sv_count > 0 && isFailSecurity) { + return TaskResult(false) + } } return TaskResult() } } +enum class Fail { + dependenciesCheck, licensesUnknownCheck, licensesCheck, securityCheck +} + @Directive class VersionEyeConfig() { var baseUrl = "https://www.versioneye.com/" - var failOnUnknownLicense = false - var licenseCheck = false + var colors = true + var failSet: MutableSet = mutableSetOf() var name = "" var org = "" - var securityCheck = false + var quiet = false var team = "" - var visibility = true + var verbose = true + var visibility = "public" + + fun failOn(vararg args: Fail) { + args.forEach { + failSet.add(it) + } + } } @Directive