Skip to content

Commit

Permalink
Merge pull request #227 from guardrail-dev/1.x
Browse files Browse the repository at this point in the history
Initial milestone release
  • Loading branch information
blast-hardcheese authored Dec 26, 2023
2 parents 242e61d + c51e479 commit 5ae2e82
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 64 deletions.
8 changes: 3 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,15 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
java: [ '8', '11', '17' ]
java: [ '1.14', '1.17' ]
scala: [ '2.12.18' ]
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Set up JDK
uses: actions/[email protected]
- uses: olafurpg/setup-scala@v14
with:
distribution: 'temurin'
java-version: ${{ matrix.java }}
java-version: zulu@${{ matrix.java }}
- name: print Java version
run: java -version
- name: Coursier cache
Expand Down
2 changes: 0 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,3 @@ lazy val root = (project in file("."))

lazy val core = (project in file("modules/core"))
.settings(commonSettings)

addCommandAlias("publishLegacy", "set ThisBuild / organization := \"com.twilio\"; set publishTo := sonatypePublishToBundle.value; publishSigned")
17 changes: 16 additions & 1 deletion modules/core/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,28 @@ description := "Core of sbt-guardrail plugin, for custom forks of guardrail"
addCompilerPlugin("org.typelevel" %% "kind-projector" % "0.10.3")

// Explicitly pinning this to a binding so we can grep for it
val guardrailCoreVersion = "0.75.3"
val guardrailCoreVersion = "1.0.0-M1"
resolvers +=
"Sonatype OSS Snapshots" at "https://s01.oss.sonatype.org/content/repositories/snapshots"

// Dependencies
libraryDependencies ++= Seq(
"dev.guardrail" %% "guardrail-core" % guardrailCoreVersion,
"org.snakeyaml" % "snakeyaml-engine" % "2.7"
)

// Versioning
enablePlugins(GitBranchPrompt)
enablePlugins(GitVersioning)
git.useGitDescribe := true

git.gitDescribedVersion := git.gitDescribedVersion(v => {
import scala.sys.process._
val nativeGitDescribeResult = ("git describe --tags --always HEAD" !!).trim
git.defaultTagByVersionStrategy(nativeGitDescribeResult)
}).value

git.gitUncommittedChanges := git.gitCurrentTags.value.isEmpty

buildInfoKeys := Seq[BuildInfoKey](organization, version)
buildInfoPackage := "dev.guardrail.sbt"
54 changes: 25 additions & 29 deletions modules/core/src/main/scala/AbstractCodegenPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ import dev.guardrail.{
Args => ArgsImpl,
AuthImplementation,
CodegenTarget => CodegenTargetImpl,
Context => ContextImpl
Context => ContextImpl,
TagsBehaviour
}

