Skip to content

Commit

Permalink
Create a repository directive (#575)
Browse files Browse the repository at this point in the history
  • Loading branch information
ennru authored Jul 11, 2023
1 parent c06d7e0 commit 3e7558e
Show file tree
Hide file tree
Showing 7 changed files with 270 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .scala-steward.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pullRequests.frequency = "@monthly"

commits.message = "bump: ${artifactName} ${nextVersion} (was ${currentVersion})"
4 changes: 2 additions & 2 deletions RELEASING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Releasing

1. Wait until all running [Travis CI jobs](https://travis-ci.com/github/lightbend/paradox/builds) complete, if any.
1. Wait until all running [GitHub Continuous Integration workflow](https://github.com/lightbend/paradox/actions/workflows/ci.yml) is complete, if any.
1. Publish the [draft release](https://github.com/lightbend/paradox/releases) with a 'v0.x.y' tag
1. Travis CI will start a [CI build](https://travis-ci.org/lightbend/paradox/builds) for the new tag and publish artifacts to Bintray and Sonatype.
1. Have someone bake the release...
1. Announce the new release in the [lightbend/paradox](https://gitter.im/lightbend/paradox) Gitter channel.
101 changes: 101 additions & 0 deletions core/src/main/scala/com/lightbend/paradox/markdown/Directive.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1056,6 +1056,107 @@ case class DependencyDirective(ctx: Writer.Context) extends LeafBlockDirective("
def dotted(symbol: String): String = symbol.replaceAll("(.)([A-Z])", "$1.$2").toLowerCase
}

/**
* Repository directive.
*/
case class RepositoryDirective(ctx: Writer.Context) extends LeafBlockDirective("repository") {
val variables: Map[String, String] = ctx.properties

def render(node: DirectiveNode, visitor: Visitor, printer: Printer): Unit =
node.contentsNode.getChildren.asScala.headOption match {
case Some(text: TextNode) => renderRepository(text.getText, node, printer)
case _ => node.contentsNode.accept(visitor)
}

def renderRepository(tools: String, node: DirectiveNode, printer: Printer): Unit = {
val classes = Seq("repository", node.attributes.classesString).filter(_.nonEmpty)

val startDelimiter = node.attributes.value("start-delimiter", "$")
val stopDelimiter = node.attributes.value("stop-delimiter", "$")

val postfixes = node.attributes
.keys()
.asScala
.toSeq
.filter(_.startsWith("name"))
.sorted
.map(_.replace("name", ""))

def coordinate(name: String): Option[String] =
Option(node.attributes.value(name)).map { value =>
variables.foldLeft(value) { case (str, (key, value)) =>
str.replace(startDelimiter + key + stopDelimiter, value)
}
}

def requiredCoordinate(name: String): String =
coordinate(name).getOrElse {
ctx.error(s"'$name' is not defined", node)
""
}

printer.print(s"""<dl class="${classes.mkString(" ")}">""")
tools.split("[,]").map(_.trim).filter(_.nonEmpty).foreach { tool =>
val (lang, code) = tool match {
case "sbt" =>
val repos = postfixes.map { p =>
val name = requiredCoordinate(s"name$p")
val url = requiredCoordinate(s"url$p")
s""""$name".at("$url")"""
}

val repoStrings = repos match {
case Seq(r) => s"repositories += $r\n"
case rs =>
Seq("repositories ++= Seq(\n", rs.map(a => s" $a").mkString(",\n"), "\n)\n").mkString
}

("scala", repoStrings)

case "gradle" | "Gradle" =>
val repos = postfixes.map { p =>
val url = requiredCoordinate(s"url$p")
s""" maven {
| url "$url"
| }\n""".stripMargin
}

(
"gradle",
"repositories {\n mavenCentral()\n" +
repos.mkString +
"}\n"
)

case "maven" | "Maven" | "mvn" =>
val artifacts = postfixes.map { dp =>
val id = requiredCoordinate(s"id$dp")
val name = requiredCoordinate(s"name$dp")
val url = requiredCoordinate(s"url$dp")
s""" &lt;repository&gt;
| &lt;id&gt;$id&lt;/id&gt;
| &lt;name>$name&lt;/name&gt;
| &lt;url>$url&lt;/url&gt;
| &lt;/repository&gt;\n""".stripMargin
}

(
"xml",
"&lt;project&gt\n ...\n &lt;repositories&gt;\n" +
artifacts.mkString +
" &lt;/repositories&gt\n&lt;/project&gt;\n"
)
}
printer.print(s"""<dt>$tool</dt>""")
printer.print(s"""<dd>""")
printer.print(s"""<pre class="prettyprint"><code class="language-$lang">$code</code></pre>""")
printer.print(s"""</dd>""")
}
printer.print("""</dl>""")
}

}

case class IncludeDirective(ctx: Writer.Context) extends LeafBlockDirective("include") with SourceDirective {

override def render(node: DirectiveNode, visitor: Visitor, printer: Printer): Unit =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ object Writer {
_ => InlineWrapDirective("span"),
(context: Context) => InlineGroupDirective(context.groups.values.flatten.map(_.toLowerCase).toSeq),
DependencyDirective.apply,
RepositoryDirective.apply,
IncludeDirective.apply
)

Expand Down
1 change: 1 addition & 0 deletions docs/src/main/paradox/directives/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ More directives are available via @ref[extensions](../customization/extensions.m
* [Index and Table Of Contents Directives](organizing-pages.md)
* [Linking Directives](linking.md)
* [dependencies](dependencies.md)
* [repositories](repositories.md)
* [Snippet Directives](snippets.md)
* [Include Directives](includes.md)
* [Fiddle Directives](fiddles.md)
Expand Down
21 changes: 21 additions & 0 deletions docs/src/main/paradox/directives/repositories.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Library repositories
--------------------

The `@@repository` block is used to show example code for how to configure a
library repository in a build tool, such as sbt.

```markdown
@@repository[sbt,Maven,Gradle] {
id="company-repo"
name="Company repository"
url="http://jars.acme.com"
}
```

Which will render as:

@@repository[sbt,Maven,Gradle] {
id="company-repo"
name="Company repository"
url="http://jars.acme.com"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/*
* Copyright © 2015 - 2019 Lightbend, Inc. <http://www.lightbend.com>
*
* 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 com.lightbend.paradox.markdown

import com.lightbend.paradox.tree.Tree.Location

class RepositoryDirectiveSpec extends MarkdownBaseSpec {

val testProperties = Map(
"project.version" -> "10.0.10",
"scala.version" -> "2.12.3",
"scala.binary.version" -> "2.12"
)

implicit val context: Location[Page] => Writer.Context = { loc =>
writerContext(loc).copy(properties = testProperties)
}

"Repository directive" should "render single repo" in {
markdown("""
|@@repository[sbt,Maven,gradle] {
| id="id1"
| name="Company repository"
| url="http://jars.acme.com"
|}""") shouldEqual html(s"""
|<dl class="repository">
|<dt>sbt</dt>
|<dd>
|<pre class="prettyprint">
|<code class="language-scala">
|repositories += "Company repository".at("http://jars.acme.com")
|</code>
|</pre>
|</dd>
|<dt>Maven</dt>
|<dd>
|<pre class="prettyprint">
|<code class="language-xml">
|&lt;project&gt;
| ...
| &lt;repositories&gt;
| &lt;repository&gt;
| &lt;id&gt;id1&lt;/id&gt;
| &lt;name&gt;Company repository&lt;/name&gt;
| &lt;url&gt;http://jars.acme.com&lt;/url&gt;
| &lt;/repository&gt;
| &lt;/repositories&gt;
|&lt;/project&gt;
|</code></pre>
|</dd>
|<dt>gradle</dt>
|<dd>
|<pre class="prettyprint">
|<code class="language-gradle">
|repositories {
| mavenCentral()
| maven {
| url "http://jars.acme.com"
| }
|}
|</code></pre>
|</dd>
|</dl>""")
}

"Repository directive" should "render two repos" in {
markdown("""
|@@repository[sbt,Maven,gradle] {
| id1="id1"
| name1="Company repository"
| url1="http://jars.acme.com"
| id2="id-2"
| name2="Company repository 2"
| url2="http://uberjars.acme.com"
|}""") shouldEqual html(s"""
|<dl class="repository">
|<dt>sbt</dt>
|<dd>
|<pre class="prettyprint">
|<code class="language-scala">
|repositories ++= Seq(
| "Company repository".at("http://jars.acme.com"),
| "Company repository 2".at("http://uberjars.acme.com")
|)
|</code>
|</pre>
|</dd>
|<dt>Maven</dt>
|<dd>
|<pre class="prettyprint">
|<code class="language-xml">
|&lt;project&gt;
| ...
| &lt;repositories&gt;
| &lt;repository&gt;
| &lt;id&gt;id1&lt;/id&gt;
| &lt;name&gt;Company repository&lt;/name&gt;
| &lt;url&gt;http://jars.acme.com&lt;/url&gt;
| &lt;/repository&gt;
| &lt;repository&gt;
| &lt;id&gt;id-2&lt;/id&gt;
| &lt;name&gt;Company repository 2&lt;/name&gt;
| &lt;url&gt;http://uberjars.acme.com&lt;/url&gt;
| &lt;/repository&gt;
| &lt;/repositories&gt;
|&lt;/project&gt;
|</code></pre>
|</dd>
|<dt>gradle</dt>
|<dd>
|<pre class="prettyprint">
|<code class="language-gradle">
|repositories {
| mavenCentral()
| maven {
| url "http://jars.acme.com"
| }
| maven {
| url "http://uberjars.acme.com"
| }
|}
|</code></pre>
|</dd>
|</dl>""")
}

}

0 comments on commit 3e7558e

Please sign in to comment.