Skip to content

Commit

Permalink
Adding scalafmt
Browse files Browse the repository at this point in the history
  • Loading branch information
muuki88 committed Sep 17, 2017
1 parent 2a8522d commit f4c614c
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 108 deletions.
4 changes: 4 additions & 0 deletions .scalafmt
@@ -0,0 +1,4 @@
align = none
maxColumn = 120

rewrite.rules = [SortImports, RedundantBraces, RedundantParens]
1 change: 1 addition & 0 deletions project/plugins.sbt
@@ -0,0 +1 @@
addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.12")
80 changes: 45 additions & 35 deletions src/main/scala/rocks/muki/graphql/GraphQLQueryPlugin.scala
Expand Up @@ -11,10 +11,12 @@ object GraphQLQueryPlugin extends AutoPlugin {
override def requires: Plugins = GraphQLSchemaPlugin

object autoImport {

/**
* Validate all queries
*/
val graphqlValidateQueries: TaskKey[Unit] = taskKey[Unit]("validate all queries in the graphql source directory")
* Validate all queries
*/
val graphqlValidateQueries: TaskKey[Unit] =
taskKey[Unit]("validate all queries in the graphql source directory")
}

import autoImport._
Expand All @@ -25,34 +27,39 @@ object GraphQLQueryPlugin extends AutoPlugin {
graphqlValidateQueries := {
val log = streams.value.log
val schemaFile = IO.read(graphqlSchemaGen.value)
val schemaDocument = QueryParser.parse(schemaFile).getOrElse(
sys.error("Invalid graphql schema generated by `graphqlSchemaGen` task")
)
val schemaDocument = QueryParser
.parse(schemaFile)
.getOrElse(
sys.error(
"Invalid graphql schema generated by `graphqlSchemaGen` task")
)
val schema = Schema.buildFromAst(schemaDocument)


val src = (sourceDirectory in (Compile, graphqlValidateQueries)).value
val graphqlFiles = (src ** "*.graphql").get
val violations = graphqlFiles.flatMap { file =>
log.info(s"Validate ${file.getPath}")
val query = IO.read(file)
val violations = QueryParser.parse(query).fold(
error => Vector(InvalidQueryValidation(error)),
query => QueryValidator.default.validateQuery(schema, query)
)
if(violations.nonEmpty) {
log.error(s"File: ${file.getAbsolutePath}")
log.error("## Query ##")
log.error(query)
log.error("## Violations ##")
violations.foreach(v => log.error(v.errorMessage))
List(QueryViolations(file, query, violations))
} else {
Nil
}
val violations = graphqlFiles.flatMap {
file =>
log.info(s"Validate ${file.getPath}")
val query = IO.read(file)
val violations = QueryParser
.parse(query)
.fold(
error => Vector(InvalidQueryValidation(error)),
query => QueryValidator.default.validateQuery(schema, query)
)
if (violations.nonEmpty) {
log.error(s"File: ${file.getAbsolutePath}")
log.error("## Query ##")
log.error(query)
log.error("## Violations ##")
violations.foreach(v => log.error(v.errorMessage))
List(QueryViolations(file, query, violations))
} else {
Nil
}
}

if(violations.nonEmpty) {
if (violations.nonEmpty) {
log.error("Validation errors in")
violations.foreach { queryViolation =>
log.error(s"File: ${queryViolation.file.getAbsolutePath}")
Expand All @@ -64,18 +71,21 @@ object GraphQLQueryPlugin extends AutoPlugin {
)

/**
* Aggregates violations for a single file
* @param file the file that was validated
* @param query the file content
* @param violations the violations found
*/
private case class QueryViolations(file: File, query: String, violations: Seq[Violation])
* Aggregates violations for a single file
* @param file the file that was validated
* @param query the file content
* @param violations the violations found
*/
private case class QueryViolations(file: File,
query: String,
violations: Seq[Violation])

/**
* Violation when parsing failed
* @param throwable the error
*/
private case class InvalidQueryValidation(throwable: Throwable) extends Violation {
* Violation when parsing failed
* @param throwable the error
*/
private case class InvalidQueryValidation(throwable: Throwable)
extends Violation {
override def errorMessage: String = s"""|Parsing file failed
|Exception: [${throwable.getClass}]
|${throwable.getMessage}""".stripMargin
Expand Down
84 changes: 45 additions & 39 deletions src/main/scala/rocks/muki/graphql/GraphQLSchemaPlugin.scala
Expand Up @@ -13,52 +13,61 @@ object GraphQLSchemaPlugin extends AutoPlugin {
private val packageName = "graphql"

object autoImport {

/**
* A scala snippet that returns the [[sangria.schema.Schema]] for your graphql application.
*
* @example if your schema is defined on an object
* {{{
* graphqlSchemaSnippet := "com.example.MySchema.schema"
* }}}
*/
val graphqlSchemaSnippet: SettingKey[String] = settingKey[String]("code snippet that returns the sangria Schema")
* A scala snippet that returns the [[sangria.schema.Schema]] for your graphql application.
*
* @example if your schema is defined on an object
* {{{
* graphqlSchemaSnippet := "com.example.MySchema.schema"
* }}}
*/
val graphqlSchemaSnippet: SettingKey[String] =
settingKey[String]("code snippet that returns the sangria Schema")

/**
* Generates a the graphql schema based on the code snippet provided via `graphqlSchemaSnippet`
*/
val graphqlSchemaGen: TaskKey[File] = taskKey[File]("generates a graphql schema file")
* Generates a the graphql schema based on the code snippet provided via `graphqlSchemaSnippet`
*/
val graphqlSchemaGen: TaskKey[File] =
taskKey[File]("generates a graphql schema file")

/**
* Returns the changes between the schema from `graphqlSchemaGen` and
*/
val graphqlSchemaChanges: TaskKey[Vector[SchemaChange]] = taskKey[Vector[SchemaChange]]("compares two schemas")
* Returns the changes between the schema from `graphqlSchemaGen` and
*/
val graphqlSchemaChanges: TaskKey[Vector[SchemaChange]] =
taskKey[Vector[SchemaChange]]("compares two schemas")

/**
* The currently active / deployed graphql schema.
*/
val graphqlProductionSchema: TaskKey[Schema[Any,Any]] = taskKey[Schema[Any,Any]]("Graphql schema from your production system")
* The currently active / deployed graphql schema.
*/
val graphqlProductionSchema: TaskKey[Schema[Any, Any]] =
taskKey[Schema[Any, Any]]("Graphql schema from your production system")

/**
* Validates the new schema against existing queries and the production schema
*/
val graphqlValidateSchema: TaskKey[Unit] = taskKey[Unit]("Validates the new schema against existing queries and the production schema")
* Validates the new schema against existing queries and the production schema
*/
val graphqlValidateSchema: TaskKey[Unit] = taskKey[Unit](
"Validates the new schema against existing queries and the production schema")

/**
* Creates realease notes for changes between the production and the current schema
*/
val graphqlReleaseNotes: TaskKey[String] = taskKey[String]("Creates realease notes for changes between the production and the current schema")
* Creates realease notes for changes between the production and the current schema
*/
val graphqlReleaseNotes: TaskKey[String] = taskKey[String](
"Creates realease notes for changes between the production and the current schema")

/**
* Helper to load schemas from different places
*/
val SchemaLoader: rocks.muki.graphql.schema.SchemaLoader.type = rocks.muki.graphql.schema.SchemaLoader
* Helper to load schemas from different places
*/
val SchemaLoader: rocks.muki.graphql.schema.SchemaLoader.type =
rocks.muki.graphql.schema.SchemaLoader
}
import autoImport._

override def projectSettings: Seq[Setting[_]] = Seq(
graphqlSchemaSnippet := """sys.error("Configure the `graphqlSchemaSnippet` setting with the correct scala code snippet to access your sangria schema")""",
graphqlProductionSchema := Schema.buildFromAst(Document.emptyStub),
graphqlSchemaChanges := SchemaLoader.fromFile(graphqlSchemaGen.value) compare graphqlProductionSchema.value,
graphqlSchemaChanges := SchemaLoader
.fromFile(graphqlSchemaGen.value) compare graphqlProductionSchema.value,
graphqlSchemaGen := {
val schemaFile = resourceManaged.value / "sbt-sangria-codegen" / "schema.graphql"
runner.value.run(
Expand All @@ -70,32 +79,29 @@ object GraphQLSchemaPlugin extends AutoPlugin {
streams.value.log.info(s"Generating schema in $schemaFile")
schemaFile
},

graphqlValidateSchema := {
val log = streams.value.log
val breakingChanges = graphqlSchemaChanges.value.filter(_.breakingChange)
if(breakingChanges.nonEmpty) {
breakingChanges.foreach(change => log.error(s" * ${change.description}"))
if (breakingChanges.nonEmpty) {
breakingChanges.foreach(change =>
log.error(s" * ${change.description}"))
quietError("Validation failed: Breaking changes found")
}
},

graphqlReleaseNotes := graphqlSchemaChanges.value
.map(change => s"* ${change.description}")
.mkString(start = "## Changes\n", sep = "\n", end = "\n"),


// Generates a small snippet that generates a graphql schema
sourceGenerators in Compile += generateSchemaGeneratorClass()
)

/**
* Generates a small code snippet that accesses the schema definition in the original
* code base and renders it as a graphql schema definition file.
*
* @see https://github.com/mediative/sangria-codegen/blob/master/sbt-sangria-codegen/src/main/scala/com.mediative.sangria.codegen.sbt/SangriaSchemagenPlugin.scala#L121-L153
* @return
*/
* Generates a small code snippet that accesses the schema definition in the original
* code base and renders it as a graphql schema definition file.
*
* @see https://github.com/mediative/sangria-codegen/blob/master/sbt-sangria-codegen/src/main/scala/com.mediative.sangria.codegen.sbt/SangriaSchemagenPlugin.scala#L121-L153
* @return
*/
private def generateSchemaGeneratorClass() = Def.task {
val schemaCode = graphqlSchemaSnippet.value
val file = sourceManaged.value / "sbt-sangria-codegen" / s"$mainClass.scala"
Expand Down
72 changes: 38 additions & 34 deletions src/main/scala/rocks/muki/graphql/schema/SchemaLoader.scala
Expand Up @@ -15,44 +15,46 @@ import scala.util.{Failure, Success}
import scalaj.http.Http

/**
* Defines a specific way for loading graphql schemas.
*/
* Defines a specific way for loading graphql schemas.
*/
trait SchemaLoader {

/**
* Load the schema.
* The Context and Val types are always any as we cannot make any
* assumptions while loading an external schema.
*
* @return the successful loaded schema
*/
* Load the schema.
* The Context and Val types are always any as we cannot make any
* assumptions while loading an external schema.
*
* @return the successful loaded schema
*/
def loadSchema(): Schema[Any, Any]
}

object SchemaLoader {

/**
* Loads a schema from an schema json file.
*
* @param file the schema json file
*/
def fromFile(file: File): Schema[Any, Any] = new FileSchemaLoader(file).loadSchema()
* Loads a schema from an schema json file.
*
* @param file the schema json file
*/
def fromFile(file: File): Schema[Any, Any] =
new FileSchemaLoader(file).loadSchema()

/**
* Loads a schema from an graphql endpoint.
*
* @param url the graphql endpoint
* @param log log output
*/
def fromIntrospection(url: String, log: Logger): Schema[Any, Any] = new IntrospectSchemaLoader(url, log).loadSchema()
* Loads a schema from an graphql endpoint.
*
* @param url the graphql endpoint
* @param log log output
*/
def fromIntrospection(url: String, log: Logger): Schema[Any, Any] =
new IntrospectSchemaLoader(url, log).loadSchema()

}

/**
* Loads a schema from an schema json file.
*
* @param file the schema json file
*/
* Loads a schema from an schema json file.
*
* @param file the schema json file
*/
class FileSchemaLoader(file: File) extends SchemaLoader {

override def loadSchema(): Schema[Any, Any] = {
Expand All @@ -65,19 +67,20 @@ class FileSchemaLoader(file: File) extends SchemaLoader {
}

/**
* Loads a schema from an graphql endpoint.
*
* @param url the graphql endpoint
* @param log log output
*/
* Loads a schema from an graphql endpoint.
*
* @param url the graphql endpoint
* @param log log output
*/
class IntrospectSchemaLoader(url: String, log: Logger) extends SchemaLoader {

override def loadSchema(): Schema[Any, Any] = Schema.buildFromIntrospection(introspect)
override def loadSchema(): Schema[Any, Any] =
Schema.buildFromIntrospection(introspect)

/**
* @see https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js
* @return the introspect query result
*/
* @see https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js
* @return the introspect query result
*/
private def introspect(): Json = {
log.info(s"Introspect graphql endpoint: $url")
val introspectQuery = gql"""
Expand Down Expand Up @@ -169,7 +172,8 @@ class IntrospectSchemaLoader(url: String, log: Logger) extends SchemaLoader {
}
}
}"""
val response = Http(url).param("query", introspectQuery.renderCompact).asString
val response =
Http(url).param("query", introspectQuery.renderCompact).asString
parse(response.body) match {
case Right(json) => json
case Left(error) =>
Expand All @@ -178,4 +182,4 @@ class IntrospectSchemaLoader(url: String, log: Logger) extends SchemaLoader {
sys.error(s"Invalid json was returned from graphql endpoint $url")
}
}
}
}

0 comments on commit f4c614c

Please sign in to comment.