Skip to content

Commit

Permalink
Merge pull request #278 from armanbilge/merge/0.4-main
Browse files Browse the repository at this point in the history
Merge 0.4 -> main
  • Loading branch information
armanbilge authored May 22, 2022
2 parents b49d062 + 6408d94 commit 8e7dd01
Show file tree
Hide file tree
Showing 13 changed files with 143 additions and 31 deletions.
2 changes: 1 addition & 1 deletion .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version = 3.5.0
version = 3.5.2

runner.dialect = scala212source3

Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,9 @@ sbt-typelevel configures [sbt](https://www.scala-sbt.org/) for developing, testi

## Get Started

```sh
sbt new typelevel/typelevel.g8
```

Visit https://typelevel.org/sbt-typelevel for a quick start example and detailed documentation.
Find the Giter8 template companion project at [typelevel.g8](https://github.com/typelevel/typelevel.g8).
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,9 @@ lazy val docs = project
laikaConfig ~= { _.withRawContent },
tlSiteApiPackage := Some("org.typelevel.sbt"),
tlSiteRelatedProjects := Seq(
"typelevel.g8" -> url("https://github.com/typelevel/typelevel.g8"),
"sbt" -> url("https://www.scala-sbt.org/"),
"sbt-crossproject" -> url("https://github.com/portable-scala/sbt-crossproject"),
"sbt-github-actions" -> url("https://github.com/djspiewak/sbt-github-actions/"),
"mima" -> url("https://github.com/lightbend/mima"),
"mdoc" -> url("https://scalameta.org/mdoc/"),
"Laika" -> url("https://planet42.github.io/Laika/"),
Expand Down
2 changes: 1 addition & 1 deletion ci/build.sbt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "1.0.1")
addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "1.1.0")
28 changes: 26 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,29 @@ sbt-typelevel configures [sbt](https://www.scala-sbt.org/) for developing, testi
- CI deployed GitHub pages websites, generated with [mdoc](https://github.com/scalameta/mdoc/) and [Laika](https://github.com/planet42/laika)
- Auto-populated settings for various boilerplate (SCM info, API doc urls, Scala.js sourcemaps, etc.)

## Adopters

You can find an approximate list of sbt-typelevel adopters [here](https://github.com/typelevel/download-java/network/dependents), which includes all active [Typelevel](https://github.com/typelevel/) and [http4s](https://github.com/http4s/) projects.

## Quick start

[![sbt-typelevel Scala version support](https://index.scala-lang.org/typelevel/sbt-typelevel/sbt-typelevel/latest-by-scala-version.svg?targetType=Sbt)](https://index.scala-lang.org/typelevel/sbt-typelevel/sbt-typelevel)
[![Discord](https://img.shields.io/discord/632277896739946517.svg?label=&logo=discord&logoColor=ffffff&color=404244&labelColor=6A7EC2)](https://discord.gg/D7wY3aH7BQ)

### Giter8 Template

We provide a [Giter8 template](http://www.foundweekends.org/giter8/index.html) for quickly starting projects with familiar workflows and best practices.

```sh
sbt new typelevel/typelevel.g8
```

This will guide you through the basic setup to create a new project with **sbt-typelevel** and **sbt-typelevel-site**.
Check out the [typelevel.g8](https://github.com/typelevel/typelevel.g8) project for more details.


### Plugins

Pick either the **sbt-typelevel** (recommended) or **sbt-typelevel-ci-release** plugin.

#### `project/plugins.sbt`
Expand All @@ -26,6 +44,9 @@ addSbtPlugin("org.typelevel" % "sbt-typelevel" % "@VERSION@")

// Set me up for CI release, but don't touch my scalacOptions!
addSbtPlugin("org.typelevel" % "sbt-typelevel-ci-release" % "@VERSION@")

// Optional. Make me a website!
addSbtPlugin("org.typelevel" % "sbt-typelevel-site" % "@VERSION@")
```

@:callout(info)
Expand All @@ -40,7 +61,8 @@ addSbtPlugin("org.typelevel" % "sbt-typelevel-ci-release" % "@VERSION@")

@:@

Then configure your build.

### Configure Your Build

#### `build.sbt`

Expand Down Expand Up @@ -91,7 +113,9 @@ lazy val tests = crossProject(JVMPlatform, JSPlatform)
)
```

Next, run `githubWorkflowGenerate` in sbt to automatically generate the GitHub Actions workflows.
### Configure GitHub Actions

Run `githubWorkflowGenerate` in sbt to automatically generate the GitHub Actions workflows.
This will create a CI matrix parallelized on Scala version and target platform (JVM, JS, etc.) and includes steps for running tests and checking binary compatibility.
It will also setup a job for publishing tagged releases e.g. `v0.4.5` and snapshots to Sonatype/Maven.

Expand Down
33 changes: 19 additions & 14 deletions github/src/main/scala/org/typelevel/sbt/TypelevelGitHubPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ object TypelevelGitHubPlugin extends AutoPlugin {
tlGitHubRepo := gitHubUserRepo.value.map(_._2),
scmInfo := gitHubUserRepo.value.map {
case (user, repo) =>
sLog.value.info(s"set scmInfo to https://github.com/$user/$repo")
gitHubScmInfo(user, repo)
},
homepage := homepage.value.orElse(scmInfo.value.map(_.browseUrl))
Expand All @@ -55,22 +56,26 @@ object TypelevelGitHubPlugin extends AutoPlugin {
s"scm:git:git@github.com:$user/$repo.git"
)

private[sbt] def gitHubUserRepo = Def.setting {
private[sbt] lazy val gitHubUserRepo = Def.setting {
import scala.sys.process._

val identifier = """([^\/]+?)"""
val GitHubHttps = s"https://github.com/$identifier/$identifier(?:\\.git)?".r
val GitHubGit = s"git://github.com:$identifier/$identifier(?:\\.git)?".r
val GitHubSsh = s"git@github.com:$identifier/$identifier(?:\\.git)?".r
Try {
val remote = List("git", "ls-remote", "--get-url", "origin").!!.trim()
remote match {
case GitHubHttps(user, repo) => Some((user, repo))
case GitHubGit(user, repo) => Some((user, repo))
case GitHubSsh(user, repo) => Some((user, repo))
case _ => None
}
}.toOption.flatten
def fromRemote(remote: String) = {
val identifier = """([^\/]+?)"""
val GitHubHttps = s"https://github.com/$identifier/$identifier(?:\\.git)?".r
val GitHubGit = s"git://github.com:$identifier/$identifier(?:\\.git)?".r
val GitHubSsh = s"git@github.com:$identifier/$identifier(?:\\.git)?".r
Try {
List("git", "ls-remote", "--get-url", remote).!!.trim() match {
case GitHubHttps(user, repo) => Some((user, repo))
case GitHubGit(user, repo) => Some((user, repo))
case GitHubSsh(user, repo) => Some((user, repo))
case _ => None
}
}.toOption.flatten
}

// upstream if this is a fork, otherwise fallback to origin
fromRemote("upstream").orElse(fromRemote("origin"))
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ object TypelevelScalaJSGitHubPlugin extends AutoPlugin {
override def requires = ScalaJSPlugin && TypelevelKernelPlugin

import TypelevelKernelPlugin.autoImport._
import ScalaJSPlugin.autoImport._

override def projectSettings = Seq(
scalacOptions ++= {
Expand All @@ -43,6 +44,9 @@ object TypelevelScalaJSGitHubPlugin extends AutoPlugin {
s"$flag$l->$g"
}
}
},
scalaJSLinkerConfig := {
scalaJSLinkerConfig.value.withBatchMode(sys.env.get("GITHUB_ACTIONS").contains("true"))
}
)
}
2 changes: 1 addition & 1 deletion mima/build.sbt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "1.0.1")
addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "1.1.0")
1 change: 1 addition & 0 deletions settings/build.sbt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
addSbtPlugin("com.github.sbt" % "sbt-git" % "2.0.0")
addSbtPlugin("org.portable-scala" % "sbt-crossproject" % "1.2.0")
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,13 @@ package org.typelevel.sbt
import sbt._, Keys._
import com.github.sbt.git.GitPlugin
import com.github.sbt.git.SbtGit.git
import java.io.File
import java.lang.management.ManagementFactory
import org.typelevel.sbt.kernel.V
import org.typelevel.sbt.kernel.GitHelper
import sbtcrossproject.CrossPlugin.autoImport._
import sbtcrossproject.CrossType
import scala.util.Try

object TypelevelSettingsPlugin extends AutoPlugin {
override def trigger = allRequirements
Expand Down Expand Up @@ -70,12 +75,6 @@ object TypelevelSettingsPlugin extends AutoPlugin {
Seq.empty
}
},
scalacOptions ++= {
if (tlFatalWarnings.value)
Seq("-Xfatal-warnings")
else
Seq.empty
},
scalacOptions ++= {
val warningsNsc = Seq("-Xlint", "-Ywarn-dead-code")

Expand Down Expand Up @@ -199,6 +198,14 @@ object TypelevelSettingsPlugin extends AutoPlugin {
"utf8",
"-Xlint:all"
),

// TODO make these respect Compile/Test config
scalacOptions ++= {
if (tlFatalWarnings.value)
Seq("-Xfatal-warnings")
else
Seq.empty
},
javacOptions ++= {
if (tlFatalWarnings.value)
Seq("-Werror")
Expand Down Expand Up @@ -231,6 +238,35 @@ object TypelevelSettingsPlugin extends AutoPlugin {
},
javacOptions ++= {
withJdkRelease(tlJdkRelease.value)(Seq.empty[String])(n => Seq("--release", n.toString))
},
javaApiMappings
) ++ inConfig(Compile)(perConfigSettings) ++ inConfig(Test)(perConfigSettings)

private val perConfigSettings = Seq(
unmanagedSourceDirectories ++= {
def extraDirs(suffix: String) =
if (crossProjectPlatform.?.value.isDefined)
List(CrossType.Pure, CrossType.Full).flatMap {
_.sharedSrcDir(baseDirectory.value, Defaults.nameForSrc(configuration.value.name))
.toList
.map(f => file(f.getPath + suffix))
}
else
List(
baseDirectory.value / "src" / Defaults.nameForSrc(
configuration.value.name) / s"scala$suffix"
)

CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, y)) if y <= 12 => extraDirs("-2.12-")
case Some((2, y)) if y >= 13 => extraDirs("-2.13+")
case Some((3, _)) => extraDirs("-2.13+")
case _ => Nil
}
},
packageSrc / mappings ++= {
val base = sourceManaged.value
managedSources.value.map(file => file -> file.relativeTo(base).get.getPath)
}
)

Expand All @@ -256,4 +292,27 @@ object TypelevelSettingsPlugin extends AutoPlugin {
}

private val isJava8: Boolean = javaRuntimeVersion == 8

private val javaApiMappings = {
// scaladoc doesn't support this automatically before 2.13
val baseUrl = javaRuntimeVersion match {
case v if v < 11 => url(s"https://docs.oracle.com/javase/${v}/docs/api/")
case v => url(s"https://docs.oracle.com/en/java/javase/${v}/docs/api/java.base/")
}
doc / apiMappings ~= { old =>
val runtimeMXBean = ManagementFactory.getRuntimeMXBean
val oldSchool = Try(
if (runtimeMXBean.isBootClassPathSupported)
runtimeMXBean
.getBootClassPath
.split(File.pathSeparatorChar)
.map(file(_) -> baseUrl)
.toMap
else Map.empty
).getOrElse(Map.empty)
val newSchool = Map(file("/modules/java.base") -> baseUrl)
// Latest one wins. We are providing a fallback.
oldSchool ++ newSchool ++ old
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ object TypelevelHeliumExtensions {
def apply(license: Option[(String, URL)], related: Seq[(String, URL)]): ThemeProvider =
apply(license, related, false)

/**
* @param license
* name and [[java.net.URL]] of project license
* @param related
* name and [[java.net.URL]] of related projects
* @param scala3
* whether to use Scala 3 syntax highlighting
*/
def apply(
license: Option[(String, URL)],
related: Seq[(String, URL)],
Expand Down
2 changes: 1 addition & 1 deletion sonatype/build.sbt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "1.0.1")
addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "1.1.0")
addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.11")
addSbtPlugin("com.github.sbt" % "sbt-unidoc" % "0.5.0")
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ object TypelevelVersioningPlugin extends AutoPlugin {
versionScheme := Some("early-semver"),
tlUntaggedAreSnapshots := true,
isSnapshot := {
val isUntagged = getTaggedVersion(git.gitCurrentTags.value).isEmpty
val isUntagged = taggedVersion.value.isEmpty
val dirty = git.gitUncommittedChanges.value
dirty || (isUntagged && tlUntaggedAreSnapshots.value)
},
Expand All @@ -67,7 +67,12 @@ object TypelevelVersioningPlugin extends AutoPlugin {
.filter(v => v.patch.isEmpty && v.prerelease.isEmpty)
.getOrElse(sys.error(s"tlBaseVersion must be of form x.y: ${tlBaseVersion.value}"))

var version = getTaggedVersion(git.gitCurrentTags.value).map(_.toString).getOrElse {
val taggedV =
if (git.gitUncommittedChanges.value)
None // tree is dirty, so ignore the tags
else taggedVersion.value.map(_.toString)

var version = taggedV.getOrElse {
// No tag, so we build our version based on this commit

val latestInSeries = GitHelper
Expand Down Expand Up @@ -121,7 +126,8 @@ object TypelevelVersioningPlugin extends AutoPlugin {

private val Description = """^.*-(\d+)-[a-zA-Z0-9]+$""".r

private def getTaggedVersion(tags: Seq[String]): Option[V] =
tags.collectFirst { case V.Tag(v) => v }
private def taggedVersion = Def.setting {
git.gitCurrentTags.value.collectFirst { case V.Tag(v) => v }
}

}

0 comments on commit 8e7dd01

Please sign in to comment.