Skip to content

Introduce :sdk:utils:svg module#932

Merged
egorikftp merged 1 commit intomainfrom
task/svg-util
Mar 10, 2026
Merged

Introduce :sdk:utils:svg module#932
egorikftp merged 1 commit intomainfrom
task/svg-util

Conversation

@egorikftp
Copy link
Member

@egorikftp egorikftp commented Mar 9, 2026


📝 Changelog

If this PR introduces user-facing changes, please update the relevant Unreleased section in changelogs:

@egorikftp egorikftp requested a review from t-regbs March 9, 2026 09:47
@egorikftp egorikftp changed the title Introduce :sdk:tools:svg module Introduce :sdk:utils:svg module Mar 9, 2026
@coderabbitai
Copy link

coderabbitai bot commented Mar 9, 2026

Walkthrough

SVG manipulation code was moved from the parser component to a new SDK module: the SvgManipulator class was removed from components/parser/jvm/svg and replaced by a new public SvgDomModifier object in sdk/utils/svg (with INSTANCE, modify, updateAttributeConditionally, and updateAttributeRecursively). SvgToXmlParser gained an overload parse(Path). The project settings and Gradle files were updated to include the new sdk:utils:svg module and add it as a dependency for the IDE plugin; tests and call sites were updated to use SvgDomModifier.

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.69% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description includes the required changelog template with checkboxes but lacks substantive explanation of the changes, objectives, or technical details about what the new module does. Add explanation of the module's purpose, the refactoring from SvgManipulator to SvgDomModifier, and which changelog sections (if any) should be updated based on the actual changes made.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: introducing a new SDK utility module for SVG handling, which aligns with the primary objective of the pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch task/svg-util

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
sdk/utils/svg/src/main/kotlin/io/github/composegears/valkyrie/sdk/utils/svg/SvgDomModifier.kt (1)

57-60: Consider using structured logging instead of println.

Using println in library code can pollute stdout unexpectedly. Consider using System.err at minimum, or better yet, a logging abstraction if available in the project.

