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

Allow PluginXmlPatcher to patch multi-line tags #129

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,23 @@ class PluginXmlPatcher(input: Path, createCopy: Boolean = false) {
content
}

private def tag(str: String, name: String, value: String): String =
if (str.matches(s"(?s)^.*<$name>.+</$name>.*$$"))
str.replaceAll(s"<$name>.+</$name>", s"<$name>$value</$name>")
else {
log.warn(s"$input doesn't have $name tag defined, not patching")
str
}
private def tag(str: String, name: String, value: String): String = {
val tagPattern = s"(?s)(<!--.*?-->)|(<$name>.*?</$name>)".r
val matches = tagPattern.findAllMatchIn(str).toList
var replacedStr = str

matches.reverse.foreach { matchItem =>
val matchedStr = matchItem.matched
val startIdx = matchItem.start
val endIdx = matchItem.end

if (!matchedStr.startsWith("<!--")) {
val newValue = matchedStr.replaceFirst(s"(?s)<$name>.*?</$name>", s"<$name>$value</$name>")
val prefix = replacedStr.substring(0, startIdx)
val postfix = replacedStr.substring(endIdx)
replacedStr = prefix + newValue + postfix
}
}
replacedStr
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<idea-plugin url="https://www.jetbrains.com/idea">
<!--12345<description>This is comment 1</description>-->
<!-- <description>This is
comment 2</description> -->
<!--<description>This is comment 3</description>12345-->
<description>DESCRIPTION
LINE2</description>
<!-- <description>This is comment 4</description>-->
<description>DESCRIPTION
LINE2</description>
</idea-plugin>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<idea-plugin url="https://www.jetbrains.com/idea">
<!--12345<description>This is comment 1</description>-->
<!-- <description>This is
comment 2</description> -->
<!--<description>This is comment 3</description>12345-->
<description>Integrates Volume Snapshot Service W10
This is a very
long description.
It has multiple lines.
</description>
<!-- <description>This is comment 4</description>-->
<description>Integrates Volume Snapshot Service W10
This is a very
long description.
It has multiple lines.
</description>
</idea-plugin>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<idea-plugin url="https://www.jetbrains.com/idea">
<description>DESCRIPTION
LINE2</description>
</idea-plugin>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<idea-plugin url="https://www.jetbrains.com/idea">
<description>Integrates Volume Snapshot Service W10
This is a very
long description.
It have multiple lines.
</description>
</idea-plugin>
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import java.nio.file.{Files, StandardCopyOption}
import scala.collection.JavaConverters.collectionAsScalaIterableConverter
import scala.util.Using

private class PluginXmlPatchingTest extends AnyFunSuite with Matchers with IdeaMock {
class PluginXmlPatchingTest extends AnyFunSuite with Matchers with IdeaMock {

private def getPluginXml = {
private def getPluginXml(pluginXmlName: String = "plugin.xml") = {
val tmpFile = createTempFile("", "plugin.xml")
Using.resource(getClass.getResourceAsStream("plugin.xml")) { stream =>
Using.resource(getClass.getResourceAsStream(pluginXmlName)) { stream =>
Files.copy(stream, tmpFile, StandardCopyOption.REPLACE_EXISTING)
}
tmpFile
Expand All @@ -27,7 +27,7 @@ private class PluginXmlPatchingTest extends AnyFunSuite with Matchers with IdeaM
xml.sinceBuild = "SINCE_BUILD"
xml.untilBuild = "UNTIL_BUILD"
}
val pluginXml = getPluginXml
val pluginXml = getPluginXml()
val initialContent = Files.readAllLines(pluginXml).asScala
val patcher = new PluginXmlPatcher(pluginXml)
val result = patcher.patch(options)
Expand All @@ -49,7 +49,7 @@ private class PluginXmlPatchingTest extends AnyFunSuite with Matchers with IdeaM
xml.pluginDescription = "DESCRIPTION"
xml.sinceBuild = "SINCE_BUILD"
}
val pluginXml = getPluginXml
val pluginXml = getPluginXml()
val initialContent = Files.readAllLines(pluginXml).asScala
val patcher = new PluginXmlPatcher(pluginXml)
val result = patcher.patch(options)
Expand All @@ -71,7 +71,7 @@ private class PluginXmlPatchingTest extends AnyFunSuite with Matchers with IdeaM
xml.pluginDescription = "DESCRIPTION"
xml.untilBuild = "UNTIL_BUILD"
}
val pluginXml = getPluginXml
val pluginXml = getPluginXml()
val initialContent = Files.readAllLines(pluginXml).asScala
val patcher = new PluginXmlPatcher(pluginXml)
val result = patcher.patch(options)
Expand All @@ -88,7 +88,7 @@ private class PluginXmlPatchingTest extends AnyFunSuite with Matchers with IdeaM

test("no modifications done if no patching options are defined") {
val options = pluginXmlOptions { _ => }
val pluginXml = getPluginXml
val pluginXml = getPluginXml()
val initialContent = Files.readAllLines(pluginXml).asScala
val patcher = new PluginXmlPatcher(pluginXml)
val result = patcher.patch(options)
Expand All @@ -99,4 +99,31 @@ private class PluginXmlPatchingTest extends AnyFunSuite with Matchers with IdeaM
diff.size shouldBe 0
}

test("multi-line tags are patched correctly") {
val pluginXml = getPluginXml("plugin-multilinetag.xml")

val options = pluginXmlOptions { xml =>
xml.pluginDescription = "DESCRIPTION\nLINE2"
}
val patcher = new PluginXmlPatcher(pluginXml)
val result = patcher.patch(options)
val newContent = Files.readAllLines(result).asScala.mkString("\n")

val golden = Files.readAllLines(getPluginXml("plugin-multilinetag-golden.xml")).asScala.mkString("\n")
newContent shouldBe golden
}

test("duplicate tags are only patched the uncommented first one") {
val pluginXml = getPluginXml("plugin-duplicatedtags.xml")

val options = pluginXmlOptions { xml =>
xml.pluginDescription = "DESCRIPTION\nLINE2"
}
val patcher = new PluginXmlPatcher(pluginXml)
val result = patcher.patch(options)
val newContent = Files.readAllLines(result).asScala.mkString("\n")

val golden = Files.readAllLines(getPluginXml("plugin-duplicatedtags-golden.xml")).asScala.mkString("\n")
newContent shouldBe golden
}
}