trait AbstractGuardrailPlugin extends GuardrailRunner { self: AutoPlugin =>
trait AbstractGuardrailPlugin { self: AutoPlugin =>
val runner = new GuardrailRunner {}
override def requires = JvmPlugin
override def trigger = allRequirements

Expand All @@ -29,7 +31,7 @@ trait AbstractGuardrailPlugin extends GuardrailRunner { self: AutoPlugin =>
encodeOptionalAs: Option[CodingConfig],
decodeOptionalAs: Option[CodingConfig],
customExtraction: Option[Boolean],
tagsBehaviour: Option[ContextImpl.TagsBehaviour],
tagsBehaviour: Option[TagsBehaviour],
authImplementation: Option[AuthImplementation]
): ArgsImpl = {
val propertyRequirement = (encodeOptionalAs, decodeOptionalAs) match {
Expand All @@ -45,27 +47,25 @@ trait AbstractGuardrailPlugin extends GuardrailRunner { self: AutoPlugin =>
def kindaLens[A](member: Option[A])(proj: A => ContextImpl => ContextImpl): ContextImpl => ContextImpl = member.fold[ContextImpl => ContextImpl](identity _)(proj)

val contextTransforms = Seq[ContextImpl => ContextImpl](
kindaLens(authImplementation)(a => _.copy(authImplementation=a)),
kindaLens(customExtraction)(a => _.copy(customExtraction=a)),
kindaLens(tagsBehaviour)(a => _.copy(tagsBehaviour=a)),
kindaLens(tracing)(a => _.copy(tracing=a))
kindaLens(authImplementation)(a => _.withAuthImplementation(a)),
kindaLens(customExtraction)(a => _.withCustomExtraction(a)),
kindaLens(tagsBehaviour)(a => _.withTagsBehaviour(a)),
kindaLens(tracing)(a => _.withTracing(a))
)

ArgsImpl.empty.copy(
defaults=defaults,
kind=kind,
specPath=specPath.map(_.getPath),
packageName=packageName.map(_.split('.').toList),
dtoPackage=dtoPackage.toList.flatMap(_.split('.').filterNot(_.isEmpty).toList),
imports=imports,
context=contextTransforms.foldLeft(
ContextImpl.empty.copy(
framework=framework,
modules=modules,
propertyRequirement=propertyRequirement
)
)({ case (acc, next) => next(acc) })
)
ArgsImpl.empty
.withDefaults(defaults)
.withKind(kind)
.withSpecPath(specPath.map(_.getPath))
.withPackageName(packageName.map(_.split('.').toList))
.withDtoPackage(dtoPackage.toList.flatMap(_.split('.').filterNot(_.isEmpty).toList))
.withImports(imports)
.withContext(contextTransforms.foldLeft(
ContextImpl.empty
.withFramework(framework)
.withModules(modules)
.withPropertyRequirement(propertyRequirement)
)({ case (acc, next) => next(acc) }))
}

sealed trait ClientServer {
Expand All @@ -83,7 +83,7 @@ trait AbstractGuardrailPlugin extends GuardrailRunner { self: AutoPlugin =>
encodeOptionalAs: Keys.GuardrailConfigValue[CodingConfig] = Keys.Default,
decodeOptionalAs: Keys.GuardrailConfigValue[CodingConfig] = Keys.Default,
customExtraction: Keys.GuardrailConfigValue[Boolean] = Keys.Default,
tagsBehaviour: Keys.GuardrailConfigValue[ContextImpl.TagsBehaviour] = Keys.Default,
tagsBehaviour: Keys.GuardrailConfigValue[TagsBehaviour] = Keys.Default,
authImplementation: Keys.GuardrailConfigValue[AuthImplementation] = Keys.Default,
): Types.Args = (language, impl(
kind = kind,
Expand Down Expand Up @@ -112,7 +112,7 @@ trait AbstractGuardrailPlugin extends GuardrailRunner { self: AutoPlugin =>
encodeOptionalAs: Keys.GuardrailConfigValue[CodingConfig] = Keys.Default,
decodeOptionalAs: Keys.GuardrailConfigValue[CodingConfig] = Keys.Default,
customExtraction: Keys.GuardrailConfigValue[Boolean] = Keys.Default,
tagsBehaviour: Keys.GuardrailConfigValue[ContextImpl.TagsBehaviour] = Keys.Default,
tagsBehaviour: Keys.GuardrailConfigValue[TagsBehaviour] = Keys.Default,
authImplementation: Keys.GuardrailConfigValue[AuthImplementation] = Keys.Default,

// Deprecated parameters
Expand Down Expand Up @@ -188,10 +188,6 @@ trait AbstractGuardrailPlugin extends GuardrailRunner { self: AutoPlugin =>
}

private def cachedGuardrailTask(projectName: String, scope: String, scalaBinaryVersion: String)(kind: String, streams: _root_.sbt.Keys.TaskStreams)(tasks: List[(String, Args)], sources: Seq[java.io.File]) = {
if (BuildInfo.organization == "com.twilio" && tasks.nonEmpty) {
streams.log.warn(s"""${projectName} / ${scope}: sbt-guardrail has changed organizations! Please change "com.twilio" to "dev.guardrail" to continue receiving updates""")
}

val inputFiles = tasks.flatMap(_._2.specPath).map(file(_)).toSet
val cacheDir = streams.cacheDirectory / "guardrail" / scalaBinaryVersion / kind

Expand All @@ -200,7 +196,7 @@ trait AbstractGuardrailPlugin extends GuardrailRunner { self: AutoPlugin =>
_ =>
GuardrailAnalysis(
BuildInfo.version,
Tasks.guardrailTask(guardrailRunner)(tasks, sources.head)
Tasks.guardrailTask(runner.guardrailRunner)(tasks, sources.head)
).products
}

Expand Down
6 changes: 3 additions & 3 deletions modules/core/src/main/scala/Keys.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import java.io.File
import _root_.sbt.{ SettingKey, TaskKey }
import scala.language.implicitConversions

import dev.guardrail.{AuthImplementation, Context}
import dev.guardrail.{AuthImplementation, Context, TagsBehaviour}
import dev.guardrail.terms.protocol.PropertyRequirement

sealed trait CodingConfig {
Expand Down Expand Up @@ -44,8 +44,8 @@ object Keys {
def codingOptional: CodingConfig = CodingConfig.Optional
def codingOptionalLegacy: CodingConfig = CodingConfig.OptionalLegacy

def tagsAreIgnored: Context.TagsBehaviour = Context.TagsAreIgnored
def tagsAsPackage: Context.TagsBehaviour = Context.PackageFromTags
def tagsAreIgnored: TagsBehaviour = TagsBehaviour.TagsAreIgnored
def tagsAsPackage: TagsBehaviour = TagsBehaviour.PackageFromTags

def authImplementationDisable: AuthImplementation = AuthImplementation.Disable
def authImplementationNative: AuthImplementation = AuthImplementation.Native
Expand Down
18 changes: 9 additions & 9 deletions modules/core/src/main/scala/Tasks.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package dev.guardrail
package sbt

import _root_.sbt.{FeedbackProvidedException, WatchSource}
import cats.data.NonEmptyList
import cats.implicits._
import cats.~>
import dev.guardrail.{Args => ArgsImpl}
Expand All @@ -15,7 +14,7 @@ class CodegenFailedException extends FeedbackProvidedException

object Tasks {
def guardrailTask(
runner: Map[String,NonEmptyList[ArgsImpl]] => Target[List[Path]]
runner: (String, Array[ArgsImpl]) => Target[List[Path]]
)(tasks: List[Types.Args], sourceDir: File): Set[File] = {
// swagger-parser uses SPI to find extensions on the classpath (by default, only the OAPI2 -> OAPI3 converter)
// See https://github.com/swagger-api/swagger-parser#extensions
Expand All @@ -28,20 +27,21 @@ object Tasks {
Thread.currentThread().setContextClassLoader(classOf[SwaggerParserExtension].getClassLoader)

try {
val preppedTasks: Map[String, NonEmptyList[ArgsImpl]] = tasks.foldLeft(Map.empty[String, NonEmptyList[ArgsImpl]]) { case (acc, (language, args)) =>
val prepped = args.copy(outputPath=Some(sourceDir.getPath))
acc.updated(language, acc.get(language).fold(NonEmptyList.one(prepped))(_ :+ prepped))
val preppedTasks: List[(String, Array[ArgsImpl])] = {
tasks.foldLeft(Map.empty[String, List[ArgsImpl]])({ case (acc, (language, args)) =>
val prepped = args.withOutputPath(Some(sourceDir.getPath))
acc.updated(language, (acc.get(language).getOrElse(List.empty[ArgsImpl]) :+ prepped))
}).mapValues(_.toList.toArray).toList
}

val /*(logger,*/ paths/*)*/ =
runner
.apply(preppedTasks)
preppedTasks.toList.traverse(runner.tupled)
.fold[List[java.nio.file.Path]]({
case MissingArg(args, Error.ArgName(arg)) =>
println(s"${AnsiColor.RED}Missing argument:${AnsiColor.RESET} ${AnsiColor.BOLD}${arg}${AnsiColor.RESET} (In block ${args})")
throw new CodegenFailedException()
case MissingDependency(name) =>
println(s"""${AnsiColor.RED}Missing dependency:${AnsiColor.RESET} ${AnsiColor.BOLD}libraryDependencies += "dev.guardrail" %% "${name}" % "<check latest version>"${AnsiColor.RESET}""")
println(s"""${AnsiColor.RED}Missing dependency:${AnsiColor.RESET} ${AnsiColor.BOLD}libraryDependencies += "dev.guardrail" %% "guardrail-${name}" % "<check latest version>"${AnsiColor.RESET}""")
throw new CodegenFailedException()
case NoArgsSpecified =>
List.empty
Expand Down Expand Up @@ -83,7 +83,7 @@ object Tasks {
case UnusedModules(unused) =>
println(s"${AnsiColor.RED}Unused modules specified:${AnsiColor.RESET} ${unused.toList.mkString(", ")}")
throw new CodegenFailedException()
}, identity)
}, _.flatten.distinct)
//.runEmpty

paths.map(_.toFile).toSet
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
else addSbtPlugin("dev.guardrail" % "sbt-guardrail" % pluginVersion)
}

libraryDependencies += "dev.guardrail" %% "guardrail-java-support" % "0.73.1"
libraryDependencies += "dev.guardrail" %% "guardrail-java-async-http" % "0.72.0"
libraryDependencies += "dev.guardrail" %% "guardrail-java-dropwizard" % "0.72.0"
libraryDependencies += "dev.guardrail" %% "guardrail-java-support" % "1.0.0-M1"
libraryDependencies += "dev.guardrail" %% "guardrail-java-async-http" % "1.0.0-M1"
libraryDependencies += "dev.guardrail" %% "guardrail-java-dropwizard" % "1.0.0-M1"
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
else addSbtPlugin("dev.guardrail" % "sbt-guardrail" % pluginVersion)
}

libraryDependencies += "dev.guardrail" %% "guardrail-scala-support" % "0.75.3"
libraryDependencies += "dev.guardrail" %% "guardrail-scala-akka-http" % "0.76.0"
libraryDependencies += "dev.guardrail" %% "guardrail-scala-support" % "1.0.0-M1"
libraryDependencies += "dev.guardrail" %% "guardrail-scala-akka-http" % "1.0.0-M1"
24 changes: 14 additions & 10 deletions src/test/scala/dev/guardrail/sbt/ContextParameterSpec.scala
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
package dev.guardrail.sbt

import dev.guardrail.Context
import dev.guardrail.{ AuthImplementation, Context, TagsBehaviour }

import org.scalatest.funsuite.AnyFunSuite
import org.scalatest.matchers.should.Matchers

class EscapeTreeSpec extends AnyFunSuite with Matchers {

test("Ensure that all Context fields are accounted for") {
val Context(
framework,
customExtraction,
tracing,
modules,
propertyRequirement,
tagsBehaviour,
authImplementation
) = Context.empty
val built = Context(
None,
customExtraction = false,
tracing = false,
modules = List.empty,
propertyRequirement = dev.guardrail.terms.protocol.PropertyRequirement.Configured(
dev.guardrail.terms.protocol.PropertyRequirement.OptionalLegacy,
dev.guardrail.terms.protocol.PropertyRequirement.OptionalLegacy
),
tagsBehaviour = TagsBehaviour.TagsAreIgnored,
authImplementation = AuthImplementation.Disable
)
built.toString() shouldBe (Context.empty.toString())
}
}

0 comments on commit 5ae2e82

Please sign in to comment.