diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 000000000..2d6c9651e
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,25 @@
+name: test
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+jobs:
+ test:
+ strategy:
+ fail-fast: false
+ matrix:
+ java: [8, 11, 17]
+ scala: [2.11.x, 2.12.x, 2.13.x]
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ fetch-depth: 0
+ - uses: actions/setup-java@v3
+ with:
+ distribution: temurin
+ java-version: ${{matrix.java}}
+ cache: sbt
+ - name: Test
+ run: sbt ++${{matrix.scala}} test versionPolicyCheck package
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 000000000..d69ab7208
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,21 @@
+name: Release
+on:
+ push:
+ tags: ["*"]
+jobs:
+ publish:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ fetch-depth: 0
+ - uses: actions/setup-java@v2
+ with:
+ distribution: temurin
+ java-version: 8
+ - run: sbt versionCheck ci-release
+ env:
+ PGP_PASSPHRASE: ${{secrets.PGP_PASSPHRASE}}
+ PGP_SECRET: ${{secrets.PGP_SECRET}}
+ SONATYPE_PASSWORD: ${{secrets.SONATYPE_PASSWORD}}
+ SONATYPE_USERNAME: ${{secrets.SONATYPE_USERNAME}}
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index bef473398..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-version: ~> 1.0 # needed for imports
-
-import: scala/scala-dev:travis/default.yml
-
-language: scala
-
-scala:
- - 2.11.12
- - 2.12.12
- - 2.13.3
-
-env:
- - SCALAJS_VERSION= ADOPTOPENJDK=8
- - SCALAJS_VERSION=0.6.33 ADOPTOPENJDK=8
- - SCALAJS_VERSION=1.0.1 ADOPTOPENJDK=8
- - SCALAJS_VERSION= ADOPTOPENJDK=11
-
-matrix:
- exclude:
- - scala: 2.11.12
- env: SCALAJS_VERSION=0.6.33 ADOPTOPENJDK=8
- - scala: 2.11.12
- env: SCALAJS_VERSION=1.0.1 ADOPTOPENJDK=8
-
-install:
- - git fetch --tags # get all tags for sbt-dynver
-
-script: ./build.sh
diff --git a/build.sbt b/build.sbt
index a35583347..72f829f69 100644
--- a/build.sbt
+++ b/build.sbt
@@ -1,37 +1,55 @@
import sbtcrossproject.CrossPlugin.autoImport.{crossProject, CrossType}
+publish / skip := true // root project
+
+ThisBuild / startYear := Some(2002)
+ThisBuild / licenses += (("Apache-2.0", url("https://www.apache.org/licenses/LICENSE-2.0")))
+
+// because it doesn't declare it itself
+ThisBuild / libraryDependencySchemes += "org.scala-js" %% "scalajs-library" % "semver-spec"
+ThisBuild / apiURL := Some(url("https://javadoc.io/doc/org.scala-lang.modules/scala-xml_2.13/"))
+
+lazy val configSettings: Seq[Setting[?]] = Seq(
+ unmanagedSourceDirectories ++= {
+ unmanagedSourceDirectories.value.flatMap { dir =>
+ def forVersion(version: String): File = file(dir.getPath ++ "-" ++ version)
+ CrossVersion.partialVersion(scalaVersion.value) match {
+ case Some((2, 13)) => Seq(forVersion("2.13"))
+ case _ => Seq(forVersion("2.11-2.12"))
+ }
+ }
+ }
+)
+
lazy val xml = crossProject(JSPlatform, JVMPlatform)
.withoutSuffixFor(JVMPlatform)
.crossType(CrossType.Full)
.in(file("."))
.settings(ScalaModulePlugin.scalaModuleSettings)
- .jvmSettings(ScalaModulePlugin.scalaModuleSettingsJVM)
+ .jvmSettings(ScalaModulePlugin.scalaModuleOsgiSettings)
.settings(
name := "scala-xml",
+ scalaModuleAutomaticModuleName := Some("scala.xml"),
+ crossScalaVersions := Seq("2.13.11", "2.12.18", "2.11.12"),
+ scalaVersion := "2.12.18",
- // Compiler team advised avoiding the -Xfuture option for releases.
- // The output with -Xfuture should be periodically checked, though.
- scalacOptions ++= "-deprecation:false -feature -Xlint:-stars-align,-nullary-unit,_".split("\\s+").to[Seq],
- scalacOptions in Test += "-Xxml:coalescing",
+ scalacOptions ++= Seq("-deprecation:false", "-feature", "-Xlint:-stars-align,-nullary-unit,_"),
- scalaModuleMimaPreviousVersion := {
- if (System.getenv("SCALAJS_VERSION") == "1.0.1") None
- else Some("1.2.0")
- },
+ Test / scalacOptions += "-Xxml:coalescing",
- unmanagedSourceDirectories in Compile ++= {
- (unmanagedSourceDirectories in Compile).value.map { dir =>
- val sv = scalaVersion.value
- CrossVersion.partialVersion(sv) match {
- case Some((2, 13)) => file(dir.getPath ++ "-2.13")
- case _ => file(dir.getPath ++ "-2.11-2.12")
- }
- }
- },
+ headerLicense := Some(HeaderLicense.Custom(
+ s"""|Scala (https://www.scala-lang.org)
+ |
+ |Copyright EPFL and Lightbend, Inc.
+ |
+ |Licensed under Apache License 2.0
+ |(http://www.apache.org/licenses/LICENSE-2.0).
+ |
+ |See the NOTICE file distributed with this work for
+ |additional information regarding copyright ownership.
+ |""".stripMargin)),
- apiURL := Some(
- url(http://github.com/s%22%22%22https://scala.github.io/scala-xml/api/$%7B%22-.*%22.r.replaceAllIn(version.value,%20%22")}/""")
- ),
+ versionPolicyIntention := Compatibility.BinaryCompatible,
apiMappings ++= scalaInstance.value.libraryJars.filter { file =>
file.getName.startsWith("scala-library") && file.getName.endsWith(".jar")
@@ -47,7 +65,7 @@ lazy val xml = crossProject(JSPlatform, JVMPlatform)
file(jarPath)
-> url("http://docs.oracle.com/javase/8/docs/api")
)
- } getOrElse {
+ }.getOrElse {
// If everything fails, jam in Java 11 modules.
Map(
file("/modules/java.base")
@@ -58,16 +76,20 @@ lazy val xml = crossProject(JSPlatform, JVMPlatform)
}
}
)
+ .settings(
+ inConfig(Compile)(configSettings) ++ inConfig(Test)(configSettings)
+ )
.jvmSettings(
OsgiKeys.exportPackage := Seq(s"scala.xml.*;version=${version.value}"),
- libraryDependencies += "junit" % "junit" % "4.13" % "test",
- libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % "test",
- libraryDependencies += "org.apache.commons" % "commons-lang3" % "3.9" % "test",
- libraryDependencies += ("org.scala-lang" % "scala-compiler" % scalaVersion.value % "test").exclude("org.scala-lang.modules", s"scala-xml_${scalaBinaryVersion.value}")
+ libraryDependencies += "junit" % "junit" % "4.13.2" % Test,
+ libraryDependencies += "com.github.sbt" % "junit-interface" % "0.13.3" % Test,
+ libraryDependencies += "org.apache.commons" % "commons-lang3" % "3.12.0" % Test,
+ libraryDependencies += ("org.scala-lang" % "scala-compiler" % scalaVersion.value % Test).exclude("org.scala-lang.modules", s"scala-xml_${scalaBinaryVersion.value}")
)
.jsSettings(
+ crossScalaVersions := crossScalaVersions.value.filterNot(_.startsWith("2.11")),
// Scala.js cannot run forked tests
- fork in Test := false
+ Test / fork := false
)
- .jsConfigure(_.enablePlugins(ScalaJSJUnitPlugin))
+ .jsEnablePlugins(ScalaJSJUnitPlugin)
diff --git a/build.sh b/build.sh
deleted file mode 100755
index 11ca2bb0a..000000000
--- a/build.sh
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/bin/bash
-
-set -e
-
-# Builds of tagged revisions are published to sonatype staging.
-
-# Travis runs a build on new revisions and on new tags, so a tagged revision is built twice.
-# Builds for a tag have TRAVIS_TAG defined, which we use for identifying tagged builds.
-
-# sbt-dynver sets the version number from the tag
-# sbt-travisci sets the Scala version from the travis job matrix
-
-# To back-publish an existing release for a new Scala / Scala.js / Scala Native version:
-# - check out the tag for the version that needs to be published
-# - change `.travis.yml` to adjust the version numbers and trim down the build matrix as necessary
-# - commit the changes and tag this new revision with an arbitrary suffix after a hash, e.g.,
-# `v1.2.3#dotty-0.27` (the suffix is ignored, the version will be `1.2.3`)
-
-# We release on JDK 8 (for Scala 2.x and Dotty 0.x)
-isReleaseJob() {
- if [[ "$ADOPTOPENJDK" == "8" ]]; then
- true
- else
- false
- fi
-}
-
-if [[ "$SCALAJS_VERSION" == "" ]]; then
- projectPrefix="xml"
-else
- projectPrefix="xmlJS"
-fi
-
-verPat="[0-9]+\.[0-9]+\.[0-9]+(-[A-Za-z0-9-]+)?"
-tagPat="^v$verPat(#.*)?$"
-
-if [[ "$TRAVIS_TAG" =~ $tagPat ]]; then
- releaseTask="ci-release"
- if ! isReleaseJob; then
- echo "Not releasing on Java $ADOPTOPENJDK with Scala $TRAVIS_SCALA_VERSION"
- exit 0
- fi
-fi
-
-# default is +publishSigned; we cross-build with travis jobs, not sbt's crossScalaVersions
-export CI_RELEASE="$projectPrefix/publishSigned"
-export CI_SNAPSHOT_RELEASE="$projectPrefix/publish"
-
-# default is sonatypeBundleRelease, which closes and releases the staging repo
-# see https://github.com/xerial/sbt-sonatype#commands
-# for now, until we're confident in the new release scripts, just close the staging repo.
-export CI_SONATYPE_RELEASE="; sonatypePrepare; sonatypeBundleUpload; sonatypeClose"
-
-sbt clean $projectPrefix/test $projectPrefix/publishLocal $releaseTask
diff --git a/project/build.properties b/project/build.properties
index 0837f7a13..875b706a8 100644
--- a/project/build.properties
+++ b/project/build.properties
@@ -1 +1 @@
-sbt.version=1.3.13
+sbt.version=1.9.2
diff --git a/project/plugins.sbt b/project/plugins.sbt
index 2f2ad8e24..6f6beee39 100644
--- a/project/plugins.sbt
+++ b/project/plugins.sbt
@@ -1,6 +1,6 @@
-val scalaJSVersion =
- Option(System.getenv("SCALAJS_VERSION")).filter(_.nonEmpty).getOrElse("0.6.33")
-
-addSbtPlugin("org.scala-lang.modules" % "sbt-scala-module" % "2.1.3")
-addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.0.0")
-addSbtPlugin("org.scala-js" % "sbt-scalajs" % scalaJSVersion)
+addSbtPlugin("org.scala-lang.modules" % "sbt-scala-module" % "3.1.0")
+addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.3.2")
+addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "1.3.2")
+addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.13.2")
+addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.14")
+addSbtPlugin("de.heikoseeberger" % "sbt-header" % "5.10.0")
diff --git a/shared/src/main/scala/scala/xml/Utility.scala b/shared/src/main/scala/scala/xml/Utility.scala
index 9374ff990..4385e5807 100755
--- a/shared/src/main/scala/scala/xml/Utility.scala
+++ b/shared/src/main/scala/scala/xml/Utility.scala
@@ -9,6 +9,7 @@
package scala
package xml
+import scala.annotation.tailrec
import scala.collection.mutable
import scala.language.implicitConversions
import scala.collection.Seq
@@ -187,9 +188,7 @@ object Utility extends AnyRef with parsing.TokenTests {
decodeEntities: Boolean = true,
preserveWhitespace: Boolean = false,
minimizeTags: Boolean = false): StringBuilder =
- {
serialize(x, pscope, sb, stripComments, decodeEntities, preserveWhitespace, if (minimizeTags) MinimizeMode.Always else MinimizeMode.Never)
- }
/**
* Serialize an XML Node to a StringBuilder.
@@ -206,35 +205,66 @@ object Utility extends AnyRef with parsing.TokenTests {
stripComments: Boolean = false,
decodeEntities: Boolean = true,
preserveWhitespace: Boolean = false,
- minimizeTags: MinimizeMode.Value = MinimizeMode.Default): StringBuilder =
- {
- x match {
- case c: Comment => if (!stripComments) c buildString sb; sb
- case s: SpecialNode => s buildString sb
- case g: Group =>
- for (c <- g.nodes) serialize(c, g.scope, sb, stripComments, decodeEntities, preserveWhitespace, minimizeTags); sb
- case el: Elem =>
- // print tag with namespace declarations
- sb.append('<')
- el.nameToString(sb)
- if (el.attributes ne null) el.attributes.buildString(sb)
- el.scope.buildString(sb, pscope)
- if (el.child.isEmpty &&
- (minimizeTags == MinimizeMode.Always ||
- (minimizeTags == MinimizeMode.Default && el.minimizeEmpty))) {
- // no children, so use short form: