Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Warning configuration DSL #4

Open
laughedelic opened this issue Aug 28, 2022 · 1 comment
Open

Warning configuration DSL #4

laughedelic opened this issue Aug 28, 2022 · 1 comment
Assignees

Comments

@laughedelic
Copy link

Hi! I have defined this little DSL for warnings configuration and thought of sharing it. It's pretty hard to remember all available filters, their short names, which actions have configurable verbosity, etc. and then piece them correctly together into a single string. With a DSL it's much easier to discover what's available via auto-complete, see full names and have a clear, readable configuration definition.

sealed trait WarningAction

case object silent extends WarningAction
case object error extends WarningAction

sealed trait WarningActionWithVerbosity extends WarningAction { action =>

  def summary: WarningAction = new WarningAction {
    override def toString = s"${action}-summary"
  }

  def verbose: WarningAction = new WarningAction {
    override def toString = s"${action}-verbose"
  }

}

case object warning extends WarningActionWithVerbosity
case object info extends WarningActionWithVerbosity

sealed class WarningFilter(val asString: String) {
  override def toString = asString

  def &(that: WarningFilter): WarningFilter = new WarningFilter(
    Seq(this.asString, that.asString).mkString("&")
  )

}

case object any extends WarningFilter("any")
case class cat(cat: String) extends WarningFilter(s"cat=${cat}")
case class msg(regex: String) extends WarningFilter(s"msg=${regex}")
case class src(regex: String) extends WarningFilter(s"src=${regex}")

case class origin(segments: String*)
    extends WarningFilter(s"origin=${segments.mkString(raw"\.")}")

case class WarningConfig(val rules: (WarningFilter, WarningAction)*) {

  override def toString = {
    val conf = rules.toSeq
      .map { case (filter, action) => Seq(filter, action).mkString(":") }
      .mkString(",")
    s"-Wconf:${conf}"
  }

  def asScalacOption =
    ScalacOption(
      option = this.toString,
      isSupported = {
        case ScalaVersion(2, 12, x) => x >= 13
        case ScalaVersion(2, 13, x) => x >= 2
        case _                      => false
      },
    )

}

Example usage:

WarningConfig(
  src("src_managed/.*") -> silent,
  cat("unused-imports") -> warning,
  (cat("deprecation") & origin("scala", ".*")) -> error,
  cat("deprecation") -> warning.verbose,
  cat("unused") -> warning.summary,
  any -> error,
)

is transformed into -Wconf:src=src_managed/.*:silent,cat=unused-imports:warning,cat=deprecation&origin=scala\..*:error,cat=deprecation:warning-verbose,cat=unused:warning-summary,any:error or with line breaks for readability:

-Wconf:
src=src_managed/.*:silent,
cat=unused-imports:warning,
cat=deprecation&origin=scala\..*:error,
cat=deprecation:warning-verbose,
cat=unused:warning-summary,
any:error

Would you be open to a pull request adding such DSL here? Details of the design are open for discussion, of course.

@SethTisue
Copy link
Member

@lrytz FYI

@satorg satorg self-assigned this Sep 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants