diff --git a/koupleless-build-plugin/koupleless-base-build-plugin/pom.xml b/koupleless-build-plugin/koupleless-base-build-plugin/pom.xml new file mode 100644 index 000000000..c01ec10d9 --- /dev/null +++ b/koupleless-build-plugin/koupleless-base-build-plugin/pom.xml @@ -0,0 +1,102 @@ + + + 4.0.0 + + com.alipay.sofa.koupleless + koupleless-build-plugin + ${revision} + ../pom.xml + + + koupleless-base-build-plugin + ${revision} + maven-plugin + + + + + org.apache.maven + maven-plugin-api + + + org.apache.maven.plugin-tools + maven-plugin-annotations + + + org.apache.maven + maven-aether-provider + + + org.apache.maven + maven-core + + + org.apache.maven + maven-project + + + com.google.guava + guava + + + org.projectlombok + lombok + compile + + + com.fasterxml.jackson.core + jackson-databind + + + com.fasterxml.jackson.core + jackson-databind + compile + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + + + org.apache.commons + commons-collections4 + + + junit + junit + test + + + org.mockito + mockito-core + test + + + + + + + src/main/resources + true + + + + + org.apache.maven.plugins + maven-plugin-plugin + 3.5 + + + org.apache.maven.plugins + maven-compiler-plugin + 3.3 + + 8 + 8 + + + + + + \ No newline at end of file diff --git a/koupleless-build-plugin/koupleless-base-build-plugin/src/main/java/com/alipay/sofa/koupleless/base/build/plugin/KouplelessBaseBuildPrePackageMojo.java b/koupleless-build-plugin/koupleless-base-build-plugin/src/main/java/com/alipay/sofa/koupleless/base/build/plugin/KouplelessBaseBuildPrePackageMojo.java new file mode 100644 index 000000000..c452ea00c --- /dev/null +++ b/koupleless-build-plugin/koupleless-base-build-plugin/src/main/java/com/alipay/sofa/koupleless/base/build/plugin/KouplelessBaseBuildPrePackageMojo.java @@ -0,0 +1,229 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package com.alipay.sofa.koupleless.base.build.plugin; + +/* + * Copyright 2001-2005 The Apache Software Foundation. + * + * 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. + */ + +import com.alipay.sofa.koupleless.base.build.plugin.common.JarFileUtils; +import com.alipay.sofa.koupleless.base.build.plugin.model.KouplelessAdapterConfig; +import com.alipay.sofa.koupleless.base.build.plugin.model.MavenDependencyAdapterMapping; +import com.alipay.sofa.koupleless.base.build.plugin.model.MavenDependencyMatcher; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import com.google.common.base.Preconditions; +import lombok.SneakyThrows; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.Dependency; +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.project.MavenProject; +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.resolution.ArtifactRequest; +import org.eclipse.aether.resolution.ArtifactResult; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import java.util.regex.Pattern; + +/** + * Goal which touches a timestamp file. + * + * @goal touch + * @phase process-sources + */ +@Mojo(name = "add-patch", defaultPhase = LifecyclePhase.PROCESS_CLASSES) +public class KouplelessBaseBuildPrePackageMojo extends AbstractMojo { + + @Parameter(defaultValue = "${project.build.directory}", readonly = true) + File outputDirectory; + + @Parameter(defaultValue = "${project}", required = true, readonly = true) + MavenProject project; + + @Parameter(defaultValue = "${session}", required = true, readonly = true) + MavenSession session; + + @Component + RepositorySystem repositorySystem; + + private ObjectMapper yamlMapper = new ObjectMapper(new YAMLFactory()); + + KouplelessAdapterConfig kouplelessAdapterConfig; + + String defaultGroupId = ""; + String defaultVersion = ""; + + void initKouplelessAdapterConfig() throws Exception { + if (kouplelessAdapterConfig == null) { + InputStream mappingConfigIS = this.getClass().getClassLoader() + .getResourceAsStream("adapter-mapping.yaml"); + + kouplelessAdapterConfig = yamlMapper.readValue(mappingConfigIS, + KouplelessAdapterConfig.class); + + for (MavenDependencyAdapterMapping mappings : CollectionUtils + .emptyIfNull(kouplelessAdapterConfig.getAdapterMappings())) { + + } + } + + Properties properties = new Properties(); + properties.load(getClass().getClassLoader().getResourceAsStream("project.properties")); + defaultGroupId = properties.getProperty("project.groupId"); + defaultVersion = properties.getProperty("project.version"); + } + + String getDependencyId(Dependency dependency) { + return dependency.getGroupId() + ":" + dependency.getArtifactId() + ":" + + dependency.getVersion() + ":" + dependency.getType() + + (dependency.getClassifier() != null ? ":" + dependency.getClassifier() : ""); + } + + // visible for testing + List getDependenciesToAdd() { + List adapterDependencies = new ArrayList<>(); + if (kouplelessAdapterConfig == null) { + getLog().info("kouplelessAdapterConfig is null, skip adding dependencies."); + return adapterDependencies; + } + + if (kouplelessAdapterConfig.getCommonDependencies() != null) { + adapterDependencies.addAll(kouplelessAdapterConfig.getCommonDependencies()); + } + + Collection adapterMappings = CollectionUtils + .emptyIfNull(kouplelessAdapterConfig.getAdapterMappings()); + for (MavenDependencyAdapterMapping adapterMapping : adapterMappings) { + MavenDependencyMatcher matcher = adapterMapping.getMatcher(); + + if (matcher != null && matcher.getRegexp() != null) { + String regexp = matcher.getRegexp(); + for (Dependency dependency : project.getDependencies()) { + String dependencyId = getDependencyId(dependency); + if (Pattern.compile(regexp).matcher(dependencyId).matches()) { + adapterDependencies.add(adapterMapping.getAdapter()); + } + } + } + + } + return adapterDependencies; + } + + void addDependenciesDynamically() { + if (kouplelessAdapterConfig == null) { + getLog().info("kouplelessAdapterConfig is null, skip adding dependencies."); + return; + } + + Collection dependencies = getDependenciesToAdd(); + for (Dependency dependency : dependencies) { + try { + if (StringUtils.isBlank(dependency.getVersion())) { + dependency.setVersion(defaultVersion); + } + if (StringUtils.isBlank(dependency.getGroupId())) { + dependency.setGroupId(defaultGroupId); + } + getLog().debug("start downloading dependency: " + dependency.toString()); + Artifact artifact = downloadAdapterDependency(dependency); + getLog().debug("start add dependency to project root: " + dependency.toString()); + addArtifactToProjectRoot(artifact); + getLog().info("success add dependency: " + dependency.toString()); + } catch (Throwable t) { + getLog().error("error add dependency: " + dependency.toString(), t); + } + } + } + + Artifact downloadAdapterDependency(Dependency dependency) { + DefaultArtifact patchArtifact = new DefaultArtifact(dependency.getGroupId() + ":" + + dependency.getArtifactId() + ":" + + dependency.getVersion()); + + try { + ArtifactRequest artifactRequest = new ArtifactRequest().setArtifact(patchArtifact) + .setRepositories(project.getRemoteProjectRepositories()); + + ArtifactResult artifactResult = repositorySystem.resolveArtifact( + session.getRepositorySession(), artifactRequest); + + Preconditions.checkState(artifactResult.isResolved(), "artifact not resolved."); + return artifactResult.getArtifact(); + } catch (Throwable t) { + getLog().error(t); + throw new RuntimeException(t); + } + } + + void addArtifactToProjectRoot(Artifact artifact) { + File file = artifact.getFile(); + Map entryToContent = JarFileUtils.getFileContentAsLines(file, + Pattern.compile(".*\\.class$")); + for (Map.Entry entry : entryToContent.entrySet()) { + addPatchToProjectRoot(entry.getKey(), entry.getValue()); + } + } + + @SneakyThrows + void addPatchToProjectRoot(String entryName, Byte[] bytes) { + Path outputfile = Paths.get(outputDirectory.getAbsolutePath(), "classes", entryName); + Path parentDir = outputfile.getParent(); + byte[] primitiveByte = new byte[bytes.length]; + for (int i = 0; i < bytes.length; i++) { + primitiveByte[i] = bytes[i]; + } + Files.createDirectories(parentDir); + Files.write(outputfile, primitiveByte); + } + + @Override + public void execute() throws MojoExecutionException { + try { + initKouplelessAdapterConfig(); + addDependenciesDynamically(); + } catch (Throwable t) { + getLog().error(t); + throw new RuntimeException(t); + } + } +} diff --git a/koupleless-build-plugin/koupleless-base-build-plugin/src/main/java/com/alipay/sofa/koupleless/base/build/plugin/common/JarFileUtils.java b/koupleless-build-plugin/koupleless-base-build-plugin/src/main/java/com/alipay/sofa/koupleless/base/build/plugin/common/JarFileUtils.java new file mode 100644 index 000000000..f697cbcc8 --- /dev/null +++ b/koupleless-build-plugin/koupleless-base-build-plugin/src/main/java/com/alipay/sofa/koupleless/base/build/plugin/common/JarFileUtils.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package com.alipay.sofa.koupleless.base.build.plugin.common; + +import lombok.SneakyThrows; + +import java.io.*; +import java.util.HashMap; +import java.util.Map; +import java.util.jar.JarEntry; +import java.util.jar.JarInputStream; +import java.util.regex.Pattern; + +/** + * jar file utils + * + * @author CodeNoobKing + */ +public class JarFileUtils { + + /** + * get content as file lines inside a bundled jar file. + * + * @param file jarfile + * @param entryPattern the target file. + * @return the content as list of string. + */ + @SneakyThrows + public static Map getFileContentAsLines(File file, Pattern entryPattern) { + Map result = new HashMap<>(); + try (JarInputStream jin = new JarInputStream(new FileInputStream(file))) { + + JarEntry entry = null; + while ((entry = jin.getNextJarEntry()) != null) { + if (!entryPattern.matcher(entry.getName()).matches() || entry.isDirectory()) { + continue; + } + + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + int nRead = -1; + byte[] data = new byte[1024]; + while ((nRead = jin.read(data, 0, data.length)) != -1) { + buffer.write(data, 0, nRead); + } + + byte[] byteArray = buffer.toByteArray(); + Byte[] boxing = new Byte[byteArray.length]; + for (int i = 0; i < byteArray.length; i++) { + boxing[i] = byteArray[i]; + } + result.put(entry.getName(), boxing); + } + } + return result; + } + +} diff --git a/koupleless-build-plugin/koupleless-base-build-plugin/src/main/java/com/alipay/sofa/koupleless/base/build/plugin/model/KouplelessAdapterConfig.java b/koupleless-build-plugin/koupleless-base-build-plugin/src/main/java/com/alipay/sofa/koupleless/base/build/plugin/model/KouplelessAdapterConfig.java new file mode 100644 index 000000000..719119432 --- /dev/null +++ b/koupleless-build-plugin/koupleless-base-build-plugin/src/main/java/com/alipay/sofa/koupleless/base/build/plugin/model/KouplelessAdapterConfig.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package com.alipay.sofa.koupleless.base.build.plugin.model; + +import lombok.*; +import org.apache.maven.model.Dependency; + +import java.util.List; + +/** + * @author CodeNoobKing + * @date 2024/2/6 + */ +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Data +public class KouplelessAdapterConfig { + + /** + * 存在一些通用的依赖,需要用户引入。 + */ + List commonDependencies; + + /** + * 适配的依赖。 + */ + List adapterMappings; +} diff --git a/koupleless-build-plugin/koupleless-base-build-plugin/src/main/java/com/alipay/sofa/koupleless/base/build/plugin/model/MavenDependencyAdapterMapping.java b/koupleless-build-plugin/koupleless-base-build-plugin/src/main/java/com/alipay/sofa/koupleless/base/build/plugin/model/MavenDependencyAdapterMapping.java new file mode 100644 index 000000000..5cb44f538 --- /dev/null +++ b/koupleless-build-plugin/koupleless-base-build-plugin/src/main/java/com/alipay/sofa/koupleless/base/build/plugin/model/MavenDependencyAdapterMapping.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package com.alipay.sofa.koupleless.base.build.plugin.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.maven.model.Dependency; + +/** + * @author CodeNoobKing + * @date 2024/2/6 + */ +@NoArgsConstructor +@AllArgsConstructor +@Data +@Builder +public class MavenDependencyAdapterMapping { + /** + * 匹配用户的以来。 + */ + private MavenDependencyMatcher matcher; + + /** + * 适配的依赖。 + */ + private Dependency adapter; +} diff --git a/koupleless-build-plugin/koupleless-base-build-plugin/src/main/java/com/alipay/sofa/koupleless/base/build/plugin/model/MavenDependencyMatcher.java b/koupleless-build-plugin/koupleless-base-build-plugin/src/main/java/com/alipay/sofa/koupleless/base/build/plugin/model/MavenDependencyMatcher.java new file mode 100644 index 000000000..b9c8cc041 --- /dev/null +++ b/koupleless-build-plugin/koupleless-base-build-plugin/src/main/java/com/alipay/sofa/koupleless/base/build/plugin/model/MavenDependencyMatcher.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package com.alipay.sofa.koupleless.base.build.plugin.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author CodeNoobKing + * @date 2024/2/6 + */ +@NoArgsConstructor +@AllArgsConstructor +@Data +@Builder +public class MavenDependencyMatcher { + /** + * 用正则表达式匹配用户的依赖。 + */ + private String regexp; +} diff --git a/koupleless-build-plugin/koupleless-base-build-plugin/src/main/resources/adapter-mapping.yaml b/koupleless-build-plugin/koupleless-base-build-plugin/src/main/resources/adapter-mapping.yaml new file mode 100644 index 000000000..9afe4e606 --- /dev/null +++ b/koupleless-build-plugin/koupleless-base-build-plugin/src/main/resources/adapter-mapping.yaml @@ -0,0 +1,17 @@ +adapterMappings: + - matcher: + regexp: ".*com\\.ctrip\\.framework\\.apollo:apollo-client.*" + adapter: + artifactId: koupleless-adapter-apollo + - matcher: + regexp: ".*(com\\.alibaba:dubbo-dependencies-bom:2\\.6|com\\.alibaba:dubbo:2\\.6).*" + adapter: + artifactId: koupleless-adapter-dubbo2.6 + - matcher: + regexp: ".*spring-boot-starter-log4j2:(?!2\\.1).*" + adapter: + artifactId: koupleless-adapter-log4j2 + - matcher: + regexp: ".*spring-boot-starter-log4j2:2\\.1.*" + adapter: + artifactId: koupleless-adapter-log4j2-springboot2.1.9 diff --git a/koupleless-build-plugin/koupleless-base-build-plugin/src/main/resources/project.properties b/koupleless-build-plugin/koupleless-base-build-plugin/src/main/resources/project.properties new file mode 100644 index 000000000..76bf73291 --- /dev/null +++ b/koupleless-build-plugin/koupleless-base-build-plugin/src/main/resources/project.properties @@ -0,0 +1,2 @@ +project.groupId=${project.groupId} +project.version=${project.version} \ No newline at end of file diff --git a/koupleless-build-plugin/koupleless-base-build-plugin/src/test/java/com/alipay/sofa/koupleless/base/build/plugin/KouplelessBaseBuildPrePackageMojoTest.java b/koupleless-build-plugin/koupleless-base-build-plugin/src/test/java/com/alipay/sofa/koupleless/base/build/plugin/KouplelessBaseBuildPrePackageMojoTest.java new file mode 100644 index 000000000..954b92440 --- /dev/null +++ b/koupleless-build-plugin/koupleless-base-build-plugin/src/test/java/com/alipay/sofa/koupleless/base/build/plugin/KouplelessBaseBuildPrePackageMojoTest.java @@ -0,0 +1,146 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package com.alipay.sofa.koupleless.base.build.plugin; + +import com.alipay.sofa.koupleless.base.build.plugin.model.MavenDependencyAdapterMapping; +import com.alipay.sofa.koupleless.base.build.plugin.model.KouplelessAdapterConfig; +import com.alipay.sofa.koupleless.base.build.plugin.model.MavenDependencyMatcher; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.Dependency; +import org.apache.maven.project.MavenProject; +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.resolution.ArtifactRequest; +import org.eclipse.aether.resolution.ArtifactResult; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import java.io.File; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +/** + * @author CodeNoobKing + * @date 2024/2/19 + */ +@RunWith(MockitoJUnitRunner.class) +public class KouplelessBaseBuildPrePackageMojoTest { + @InjectMocks + private KouplelessBaseBuildPrePackageMojo mojo; + + // create a tmp directory using os tmp + private File outputDirectory = null; + + @Mock + MavenProject project; + + @Mock + MavenSession session; + + @Mock + RepositorySystem repositorySystem; + + @Test + public void testLazyInitKouplelessAdapterConfig() throws Exception { + Dependency mockDependency = new Dependency(); + mockDependency.setGroupId("XXX"); + mockDependency.setArtifactId("YYY"); + mockDependency.setVersion("ZZZ"); + + List commonDependencies = new ArrayList<>(); + commonDependencies.add(mockDependency); + + List mappings = new ArrayList<>(); + mappings.add(MavenDependencyAdapterMapping.builder().adapter(mockDependency) + .matcher(MavenDependencyMatcher.builder().regexp(".*").build()).build()); + + mojo.initKouplelessAdapterConfig(); + KouplelessAdapterConfig expected = KouplelessAdapterConfig.builder() + .commonDependencies(commonDependencies).adapterMappings(mappings).build(); + + Assert.assertEquals(expected.toString(), mojo.kouplelessAdapterConfig.toString()); + } + + @Test + public void testAddDependencyDynamically() throws Exception { + { + // init the adapter config + Dependency mockDependency = new Dependency(); + mockDependency.setGroupId("XXX"); + mockDependency.setArtifactId("YYY"); + mockDependency.setVersion("ZZZ"); + + List commonDependencies = new ArrayList<>(); + commonDependencies.add(mockDependency); + + List mappings = new ArrayList<>(); + mappings.add(MavenDependencyAdapterMapping.builder().adapter(mockDependency) + .matcher(MavenDependencyMatcher.builder().regexp(".*A:B:C.*").build()).build()); + + mojo.kouplelessAdapterConfig = KouplelessAdapterConfig.builder() + .commonDependencies(commonDependencies).adapterMappings(mappings).build(); + } + + { + // init maven project + List dependencies = new ArrayList<>(); + Dependency mockDependency = new Dependency(); + mockDependency.setGroupId("A"); + mockDependency.setArtifactId("B"); + mockDependency.setVersion("C"); + dependencies.add(mockDependency); + + doReturn(dependencies).when(project).getDependencies(); + } + + { + // mock the repository system + ArtifactResult mockArtifactResult = new ArtifactResult(new ArtifactRequest()); + Artifact mockArtifact = mock(Artifact.class); + mockArtifactResult.setArtifact(mockArtifact); + + URL demoJarUrl = getClass().getClassLoader().getResource("demo.jar"); + doReturn(new File(demoJarUrl.toURI())).when(mockArtifact).getFile(); + doReturn(mockArtifactResult).when(repositorySystem).resolveArtifact(any(), any()); + } + + { + // init output directory + mojo.outputDirectory = Files.createTempDirectory("mojotest").toFile(); + } + + mojo.execute(); + + { + Assert.assertTrue(Paths + .get(mojo.outputDirectory.getAbsolutePath(), "classes", "com", "example", "demo") + .toFile().exists()); + } + } + +} diff --git a/koupleless-build-plugin/koupleless-base-build-plugin/src/test/resources/adapter-mapping.yaml b/koupleless-build-plugin/koupleless-base-build-plugin/src/test/resources/adapter-mapping.yaml new file mode 100644 index 000000000..5b6d12e83 --- /dev/null +++ b/koupleless-build-plugin/koupleless-base-build-plugin/src/test/resources/adapter-mapping.yaml @@ -0,0 +1,12 @@ +commonDependencies: + - groupId: XXX + artifactId: YYY + version: ZZZ + +adapterMappings: + - matcher: + regexp: ".*" + adapter: + groupId: XXX + artifactId: YYY + version: ZZZ \ No newline at end of file diff --git a/koupleless-build-plugin/koupleless-base-build-plugin/src/test/resources/demo.jar b/koupleless-build-plugin/koupleless-base-build-plugin/src/test/resources/demo.jar new file mode 100644 index 000000000..fcb018d45 Binary files /dev/null and b/koupleless-build-plugin/koupleless-base-build-plugin/src/test/resources/demo.jar differ diff --git a/koupleless-build-plugin/pom.xml b/koupleless-build-plugin/pom.xml new file mode 100644 index 000000000..cee193d85 --- /dev/null +++ b/koupleless-build-plugin/pom.xml @@ -0,0 +1,96 @@ + + + 4.0.0 + + com.alipay.sofa.koupleless + koupleless-runtime + ${revision} + ../pom.xml + + + koupleless-build-plugin + ${revision} + pom + + + koupleless-base-build-plugin + + + + + + + org.apache.maven + maven-plugin-api + 3.9.0 + + + org.apache.maven.plugin-tools + maven-plugin-annotations + 3.8.1 + + + org.apache.maven + maven-aether-provider + 3.3.9 + + + org.apache.maven + maven-core + 3.8.1 + + + org.apache.maven + maven-project + 2.2.1 + + + com.google.guava + guava + 31.0.1-jre + + + org.projectlombok + lombok + 1.18.30 + compile + + + com.fasterxml.jackson.core + jackson-databind + 2.13.1 + + + com.fasterxml.jackson.core + jackson-databind + 2.13.5 + compile + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + 2.13.5 + + + org.apache.commons + commons-collections4 + 4.4 + + + junit + junit + 4.13.1 + test + + + org.mockito + mockito-core + test + 4.5.1 + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 54d9bc0fc..45a5e418e 100644 --- a/pom.xml +++ b/pom.xml @@ -82,6 +82,7 @@ koupleless-adapter-ext koupleless-base-loader koupleless-ext + koupleless-build-plugin