From 6a22c6fab89f935b8b5a523e2f028fbd4cb93a77 Mon Sep 17 00:00:00 2001 From: Yass Almardoud <149265907+yaseno2186@users.noreply.github.com> Date: Wed, 17 Jul 2024 10:38:57 +0200 Subject: [PATCH 1/2] 478 jqa tries to load rules from jqa report file (#482) --- .../core/rule/impl/reader/XmlHelper.java | 31 -------- .../rule/impl/reader/XmlRuleParserPlugin.java | 6 +- .../api/model/XmlRuleParserPluginTest.java | 37 +++++++++ .../plugin/PluginConfigurationReaderImpl.java | 2 +- .../core/shared/xml/XmlHelper.java | 75 +++++++++++++++++++ 5 files changed, 118 insertions(+), 33 deletions(-) delete mode 100644 core/rule/src/main/java/com/buschmais/jqassistant/core/rule/impl/reader/XmlHelper.java create mode 100644 core/shared/src/main/java/com/buschmais/jqassistant/core/shared/xml/XmlHelper.java diff --git a/core/rule/src/main/java/com/buschmais/jqassistant/core/rule/impl/reader/XmlHelper.java b/core/rule/src/main/java/com/buschmais/jqassistant/core/rule/impl/reader/XmlHelper.java deleted file mode 100644 index cf73aada3b..0000000000 --- a/core/rule/src/main/java/com/buschmais/jqassistant/core/rule/impl/reader/XmlHelper.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.buschmais.jqassistant.core.rule.impl.reader; - -import javax.xml.XMLConstants; -import javax.xml.validation.Schema; -import javax.xml.validation.SchemaFactory; - -import org.xml.sax.SAXException; - -/** - * Provides utility functions for working with XML files. - */ -public class XmlHelper { - - /** - * Return a {@link Schema} instance for the given resource. - * - * @param resource - * The resource. - * @return The {@link Schema} instance. - */ - public static Schema getSchema(String resource) { - Schema schema; - try { - SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); - schema = schemaFactory.newSchema(XmlHelper.class.getResource(resource)); - } catch (SAXException e) { - throw new IllegalStateException("Cannot read rules schema.", e); - } - return schema; - } -} diff --git a/core/rule/src/main/java/com/buschmais/jqassistant/core/rule/impl/reader/XmlRuleParserPlugin.java b/core/rule/src/main/java/com/buschmais/jqassistant/core/rule/impl/reader/XmlRuleParserPlugin.java index 06a736d291..503037c36e 100644 --- a/core/rule/src/main/java/com/buschmais/jqassistant/core/rule/impl/reader/XmlRuleParserPlugin.java +++ b/core/rule/src/main/java/com/buschmais/jqassistant/core/rule/impl/reader/XmlRuleParserPlugin.java @@ -14,10 +14,12 @@ import com.buschmais.jqassistant.core.rule.api.source.RuleSource; import com.buschmais.jqassistant.core.rule.impl.SourceExecutable; import com.buschmais.jqassistant.core.shared.xml.JAXBUnmarshaller; +import com.buschmais.jqassistant.core.shared.xml.XmlHelper; import org.jqassistant.schema.rule.v2.*; import static com.buschmais.jqassistant.core.rule.impl.reader.IndentHelper.removeIndent; +import static com.buschmais.jqassistant.core.shared.xml.XmlHelper.rootElementMatches; import static java.util.stream.Collectors.toSet; /** * A {@link RuleParserPlugin} implementation. @@ -38,7 +40,9 @@ public void initialize() { @Override public boolean accepts(RuleSource ruleSource) { - return ruleSource.getId().toLowerCase().endsWith(".xml"); + return ruleSource.getId() + .toLowerCase() + .endsWith(".xml") && rootElementMatches(ruleSource::getInputStream, qname -> "jqassistant-rules".equals(qname.getLocalPart())); } @Override diff --git a/core/rule/src/test/java/com/buschmais/jqassistant/core/rule/api/model/XmlRuleParserPluginTest.java b/core/rule/src/test/java/com/buschmais/jqassistant/core/rule/api/model/XmlRuleParserPluginTest.java index d3cf6baf39..817003da52 100644 --- a/core/rule/src/test/java/com/buschmais/jqassistant/core/rule/api/model/XmlRuleParserPluginTest.java +++ b/core/rule/src/test/java/com/buschmais/jqassistant/core/rule/api/model/XmlRuleParserPluginTest.java @@ -1,5 +1,7 @@ package com.buschmais.jqassistant.core.rule.api.model; +import java.io.ByteArrayInputStream; +import java.io.IOException; import java.net.URL; import java.util.Collection; import java.util.Map; @@ -7,6 +9,7 @@ import com.buschmais.jqassistant.core.rule.api.configuration.Rule; import com.buschmais.jqassistant.core.rule.api.reader.RuleParserPlugin; +import com.buschmais.jqassistant.core.rule.api.source.RuleSource; import com.buschmais.jqassistant.core.rule.api.source.UrlRuleSource; import com.buschmais.jqassistant.core.rule.impl.reader.XmlRuleParserPlugin; @@ -18,6 +21,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) class XmlRuleParserPluginTest { @@ -112,4 +116,37 @@ void ruleSchema_1_8() throws RuleException { assertThat(conceptIds.size()).isEqualTo(1); MatcherAssert.assertThat(conceptIds, IsCollectionContaining.hasItems("test")); } + + @Test + void testAccepts_ValidXmlFile_ReturnsTrue() throws IOException { + XmlRuleParserPlugin xmlRuleParserPlugin = new XmlRuleParserPlugin(); + RuleSource mockRuleSource = mock(RuleSource.class); + + doReturn("jqassistant-rules.xml").when(mockRuleSource) + .getId(); + when(mockRuleSource.getInputStream()).thenReturn(new ByteArrayInputStream("".getBytes())); + assertThat(xmlRuleParserPlugin.accepts(mockRuleSource)).isTrue(); + } + + @Test + void testAccepts_InvalidXmlFile_ReturnsFalse() throws IOException { + XmlRuleParserPlugin xmlRuleParserPlugin = new XmlRuleParserPlugin(); + RuleSource mockRuleSource = mock(RuleSource.class); + + doReturn("jqassistant-report.xml").when(mockRuleSource) + .getId(); + when(mockRuleSource.getInputStream()).thenReturn(new ByteArrayInputStream("".getBytes())); + assertThat(xmlRuleParserPlugin.accepts(mockRuleSource)).isFalse(); + } + + @Test + void testAccepts_InvalidXFile_ReturnsFalse() { + XmlRuleParserPlugin xmlRuleParserPlugin = new XmlRuleParserPlugin(); + RuleSource mockRuleSource = mock(RuleSource.class); + + doReturn("report.txt").when(mockRuleSource) + .getId(); + assertThat(xmlRuleParserPlugin.accepts(mockRuleSource)).isFalse(); + } + } diff --git a/core/runtime/src/main/java/com/buschmais/jqassistant/core/runtime/impl/plugin/PluginConfigurationReaderImpl.java b/core/runtime/src/main/java/com/buschmais/jqassistant/core/runtime/impl/plugin/PluginConfigurationReaderImpl.java index 5576dd3bba..af3e8eb20b 100644 --- a/core/runtime/src/main/java/com/buschmais/jqassistant/core/runtime/impl/plugin/PluginConfigurationReaderImpl.java +++ b/core/runtime/src/main/java/com/buschmais/jqassistant/core/runtime/impl/plugin/PluginConfigurationReaderImpl.java @@ -11,10 +11,10 @@ import javax.xml.validation.Schema; -import com.buschmais.jqassistant.core.rule.impl.reader.XmlHelper; import com.buschmais.jqassistant.core.runtime.api.plugin.PluginClassLoader; import com.buschmais.jqassistant.core.runtime.api.plugin.PluginConfigurationReader; import com.buschmais.jqassistant.core.shared.xml.JAXBUnmarshaller; +import com.buschmais.jqassistant.core.shared.xml.XmlHelper; import org.jqassistant.schema.plugin.v2.JqassistantPlugin; import org.slf4j.Logger; diff --git a/core/shared/src/main/java/com/buschmais/jqassistant/core/shared/xml/XmlHelper.java b/core/shared/src/main/java/com/buschmais/jqassistant/core/shared/xml/XmlHelper.java new file mode 100644 index 0000000000..066aed98e0 --- /dev/null +++ b/core/shared/src/main/java/com/buschmais/jqassistant/core/shared/xml/XmlHelper.java @@ -0,0 +1,75 @@ +package com.buschmais.jqassistant.core.shared.xml; + +import java.io.IOException; +import java.io.InputStream; +import java.util.function.Predicate; + +import javax.xml.XMLConstants; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; + +import lombok.extern.slf4j.Slf4j; +import org.xml.sax.SAXException; + +/** + * Provides utility functions for working with XML files. + */ +@Slf4j +public class XmlHelper { + + private final static XMLInputFactory xmlInputFactory; + + static { + xmlInputFactory = XMLInputFactory.newInstance(); + xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false); + } + + public static XMLInputFactory getXMLInputFactory() { + return xmlInputFactory; + } + + public static boolean rootElementMatches(InputStreamSupplier inputStreamSupplier, Predicate rootElementPredicate) { + try (InputStream stream = inputStreamSupplier.get()) { + XMLStreamReader reader = xmlInputFactory.createXMLStreamReader(stream); + while (reader.hasNext()) { + if (reader.next() == XMLStreamConstants.START_ELEMENT) { + return rootElementPredicate.test(reader.getName()); + } + } + } catch (XMLStreamException e) { + log.warn("Cannot parse XML file."); + } catch (IOException e) { + throw new IllegalStateException("Cannot close XML document.", e); + } + return false; + } + + public interface InputStreamSupplier { + + InputStream get() throws IOException; + + } + + /** + * Return a {@link Schema} instance for the given resource. + * + * @param resource + * The resource. + * @return The {@link Schema} instance. + */ + public static Schema getSchema(String resource) { + Schema schema; + try { + SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + schema = schemaFactory.newSchema(XmlHelper.class.getResource(resource)); + } catch (SAXException e) { + throw new IllegalStateException("Cannot read rules schema.", e); + } + return schema; + } +} From d689435920239e3b6723d9a78f40656e940055bf Mon Sep 17 00:00:00 2001 From: Yass Almardoud <149265907+yaseno2186@users.noreply.github.com> Date: Wed, 17 Jul 2024 12:10:29 +0200 Subject: [PATCH 2/2] #479 Added dryRun (#485) --- .github/workflows/release.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 811cfe0cb4..8f4dd33a95 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,7 +21,11 @@ on: description: "Default version to use for new local working copy." required: true default: "X.Y.Z-SNAPSHOT" - + dryRun: + description: "Perform a dry run" + required: true + default: false + type: boolean jobs: build: uses: jqassistant-tooling/jqassistant-github-actions/.github/workflows/release.yml@main @@ -29,9 +33,10 @@ jobs: branch: ${{ github.event.inputs.branch }} releaseVersion: ${{ github.event.inputs.releaseVersion }} developmentVersion: ${{ github.event.inputs.developmentVersion }} + dryRun: ${{ github.event.inputs.dryRun }} secrets: ossrh_username: ${{ secrets.OSSRH_USERNAME }} ossrh_password: ${{ secrets.OSSRH_PASSWORD }} ossrh_signing_key: ${{ secrets.OSSRH_SIGNING_KEY }} ossrh_signing_password: ${{ secrets.OSSRH_SIGNING_PASSWORD }} - sonar_token: ${{ secrets.SONAR_TOKEN }} \ No newline at end of file + sonar_token: ${{ secrets.SONAR_TOKEN }}