♻️ Suggested improvement
         } catch (e: Exception) {
-            println("Failed to parse SVG for modification: ${e.message}")
+            System.err.println("Failed to parse SVG for modification: ${e.message}")
             svgContent
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@sdk/utils/svg/src/main/kotlin/io/github/composegears/valkyrie/sdk/utils/svg/SvgDomModifier.kt`
around lines 57 - 60, Replace the println call in the catch block inside
SvgDomModifier (the catch (e: Exception) { ... } that currently prints "Failed
to parse SVG for modification: ${e.message}") with a structured logging call or
at minimum System.err; use the project's logging abstraction if available (or
java.util.logging/SLF4J) to log the error and include the exception (e) so
stacktrace is preserved, while returning svgContent as before.
sdk/utils/svg/src/test/kotlin/io/github/composegears/valkyrie/sdk/utils/svg/SvgDomModifierTest.kt (1)

14-14: Consider updating test method names to reflect the renamed API.

Several test methods still reference modifySvg (e.g., lines 14, 110, 134, 149, 164, 175) while the actual method is now modify. This is purely cosmetic but would improve consistency.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@sdk/utils/svg/src/test/kotlin/io/github/composegears/valkyrie/sdk/utils/svg/SvgDomModifierTest.kt`
at line 14, Update the test method names that still reference the old API name
`modifySvg` to match the renamed API `modify` (e.g., rename test methods like
`modifySvg updates root element attribute` and other tests mentioning
`modifySvg` to `modify updates root element attribute` etc.), ensuring all
occurrences in SvgDomModifierTest (test names and any display strings)
consistently use `modify` so names reflect the current API; keep the test bodies
unchanged, only rename the test method identifiers/descriptive names.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@sdk/utils/svg/build.gradle.kts`:
- Around line 7-8: Remove the unused Android build tools dependency by deleting
the implementation(libs.android.build.tools) entry from the dependencies block;
the module only uses standard JDK XML APIs so keep the remaining
testImplementation(libs.bundles.kmp.test) line and ensure no other references to
libs.android.build.tools exist in the file or build scripts.

---

Nitpick comments:
In
`@sdk/utils/svg/src/main/kotlin/io/github/composegears/valkyrie/sdk/utils/svg/SvgDomModifier.kt`:
- Around line 57-60: Replace the println call in the catch block inside
SvgDomModifier (the catch (e: Exception) { ... } that currently prints "Failed
to parse SVG for modification: ${e.message}") with a structured logging call or
at minimum System.err; use the project's logging abstraction if available (or
java.util.logging/SLF4J) to log the error and include the exception (e) so
stacktrace is preserved, while returning svgContent as before.

In
`@sdk/utils/svg/src/test/kotlin/io/github/composegears/valkyrie/sdk/utils/svg/SvgDomModifierTest.kt`:
- Line 14: Update the test method names that still reference the old API name
`modifySvg` to match the renamed API `modify` (e.g., rename test methods like
`modifySvg updates root element attribute` and other tests mentioning
`modifySvg` to `modify updates root element attribute` etc.), ensuring all
occurrences in SvgDomModifierTest (test names and any display strings)
consistently use `modify` so names reflect the current API; keep the test bodies
unchanged, only rename the test method identifiers/descriptive names.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 3d01e045-0e2a-4a4f-b345-3a83c71cf99c

📥 Commits

Reviewing files that changed from the base of the PR and between fc3fa83 and 6d56db9.

📒 Files selected for processing (9)
  • components/parser/jvm/svg/api/svg.api
  • components/parser/jvm/svg/build.gradle.kts
  • sdk/utils/svg/api/svg.api
  • sdk/utils/svg/build.gradle.kts
  • sdk/utils/svg/src/main/kotlin/io/github/composegears/valkyrie/sdk/utils/svg/SvgDomModifier.kt
  • sdk/utils/svg/src/test/kotlin/io/github/composegears/valkyrie/sdk/utils/svg/SvgDomModifierTest.kt
  • settings.gradle.kts
  • tools/idea-plugin/build.gradle.kts
  • tools/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/webimport/standard/common/domain/SvgSizeCustomizer.kt
💤 Files with no reviewable changes (2)
  • components/parser/jvm/svg/build.gradle.kts
  • components/parser/jvm/svg/api/svg.api

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
sdk/utils/svg/src/main/kotlin/io/github/composegears/valkyrie/sdk/utils/svg/SvgDomModifier.kt (1)

35-59: ⚠️ Potential issue | 🟠 Major

Don’t swallow exceptions thrown by the caller’s modification lambda.

modifications(svgElement) currently runs inside the broad catch, so any bug in caller code is converted into a silent “return original SVG”. That makes failures very hard to spot and can produce incorrect output without any signal.

💡 Suggested fix
-        return try {
+        val document = try {
             val factory = DocumentBuilderFactory.newInstance()
             factory.apply {
                 setFeature("http://apache.org/xml/features/disallow-doctype-decl", true)
                 setFeature("http://xml.org/sax/features/external-general-entities", false)
                 setFeature("http://xml.org/sax/features/external-parameter-entities", false)
             }
             val builder = factory.newDocumentBuilder()
-            val document = builder.parse(InputSource(StringReader(svgContent)))
-
-            val svgElement = document.documentElement
-            modifications(svgElement)
-
-            val transformerFactory = TransformerFactory.newInstance().apply {
-                setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "")
-                setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "")
-            }
-            val transformer = transformerFactory.newTransformer()
-            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes")
-            val writer = StringWriter()
-            transformer.transform(DOMSource(document), StreamResult(writer))
-            writer.toString()
+            builder.parse(InputSource(StringReader(svgContent)))
         } catch (e: Exception) {
             println("Failed to parse SVG for modification: ${e.message}")
-            svgContent
+            return svgContent
         }
+
+        val svgElement = document.documentElement
+        modifications(svgElement)
+
+        return try {
+            val transformerFactory = TransformerFactory.newInstance().apply {
+                setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "")
+                setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "")
+            }
+            val transformer = transformerFactory.newTransformer()
+            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes")
+            val writer = StringWriter()
+            transformer.transform(DOMSource(document), StreamResult(writer))
+            writer.toString()
+        } catch (e: Exception) {
+            println("Failed to serialize modified SVG: ${e.message}")
+            svgContent
+        }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@sdk/utils/svg/src/main/kotlin/io/github/composegears/valkyrie/sdk/utils/svg/SvgDomModifier.kt`
around lines 35 - 59, The current try/catch in SvgDomModifier.kt swallows
exceptions from the caller-provided modifications(svgElement) lambda causing
silent failures; change the flow so that parsing and transformation are caught
separately while allowing exceptions from modifications(svgElement) to propagate
(or at least be rethrown after logging). Concretely, perform document parsing
and obtaining svgElement inside the try block, then call
modifications(svgElement) outside that broad catch (or catch and rethrow the
caught modification exception), and keep only the IO/XML-specific operations
(parsing/transforming) inside a narrow try that returns svgContent on
parse/transform failures; ensure you reference the existing
modifications(svgElement), DocumentBuilderFactory/newDocumentBuilder/parse, and
TransformerFactory/transform symbols when relocating or narrowing the catch.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@sdk/utils/svg/api/svg.api`:
- Around line 1-5: The public API was renamed
(sdk.utils.svg.SvgDomModifier.modify replaces
parser.jvm.svg.SvgManipulator.modifySvg) which breaks consumers; restore a
deprecated forwarding shim by adding a class named parser.jvm.svg.SvgManipulator
with the original public method modifySvg having the original signature that
simply delegates to sdk.utils.svg.SvgDomModifier.INSTANCE.modify (preserve
parameter types and return type), annotate the old class/method as `@Deprecated`
and include a KDoc/JavaDoc note pointing to the new
sdk.utils.svg.SvgDomModifier.modify to guide users.

---

Outside diff comments:
In
`@sdk/utils/svg/src/main/kotlin/io/github/composegears/valkyrie/sdk/utils/svg/SvgDomModifier.kt`:
- Around line 35-59: The current try/catch in SvgDomModifier.kt swallows
exceptions from the caller-provided modifications(svgElement) lambda causing
silent failures; change the flow so that parsing and transformation are caught
separately while allowing exceptions from modifications(svgElement) to propagate
(or at least be rethrown after logging). Concretely, perform document parsing
and obtaining svgElement inside the try block, then call
modifications(svgElement) outside that broad catch (or catch and rethrow the
caught modification exception), and keep only the IO/XML-specific operations
(parsing/transforming) inside a narrow try that returns svgContent on
parse/transform failures; ensure you reference the existing
modifications(svgElement), DocumentBuilderFactory/newDocumentBuilder/parse, and
TransformerFactory/transform symbols when relocating or narrowing the catch.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: ff6178b1-97af-47ad-ac69-ed3ffb95ebe5

📥 Commits

Reviewing files that changed from the base of the PR and between 6d56db9 and 08d3189.

📒 Files selected for processing (9)
  • components/parser/jvm/svg/api/svg.api
  • components/parser/jvm/svg/build.gradle.kts
  • sdk/utils/svg/api/svg.api
  • sdk/utils/svg/build.gradle.kts
  • sdk/utils/svg/src/main/kotlin/io/github/composegears/valkyrie/sdk/utils/svg/SvgDomModifier.kt
  • sdk/utils/svg/src/test/kotlin/io/github/composegears/valkyrie/sdk/utils/svg/SvgDomModifierTest.kt
  • settings.gradle.kts
  • tools/idea-plugin/build.gradle.kts
  • tools/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/webimport/standard/common/domain/SvgSizeCustomizer.kt
💤 Files with no reviewable changes (2)
  • components/parser/jvm/svg/api/svg.api
  • components/parser/jvm/svg/build.gradle.kts
🚧 Files skipped from review as they are similar to previous changes (3)
  • tools/idea-plugin/build.gradle.kts
  • sdk/utils/svg/build.gradle.kts
  • settings.gradle.kts

@egorikftp egorikftp merged commit 697ee5f into main Mar 10, 2026
3 checks passed
@egorikftp egorikftp deleted the task/svg-util branch March 10, 2026 04:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants