Skip to content

Commit

Permalink
Paradox magnolify site
Browse files Browse the repository at this point in the history
  • Loading branch information
Michel Davit committed Jan 9, 2024
1 parent 43ce752 commit 937b333
Show file tree
Hide file tree
Showing 23 changed files with 377 additions and 166 deletions.
9 changes: 1 addition & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,7 @@ This library includes the following modules.

# Usage

See [derivation.md](https://github.com/spotify/magnolify/tree/master/docs/derivation.md) for type class derivation for Cats, Scalacheck, and Guava.

See [avro.md](https://github.com/spotify/magnolify/tree/master/docs/avro.md)
[bigquery.md](https://github.com/spotify/magnolify/tree/master/docs/bigquery.md)
[bigtable.md](https://github.com/spotify/magnolify/tree/master/docs/bigtable.md)
[datastore.md](https://github.com/spotify/magnolify/tree/master/docs/datastore.md)
[protobuf.md](https://github.com/spotify/magnolify/tree/master/docs/protobuf.md)
[tensorflow.md](https://github.com/spotify/magnolify/tree/master/docs/tensorflow.md) for data type conversions for these libraries. See [parquet.md](https://github.com/spotify/magnolify/tree/master/docs/parquet.md) for Parquet IO support. Also see [enums.md](https://github.com/spotify/magnolify/tree/master/docs/enums.md) for enum types and [refined.md](https://github.com/spotify/magnolify/tree/master/docs/derivation.md) for refinement types support. Finally see [mapping.md](https://github.com/spotify/magnolify/blob/master/docs/mapping.md) for a mapping table of Scala types supported by conversion and IO modules.
See [micro-site](https://spotify.github.io/magnolify/) for documentation.

# How to Release

Expand Down
82 changes: 82 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
import sbt._
import sbtprotoc.ProtocPlugin.ProtobufConfig
import com.github.sbt.git.SbtGit.GitKeys.gitRemoteRepo
import com.typesafe.tools.mima.core._

val magnoliaScala2Version = "1.1.6"
Expand Down Expand Up @@ -624,3 +625,84 @@ lazy val jmh: Project = project
"org.tensorflow" % "tensorflow-core-api" % tensorflowVersion % Test
)
)

// =======================================================================
// Site settings
// =======================================================================
lazy val site = project
.in(file("site"))
.enablePlugins(
ParadoxSitePlugin,
ParadoxMaterialThemePlugin,
GhpagesPlugin,
SiteScaladocPlugin,
MdocPlugin
)
.dependsOn(
avro % "compile->compile,provided",
bigquery % "compile->compile,provided",
bigtable % "compile->compile,provided",
cats % "compile->compile,provided",
datastore % "compile->compile,provided",
guava % "compile->compile,provided",
neo4j % "compile->compile,provided",
parquet % "compile->compile,provided",
protobuf % "compile->compile,provided",
refined % "compile->compile,provided",
shared,
scalacheck % "compile->compile,provided",
tensorflow % "compile->compile,provided",
unidocs
)
.settings(commonSettings)
.settings(
description := "Magnolify - Documentation",
fork := false,
publish / skip := true,
autoAPIMappings := true,
gitRemoteRepo := "[email protected]:spotify/magnolify.git",
// mdoc
// pre-compile md using mdoc
mdocIn := (paradox / sourceDirectory).value,
mdocExtraArguments ++= Seq("--no-link-hygiene"),
// paradox
Compile / paradox / sourceManaged := mdocOut.value,
paradoxProperties ++= Map(
"github.base_url" -> "https://github.com/spotify/magnolify"
),
Compile / paradoxMaterialTheme := ParadoxMaterialTheme()
.withFavicon("images/favicon.ico")
.withColor("white", "indigo")
.withLogo("images/logo.png")
.withCopyright("Copyright (C) 2024 Spotify AB")
.withRepository(uri("https://github.com/spotify/magnolify"))
.withSocial(uri("https://github.com/spotify"), uri("https://twitter.com/spotifyeng")),
// sbt-site
addMappingsToSiteDir(
unidocs / ScalaUnidoc / packageDoc / mappings,
unidocs / ScalaUnidoc / siteSubdirName
),
makeSite := makeSite.dependsOn(mdoc.toTask("")).value
)

lazy val unidocs = project
.in(file("unidocs"))
.enablePlugins(TypelevelUnidocPlugin)
.settings(commonSettings)
.settings(
moduleName := "magnolify-docs",
crossScalaVersions := Seq(scalaDefault),
scalaVersion := scalaDefault,
// unidoc
ScalaUnidoc / siteSubdirName := "api",
ScalaUnidoc / scalacOptions := Seq.empty,
ScalaUnidoc / unidoc / unidocProjectFilter := inAnyProject -- inProjects(test, jmh),
ScalaUnidoc / unidoc / unidocAllClasspaths ~= { cp =>
// somehow protobuf 2 is in classpath and fails doc
cp.map(_.filterNot(_.data.getName.endsWith("protobuf-java-2.5.0.jar")))
},
ScalaUnidoc / unidoc / unidocAllSources ~= { sources =>
// filter out doc from generated proto TFMD sources
sources.map(_.filterNot(_.getPath.contains("compiled_proto")))
}
)
71 changes: 0 additions & 71 deletions docs/derivation.md

This file was deleted.

8 changes: 7 additions & 1 deletion project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
addSbtPlugin("org.typelevel" % "sbt-typelevel" % "0.6.3")
addSbtPlugin("com.github.sbt" % "sbt-ghpages" % "0.8.0")
addSbtPlugin("com.github.sbt" % "sbt-site-paradox" % "1.5.0")
addSbtPlugin("com.github.sbt" % "sbt-unidoc" % "0.5.0")
addSbtPlugin("com.lightbend.paradox" % "sbt-paradox" % "0.10.5")
addSbtPlugin("com.thesamet" % "sbt-protoc" % "1.0.6")
addSbtPlugin("io.github.jonas" % "sbt-paradox-material-theme" % "0.6.0")
addSbtPlugin("org.scalameta" % "sbt-mdoc" % "2.5.1")
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "2.0.9")
addSbtPlugin("org.typelevel" % "sbt-typelevel" % "0.6.3")
addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.4.6")
10 changes: 10 additions & 0 deletions site/src/main/paradox/_template/scaladoc.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<!-- HTML meta refresh URL redirection -->
<meta http-equiv="refresh" content="0; url=api/magnolify/index.html">
</head>
<body>
<p>The page has moved to: <a href="api/magnolify/index.html">this page</a></p>
</body>
</html>
37 changes: 22 additions & 15 deletions docs/avro.md → site/src/main/paradox/avro.md
Original file line number Diff line number Diff line change
@@ -1,59 +1,63 @@
AvroType
========
# Avro

`AvroType[T]` provides conversion between Scala type `T` and Avro `GenericRecord`. Custom support for type `T` can be added with an implicit instance of `AvroField[T]`.

```scala
```scala mdoc:compile-only
import java.net.URI

case class CountryCode(code: String)
case class Inner(long: Long, str: String, uri: URI, cc: CountryCode)
case class Outer(inner: Inner)
val record = Outer(Inner(1L, "hello", URI.create("https://www.spotify.com"), "US"))
val record = Outer(Inner(1L, "hello", URI.create("https://www.spotify.com"), CountryCode("US")))

import magnolify.avro._
import org.apache.avro.generic.GenericRecord

// Encode custom type URI as String
implicit val uriField = AvroField.from[String](URI.create)(_.toString)
implicit val uriField: AvroField[URI] = AvroField.from[String](URI.create)(_.toString)

// Encode country code as fixed type
implicit val afCountryCode =
implicit val afCountryCode: AvroField[CountryCode] =
AvroField.fixed[CountryCode](2)(bs => CountryCode(new String(bs)))(cc => cc.code.getBytes)

val avroType = AvroType[Outer]
val genericRecord: GenericRecord = avroType.to(record)
val copy: Outer = avroType.from(genericRecord)

// Avro Schema
avroType.schema
val schema = avroType.schema
```

Enum-like types map to Avro enums. See [enums.md](https://github.com/spotify/magnolify/tree/master/docs/enums.md) for more details. Additional `AvroField[T]` instances for `Byte`, `Char`, `Short`, and `UnsafeEnum[T]` are available from `import magnolify.avro.unsafe._`. These conversions are unsafe due to potential overflow.
Enum-like types map to Avro enums. See @ref:[EnumType](enums.md) for more details. Additional `AvroField[T]` instances for `Byte`, `Char`, `Short`, and `UnsafeEnum[T]` are available from `import magnolify.avro.unsafe._`. These conversions are unsafe due to potential overflow.

Achieving backward compatibility when adding new fields to the case class: new fields must have a default parameter value in order to generate backward compatible Avro schema `avroType.schema`.

```scala
```scala mdoc:compile-only
case class Record(oldField: String, newField: String = "")
// OR
case class Record2(oldField: String, newField: Option[String] = None)
```

To populate Avro type and field `doc`s, annotate the case class and its fields with the `@doc` annotation.

```scala
```scala mdoc:compile-only
import magnolify.avro._

@doc("My record")
case class Record(@doc("int field") i: Int, @doc("string field") s: String)

@doc("My enum")
object Color extends Enumeration {
type Type = Value
value Red, Gree, Blue = Value
val Red, Green, Blue = Value
}
```

The `@doc` annotation can also be extended to support custom format.

```scala
```scala mdoc:compile-only
import magnolify.avro._

class myDoc(doc: String, version: Int) extends doc(s"doc: $doc, version: $version")

@myDoc("My record", 2)
Expand All @@ -62,7 +66,8 @@ case class Record(@myDoc("int field", 1) i: Int, @myDoc("string field", 2) s: St

To use a different field case format in target records, add an optional `CaseMapper` argument to `AvroType`. The following example maps `firstName` & `lastName` to `first_name` & `last_name`.

```scala
```scala mdoc:compile-only
import magnolify.avro._
import magnolify.shared.CaseMapper
import com.google.common.base.CaseFormat

Expand All @@ -75,8 +80,10 @@ avroType.to(LowerCamel("John", "Doe"))

Avro `decimal` and `uuid` logical types map to `BigDecimal` and `java.util.UUID`. Additionally `decimal` requires `precision` and optional `scale` parameter.

```scala
implicit val afBigDecimal = AvroField.bigDecimal(20, 4)
```scala mdoc:compile-only
import magnolify.avro._

implicit val afBigDecimal: AvroField[BigDecimal] = AvroField.bigDecimal(20, 4)
```

Among the date/time types, `date` maps to `java.time.LocalDate`. The other types, `timestamp`, `time` and `local-timestamp`, map to `Instant`, `LocalTime` and `LocalDateTime` in either micro or milliseconds precision with `import magnolify.avro.logical.micros._` or `import magnolify.avro.logical.millis._`.
Expand Down
24 changes: 14 additions & 10 deletions docs/bigquery.md → site/src/main/paradox/bigquery.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
TableRowType
============
# BigQuery

`TableRowType[T]` provides conversion between Scala type `T` and BigQuery `TableRow`. Custom support for type `T` can be added with an implicit instance of `TableRowField[T]`.

```scala
```scala mdoc:compile-only
import java.net.URI
case class Inner(long: Long, str: String, uri: URI)
case class Outer(inner: Inner)
Expand All @@ -13,38 +12,43 @@ import magnolify.bigquery._
import com.google.api.services.bigquery.model.TableRow

// Encode custom type URI as String
implicit val uriField = TableRowField.from[String](URI.create)(_.toString)
implicit val uriField: TableRowField[URI] = TableRowField.from[String](URI.create)(_.toString)

val tableRowType = TableRowType[Outer]
val tableRow: TableRow = tableRowType.to(record)
val copy: Outer = tableRowType.from(tableRow)

// BigQuery TableSchema
tableRowType.schema
val schema = tableRowType.schema
```

Additional `TableRowField[T]` instances for `Byte`, `Char`, `Short`, `Int`, `Float`, and enum-like types are available from `import magnolify.bigquery.unsafe._`. These conversions are unsafe due to potential overflow or encoding errors. See [enums.md](https://github.com/spotify/magnolify/tree/master/docs/enums.md) for more details.
Additional `TableRowField[T]` instances for `Byte`, `Char`, `Short`, `Int`, `Float`, and enum-like types are available from `import magnolify.bigquery.unsafe._`. These conversions are unsafe due to potential overflow or encoding errors. See @ref:[EnumType](enums.md) for more details.

To populate BigQuery table and field `description`s, annotate the case class and its fields with the `@description` annotation.

```scala
```scala mdoc:compile-only
import magnolify.bigquery._

@description("My record")
case class Record(@description("int field") i: Int, @description("string field") s: String)
```

The `@description` annotation can also be extended to support custom format.

```scala
```scala mdoc:compile-only
import magnolify.bigquery._

class myDesc(description: String, version: Int)
extends description(s"description: description, version: $version")
extends description(s"description: $description, version: $version")

@myDesc("My record", 2)
case class Record(@myDesc("int field", 1) i: Int, @myDesc("string field", 2) s: String)
```

To use a different field case format in target records, add an optional `CaseMapper` argument to `TableRowType`. The following example maps `firstName` & `lastName` to `first_name` & `last_name`.

```scala
```scala mdoc:compile-only
import magnolify.bigquery._
import magnolify.shared.CaseMapper
import com.google.common.base.CaseFormat

Expand Down
Loading

0 comments on commit 937b333

Please sign in to comment.