diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 6bb82d0..89f2405 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,6 +1,272 @@
+# This file was automatically generated by sbt-github-actions using the
+# githubWorkflowGenerate task. You should add and commit this file to
+# your git repository. It goes without saying that you shouldn't edit
+# this file by hand! Instead, if you wish to make changes, you should
+# change your sbt build configuration to revise the workflow description
+# to meet your needs, then regenerate this file.
+
+name: Continuous Integration
+
on:
pull_request:
branches: ['**', '!update/**', '!pr/**']
push:
branches: ['**', '!update/**', '!pr/**']
tags: [v*]
+
+env:
+ PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }}
+ SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
+ SONATYPE_CREDENTIAL_HOST: ${{ secrets.SONATYPE_CREDENTIAL_HOST }}
+ SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
+ PGP_SECRET: ${{ secrets.PGP_SECRET }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+jobs:
+ build:
+ name: Build and Test
+ strategy:
+ matrix:
+ os: [ubuntu-latest]
+ scala: [2.12.17]
+ java: [temurin@11, temurin@17]
+ runs-on: ${{ matrix.os }}
+ steps:
+ - name: Checkout current branch (full)
+ uses: actions/checkout@v2
+ with:
+ fetch-depth: 0
+
+ - name: Download Java (temurin@11)
+ id: download-java-temurin-11
+ if: matrix.java == 'temurin@11'
+ uses: typelevel/download-java@v1
+ with:
+ distribution: temurin
+ java-version: 11
+
+ - name: Setup Java (temurin@11)
+ if: matrix.java == 'temurin@11'
+ uses: actions/setup-java@v2
+ with:
+ distribution: jdkfile
+ java-version: 11
+ jdkFile: ${{ steps.download-java-temurin-11.outputs.jdkFile }}
+
+ - name: Download Java (temurin@17)
+ id: download-java-temurin-17
+ if: matrix.java == 'temurin@17'
+ uses: typelevel/download-java@v1
+ with:
+ distribution: temurin
+ java-version: 17
+
+ - name: Setup Java (temurin@17)
+ if: matrix.java == 'temurin@17'
+ uses: actions/setup-java@v2
+ with:
+ distribution: jdkfile
+ java-version: 17
+ jdkFile: ${{ steps.download-java-temurin-17.outputs.jdkFile }}
+
+ - name: Cache sbt
+ uses: actions/cache@v2
+ with:
+ path: |
+ ~/.sbt
+ ~/.ivy2/cache
+ ~/.coursier/cache/v1
+ ~/.cache/coursier/v1
+ ~/AppData/Local/Coursier/Cache/v1
+ ~/Library/Caches/Coursier/v1
+ key: ${{ runner.os }}-sbt-cache-v2-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }}
+
+ - name: Check that workflows are up to date
+ run: sbt githubWorkflowCheck
+
+ - name: Check headers and formatting
+ if: matrix.java == 'temurin@11'
+ run: sbt '++${{ matrix.scala }}' headerCheckAll scalafmtCheckAll 'project /' scalafmtSbtCheck
+
+ - name: Test
+ run: sbt '++${{ matrix.scala }}' test
+
+ - name: Check scalafix lints
+ if: matrix.java == 'temurin@11'
+ run: sbt '++${{ matrix.scala }}' 'scalafixAll --check'
+
+ - name: Check binary compatibility
+ if: matrix.java == 'temurin@11'
+ run: sbt '++${{ matrix.scala }}' mimaReportBinaryIssues
+
+ - name: Generate API documentation
+ if: matrix.java == 'temurin@11'
+ run: sbt '++${{ matrix.scala }}' doc
+
+ - name: Make target directories
+ if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main')
+ run: mkdir -p target site/target core/target project/target
+
+ - name: Compress target directories
+ if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main')
+ run: tar cf targets.tar target site/target core/target project/target
+
+ - name: Upload target directories
+ if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main')
+ uses: actions/upload-artifact@v2
+ with:
+ name: target-${{ matrix.os }}-${{ matrix.java }}-${{ matrix.scala }}
+ path: targets.tar
+
+ publish:
+ name: Publish Artifacts
+ needs: [build]
+ if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main')
+ strategy:
+ matrix:
+ os: [ubuntu-latest]
+ scala: [2.12.17]
+ java: [temurin@11]
+ runs-on: ${{ matrix.os }}
+ steps:
+ - name: Checkout current branch (full)
+ uses: actions/checkout@v2
+ with:
+ fetch-depth: 0
+
+ - name: Download Java (temurin@11)
+ id: download-java-temurin-11
+ if: matrix.java == 'temurin@11'
+ uses: typelevel/download-java@v1
+ with:
+ distribution: temurin
+ java-version: 11
+
+ - name: Setup Java (temurin@11)
+ if: matrix.java == 'temurin@11'
+ uses: actions/setup-java@v2
+ with:
+ distribution: jdkfile
+ java-version: 11
+ jdkFile: ${{ steps.download-java-temurin-11.outputs.jdkFile }}
+
+ - name: Download Java (temurin@17)
+ id: download-java-temurin-17
+ if: matrix.java == 'temurin@17'
+ uses: typelevel/download-java@v1
+ with:
+ distribution: temurin
+ java-version: 17
+
+ - name: Setup Java (temurin@17)
+ if: matrix.java == 'temurin@17'
+ uses: actions/setup-java@v2
+ with:
+ distribution: jdkfile
+ java-version: 17
+ jdkFile: ${{ steps.download-java-temurin-17.outputs.jdkFile }}
+
+ - name: Cache sbt
+ uses: actions/cache@v2
+ with:
+ path: |
+ ~/.sbt
+ ~/.ivy2/cache
+ ~/.coursier/cache/v1
+ ~/.cache/coursier/v1
+ ~/AppData/Local/Coursier/Cache/v1
+ ~/Library/Caches/Coursier/v1
+ key: ${{ runner.os }}-sbt-cache-v2-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }}
+
+ - name: Download target directories (2.12.17)
+ uses: actions/download-artifact@v2
+ with:
+ name: target-${{ matrix.os }}-${{ matrix.java }}-2.12.17
+
+ - name: Inflate target directories (2.12.17)
+ run: |
+ tar xf targets.tar
+ rm targets.tar
+
+ - name: Import signing key
+ if: env.PGP_SECRET != '' && env.PGP_PASSPHRASE == ''
+ run: echo $PGP_SECRET | base64 -di | gpg --import
+
+ - name: Import signing key and strip passphrase
+ if: env.PGP_SECRET != '' && env.PGP_PASSPHRASE != ''
+ run: |
+ echo "$PGP_SECRET" | base64 -di > /tmp/signing-key.gpg
+ echo "$PGP_PASSPHRASE" | gpg --pinentry-mode loopback --passphrase-fd 0 --import /tmp/signing-key.gpg
+ (echo "$PGP_PASSPHRASE"; echo; echo) | gpg --command-fd 0 --pinentry-mode loopback --change-passphrase $(gpg --list-secret-keys --with-colons 2> /dev/null | grep '^sec:' | cut --delimiter ':' --fields 5 | tail -n 1)
+
+ - name: Publish
+ run: sbt '++${{ matrix.scala }}' tlRelease
+
+ site:
+ name: Generate Site
+ strategy:
+ matrix:
+ os: [ubuntu-latest]
+ scala: [2.12.17]
+ java: [temurin@11]
+ runs-on: ${{ matrix.os }}
+ steps:
+ - name: Checkout current branch (full)
+ uses: actions/checkout@v2
+ with:
+ fetch-depth: 0
+
+ - name: Download Java (temurin@11)
+ id: download-java-temurin-11
+ if: matrix.java == 'temurin@11'
+ uses: typelevel/download-java@v1
+ with:
+ distribution: temurin
+ java-version: 11
+
+ - name: Setup Java (temurin@11)
+ if: matrix.java == 'temurin@11'
+ uses: actions/setup-java@v2
+ with:
+ distribution: jdkfile
+ java-version: 11
+ jdkFile: ${{ steps.download-java-temurin-11.outputs.jdkFile }}
+
+ - name: Download Java (temurin@17)
+ id: download-java-temurin-17
+ if: matrix.java == 'temurin@17'
+ uses: typelevel/download-java@v1
+ with:
+ distribution: temurin
+ java-version: 17
+
+ - name: Setup Java (temurin@17)
+ if: matrix.java == 'temurin@17'
+ uses: actions/setup-java@v2
+ with:
+ distribution: jdkfile
+ java-version: 17
+ jdkFile: ${{ steps.download-java-temurin-17.outputs.jdkFile }}
+
+ - name: Cache sbt
+ uses: actions/cache@v2
+ with:
+ path: |
+ ~/.sbt
+ ~/.ivy2/cache
+ ~/.coursier/cache/v1
+ ~/.cache/coursier/v1
+ ~/AppData/Local/Coursier/Cache/v1
+ ~/Library/Caches/Coursier/v1
+ key: ${{ runner.os }}-sbt-cache-v2-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }}
+
+ - name: Generate site
+ run: sbt '++${{ matrix.scala }}' docs/tlSite
+
+ - name: Publish site
+ if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main'
+ uses: peaceiris/actions-gh-pages@v3.8.0
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ publish_dir: site/target/docs/site
+ keep_files: true
diff --git a/.github/workflows/clean.yml b/.github/workflows/clean.yml
new file mode 100644
index 0000000..547aaa4
--- /dev/null
+++ b/.github/workflows/clean.yml
@@ -0,0 +1,59 @@
+# This file was automatically generated by sbt-github-actions using the
+# githubWorkflowGenerate task. You should add and commit this file to
+# your git repository. It goes without saying that you shouldn't edit
+# this file by hand! Instead, if you wish to make changes, you should
+# change your sbt build configuration to revise the workflow description
+# to meet your needs, then regenerate this file.
+
+name: Clean
+
+on: push
+
+jobs:
+ delete-artifacts:
+ name: Delete Artifacts
+ runs-on: ubuntu-latest
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ steps:
+ - name: Delete artifacts
+ run: |
+ # Customize those three lines with your repository and credentials:
+ REPO=${GITHUB_API_URL}/repos/${{ github.repository }}
+
+ # A shortcut to call GitHub API.
+ ghapi() { curl --silent --location --user _:$GITHUB_TOKEN "$@"; }
+
+ # A temporary file which receives HTTP response headers.
+ TMPFILE=/tmp/tmp.$$
+
+ # An associative array, key: artifact name, value: number of artifacts of that name.
+ declare -A ARTCOUNT
+
+ # Process all artifacts on this repository, loop on returned "pages".
+ URL=$REPO/actions/artifacts
+ while [[ -n "$URL" ]]; do
+
+ # Get current page, get response headers in a temporary file.
+ JSON=$(ghapi --dump-header $TMPFILE "$URL")
+
+ # Get URL of next page. Will be empty if we are at the last page.
+ URL=$(grep '^Link:' "$TMPFILE" | tr ',' '\n' | grep 'rel="next"' | head -1 | sed -e 's/.*/' -e 's/>.*//')
+ rm -f $TMPFILE
+
+ # Number of artifacts on this page:
+ COUNT=$(( $(jq <<<$JSON -r '.artifacts | length') ))
+
+ # Loop on all artifacts on this page.
+ for ((i=0; $i < $COUNT; i++)); do
+
+ # Get name of artifact and count instances of this name.
+ name=$(jq <<<$JSON -r ".artifacts[$i].name?")
+ ARTCOUNT[$name]=$(( $(( ${ARTCOUNT[$name]} )) + 1))
+
+ id=$(jq <<<$JSON -r ".artifacts[$i].id?")
+ size=$(( $(jq <<<$JSON -r ".artifacts[$i].size_in_bytes?") ))
+ printf "Deleting '%s' #%d, %'d bytes\n" $name ${ARTCOUNT[$name]} $size
+ ghapi -X DELETE $REPO/actions/artifacts/$id
+ done
+ done
diff --git a/.gitignore b/.gitignore
index 9c07d4a..eca1de3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,8 @@
-*.class
-*.log
+target/
+.idea/
+.vscode
+.bloop
+.metals
+project/metals.sbt
+project/project
+.bsp/
diff --git a/.scala-steward.conf b/.scala-steward.conf
new file mode 100644
index 0000000..ab234af
--- /dev/null
+++ b/.scala-steward.conf
@@ -0,0 +1,3 @@
+updates.pin = [
+ { groupId = "org.scala-lang", artifactId = "scala-library", version = "2.12." }
+]
diff --git a/.scalafix.conf b/.scalafix.conf
new file mode 100644
index 0000000..edf55ae
--- /dev/null
+++ b/.scalafix.conf
@@ -0,0 +1,3 @@
+rules = [
+ OrganizeImports
+]
diff --git a/.scalafmt.conf b/.scalafmt.conf
new file mode 100644
index 0000000..a7c8cc5
--- /dev/null
+++ b/.scalafmt.conf
@@ -0,0 +1,21 @@
+version = 3.5.3
+project.git = true
+runner.dialect = scala213
+project.layout = StandardConvention
+continuationIndent.defnSite = 2
+docstrings.style = Asterisk
+docstrings.wrap = no
+includeCurlyBraceInSelectChains = false
+maxColumn = 120
+newlines.alwaysBeforeElseAfterCurlyIf = false
+newlines.alwaysBeforeMultilineDef = false
+optIn.breakChainOnFirstMethodDot = false
+spaces.inImportCurlyBraces = true
+rewrite.rules = [
+ AvoidInfix,
+ RedundantParens,
+ AsciiSortImports,
+ PreferCurlyFors
+]
+newlines.afterCurlyLambda = preserve
+newlines.beforeCurlyLambdaParams = multilineWithCaseOnly
diff --git a/README.md b/README.md
index cc2792f..2dc4843 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,39 @@
# sbt-circe-org
-An SBT plugin to support circe org projects
+
+This project is intended to set up sensible defaults and standards for projects under `io.circe`. If it's useful
+outside `io.circe`, it probably should be pushed further upstream
+into [sbt-typelevel](https://github.com/typelevel/sbt-typelevel).
+
+## Installing it
+
+The plugin is deployed to Sonatype.
+
+```scala
+addSbtPlugin("io.circe" % "sbt-circe-org" % "@VERSION@")
+```
+
+## What does it do?
+
+### `CirceOrgPlugin`
+
+Triggers automatically. Use on all published `circe` modules.
+
+* Activates the sensible defaults of [sbt-typelevel](https://github.com/typelevel/sbt-typelevel/)
+* Sets the organization info
+* Enables automated license headers with appropriate years
+* Enables [sbt-github-actions](https://typelevel.org/sbt-typelevel/gha.html) with settings appropriate to our
+ workflow
+* by default does not run code coverage in all `io.circe.examples.*` packages
+
+### `CirceOrgSitePlugin`
+
+Must be manually triggered. Extends the `TypelevelSitePlugin` with the `circe.io` theme. See
+the [sbt-typelevel-site docs](https://typelevel.org/sbt-typelevel/site.html) for usage.
+
+#### Provided images
+
+You can refer to the following images in customizing the `laika` theme:
+
+- `Path.Root / "images" / "circe_dark.svg"`
+- `Path.Root / "images" / "circe_light_no_border.svg"`
+- `Path.Root / "images" / "circe_light_no_border_146x173.png"`
diff --git a/build.sbt b/build.sbt
new file mode 100644
index 0000000..830599d
--- /dev/null
+++ b/build.sbt
@@ -0,0 +1,27 @@
+lazy val `sbt-circe-org` =
+ project.in(file(".")).enablePlugins(NoPublishPlugin).aggregate(core)
+
+// we're not doing code coverage on this plugin. Set to Some("sbt-circe-org") if you wish to run it.
+ThisBuild / circeRootOfCodeCoverage := None
+ThisBuild / tlCiScalafixCheck := true
+
+lazy val docs = project
+ .in(file("site"))
+ .enablePlugins(CirceOrgSitePlugin)
+ .settings(
+ tlSiteRelatedProjects += "sbt-typelevel" -> url("https://typelevel.org/sbt-typelevel/")
+ )
+
+lazy val core = project
+ .in(file("core"))
+ .enablePlugins(SbtPlugin)
+ .settings(
+ name := "sbt-circe-org"
+ )
+
+ThisBuild / tlBaseVersion := "0.1"
+ThisBuild / crossScalaVersions := Seq("2.12.17")
+ThisBuild / developers := List(
+ tlGitHubDev("lorandszakacs", "Loránd Szakács")
+)
+ThisBuild / startYear := Some(2022)
diff --git a/core/build.sbt b/core/build.sbt
new file mode 100644
index 0000000..0a18b18
--- /dev/null
+++ b/core/build.sbt
@@ -0,0 +1,9 @@
+val sbtTypelevelVersion = "0.4.16" // https://github.com/typelevel/sbt-typelevel/releases
+val sbtScoverageVersion = "2.0.6" // https://github.com/scoverage/sbt-scoverage/releases
+val sbtScalaNativeVersion = "0.4.7" // https://github.com/scala-native/scala-native/releases
+
+addSbtPlugin("org.typelevel" % "sbt-typelevel" % sbtTypelevelVersion)
+addSbtPlugin("org.typelevel" % "sbt-typelevel-site" % sbtTypelevelVersion)
+addSbtPlugin("org.typelevel" % "sbt-typelevel-scalafix" % sbtTypelevelVersion)
+addSbtPlugin("org.scala-native" % "sbt-scala-native" % sbtScalaNativeVersion)
+addSbtPlugin("org.scoverage" % "sbt-scoverage" % sbtScoverageVersion)
diff --git a/core/src/main/resources/io/circe/sbt/site/images/circe_dark.svg b/core/src/main/resources/io/circe/sbt/site/images/circe_dark.svg
new file mode 100644
index 0000000..1c8bbbd
--- /dev/null
+++ b/core/src/main/resources/io/circe/sbt/site/images/circe_dark.svg
@@ -0,0 +1,16 @@
+
+
\ No newline at end of file
diff --git a/core/src/main/resources/io/circe/sbt/site/images/circe_light_no_border.svg b/core/src/main/resources/io/circe/sbt/site/images/circe_light_no_border.svg
new file mode 100644
index 0000000..b0de429
--- /dev/null
+++ b/core/src/main/resources/io/circe/sbt/site/images/circe_light_no_border.svg
@@ -0,0 +1,13 @@
+
+
diff --git a/core/src/main/resources/io/circe/sbt/site/images/circe_light_no_border_146x173.png b/core/src/main/resources/io/circe/sbt/site/images/circe_light_no_border_146x173.png
new file mode 100644
index 0000000..2bcc604
Binary files /dev/null and b/core/src/main/resources/io/circe/sbt/site/images/circe_light_no_border_146x173.png differ
diff --git a/core/src/main/resources/io/circe/sbt/site/site/styles.css b/core/src/main/resources/io/circe/sbt/site/site/styles.css
new file mode 100644
index 0000000..fad1e6c
--- /dev/null
+++ b/core/src/main/resources/io/circe/sbt/site/site/styles.css
@@ -0,0 +1,5 @@
+header img {
+ height: 28px;
+ width: auto;
+ margin-top: 6px;
+}
diff --git a/core/src/main/scala/io/circe/sbt/CirceOrgPlugin.scala b/core/src/main/scala/io/circe/sbt/CirceOrgPlugin.scala
new file mode 100644
index 0000000..e3f803b
--- /dev/null
+++ b/core/src/main/scala/io/circe/sbt/CirceOrgPlugin.scala
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2022 circe
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.circe.sbt
+
+import org.typelevel.sbt._
+import org.typelevel.sbt.gha._
+import sbt.Keys._
+import sbt._
+import scalafix.sbt.ScalafixPlugin.autoImport._
+import scoverage.ScoverageSbtPlugin.autoImport._
+import scoverage._
+
+import GenerativeKeys._
+import TypelevelSettingsPlugin.autoImport._
+import TypelevelCiPlugin.autoImport._
+import TypelevelSonatypePlugin.autoImport._
+
+object CirceOrgPlugin extends AutoPlugin {
+ object autoImport {
+ lazy val circeRootOfCodeCoverage = settingKey[Option[String]](
+ "None if code coverage is disabled. Defined with name of the root project from which to run code coverage."
+ )
+ }
+
+ import autoImport._
+
+ override def trigger = allRequirements
+
+ override def requires: Plugins = TypelevelPlugin && ScoverageSbtPlugin
+
+ override def buildSettings: Seq[Setting[_]] =
+ codeCoverageSettings ++ publishSettings ++ organizationSettings ++ scalafixSettings ++ githubActionsSettings
+
+ override def projectSettings: Seq[Setting[_]] = Seq.empty
+
+ lazy val codeCoverageSettings: Seq[Setting[_]] = Seq(
+ coverageHighlighting := true,
+ coverageExcludedPackages := "io.circe.examples.*"
+ )
+
+ lazy val publishSettings: Seq[Setting[_]] =
+ Seq(
+ tlSonatypeUseLegacyHost := true,
+ tlJdkRelease := Some(8)
+ )
+
+ lazy val organizationSettings: Seq[Setting[_]] =
+ Seq(
+ organization := "io.circe",
+ organizationName := "circe"
+ )
+
+ @scala.annotation.nowarn("msg=possible missing interpolator")
+ lazy val githubActionsSettings: Seq[Setting[_]] = Seq(
+ githubWorkflowJavaVersions := List("11", "17").map(JavaSpec.temurin(_)),
+ tlCiScalafixCheck := true, // yolo, let's see how it works on scala 3 :D
+ tlCiScalafmtCheck := true,
+ githubWorkflowAddedJobs ++=
+ (circeRootOfCodeCoverage.value match {
+ case None => List.empty
+ case Some(rootProj) =>
+ List(
+ WorkflowJob(
+ id = "coverage",
+ name = "Generate coverage report",
+ scalas = crossScalaVersions.value.filterNot(_.startsWith("3.")).toList,
+ steps = List(WorkflowStep.Checkout) ++ WorkflowStep.SetupJava(
+ List(githubWorkflowJavaVersions.value.last)
+ ) ++ githubWorkflowGeneratedCacheSteps.value ++ List(
+ WorkflowStep.Sbt(List("coverage", s"$rootProj/test", "coverageAggregate")),
+ WorkflowStep.Use(
+ UseRef.Public(
+ "codecov",
+ "codecov-action",
+ "v2"
+ ),
+ params = Map(
+ "flags" -> List("${{matrix.scala}}", "${{matrix.java}}").mkString(",")
+ )
+ )
+ )
+ )
+ )
+ })
+ )
+
+ lazy val scalafixSettings: Seq[Setting[_]] =
+ Seq(
+ scalafixScalaBinaryVersion := (LocalRootProject / scalaBinaryVersion).value,
+ scalafixDependencies ++= Seq(
+ "com.github.liancheng" %% "organize-imports" % "0.6.0" // https://github.com/liancheng/scalafix-organize-imports/tags
+ )
+ )
+
+}
diff --git a/core/src/main/scala/io/circe/sbt/CirceOrgScalaJSPlugin.scala b/core/src/main/scala/io/circe/sbt/CirceOrgScalaJSPlugin.scala
new file mode 100644
index 0000000..8c7c78e
--- /dev/null
+++ b/core/src/main/scala/io/circe/sbt/CirceOrgScalaJSPlugin.scala
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2022 circe
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.circe.sbt
+
+/**
+ * automatically loaded for all projects that are cross-compiled to ScalaJS, no need too reference it explicitly in builds
+ */
+
+import org.scalajs.sbtplugin.ScalaJSPlugin
+import sbt.*
+import scoverage.ScoverageSbtPlugin.autoImport._
+
+object CirceOrgScalaJSPlugin extends AutoPlugin {
+
+ override def trigger = allRequirements
+
+ override def requires: Plugins = CirceOrgPlugin && ScalaJSPlugin
+
+ override def projectSettings: Seq[Setting[_]] = Seq(
+ coverageEnabled := false
+ )
+
+}
diff --git a/core/src/main/scala/io/circe/sbt/CirceOrgScalaNativePlugin.scala b/core/src/main/scala/io/circe/sbt/CirceOrgScalaNativePlugin.scala
new file mode 100644
index 0000000..18fb0f3
--- /dev/null
+++ b/core/src/main/scala/io/circe/sbt/CirceOrgScalaNativePlugin.scala
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2022 circe
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.circe.sbt
+
+/**
+ * automatically loaded for all projects that are cross-compiled to ScalaJS, no need too reference it explicitly in builds
+ */
+import sbt.*
+import scoverage.ScoverageSbtPlugin.autoImport._
+
+import scala.scalanative.sbtplugin.ScalaNativePlugin
+
+object CirceOrgScalaNativePlugin extends AutoPlugin {
+
+ override def trigger = allRequirements
+
+ override def requires: Plugins = CirceOrgPlugin && ScalaNativePlugin
+
+ override def projectSettings: Seq[Setting[_]] = Seq(
+ coverageEnabled := false
+ )
+
+}
diff --git a/core/src/main/scala/io/circe/sbt/CirceOrgSitePlugin.scala b/core/src/main/scala/io/circe/sbt/CirceOrgSitePlugin.scala
new file mode 100644
index 0000000..dcb44b2
--- /dev/null
+++ b/core/src/main/scala/io/circe/sbt/CirceOrgSitePlugin.scala
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2022 circe
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.circe.sbt
+
+import laika.ast.LengthUnit._
+import laika.ast.Path.Root
+import laika.ast._
+import laika.helium.Helium
+import laika.helium.config.Favicon
+import laika.helium.config.HeliumIcon
+import laika.helium.config.IconLink
+import laika.helium.config.ImageLink
+import laika.sbt.LaikaPlugin
+import laika.theme.config.Color
+import org.typelevel.sbt.TypelevelGitHubPlugin
+import org.typelevel.sbt.TypelevelSitePlugin
+import sbt.Keys._
+import sbt._
+
+object CirceOrgSitePlugin extends AutoPlugin {
+
+ override def requires = TypelevelSitePlugin && LaikaPlugin
+
+ import TypelevelGitHubPlugin.autoImport._
+ import TypelevelSitePlugin.autoImport._
+ import LaikaPlugin.autoImport._
+
+ override def projectSettings: Seq[Setting[_]] = Seq(
+ tlSiteRelatedProjects := {
+ Seq(
+ "circe" -> url("https://github.com/circe/circe"),
+ // streaming helpers
+ "circe-fs2" -> url("https://github.com/circe/circe-fs2"),
+ "circe-iteratee" -> url("https://github.com/circe/circe-iteratee"),
+ // derivation helpers
+ "circe-generic-extras" -> url("https://github.com/circe/circe-generic-extras"),
+ "circe-derivation" -> url("https://github.com/circe/circe-derivation"),
+ // end-user utils
+ "circe-optics" -> url("https://github.com/circe/circe-optics"),
+ // 3rd-party integrations
+ "circe-droste" -> url("https://github.com/circe/circe-droste"),
+ "circe-spire" -> url("https://github.com/circe/circe-spire"),
+ "circe-config" -> url("https://github.com/circe/circe-config"),
+ // other formats
+ "circe-yaml" -> url("https://github.com/circe/circe-yaml"),
+ "circe-bson" -> url("https://github.com/circe/circe-bson"),
+ // schemas
+ "circe-schema" -> url("https://github.com/circe/circe-schema"),
+ "circe-golden" -> url("https://github.com/circe/circe-golden"),
+ "circe-json-schema" -> url("https://github.com/circe/circe-json-schema"),
+ // other backends
+ "circe-jackson" -> url("https://github.com/circe/circe-jackson"),
+ "circe-argus" -> url("https://github.com/circe/circe-argus")
+ ).filterNot {
+ case (repo, _) =>
+ tlGitHubRepo.value.contains(repo) // omit ourselves!
+ }
+ },
+ laikaTheme ~= { _.extend(site.CirceOrgHeliumExtensions) },
+ tlSiteHeliumConfig := {
+ Helium.defaults.all
+ .metadata(
+ title = tlGitHubRepo.value,
+ authors = developers.value.map(_.name),
+ language = Some("en"),
+ version = Some(version.value)
+ )
+ .site
+ .layout(
+ contentWidth = px(860),
+ navigationWidth = px(275),
+ topBarHeight = px(35),
+ defaultBlockSpacing = px(10),
+ defaultLineHeight = 1.5,
+ anchorPlacement = laika.helium.config.AnchorPlacement.Right
+ )
+ .site
+ /* See scaladoc on laika.helium.config.CommonConfigOps#themeColors()
+ * old circe website color theme reference point:
+ * https://github.com/circe/circe/blob/c666f32f3bd02644a927b624f7534fdeccbd62a6/build.sbt#L151
+ */
+ .themeColors(
+ primary = Color.hex("222749"),
+ secondary = Color.hex("222749"),
+ primaryMedium = Color.hex("292E53"),
+ primaryLight = Color.hex("5B5988"),
+ text = Color.hex("5f5f5f"),
+ background = Color.hex("F4F3F4"),
+ bgGradient = (Color.hex("F4F3F4"), Color.hex("E5E5E6"))
+ )
+ .site
+ .favIcons(
+ Favicon.internal(Root / "images" / "circe_light_no_border_146x173.png", "32x32")
+ )
+ .site
+ .darkMode
+ .disabled
+ .site
+ .topNavigationBar(
+ homeLink = ImageLink.external(
+ "https://github.com/circe/circe",
+ Image.internal(Root / "images" / "circe_light_no_border_146x173.png")
+ ),
+ navLinks = tlSiteApiUrl.value.toList.map { url =>
+ IconLink.external(
+ url.toString,
+ HeliumIcon.api,
+ options = Styles("svg-link")
+ )
+ } ++ Seq(
+ IconLink.external(
+ scmInfo.value.fold("https://github.com/circe")(_.browseUrl.toString),
+ HeliumIcon.github,
+ options = Styles("svg-link")
+ ),
+ IconLink.external("https://discord.gg/XF3CXcMzqD", HeliumIcon.chat)
+ )
+ )
+ }
+ )
+
+}
diff --git a/core/src/main/scala/io/circe/sbt/site/CirceOrgHeliumExtensions.scala b/core/src/main/scala/io/circe/sbt/site/CirceOrgHeliumExtensions.scala
new file mode 100644
index 0000000..c455f5f
--- /dev/null
+++ b/core/src/main/scala/io/circe/sbt/site/CirceOrgHeliumExtensions.scala
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2022 circe
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.circe.sbt.site
+
+import cats.effect.Resource
+import cats.effect.kernel.Sync
+import laika.ast.Path
+import laika.io.model.InputTree
+import laika.theme.Theme
+import laika.theme.ThemeBuilder
+import laika.theme.ThemeProvider
+
+object CirceOrgHeliumExtensions extends ThemeProvider {
+
+ override def build[F[_]](implicit F: Sync[F]): Resource[F, Theme[F]] =
+ ThemeBuilder[F]("Circe Helium Extensions")
+ .addInputs(
+ InputTree[F].addStream(
+ F.blocking(getClass.getResourceAsStream("site/styles.css")),
+ Path.Root / "site" / "styles.css"
+ )
+ )
+ .addInputs(
+ InputTree[F].addStream(
+ F.blocking(getClass.getResourceAsStream("images/circe_dark.svg")),
+ Path.Root / "images" / "circe_dark.svg"
+ )
+ )
+ .addInputs(
+ InputTree[F].addStream(
+ F.blocking(getClass.getResourceAsStream("images/circe_light_no_border.svg")),
+ Path.Root / "images" / "circe_light_no_border.svg"
+ )
+ )
+ .addInputs(
+ InputTree[F].addStream(
+ F.blocking(getClass.getResourceAsStream("images/circe_light_no_border_146x173.png")),
+ Path.Root / "images" / "circe_light_no_border_146x173.png"
+ )
+ )
+ .build
+
+}
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 0000000..2dc4843
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,39 @@
+# sbt-circe-org
+
+This project is intended to set up sensible defaults and standards for projects under `io.circe`. If it's useful
+outside `io.circe`, it probably should be pushed further upstream
+into [sbt-typelevel](https://github.com/typelevel/sbt-typelevel).
+
+## Installing it
+
+The plugin is deployed to Sonatype.
+
+```scala
+addSbtPlugin("io.circe" % "sbt-circe-org" % "@VERSION@")
+```
+
+## What does it do?
+
+### `CirceOrgPlugin`
+
+Triggers automatically. Use on all published `circe` modules.
+
+* Activates the sensible defaults of [sbt-typelevel](https://github.com/typelevel/sbt-typelevel/)
+* Sets the organization info
+* Enables automated license headers with appropriate years
+* Enables [sbt-github-actions](https://typelevel.org/sbt-typelevel/gha.html) with settings appropriate to our
+ workflow
+* by default does not run code coverage in all `io.circe.examples.*` packages
+
+### `CirceOrgSitePlugin`
+
+Must be manually triggered. Extends the `TypelevelSitePlugin` with the `circe.io` theme. See
+the [sbt-typelevel-site docs](https://typelevel.org/sbt-typelevel/site.html) for usage.
+
+#### Provided images
+
+You can refer to the following images in customizing the `laika` theme:
+
+- `Path.Root / "images" / "circe_dark.svg"`
+- `Path.Root / "images" / "circe_light_no_border.svg"`
+- `Path.Root / "images" / "circe_light_no_border_146x173.png"`
diff --git a/project/build.properties b/project/build.properties
new file mode 100644
index 0000000..563a014
--- /dev/null
+++ b/project/build.properties
@@ -0,0 +1 @@
+sbt.version=1.7.2
diff --git a/project/build.sbt b/project/build.sbt
new file mode 120000
index 0000000..f24fe19
--- /dev/null
+++ b/project/build.sbt
@@ -0,0 +1 @@
+../core/build.sbt
\ No newline at end of file
diff --git a/project/src b/project/src
new file mode 120000
index 0000000..5bc79fa
--- /dev/null
+++ b/project/src
@@ -0,0 +1 @@
+../core/src
\ No newline at end of file