This is an automated email from the ASF dual-hosted git repository. lgcareer pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-dolphinscheduler-maven-plugin.git
commit 9cee2966735201c3af84feca0e0b70b7708cf085 Author: gaojun2048 <540957...@qq.com> AuthorDate: Tue Jun 2 14:04:05 2020 +0800 first commit --- .gitignore | 47 +++++ LICENSE | 202 +++++++++++++++++++++ README.md | 8 + pom.xml | 138 ++++++++++++++ .../maven/DolphinDescriptorGenerator.java | 137 ++++++++++++++ .../maven/SpiDependencyChecker.java | 147 +++++++++++++++ .../META-INF/m2e/lifecycle-mapping-metadata.xml | 14 ++ .../META-INF/plexus/components.xml | 62 +++++++ .../META-INF/provisio/dolphinscheduler-plugin.xml | 4 + .../maven/DolphinDescriptorGeneratorTest.java | 67 +++++++ .../maven/SpiDependencyCheckerTest.java | 101 +++++++++++ src/test/projects/abstract-plugin-class/pom.xml | 33 ++++ .../src/main/java/its/AbsTestPlugin.java | 6 + .../src/main/java/its/TestPluginImpl.java | 6 + src/test/projects/error-scope-but-skip/pom.xml | 44 +++++ .../src/main/java/its/ErrorScopeButSkipPlugin.java | 6 + src/test/projects/error-scope-dependency/pom.xml | 41 +++++ .../main/java/its/ErrorScopeDependencyPlugin.java | 6 + src/test/projects/error-scope-spi/pom.xml | 33 ++++ .../src/main/java/its/ErrorScopeSpiPlugin.java | 6 + src/test/projects/excluded-dependency/pom.xml | 46 +++++ .../src/main/java/its/SimplestPlugin.java | 6 + src/test/projects/interface-plugin-class/pom.xml | 33 ++++ .../src/main/java/its/ITestPlugin.java | 6 + .../src/main/java/its/TestPluginImpl.java | 6 + src/test/projects/more-excluded-dependency/pom.xml | 54 ++++++ .../src/main/java/its/SimplestPlugin.java | 6 + src/test/projects/simplest/pom.xml | 34 ++++ .../simplest/src/main/java/its/SimplestPlugin.java | 6 + 29 files changed, 1305 insertions(+) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..17b0dc6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,47 @@ +.git +.svn +.hg +.zip +.gz +.DS_Store +.idea/ +dist/ +all-dependencies.txt +self-modules.txt +third-party-dependencies.txt +**/target/ +.settings +.nbproject +.classpath +.project +**/*.iml +*.ipr +*.iws +*.tgz +.*.swp +.vim +.tmp +**/node_modules +npm-debug.log +.vscode +logs/* +.www +t.* +yarn.lock +package-lock.json +config.gypi +test/coverage +/docs/zh_CN/介绍 +/docs/zh_CN/贡献代码.md +/dolphinscheduler-common/src/main/resources/zookeeper.properties +dolphinscheduler-alert/logs/ +dolphinscheduler-alert/src/main/resources/alert.properties_bak +dolphinscheduler-alert/src/main/resources/logback.xml +dolphinscheduler-server/src/main/resources/logback.xml +dolphinscheduler-ui/dist/ +dolphinscheduler-ui/node +dolphinscheduler-dao/src/main/resources/dao/data_source.properties + +.mvn/wrapper/*.jar + +!/zookeeper_data/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..57bc88a --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + diff --git a/README.md b/README.md new file mode 100644 index 0000000..bbdea6a --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +This is a maven plugin for DolphinScheduler , It has tow functions: + +1. It is allowed to add <packaging>dolphinscheduler-plugin</packaging> to the pom file. If <packaging>dolphinscheduler-plugin</packaging> is added to the pom file, the DolphinScheduler service will load this model as a DolphinScheduler plugin. + +2. Automatically check the model with <packaging>dolphinscheduler-plugin</packaging> added to the pom file, and will automatically generate META-INF/services/org.apache.dolphinscheduler.spi.DolphinScheduler file when compile. + +3. Automatically check DolphinScheduler's maven dependency. Especially the dependencies used by plugins. + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..cb726b8 --- /dev/null +++ b/pom.xml @@ -0,0 +1,138 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>io.takari</groupId> + <artifactId>takari</artifactId> + <version>24</version> + </parent> + + <groupId>org.apache.dolphinscheduler</groupId> + <artifactId>dolphinscheduler-maven-plugin</artifactId> + <version>1.0.0-SNAPSHOT</version> + <packaging>takari-maven-plugin</packaging> + + <name>dolphinscheduler-maven-plugin</name> + <url>http://dolphinscheduler.apache.org</url> + <description>Dolphin Scheduler Maven Plugin provides a packing and lifecycle for DolphinScheduler plugins + </description> + <!--<licenses>--> + <!--<license>--> + <!--<name>Apache License 2.0</name>--> + <!--<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>--> + <!--<distribution>repo</distribution>--> + <!--</license>--> + <!--</licenses>--> + <!--<scm>--> + <!--<connection>scm:git:https://github.com/apache/incubator-dolphinscheduler-maven-plugin.git</connection>--> + <!--<developerConnection>scm:git:https://github.com/apache/incubator-dolphinscheduler-maven-plugin.git</developerConnection>--> + <!--<url>https://github.com/apache/incubator-dolphinscheduler-maven-plugin</url>--> + <!--<tag>HEAD</tag>--> + <!--</scm>--> + <!--<mailingLists>--> + <!--<mailingList>--> + <!--<name>DolphinScheduler Developer List</name>--> + <!--<post>d...@dolphinscheduler.incubator.apache.org</post>--> + <!--<subscribe>dev-subscr...@dolphinscheduler.incubator.apache.org</subscribe>--> + <!--<unsubscribe>dev-unsubscr...@dolphinscheduler.incubator.apache.org</unsubscribe>--> + <!--</mailingList>--> + <!--</mailingLists>--> + + <properties> + <mavenVersion>3.2.3</mavenVersion> + <mavenPluginPluginVersion>3.2</mavenPluginPluginVersion> + <provisioVersion>1.0.7</provisioVersion> + <takari.javaSourceVersion>1.8</takari.javaSourceVersion> + + <!-- declare language version for IntelliJ IDEA --> + <maven.compiler.source>${takari.javaSourceVersion}</maven.compiler.source> + <maven.compiler.target>${takari.javaSourceVersion}</maven.compiler.target> + </properties> + + <prerequisites> + <maven>[3.2.1,)</maven> + </prerequisites> + + <dependencies> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>${mavenVersion}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.maven.plugin-tools</groupId> + <artifactId>maven-plugin-annotations</artifactId> + <version>${mavenPluginPluginVersion}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <version>${mavenVersion}</version> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>org.eclipse.aether</groupId> + <artifactId>aether-api</artifactId> + <version>1.1.0</version> + </dependency> + + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.0.17</version> + </dependency> + + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact</artifactId> + <version>3.2.3</version> + </dependency> + + <!-- for testing --> + <dependency> + <groupId>io.takari.maven.plugins</groupId> + <artifactId>takari-plugin-testing</artifactId> + <version>2.9.1</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>io.takari.maven.plugins</groupId> + <artifactId>takari-plugin-integration-testing</artifactId> + <version>2.9.1</version> + <type>pom</type> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.11</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.assertj</groupId> + <artifactId>assertj-core</artifactId> + <version>3.15.0</version> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <directory>src/main/resources</directory> + </resource> + <resource> + <directory>src/main/resources-filtered</directory> + <filtering>true</filtering> + </resource> + </resources> + </build> + +</project> \ No newline at end of file diff --git a/src/main/java/org/apache/dolphinscheduler/maven/DolphinDescriptorGenerator.java b/src/main/java/org/apache/dolphinscheduler/maven/DolphinDescriptorGenerator.java new file mode 100644 index 0000000..0733531 --- /dev/null +++ b/src/main/java/org/apache/dolphinscheduler/maven/DolphinDescriptorGenerator.java @@ -0,0 +1,137 @@ +package org.apache.dolphinscheduler.maven; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.AbstractMojo; +import static java.nio.charset.StandardCharsets.UTF_8; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.annotations.ResolutionScope; +import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.util.FileUtils; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Modifier; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; + +/** + * Mojo that generates the service descriptor JAR for DolphinScheduler plugins. + */ +@Mojo(name = "generate-dolphin-service-descriptor", + defaultPhase = LifecyclePhase.PACKAGE, + requiresDependencyResolution = ResolutionScope.COMPILE) +public class DolphinDescriptorGenerator extends AbstractMojo { + private static final String LS_ALIAS = System.getProperty("line.separator"); + + @Parameter(defaultValue = "org.apache.dolphinscheduler.spi.DolphinSchedulerPlugin") + private String pluginClassName; + + @Parameter(defaultValue = "${project.build.outputDirectory}/META-INF/services") + private File servicesDirectory; + + @Parameter(defaultValue = "${project.build.outputDirectory}") + private File classesDirectory; + + @Parameter(defaultValue = "${project}") + private MavenProject project; + + @Override + public void execute() + throws MojoExecutionException + { + File servicesFile = new File(servicesDirectory, pluginClassName); + + // If users have already provided their own service file then we will not overwrite it + if (servicesFile.exists()) { + return; + } + + if (!servicesFile.getParentFile().exists()) { + mkdirs(servicesFile.getParentFile()); + } + + List<Class<?>> pluginImplClasses; + try { + URLClassLoader loader = createCLFromCompileTimeDependencies(); + pluginImplClasses = findPluginImplClasses(loader); + } + catch (Exception e) { + throw new MojoExecutionException(String.format("%n%nError scanning for classes implementing %s.", pluginClassName), e); + } + if (pluginImplClasses.isEmpty()) { + throw new MojoExecutionException(String.format("%n%nYou must have at least one class that implements %s.", pluginClassName)); + } + + if (pluginImplClasses.size() > 1) { + StringBuilder sb = new StringBuilder(); + for (Class<?> pluginClass : pluginImplClasses) { + sb.append(pluginClass.getName()).append(LS_ALIAS); + } + throw new MojoExecutionException(String.format("%n%nYou have more than one class that implements %s:%n%n%s%nYou can only have one per plugin project.", pluginClassName, sb)); + } + + try { + Class<?> pluginClass = pluginImplClasses.get(0); + Files.write(servicesFile.toPath(), pluginClass.getName().getBytes(UTF_8)); + getLog().info(String.format("Wrote %s to %s", pluginClass.getName(), servicesFile)); + } + catch (IOException e) { + throw new MojoExecutionException("Failed to write services JAR file.", e); + } + } + + private URLClassLoader createCLFromCompileTimeDependencies() + throws Exception + { + List<URL> urls = new ArrayList<>(); + urls.add(classesDirectory.toURI().toURL()); + for (Artifact artifact : project.getArtifacts()) { + if (artifact.getFile() != null) { + urls.add(artifact.getFile().toURI().toURL()); + } + } + return new URLClassLoader(urls.toArray(new URL[0])); + } + + private List<Class<?>> findPluginImplClasses(URLClassLoader searchRealm) + throws IOException, MojoExecutionException + { + List<Class<?>> implementations = new ArrayList<>(); + List<String> classes = FileUtils.getFileNames(classesDirectory, "**/*.class", null, false); + for (String classPath : classes) { + String className = classPath.substring(0, classPath.length() - 6).replace(File.separatorChar, '.'); + try { + Class<?> pluginClass = searchRealm.loadClass(pluginClassName); + Class<?> clazz = searchRealm.loadClass(className); + if (isImplementation(clazz, pluginClass)) { + implementations.add(clazz); + } + } + catch (ClassNotFoundException e) { + throw new MojoExecutionException("Failed to load class.", e); + } + } + return implementations; + } + + @SuppressWarnings("ResultOfMethodCallIgnored") + private static void mkdirs(File file) + throws MojoExecutionException + { + file.mkdirs(); + if (!file.isDirectory()) { + throw new MojoExecutionException(String.format("%n%nFailed to create directory: %s", file)); + } + } + + private static boolean isImplementation(Class<?> clazz, Class<?> pluginClass) + { + return pluginClass.isAssignableFrom(clazz) && !Modifier.isAbstract(clazz.getModifiers()) && !Modifier.isInterface(clazz.getModifiers()); + } +} diff --git a/src/main/java/org/apache/dolphinscheduler/maven/SpiDependencyChecker.java b/src/main/java/org/apache/dolphinscheduler/maven/SpiDependencyChecker.java new file mode 100644 index 0000000..6738cc9 --- /dev/null +++ b/src/main/java/org/apache/dolphinscheduler/maven/SpiDependencyChecker.java @@ -0,0 +1,147 @@ +package org.apache.dolphinscheduler.maven; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.Component; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.annotations.ResolutionScope; +import org.apache.maven.project.MavenProject; +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.collection.CollectRequest; +import org.eclipse.aether.collection.CollectResult; +import org.eclipse.aether.collection.DependencyCollectionException; +import org.eclipse.aether.graph.Dependency; +import org.eclipse.aether.graph.DependencyNode; + +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; + + +/** + * 检查spi依赖 + */ + +@Mojo(name = "spi-dependencies-check", + defaultPhase = LifecyclePhase.VALIDATE, + requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME) +public class SpiDependencyChecker extends AbstractMojo { + + @Parameter(defaultValue = "org.apache.dolphinscheduler") + private String spiGroupId; + + @Parameter(defaultValue = "dolphinscheduler-spi") + private String spiArtifactId; + + @Parameter(defaultValue = "false") + private boolean skipCheckSpiDependencies; + + @Parameter(defaultValue = "${project}") + private MavenProject mavenProject; + + @Parameter + private final Set<String> allowedProvidedDependencies = new HashSet<>(); + + @Parameter(defaultValue = "${repositorySystemSession}") + private RepositorySystemSession repositorySession; + + @Component + private RepositorySystem repositorySystem; + + @Override + public void execute() throws MojoExecutionException { + if (skipCheckSpiDependencies) { + getLog().info("Skipping Dolphinscheduler SPI dependency checks"); + return; + } + + Set<String> spiDependencies = getSpiDependencies(); + getLog().debug("SPI dependencies: " + spiDependencies); + + for (Artifact artifact : mavenProject.getArtifacts()) { + if (isSpiArtifact(artifact)) { + continue; + } + String name = artifact.getGroupId() + ":" + artifact.getArtifactId(); + if (spiDependencies.contains(name)) { + if (!"jar".equals(artifact.getType())) { + throw new MojoExecutionException(String.format("%n%nDolphinscheduler plugin dependency %s must have type 'jar'.", name)); + } + if (artifact.getClassifier() != null) { + throw new MojoExecutionException(String.format("%n%nDolphinscheduler plugin dependency %s must not have a classifier.", name)); + } + if (!"provided".equals(artifact.getScope())) { + throw new MojoExecutionException(String.format("%n%nDolphinscheduler plugin dependency %s must have scope 'provided'. It is part of the SPI and will be provided at runtime.", name)); + } + } + else if ("provided".equals(artifact.getScope()) && !allowedProvidedDependencies.contains(name)) { + throw new MojoExecutionException(String.format("%n%nDolphinscheduler plugin dependency %s must not have scope 'provided'. It is not part of the SPI and will not be available at runtime.", name)); + } + } + } + + private Set<String> getSpiDependencies() + throws MojoExecutionException + { + return getArtifactDependencies(getSpiDependency()) + .getRoot().getChildren().stream() + .filter(node -> !node.getDependency().isOptional()) + .map(DependencyNode::getArtifact) + .map(artifact -> artifact.getGroupId() + ":" + artifact.getArtifactId()) + .collect(Collectors.toSet()); + } + + private CollectResult getArtifactDependencies(Artifact artifact) + throws MojoExecutionException + { + try { + Dependency dependency = new Dependency(aetherArtifact(artifact), null); + return repositorySystem.collectDependencies(repositorySession, new CollectRequest(dependency, null)); + } + catch (DependencyCollectionException e) { + throw new MojoExecutionException("Failed to resolve dependencies.", e); + } + } + + private Artifact getSpiDependency() + throws MojoExecutionException + { + for (Artifact artifact : mavenProject.getArtifacts()) { + if (isSpiArtifact(artifact)) { + if (!"provided".equals(artifact.getScope())) { + throw new MojoExecutionException(String.format("DolphinScheduler plugin dependency %s must have scope 'provided'.", spiName())); + } + return artifact; + } + } + throw new MojoExecutionException(String.format("DolphinScheduler plugin must depend on %s.", spiName())); + } + + private boolean isSpiArtifact(Artifact artifact) + { + return spiGroupId.equals(artifact.getGroupId()) && + spiArtifactId.equals(artifact.getArtifactId()) && + "jar".equals(artifact.getType()) && + (artifact.getClassifier() == null); + } + + private String spiName() + { + return spiGroupId + ":" + spiArtifactId; + } + + private static org.eclipse.aether.artifact.Artifact aetherArtifact(Artifact artifact) + { + return new DefaultArtifact( + artifact.getGroupId(), + artifact.getArtifactId(), + artifact.getClassifier(), + artifact.getType(), + artifact.getVersion()); + } +} diff --git a/src/main/resources-filtered/META-INF/m2e/lifecycle-mapping-metadata.xml b/src/main/resources-filtered/META-INF/m2e/lifecycle-mapping-metadata.xml new file mode 100644 index 0000000..1fc1c7f --- /dev/null +++ b/src/main/resources-filtered/META-INF/m2e/lifecycle-mapping-metadata.xml @@ -0,0 +1,14 @@ +<lifecycleMappingMetadata> + <pluginExecutions> + <pluginExecution> + <pluginExecutionFilter> + <goals> + <goal>generate-dolphin-service-descriptor</goal> + </goals> + </pluginExecutionFilter> + <action> + <execute /> + </action> + </pluginExecution> + </pluginExecutions> +</lifecycleMappingMetadata> \ No newline at end of file diff --git a/src/main/resources-filtered/META-INF/plexus/components.xml b/src/main/resources-filtered/META-INF/plexus/components.xml new file mode 100644 index 0000000..6e428b8 --- /dev/null +++ b/src/main/resources-filtered/META-INF/plexus/components.xml @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8"?> +<component-set> + <components> + <component> + <role>org.apache.maven.artifact.handler.ArtifactHandler</role> + <role-hint>dolphinscheduler-plugin</role-hint> + <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation> + <configuration> + <type>dolphinscheduler-plugin</type> + <extension>zip</extension> + <language>java</language> + <addedToClasspath>false</addedToClasspath> + </configuration> + </component> + + <component> + <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role> + <role-hint>dolphinscheduler-plugin</role-hint> + <implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation> + <configuration> + <lifecycles> + <lifecycle> + <id>default</id> + <phases> + <validate> + org.apache.dolphinscheduler:dolphinscheduler-maven-plugin:${project.version}:spi-dependencies-check + </validate> + <process-resources> + org.apache.maven.plugins:maven-resources-plugin:2.6:resources + </process-resources> + <compile> + org.apache.maven.plugins:maven-compiler-plugin:2.5.1:compile + </compile> + <process-classes> + org.apache.dolphinscheduler:dolphinscheduler-maven-plugin:${project.version}:generate-dolphin-service-descriptor + </process-classes> + <process-test-resources> + org.apache.maven.plugins:maven-resources-plugin:2.6:testResources + </process-test-resources> + <test-compile> + org.apache.maven.plugins:maven-compiler-plugin:2.5.1:testCompile + </test-compile> + <test> + org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test + </test> + <package> + org.apache.maven.plugins:maven-jar-plugin:2.4:jar, + ca.vanzyl.maven.plugins:provisio-maven-plugin:${provisioVersion}:provision + </package> + <install> + org.apache.maven.plugins:maven-install-plugin:2.4:install + </install> + <deploy> + org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy + </deploy> + </phases> + </lifecycle> + </lifecycles> + </configuration> + </component> + </components> +</component-set> \ No newline at end of file diff --git a/src/main/resources/META-INF/provisio/dolphinscheduler-plugin.xml b/src/main/resources/META-INF/provisio/dolphinscheduler-plugin.xml new file mode 100644 index 0000000..c234ce9 --- /dev/null +++ b/src/main/resources/META-INF/provisio/dolphinscheduler-plugin.xml @@ -0,0 +1,4 @@ +<assembly> + <artifactSet to="/" ref="runtime.classpath" /> + <archive name="${project.artifactId}-${project.version}.zip" /> +</assembly> \ No newline at end of file diff --git a/src/test/java/org/apache/dolphinscheduler/maven/DolphinDescriptorGeneratorTest.java b/src/test/java/org/apache/dolphinscheduler/maven/DolphinDescriptorGeneratorTest.java new file mode 100644 index 0000000..6a1c09a --- /dev/null +++ b/src/test/java/org/apache/dolphinscheduler/maven/DolphinDescriptorGeneratorTest.java @@ -0,0 +1,67 @@ +package org.apache.dolphinscheduler.maven; + +import io.takari.maven.testing.TestResources; +import io.takari.maven.testing.executor.MavenRuntime; + +import io.takari.maven.testing.executor.MavenVersions; +import io.takari.maven.testing.executor.junit.MavenJUnitTestRunner; +import org.junit.Rule; +import static java.nio.charset.StandardCharsets.UTF_8; +import org.junit.Test; +import org.junit.runner.RunWith; +import static java.nio.file.Files.readAllLines; +import static org.junit.Assert.assertEquals; +import static java.util.Collections.singletonList; +import java.io.File; +import java.util.List; + +@RunWith(MavenJUnitTestRunner.class) +@MavenVersions({"3.3.9", "3.5.4", "3.6.2"}) +@SuppressWarnings({"JUnitTestNG", "PublicField"}) +public class DolphinDescriptorGeneratorTest { + + private static final String DESCRIPTOR = "META-INF/services/org.apache.dolphinscheduler.spi.DolphinSchedulerPlugin"; + + @Rule + public final TestResources resources = new TestResources(); + + public final MavenRuntime maven; + + public DolphinDescriptorGeneratorTest(MavenRuntime.MavenRuntimeBuilder mavenBuilder) + throws Exception + { + this.maven = mavenBuilder.withCliOptions("-B", "-U").build(); + } + + @Test + public void testSimplest() throws Exception + { + testProjectPackaging("simplest", "its.SimplestPlugin"); + } + + @Test + public void testAbstractPluginClass() throws Exception + { + testProjectPackaging("abstract-plugin-class", "its.TestPluginImpl"); + } + + @Test + public void testInterfacePluginClass() throws Exception + { + testProjectPackaging("interface-plugin-class", "its.TestPluginImpl"); + } + + protected void testProjectPackaging(String projectId, String expectedPluginClass) + throws Exception + { + File basedir = resources.getBasedir(projectId); + maven.forProject(basedir) + .execute("package") + .assertErrorFreeLog(); + + File output = new File(basedir, "target/classes/" + DESCRIPTOR); + + List<String> lines = readAllLines(output.toPath(), UTF_8); + assertEquals(singletonList(expectedPluginClass), lines); + } +} diff --git a/src/test/java/org/apache/dolphinscheduler/maven/SpiDependencyCheckerTest.java b/src/test/java/org/apache/dolphinscheduler/maven/SpiDependencyCheckerTest.java new file mode 100644 index 0000000..fe8abd2 --- /dev/null +++ b/src/test/java/org/apache/dolphinscheduler/maven/SpiDependencyCheckerTest.java @@ -0,0 +1,101 @@ +package org.apache.dolphinscheduler.maven; + +import io.takari.maven.testing.TestResources; +import io.takari.maven.testing.executor.MavenExecutionResult; +import io.takari.maven.testing.executor.MavenRuntime; +import io.takari.maven.testing.executor.MavenVersions; +import io.takari.maven.testing.executor.junit.MavenJUnitTestRunner; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.io.File; + +@RunWith(MavenJUnitTestRunner.class) +@MavenVersions({"3.3.9", "3.5.4", "3.6.2"}) +@SuppressWarnings({"JUnitTestNG", "PublicField"}) +public class SpiDependencyCheckerTest { + + @Rule + public final TestResources resources = new TestResources(); + + public final MavenRuntime maven; + + public SpiDependencyCheckerTest(MavenRuntime.MavenRuntimeBuilder mavenRuntimeBuilder) throws Exception { + this.maven = mavenRuntimeBuilder.withCliOptions("-B", "-U").build(); + } + + @Test + public void testBasic() throws Exception + { + File basedir = resources.getBasedir("simplest"); + maven.forProject(basedir) + .execute("verify") + .assertErrorFreeLog(); + } + + @Test + public void testErrorScopeSpi() throws Exception + { + File basedir = resources.getBasedir("error-scope-spi"); + MavenExecutionResult verify = maven.forProject(basedir) + .execute("verify"); + verify.assertLogText("[ERROR] Failed to execute goal org.apache.dolphinscheduler:dolphinscheduler-maven-plugin:1.0.0-SNAPSHOT:spi-dependencies-check (default-spi-dependencies-check) on project error-scope-spi: DolphinScheduler plugin dependency org.apache.dolphinscheduler:dolphinscheduler-spi must have scope 'provided'. "); + } + + @Test + public void testAbstractPluginClass() throws Exception + { + File basedir = resources.getBasedir("abstract-plugin-class"); + maven.forProject(basedir) + .execute("verify") + .assertErrorFreeLog(); + } +// + @Test + public void testInterfacePluginClass() throws Exception + { + File basedir = resources.getBasedir("interface-plugin-class"); + maven.forProject(basedir) + .execute("verify") + .assertErrorFreeLog(); + } + + @Test + public void testExcludedDependency() throws Exception + { + File basedir = resources.getBasedir("excluded-dependency"); + maven.forProject(basedir) + .execute("verify") + .assertErrorFreeLog(); + } + + @Test + public void testMoreExcludedDependency() throws Exception + { + File basedir = resources.getBasedir("more-excluded-dependency"); + maven.forProject(basedir) + .execute("verify") + .assertErrorFreeLog(); + } + + + @Test + public void testErrorScopeDependency() throws Exception + { + File basedir = resources.getBasedir("error-scope-dependency"); + MavenExecutionResult verify = maven.forProject(basedir) + .execute("verify"); + verify.assertLogText("[ERROR] Dolphinscheduler plugin dependency com.google.guava:guava must not have scope 'provided'. It is not part of the SPI and will not be available at runtime."); + } + + + @Test + public void testErrorScopeButSkip() throws Exception + { + File basedir = resources.getBasedir("error-scope-but-skip"); + MavenExecutionResult verify = maven.forProject(basedir) + .execute("verify"); + verify.assertErrorFreeLog(); + } +} diff --git a/src/test/projects/abstract-plugin-class/pom.xml b/src/test/projects/abstract-plugin-class/pom.xml new file mode 100644 index 0000000..2385250 --- /dev/null +++ b/src/test/projects/abstract-plugin-class/pom.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.apache.dolphinscheduler.maven.test</groupId> + <artifactId>abstract-plugin-class</artifactId> + <version>1.0</version> + <packaging>dolphinscheduler-plugin</packaging> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.dolphinscheduler</groupId> + <artifactId>dolphinscheduler-spi</artifactId> + <version>1.2.1-SNAPSHOT</version> + <scope>provided</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.dolphinscheduler</groupId> + <artifactId>dolphinscheduler-maven-plugin</artifactId> + <version>${it-plugin.version}</version> + <extensions>true</extensions> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file diff --git a/src/test/projects/abstract-plugin-class/src/main/java/its/AbsTestPlugin.java b/src/test/projects/abstract-plugin-class/src/main/java/its/AbsTestPlugin.java new file mode 100644 index 0000000..bde697e --- /dev/null +++ b/src/test/projects/abstract-plugin-class/src/main/java/its/AbsTestPlugin.java @@ -0,0 +1,6 @@ +package its; + +import org.apache.dolphinscheduler.spi.DolphinSchedulerPlugin; + +public abstract class AbsTestPlugin implements DolphinSchedulerPlugin { +} diff --git a/src/test/projects/abstract-plugin-class/src/main/java/its/TestPluginImpl.java b/src/test/projects/abstract-plugin-class/src/main/java/its/TestPluginImpl.java new file mode 100644 index 0000000..7b3306d --- /dev/null +++ b/src/test/projects/abstract-plugin-class/src/main/java/its/TestPluginImpl.java @@ -0,0 +1,6 @@ +package its; + +import org.apache.dolphinscheduler.spi.DolphinSchedulerPlugin; + +public class TestPluginImpl extends AbsTestPlugin { +} diff --git a/src/test/projects/error-scope-but-skip/pom.xml b/src/test/projects/error-scope-but-skip/pom.xml new file mode 100644 index 0000000..7ef545b --- /dev/null +++ b/src/test/projects/error-scope-but-skip/pom.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.apache.dolphinscheduler.maven.test</groupId> + <artifactId>error-scope-but-skip</artifactId> + <version>1.0</version> + <packaging>dolphinscheduler-plugin</packaging> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.dolphinscheduler</groupId> + <artifactId>dolphinscheduler-spi</artifactId> + <version>1.2.1-SNAPSHOT</version> + <scope>provided</scope> + </dependency> + + <!-- this dependency is not part of the SPI but skipCheckSpiDependencies is true so it can be provided --> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + <version>18.0</version> + <scope>provided</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.dolphinscheduler</groupId> + <artifactId>dolphinscheduler-maven-plugin</artifactId> + <version>${it-plugin.version}</version> + <extensions>true</extensions> + <configuration> + <skipCheckSpiDependencies>true</skipCheckSpiDependencies> + </configuration> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file diff --git a/src/test/projects/error-scope-but-skip/src/main/java/its/ErrorScopeButSkipPlugin.java b/src/test/projects/error-scope-but-skip/src/main/java/its/ErrorScopeButSkipPlugin.java new file mode 100644 index 0000000..1a9fc98 --- /dev/null +++ b/src/test/projects/error-scope-but-skip/src/main/java/its/ErrorScopeButSkipPlugin.java @@ -0,0 +1,6 @@ +package its; + +import org.apache.dolphinscheduler.spi.DolphinSchedulerPlugin; + +public class ErrorScopeButSkipPlugin implements DolphinSchedulerPlugin { +} diff --git a/src/test/projects/error-scope-dependency/pom.xml b/src/test/projects/error-scope-dependency/pom.xml new file mode 100644 index 0000000..c3d3031 --- /dev/null +++ b/src/test/projects/error-scope-dependency/pom.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.apache.dolphinscheduler.maven.test</groupId> + <artifactId>error-scope-dependency</artifactId> + <version>1.0</version> + <packaging>dolphinscheduler-plugin</packaging> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.dolphinscheduler</groupId> + <artifactId>dolphinscheduler-spi</artifactId> + <version>1.2.1-SNAPSHOT</version> + <scope>provided</scope> + </dependency> + + <!-- this dependency is not part of the SPI and thus should not be provided --> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + <version>18.0</version> + <scope>provided</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.dolphinscheduler</groupId> + <artifactId>dolphinscheduler-maven-plugin</artifactId> + <version>${it-plugin.version}</version> + <extensions>true</extensions> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file diff --git a/src/test/projects/error-scope-dependency/src/main/java/its/ErrorScopeDependencyPlugin.java b/src/test/projects/error-scope-dependency/src/main/java/its/ErrorScopeDependencyPlugin.java new file mode 100644 index 0000000..ad63c10 --- /dev/null +++ b/src/test/projects/error-scope-dependency/src/main/java/its/ErrorScopeDependencyPlugin.java @@ -0,0 +1,6 @@ +package its; + + import org.apache.dolphinscheduler.spi.DolphinSchedulerPlugin; + +public class ErrorScopeDependencyPlugin implements DolphinSchedulerPlugin { +} diff --git a/src/test/projects/error-scope-spi/pom.xml b/src/test/projects/error-scope-spi/pom.xml new file mode 100644 index 0000000..5c3fbb8 --- /dev/null +++ b/src/test/projects/error-scope-spi/pom.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.apache.dolphinscheduler.maven.test</groupId> + <artifactId>error-scope-spi</artifactId> + <version>1.0</version> + <packaging>dolphinscheduler-plugin</packaging> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <dependencies> + <!-- dolphinscheduler-spi must be provided --> + <dependency> + <groupId>org.apache.dolphinscheduler</groupId> + <artifactId>dolphinscheduler-spi</artifactId> + <version>1.2.1-SNAPSHOT</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.dolphinscheduler</groupId> + <artifactId>dolphinscheduler-maven-plugin</artifactId> + <version>${it-plugin.version}</version> + <extensions>true</extensions> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file diff --git a/src/test/projects/error-scope-spi/src/main/java/its/ErrorScopeSpiPlugin.java b/src/test/projects/error-scope-spi/src/main/java/its/ErrorScopeSpiPlugin.java new file mode 100644 index 0000000..8300a91 --- /dev/null +++ b/src/test/projects/error-scope-spi/src/main/java/its/ErrorScopeSpiPlugin.java @@ -0,0 +1,6 @@ +package its; + + import org.apache.dolphinscheduler.spi.DolphinSchedulerPlugin; + +public class ErrorScopeSpiPlugin implements DolphinSchedulerPlugin { +} diff --git a/src/test/projects/excluded-dependency/pom.xml b/src/test/projects/excluded-dependency/pom.xml new file mode 100644 index 0000000..b0cb6ee --- /dev/null +++ b/src/test/projects/excluded-dependency/pom.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.apache.dolphinscheduler.maven.test</groupId> + <artifactId>excluded-dependency</artifactId> + <version>1.0</version> + <packaging>dolphinscheduler-plugin</packaging> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.dolphinscheduler</groupId> + <artifactId>dolphinscheduler-spi</artifactId> + <version>1.2.1-SNAPSHOT</version> + <scope>provided</scope> + </dependency> + + <!-- this dependency is not part of the SPI; it can be provided because it's individually excluded from the check --> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + <version>18.0</version> + <scope>provided</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.dolphinscheduler</groupId> + <artifactId>dolphinscheduler-maven-plugin</artifactId> + <version>${it-plugin.version}</version> + <extensions>true</extensions> + <configuration> + <allowedProvidedDependencies> + <allowedProvidedDependency>com.google.guava:guava</allowedProvidedDependency> + </allowedProvidedDependencies> + </configuration> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file diff --git a/src/test/projects/excluded-dependency/src/main/java/its/SimplestPlugin.java b/src/test/projects/excluded-dependency/src/main/java/its/SimplestPlugin.java new file mode 100644 index 0000000..5965dd6 --- /dev/null +++ b/src/test/projects/excluded-dependency/src/main/java/its/SimplestPlugin.java @@ -0,0 +1,6 @@ +package its; + +import org.apache.dolphinscheduler.spi.DolphinSchedulerPlugin; + +public class SimplestPlugin implements DolphinSchedulerPlugin { +} diff --git a/src/test/projects/interface-plugin-class/pom.xml b/src/test/projects/interface-plugin-class/pom.xml new file mode 100644 index 0000000..8add0d9 --- /dev/null +++ b/src/test/projects/interface-plugin-class/pom.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.apache.dolphinscheduler.maven.test</groupId> + <artifactId>interface-plugin-class</artifactId> + <version>1.0</version> + <packaging>dolphinscheduler-plugin</packaging> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.dolphinscheduler</groupId> + <artifactId>dolphinscheduler-spi</artifactId> + <version>1.2.1-SNAPSHOT</version> + <scope>provided</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.dolphinscheduler</groupId> + <artifactId>dolphinscheduler-maven-plugin</artifactId> + <version>${it-plugin.version}</version> + <extensions>true</extensions> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file diff --git a/src/test/projects/interface-plugin-class/src/main/java/its/ITestPlugin.java b/src/test/projects/interface-plugin-class/src/main/java/its/ITestPlugin.java new file mode 100644 index 0000000..351c0b1 --- /dev/null +++ b/src/test/projects/interface-plugin-class/src/main/java/its/ITestPlugin.java @@ -0,0 +1,6 @@ +package its; + +import org.apache.dolphinscheduler.spi.DolphinSchedulerPlugin; + +public interface ITestPlugin extends DolphinSchedulerPlugin { +} diff --git a/src/test/projects/interface-plugin-class/src/main/java/its/TestPluginImpl.java b/src/test/projects/interface-plugin-class/src/main/java/its/TestPluginImpl.java new file mode 100644 index 0000000..8109d48 --- /dev/null +++ b/src/test/projects/interface-plugin-class/src/main/java/its/TestPluginImpl.java @@ -0,0 +1,6 @@ +package its; + +import org.apache.dolphinscheduler.spi.DolphinSchedulerPlugin; + +public class TestPluginImpl implements ITestPlugin { +} diff --git a/src/test/projects/more-excluded-dependency/pom.xml b/src/test/projects/more-excluded-dependency/pom.xml new file mode 100644 index 0000000..1edaf49 --- /dev/null +++ b/src/test/projects/more-excluded-dependency/pom.xml @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.apache.dolphinscheduler.maven.test</groupId> + <artifactId>excluded-dependency</artifactId> + <version>1.0</version> + <packaging>dolphinscheduler-plugin</packaging> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.dolphinscheduler</groupId> + <artifactId>dolphinscheduler-spi</artifactId> + <version>1.2.1-SNAPSHOT</version> + <scope>provided</scope> + </dependency> + + <!-- this dependency is not part of the SPI; it can be provided because it's individually excluded from the check --> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + <version>18.0</version> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>mysql</groupId> + <artifactId>mysql-connector-java</artifactId> + <version>5.1.34</version> + <scope>provided</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.dolphinscheduler</groupId> + <artifactId>dolphinscheduler-maven-plugin</artifactId> + <version>${it-plugin.version}</version> + <extensions>true</extensions> + <configuration> + <allowedProvidedDependencies> + <allowedProvidedDependency>com.google.guava:guava</allowedProvidedDependency> + <allowedProvidedDependency>mysql:mysql-connector-java</allowedProvidedDependency> + </allowedProvidedDependencies> + </configuration> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file diff --git a/src/test/projects/more-excluded-dependency/src/main/java/its/SimplestPlugin.java b/src/test/projects/more-excluded-dependency/src/main/java/its/SimplestPlugin.java new file mode 100644 index 0000000..5965dd6 --- /dev/null +++ b/src/test/projects/more-excluded-dependency/src/main/java/its/SimplestPlugin.java @@ -0,0 +1,6 @@ +package its; + +import org.apache.dolphinscheduler.spi.DolphinSchedulerPlugin; + +public class SimplestPlugin implements DolphinSchedulerPlugin { +} diff --git a/src/test/projects/simplest/pom.xml b/src/test/projects/simplest/pom.xml new file mode 100644 index 0000000..5a99281 --- /dev/null +++ b/src/test/projects/simplest/pom.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.apache.dolphinscheduler.maven.test</groupId> + <artifactId>simplest</artifactId> + <version>1.0</version> + <packaging>dolphinscheduler-plugin</packaging> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.dolphinscheduler</groupId> + <artifactId>dolphinscheduler-spi</artifactId> + <version>1.2.1-SNAPSHOT</version> + <scope>provided</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.dolphinscheduler</groupId> + <artifactId>dolphinscheduler-maven-plugin</artifactId> + <version>${it-plugin.version}</version> + <!--<version>1.0.0-SNAPSHOT</version>--> + <extensions>true</extensions> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file diff --git a/src/test/projects/simplest/src/main/java/its/SimplestPlugin.java b/src/test/projects/simplest/src/main/java/its/SimplestPlugin.java new file mode 100644 index 0000000..5965dd6 --- /dev/null +++ b/src/test/projects/simplest/src/main/java/its/SimplestPlugin.java @@ -0,0 +1,6 @@ +package its; + +import org.apache.dolphinscheduler.spi.DolphinSchedulerPlugin; + +public class SimplestPlugin implements DolphinSchedulerPlugin { +}