diff --git a/core/deployment/src/main/java/io/quarkus/deployment/ApplicationArchive.java b/core/deployment/src/main/java/io/quarkus/deployment/ApplicationArchive.java index aeed65324a2e8..5c8001efcd460 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/ApplicationArchive.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/ApplicationArchive.java @@ -9,6 +9,8 @@ import io.quarkus.bootstrap.model.AppArtifactKey; import io.quarkus.bootstrap.model.PathsCollection; +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.paths.PathCollection; /** * Represents an archive that is part of application code. @@ -25,35 +27,28 @@ public interface ApplicationArchive { IndexView getIndex(); /** + * If this archive is a jar file it will return the path to the jar file on the file system, + * otherwise it will return the directory that this corresponds to. * - * Returns a path representing the archive root. Note that if this is a jar archive this is not the path to the - * jar, but rather a path to the root of the mounted {@link com.sun.nio.zipfs.ZipFileSystem} - * - * @return The archive root. - * @deprecated in favor of {@link #getRootDirs()} + * @deprecated in favor of {@link #getResolvedPaths()} */ @Deprecated - Path getArchiveRoot(); + Path getArchiveLocation(); /** + * @deprecated in favor of {@link #getRootDirectories()} * - * @return true if this archive is a jar - * @deprecated does not appear to be used anywhere and now it shouldn't be - */ - @Deprecated - boolean isJarArchive(); - - /** - * If this archive is a jar file it will return the path to the jar file on the file system, - * otherwise it will return the directory that this corresponds to. + * Returns paths representing the archive root directories. Note that every path in this collection + * is guaranteed to be a directory. If the actual application archive appears to be a JAR, + * this collection will include a path to the root of the mounted {@link java.nio.file.FileSystem} + * created from the JAR. * - * @deprecated in favor of {@link #getPaths()} + * @return The archive root directories. */ @Deprecated - Path getArchiveLocation(); + PathsCollection getRootDirs(); /** - * * Returns paths representing the archive root directories. Note that every path in this collection * is guaranteed to be a directory. If the actual application archive appears to be a JAR, * this collection will include a path to the root of the mounted {@link java.nio.file.FileSystem} @@ -61,20 +56,33 @@ public interface ApplicationArchive { * * @return The archive root directories. */ - PathsCollection getRootDirs(); + PathCollection getRootDirectories(); /** - * + * @deprecated in favor of {@link #getResolvedPaths()} * @return The paths representing the application root paths. */ + @Deprecated PathsCollection getPaths(); /** * + * @return The paths representing the application root paths. + */ + PathCollection getResolvedPaths(); + + /** + * @deprecated in favor of {@link #getKey()} * @return the artifact key or null if not available */ AppArtifactKey getArtifactKey(); + /** + * + * @return the artifact key or null if not available + */ + ArtifactKey getKey(); + /** * Convenience method, returns the child path if it exists, otherwise null. * @@ -82,7 +90,7 @@ public interface ApplicationArchive { * @return The child path, or null if it does not exist. */ default Path getChildPath(String path) { - return getRootDirs().resolveExistingOrNull(path); + return getRootDirectories().resolveExistingOrNull(path); } /** @@ -94,8 +102,8 @@ default Path getChildPath(String path) { * @param consumer entry consumer */ default void processEntry(String path, BiConsumer consumer) { - final Iterator dirs = getRootDirs().iterator(); - final Iterator paths = getPaths().iterator(); + final Iterator dirs = getRootDirectories().iterator(); + final Iterator paths = getResolvedPaths().iterator(); while (dirs.hasNext()) { final Path child = dirs.next().resolve(path); if (Files.exists(child)) { diff --git a/core/deployment/src/main/java/io/quarkus/deployment/ApplicationArchiveImpl.java b/core/deployment/src/main/java/io/quarkus/deployment/ApplicationArchiveImpl.java index b415317a34b9e..5ec62ab2fc928 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/ApplicationArchiveImpl.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/ApplicationArchiveImpl.java @@ -1,6 +1,5 @@ package io.quarkus.deployment; -import java.io.Closeable; import java.nio.file.Path; import org.jboss.jandex.IndexView; @@ -8,31 +7,27 @@ import io.quarkus.bootstrap.model.AppArtifactKey; import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.builder.item.MultiBuildItem; +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.paths.PathCollection; +import io.quarkus.paths.PathList; public final class ApplicationArchiveImpl extends MultiBuildItem implements ApplicationArchive { private final IndexView indexView; - private final PathsCollection rootDirs; - private final boolean jar; - private final PathsCollection paths; - private final AppArtifactKey artifactKey; + private final PathCollection rootDirs; + private final PathCollection paths; + private final ArtifactKey artifactKey; - public ApplicationArchiveImpl(IndexView indexView, Path archiveRoot, Closeable closeable, boolean jar, - Path archiveLocation, AppArtifactKey artifactKey) { - this(indexView, PathsCollection.of(archiveRoot), PathsCollection.of(archiveLocation), artifactKey); + public ApplicationArchiveImpl(IndexView indexView, Path archiveRoot, + Path archiveLocation, ArtifactKey artifactKey) { + this(indexView, PathList.of(archiveRoot), PathList.of(archiveLocation), artifactKey); } - public ApplicationArchiveImpl(IndexView indexView, PathsCollection rootDirs, PathsCollection paths, - AppArtifactKey artifactKey) { - this(indexView, rootDirs, paths, false, artifactKey); - } - - private ApplicationArchiveImpl(IndexView indexView, PathsCollection rootDirs, PathsCollection paths, boolean jar, - AppArtifactKey artifactKey) { + public ApplicationArchiveImpl(IndexView indexView, PathCollection rootDirs, PathCollection paths, + ArtifactKey artifactKey) { this.indexView = indexView; this.rootDirs = rootDirs; this.paths = paths; - this.jar = jar; this.artifactKey = artifactKey; } @@ -43,35 +38,41 @@ public IndexView getIndex() { @Override @Deprecated - public Path getArchiveRoot() { - return rootDirs.iterator().next(); + public Path getArchiveLocation() { + return paths.iterator().next(); } @Override @Deprecated - public boolean isJarArchive() { - return jar; + public PathsCollection getRootDirs() { + return PathsCollection.from(rootDirs); } @Override - @Deprecated - public Path getArchiveLocation() { - return paths.iterator().next(); + public PathCollection getRootDirectories() { + return rootDirs; } @Override - public PathsCollection getRootDirs() { - return rootDirs; + @Deprecated + public PathsCollection getPaths() { + return PathsCollection.from(paths); } @Override - public PathsCollection getPaths() { + public PathCollection getResolvedPaths() { return paths; } @Override public AppArtifactKey getArtifactKey() { - return artifactKey; + return artifactKey == null ? null + : new AppArtifactKey(artifactKey.getGroupId(), artifactKey.getArtifactId(), artifactKey.getClassifier(), + artifactKey.getType()); } + @Override + public ArtifactKey getKey() { + return artifactKey; + } } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/CodeGenContext.java b/core/deployment/src/main/java/io/quarkus/deployment/CodeGenContext.java index a0c5dfb669c3e..d901f56d74a8d 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/CodeGenContext.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/CodeGenContext.java @@ -4,16 +4,18 @@ import java.util.Map; import io.quarkus.bootstrap.model.AppModel; +import io.quarkus.bootstrap.model.ApplicationModel; +import io.quarkus.bootstrap.util.BootstrapUtils; public class CodeGenContext { - private final AppModel model; + private final ApplicationModel model; private final Path outDir; private final Path workDir; private final Path inputDir; private final boolean redirectIO; private final Map properties; - public CodeGenContext(AppModel model, Path outDir, Path workDir, Path inputDir, boolean redirectIO, + public CodeGenContext(ApplicationModel model, Path outDir, Path workDir, Path inputDir, boolean redirectIO, Map properties) { this.model = model; this.outDir = outDir; @@ -23,7 +25,16 @@ public CodeGenContext(AppModel model, Path outDir, Path workDir, Path inputDir, this.properties = properties; } + /** + * @deprecated in favor of {@link #applicationModel()} + * @return + */ + @Deprecated public AppModel appModel() { + return BootstrapUtils.convert(model); + } + + public ApplicationModel applicationModel() { return model; } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/CodeGenerator.java b/core/deployment/src/main/java/io/quarkus/deployment/CodeGenerator.java index c42d1524fc7f7..b6fe63616c2f9 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/CodeGenerator.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/CodeGenerator.java @@ -9,7 +9,7 @@ import java.util.ServiceLoader; import java.util.function.Consumer; -import io.quarkus.bootstrap.model.AppModel; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.bootstrap.prebuild.CodeGenException; import io.quarkus.deployment.codegen.CodeGenData; @@ -20,11 +20,10 @@ public class CodeGenerator { // used by Gradle - @SuppressWarnings("unused") public static void initAndRun(ClassLoader classLoader, PathsCollection sourceParentDirs, Path generatedSourcesDir, Path buildDir, Consumer sourceRegistrar, - AppModel appModel, Map properties) throws CodeGenException { + ApplicationModel appModel, Map properties) throws CodeGenException { List generators = init(classLoader, sourceParentDirs, generatedSourcesDir, buildDir, sourceRegistrar); for (CodeGenData generator : generators) { generator.setRedirectIO(true); @@ -82,7 +81,7 @@ private static T callWithClassloader(ClassLoader deploymentClassLoader, Code */ public static boolean trigger(ClassLoader deploymentClassLoader, CodeGenData data, - AppModel appModel, + ApplicationModel appModel, Map properties) throws CodeGenException { return callWithClassloader(deploymentClassLoader, () -> { CodeGenProvider provider = data.provider; diff --git a/core/deployment/src/main/java/io/quarkus/deployment/ExtensionLoader.java b/core/deployment/src/main/java/io/quarkus/deployment/ExtensionLoader.java index 47d6990c9d4fb..316bb7c692b9e 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/ExtensionLoader.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/ExtensionLoader.java @@ -44,7 +44,7 @@ import org.jboss.logging.Logger; import org.wildfly.common.function.Functions; -import io.quarkus.bootstrap.model.AppModel; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.builder.BuildChainBuilder; import io.quarkus.builder.BuildContext; import io.quarkus.builder.BuildStepBuilder; @@ -125,7 +125,7 @@ private static boolean isRecorder(AnnotatedElement element) { * @throws ClassNotFoundException if a build step class is not found */ public static Consumer loadStepsFrom(ClassLoader classLoader, Properties buildSystemProps, - AppModel appModel, LaunchMode launchMode, DevModeType devModeType, + ApplicationModel appModel, LaunchMode launchMode, DevModeType devModeType, Consumer configCustomizer) throws IOException, ClassNotFoundException { // populate with all known types diff --git a/core/deployment/src/main/java/io/quarkus/deployment/QuarkusAugmentor.java b/core/deployment/src/main/java/io/quarkus/deployment/QuarkusAugmentor.java index 99df303269ebf..5ae5264e33b2b 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/QuarkusAugmentor.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/QuarkusAugmentor.java @@ -17,7 +17,7 @@ import org.jboss.logging.Logger; import io.quarkus.bootstrap.classloading.QuarkusClassLoader; -import io.quarkus.bootstrap.model.AppModel; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.builder.BuildChain; import io.quarkus.builder.BuildChainBuilder; @@ -36,6 +36,7 @@ import io.quarkus.deployment.builditem.ShutdownContextBuildItem; import io.quarkus.deployment.pkg.builditem.BuildSystemTargetBuildItem; import io.quarkus.dev.spi.DevModeType; +import io.quarkus.paths.PathCollection; import io.quarkus.runtime.LaunchMode; import io.quarkus.runtime.util.JavaVersionUtil; @@ -50,12 +51,12 @@ public class QuarkusAugmentor { private final List> buildChainCustomizers; private final LaunchMode launchMode; private final DevModeType devModeType; - private final List additionalApplicationArchives; + private final List additionalApplicationArchives; private final Collection excludedFromIndexing; private final LiveReloadBuildItem liveReloadBuildItem; private final Properties buildSystemProperties; private final Path targetDir; - private final AppModel effectiveModel; + private final ApplicationModel effectiveModel; private final String baseName; private final Consumer configCustomizer; private final boolean rebuild; @@ -154,7 +155,7 @@ public BuildResult run() throws Exception { .produce(new BuildSystemTargetBuildItem(targetDir, baseName, rebuild, buildSystemProperties == null ? new Properties() : buildSystemProperties)) .produce(new AppModelProviderBuildItem(effectiveModel)); - for (PathsCollection i : additionalApplicationArchives) { + for (PathCollection i : additionalApplicationArchives) { execBuilder.produce(new AdditionalApplicationArchiveBuildItem(i)); } BuildResult buildResult = execBuilder.execute(); @@ -189,7 +190,7 @@ public static final class Builder { public DevModeType auxiliaryDevModeType; boolean rebuild; - List additionalApplicationArchives = new ArrayList<>(); + List additionalApplicationArchives = new ArrayList<>(); Collection excludedFromIndexing = Collections.emptySet(); ClassLoader classLoader; PathsCollection root; @@ -200,7 +201,7 @@ public static final class Builder { LiveReloadBuildItem liveReloadState = new LiveReloadBuildItem(); Properties buildSystemProperties; - AppModel effectiveModel; + ApplicationModel effectiveModel; String baseName = "quarkus-application"; Consumer configCustomizer; ClassLoader deploymentClassLoader; @@ -213,11 +214,11 @@ public Builder addBuildChainCustomizer(Consumer customizer) { return this; } - public List getAdditionalApplicationArchives() { + public List getAdditionalApplicationArchives() { return additionalApplicationArchives; } - public Builder addAdditionalApplicationArchive(PathsCollection archive) { + public Builder addAdditionalApplicationArchive(PathCollection archive) { this.additionalApplicationArchives.add(archive); return this; } @@ -328,7 +329,7 @@ public Builder setTargetDir(Path outputDir) { return this; } - public Builder setEffectiveModel(AppModel effectiveModel) { + public Builder setEffectiveModel(ApplicationModel effectiveModel) { this.effectiveModel = effectiveModel; return this; } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/builditem/AdditionalApplicationArchiveBuildItem.java b/core/deployment/src/main/java/io/quarkus/deployment/builditem/AdditionalApplicationArchiveBuildItem.java index ab0efa183b33e..0adb2c76867e4 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/builditem/AdditionalApplicationArchiveBuildItem.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/builditem/AdditionalApplicationArchiveBuildItem.java @@ -1,27 +1,30 @@ package io.quarkus.deployment.builditem; -import java.nio.file.Path; - import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.builder.item.MultiBuildItem; +import io.quarkus.paths.PathCollection; /** * An additional application archive. This build item can only be consumed, it should not be produced by build steps. */ public final class AdditionalApplicationArchiveBuildItem extends MultiBuildItem { - private final PathsCollection path; + private final PathCollection path; - public AdditionalApplicationArchiveBuildItem(PathsCollection path) { + public AdditionalApplicationArchiveBuildItem(PathCollection path) { this.path = path; } + /** + * @deprecated in favor of {@link #getResolvedPaths()} + * @return + */ @Deprecated - public Path getPath() { - return path.getSinglePath(); + public PathsCollection getPaths() { + return PathsCollection.from(path); } - public PathsCollection getPaths() { + public PathCollection getResolvedPaths() { return path; } } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/builditem/AppModelProviderBuildItem.java b/core/deployment/src/main/java/io/quarkus/deployment/builditem/AppModelProviderBuildItem.java index 30784eb6f4f8d..19e8d697a8ef4 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/builditem/AppModelProviderBuildItem.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/builditem/AppModelProviderBuildItem.java @@ -2,7 +2,7 @@ import org.jboss.logging.Logger; -import io.quarkus.bootstrap.model.AppModel; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.model.PlatformImports; import io.quarkus.builder.item.SimpleBuildItem; import io.quarkus.deployment.BootstrapConfig; @@ -11,13 +11,13 @@ public final class AppModelProviderBuildItem extends SimpleBuildItem { private static final Logger log = Logger.getLogger(AppModelProviderBuildItem.class); - private final AppModel appModel; + private final ApplicationModel appModel; - public AppModelProviderBuildItem(AppModel appModel) { + public AppModelProviderBuildItem(ApplicationModel appModel) { this.appModel = appModel; } - public AppModel validateAndGet(BootstrapConfig config) { + public ApplicationModel validateAndGet(BootstrapConfig config) { final PlatformImports platforms = appModel.getPlatforms(); if (platforms != null && !BootstrapConfig.MisalignedPlatformImports.IGNORE.equals(config.misalignedPlatformImports) && !platforms.isAligned()) { diff --git a/core/deployment/src/main/java/io/quarkus/deployment/builditem/ArchiveRootBuildItem.java b/core/deployment/src/main/java/io/quarkus/deployment/builditem/ArchiveRootBuildItem.java index e5040da4d992c..5d96878396507 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/builditem/ArchiveRootBuildItem.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/builditem/ArchiveRootBuildItem.java @@ -89,7 +89,7 @@ private ArchiveRootBuildItem(Builder builder, QuarkusBuildCloseablesBuildItem bu if (Files.isDirectory(root)) { rootDirs.add(root); } else { - final FileSystem fs = buildCloseables.add(FileSystems.newFileSystem(root, null)); + final FileSystem fs = buildCloseables.add(FileSystems.newFileSystem(root, (ClassLoader) null)); fs.getRootDirectories().forEach(rootDirs::add); } } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/builditem/RemovedResourceBuildItem.java b/core/deployment/src/main/java/io/quarkus/deployment/builditem/RemovedResourceBuildItem.java index af1e2eba99bdf..25b34d5ecefb5 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/builditem/RemovedResourceBuildItem.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/builditem/RemovedResourceBuildItem.java @@ -2,20 +2,20 @@ import java.util.Set; -import io.quarkus.bootstrap.model.AppArtifactKey; import io.quarkus.builder.item.MultiBuildItem; +import io.quarkus.maven.dependency.ArtifactKey; public final class RemovedResourceBuildItem extends MultiBuildItem { - private final AppArtifactKey artifact; + private final ArtifactKey artifact; private final Set resources; - public RemovedResourceBuildItem(AppArtifactKey artifact, Set resources) { + public RemovedResourceBuildItem(ArtifactKey artifact, Set resources) { this.artifact = artifact; this.resources = resources; } - public AppArtifactKey getArtifact() { + public ArtifactKey getArtifact() { return artifact; } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/DevModeContext.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/DevModeContext.java index b52164b6a8136..2935aa4796398 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/dev/DevModeContext.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/DevModeContext.java @@ -17,6 +17,7 @@ import io.quarkus.bootstrap.app.QuarkusBootstrap; import io.quarkus.bootstrap.model.AppArtifactKey; import io.quarkus.bootstrap.model.PathsCollection; +import io.quarkus.maven.dependency.ArtifactKey; /** * Object that is used to pass context data from the plugin doing the invocation @@ -228,7 +229,7 @@ public Set getLocalArtifacts() { public static class ModuleInfo implements Serializable { - private final AppArtifactKey appArtifactKey; + private final ArtifactKey appArtifactKey; private final String name; private final String projectDirectory; private final CompilationUnit main; @@ -285,7 +286,7 @@ public String getTargetDir() { return targetDir; } - public AppArtifactKey getAppArtifactKey() { + public ArtifactKey getArtifactKey() { return appArtifactKey; } @@ -299,7 +300,7 @@ public Optional getTest() { public static class Builder { - private AppArtifactKey appArtifactKey; + private ArtifactKey appArtifactKey; private String name; private String projectDirectory; private PathsCollection sourcePaths = PathsCollection.of(); @@ -316,7 +317,7 @@ public static class Builder { private PathsCollection testResourcePaths = PathsCollection.of(); private String testResourcesOutputPath; - public Builder setAppArtifactKey(AppArtifactKey appArtifactKey) { + public Builder setArtifactKey(ArtifactKey appArtifactKey) { this.appArtifactKey = appArtifactKey; return this; } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/IDEDevModeMain.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/IDEDevModeMain.java index 886771374c893..f5ad2cc7224de 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/dev/IDEDevModeMain.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/IDEDevModeMain.java @@ -1,30 +1,31 @@ package io.quarkus.deployment.dev; import java.io.Closeable; -import java.io.File; import java.nio.file.Path; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import java.util.function.BiConsumer; -import java.util.stream.Collectors; import org.jboss.logging.Logger; +import io.quarkus.bootstrap.BootstrapConstants; import io.quarkus.bootstrap.BootstrapGradleException; import io.quarkus.bootstrap.app.CuratedApplication; +import io.quarkus.bootstrap.devmode.DependenciesFilter; import io.quarkus.bootstrap.model.AppArtifactKey; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.model.PathsCollection; -import io.quarkus.bootstrap.model.gradle.QuarkusModel; -import io.quarkus.bootstrap.model.gradle.WorkspaceModule; import io.quarkus.bootstrap.resolver.AppModelResolverException; -import io.quarkus.bootstrap.resolver.maven.workspace.LocalProject; -import io.quarkus.bootstrap.resolver.maven.workspace.LocalWorkspace; -import io.quarkus.bootstrap.util.PathsUtils; -import io.quarkus.bootstrap.util.QuarkusModelHelper; +import io.quarkus.bootstrap.util.BootstrapUtils; import io.quarkus.bootstrap.utils.BuildToolHelper; +import io.quarkus.bootstrap.workspace.ProcessedSources; +import io.quarkus.bootstrap.workspace.WorkspaceModule; +import io.quarkus.deployment.dev.DevModeContext.ModuleInfo; import io.quarkus.dev.spi.DevModeType; +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.GACT; public class IDEDevModeMain implements BiConsumer>, Closeable { @@ -38,41 +39,27 @@ public void accept(CuratedApplication curatedApplication, Map st Path appClasses = (Path) stringObjectMap.get("app-classes"); DevModeContext devModeContext = new DevModeContext(); devModeContext.setArgs((String[]) stringObjectMap.get("args")); + + ApplicationModel appModel = null; try { if (BuildToolHelper.isMavenProject(appClasses)) { - LocalProject project = (LocalProject) stringObjectMap.get(APP_PROJECT); - if (project == null) { - project = LocalProject.loadWorkspace(appClasses); - } - - DevModeContext.ModuleInfo root = toModule(project); - devModeContext.setApplicationRoot(root); - - final LocalWorkspace workspace = project.getWorkspace(); - for (AppArtifactKey localKey : curatedApplication.getAppModel().getLocalProjectArtifacts()) { - final LocalProject depProject = workspace.getProject(localKey.getGroupId(), localKey.getArtifactId()); - if (project == depProject) { - continue; - } - if (depProject == null) { - throw new IllegalStateException( - "Failed to locate project dependency " + localKey + " in the workspace"); - } - devModeContext.getAdditionalModules().add(toModule(depProject)); - devModeContext.getLocalArtifacts().add(localKey); - } + appModel = curatedApplication.getApplicationModel(); } else { - final QuarkusModel model = QuarkusModelHelper - .deserializeQuarkusModel((Path) stringObjectMap.get(QuarkusModelHelper.SERIALIZED_QUARKUS_MODEL)); - final WorkspaceModule launchingModule = model.getWorkspace().getMainModule(); - DevModeContext.ModuleInfo root = toModule(launchingModule); - devModeContext.setApplicationRoot(root); - for (WorkspaceModule additionalModule : model.getWorkspace().getAllModules()) { - if (!additionalModule.getArtifactCoords().equals(launchingModule.getArtifactCoords())) { - devModeContext.getAdditionalModules().add(toModule(additionalModule)); + appModel = BootstrapUtils + .deserializeQuarkusModel((Path) stringObjectMap.get(BootstrapConstants.SERIALIZED_APP_MODEL)); + } + + if (appModel != null) { + for (WorkspaceModule project : DependenciesFilter.getReloadableModules(appModel)) { + final ModuleInfo module = toModule(project); + if (project == appModel.getApplicationModule()) { + devModeContext.setApplicationRoot(module); + } else { + devModeContext.getAdditionalModules().add(module); + devModeContext.getLocalArtifacts() + .add(new AppArtifactKey(project.getId().getGroupId(), project.getId().getArtifactId())); } } - } } catch (AppModelResolverException e) { log.error("Failed to load workspace, hot reload will not be available", e); @@ -99,50 +86,39 @@ private void terminateIfRunning() { } private DevModeContext.ModuleInfo toModule(WorkspaceModule module) throws BootstrapGradleException { - AppArtifactKey key = new AppArtifactKey(module.getArtifactCoords().getGroupId(), - module.getArtifactCoords().getArtifactId(), module.getArtifactCoords().getClassifier()); + String classesDir = null; final Set sourceParents = new LinkedHashSet<>(); - for (File srcDir : module.getSourceSourceSet().getSourceDirectories()) { - sourceParents.add(srcDir.getParentFile().toPath()); + final PathsCollection.Builder srcPaths = PathsCollection.builder(); + for (ProcessedSources src : module.getMainSources()) { + sourceParents.add(src.getSourceDir().getParentFile().toPath()); + srcPaths.add(src.getSourceDir().toPath()); + if (classesDir == null) { + classesDir = src.getDestinationDir().toString(); + } } + String resourceDirectory = null; - if (!module.getSourceSet().getResourceDirectories().isEmpty()) { - // Peek the first one as we assume that it is the primary - resourceDirectory = module.getSourceSet().getResourceDirectories().iterator().next().toString(); + final PathsCollection.Builder resourcesPaths = PathsCollection.builder(); + for (ProcessedSources src : module.getMainResources()) { + resourcesPaths.add(src.getSourceDir().toPath()); + if (resourceDirectory == null) { + // Peek the first one as we assume that it is the primary + resourceDirectory = src.getDestinationDir().toString(); + } } + final ArtifactKey key = new GACT(module.getId().getGroupId(), module.getId().getArtifactId()); return new DevModeContext.ModuleInfo.Builder() - .setAppArtifactKey(key) - .setName(module.getArtifactCoords().getArtifactId()) - .setProjectDirectory(module.getProjectRoot().getPath()) - .setSourcePaths(PathsUtils.toPathsCollection(module.getSourceSourceSet().getSourceDirectories())) - .setClassesPath(QuarkusModelHelper.getClassPath(module).toAbsolutePath().toString()) - .setResourcePaths(PathsUtils.toPathsCollection(module.getSourceSourceSet().getResourceDirectories())) + .setArtifactKey(key) + .setName(module.getId().getArtifactId()) + .setProjectDirectory(module.getModuleDir().getPath()) + .setSourcePaths(srcPaths.build()) + .setClassesPath(classesDir) + .setResourcePaths(resourcesPaths.build()) .setResourcesOutputPath(resourceDirectory) .setSourceParents(PathsCollection.from(sourceParents)) .setPreBuildOutputDir(module.getBuildDir().toPath().resolve("generated-sources").toAbsolutePath().toString()) .setTargetDir(module.getBuildDir().toString()).build(); } - - private DevModeContext.ModuleInfo toModule(LocalProject project) { - return new DevModeContext.ModuleInfo.Builder() - .setAppArtifactKey(project.getKey()) - .setName(project.getArtifactId()) - .setProjectDirectory(project.getDir().toAbsolutePath().toString()) - .setSourcePaths(PathsCollection.of(project.getSourcesSourcesDir().toAbsolutePath())) - .setClassesPath(project.getClassesDir().toAbsolutePath().toString()) - .setResourcesOutputPath(project.getClassesDir().toAbsolutePath().toString()) - .setResourcePaths( - PathsCollection.from(project.getResourcesSourcesDirs().toList().stream() - .map(Path::toAbsolutePath) - .collect(Collectors.toCollection(LinkedHashSet::new)))) - .setSourceParents(PathsCollection.of(project.getSourcesDir())) - .setPreBuildOutputDir(project.getCodeGenOutputDir().toString()) - .setTargetDir(project.getOutputDir().toString()) - .setTestSourcePaths(PathsCollection.of(project.getTestSourcesSourcesDir())) - .setTestClassesPath(project.getTestClassesDir().toAbsolutePath().toString()) - .setTestResourcesOutputPath(project.getTestClassesDir().toAbsolutePath().toString()) - .setTestResourcePaths(PathsCollection.from(project.getTestResourcesSourcesDirs())).build(); - } } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/IsolatedDevModeMain.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/IsolatedDevModeMain.java index c38d687364c70..bf62d68499827 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/dev/IsolatedDevModeMain.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/IsolatedDevModeMain.java @@ -195,7 +195,7 @@ private void startCodeGenWatcher(QuarkusClassLoader classLoader, List urls = new HashSet<>(); - for (AppDependency i : application.getAppModel().getUserDependencies()) { - for (Path p : i.getArtifact().getPaths()) { + for (ResolvedDependency i : application.getApplicationModel().getRuntimeDependencies()) { + for (Path p : i.getResolvedPaths()) { urls.add(p.toUri().toURL()); } } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/TestSupport.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/TestSupport.java index 401cff00adaf2..ed08688b1e3e4 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/TestSupport.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/TestSupport.java @@ -148,13 +148,13 @@ public void init() { continue; } else if (config.includeModulePattern.isPresent()) { Pattern p = Pattern.compile(config.includeModulePattern.get()); - if (!p.matcher(module.getAppArtifactKey().getGroupId() + ":" + module.getAppArtifactKey().getArtifactId()) + if (!p.matcher(module.getArtifactKey().getGroupId() + ":" + module.getArtifactKey().getArtifactId()) .matches()) { continue; } } else if (config.excludeModulePattern.isPresent()) { Pattern p = Pattern.compile(config.excludeModulePattern.get()); - if (p.matcher(module.getAppArtifactKey().getGroupId() + ":" + module.getAppArtifactKey().getArtifactId()) + if (p.matcher(module.getArtifactKey().getGroupId() + ":" + module.getArtifactKey().getArtifactId()) .matches()) { continue; } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/index/ApplicationArchiveBuildStep.java b/core/deployment/src/main/java/io/quarkus/deployment/index/ApplicationArchiveBuildStep.java index 4d471d61ae611..0b95aa42ecd2c 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/index/ApplicationArchiveBuildStep.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/index/ApplicationArchiveBuildStep.java @@ -8,6 +8,7 @@ import java.nio.file.Path; import java.nio.file.ProviderNotFoundException; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -22,10 +23,6 @@ import org.jboss.jandex.Indexer; import org.jboss.logging.Logger; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppArtifactKey; -import io.quarkus.bootstrap.model.AppDependency; -import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.deployment.ApplicationArchive; import io.quarkus.deployment.ApplicationArchiveImpl; import io.quarkus.deployment.annotations.BuildProducer; @@ -40,6 +37,12 @@ import io.quarkus.deployment.builditem.QuarkusBuildCloseablesBuildItem; import io.quarkus.deployment.configuration.ClassLoadingConfig; import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem; +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.GACT; +import io.quarkus.maven.dependency.GACTV; +import io.quarkus.maven.dependency.ResolvedDependency; +import io.quarkus.paths.PathCollection; +import io.quarkus.paths.PathList; import io.quarkus.runtime.annotations.ConfigDocMapKey; import io.quarkus.runtime.annotations.ConfigDocSection; import io.quarkus.runtime.annotations.ConfigItem; @@ -95,9 +98,9 @@ ApplicationArchivesBuildItem build( liveReloadContext.setContextObject(IndexCache.class, indexCache); } - Map> removedResources = new HashMap<>(); + Map> removedResources = new HashMap<>(); for (Map.Entry> entry : classLoadingConfig.removedResources.entrySet()) { - removedResources.put(new AppArtifactKey(entry.getKey().split(":")), entry.getValue()); + removedResources.put(new GACT(entry.getKey().split(":")), entry.getValue()); } List applicationArchives = scanForOtherIndexes(buildCloseables, @@ -105,7 +108,8 @@ ApplicationArchivesBuildItem build( markerFiles, root, additionalApplicationArchiveBuildItem, indexDependencyBuildItems, indexCache, curateOutcomeBuildItem, removedResources); return new ApplicationArchivesBuildItem( - new ApplicationArchiveImpl(appindex.getIndex(), root.getRootDirs(), root.getPaths(), null), + new ApplicationArchiveImpl(appindex.getIndex(), PathList.from(root.getRootDirs()), + PathList.from(root.getPaths()), null), applicationArchives); } @@ -113,7 +117,7 @@ private List scanForOtherIndexes(QuarkusBuildCloseablesBuild ClassLoader classLoader, Set applicationArchiveFiles, ArchiveRootBuildItem root, List additionalApplicationArchives, List indexDependencyBuildItem, IndexCache indexCache, - CurateOutcomeBuildItem curateOutcomeBuildItem, Map> removedResources) + CurateOutcomeBuildItem curateOutcomeBuildItem, Map> removedResources) throws IOException { List appArchives = new ArrayList<>(); @@ -130,7 +134,7 @@ private List scanForOtherIndexes(QuarkusBuildCloseablesBuild indexCache, curateOutcomeBuildItem, removedResources); for (AdditionalApplicationArchiveBuildItem i : additionalApplicationArchives) { - for (Path apPath : i.getPaths()) { + for (Path apPath : i.getResolvedPaths()) { if (!root.getPaths().contains(apPath) && indexedPaths.add(apPath)) { appArchives.add(createApplicationArchive(buildCloseables, classLoader, indexCache, apPath, null, removedResources)); @@ -145,27 +149,29 @@ public void addIndexDependencyPaths(List indexDependen ClassLoader classLoader, ArchiveRootBuildItem root, Set indexedDeps, List appArchives, QuarkusBuildCloseablesBuildItem buildCloseables, IndexCache indexCache, CurateOutcomeBuildItem curateOutcomeBuildItem, - Map> removedResources) { + Map> removedResources) { if (indexDependencyBuildItems.isEmpty()) { return; } - final List userDeps = curateOutcomeBuildItem.getEffectiveModel().getUserDependencies(); - final Map userMap = new HashMap<>(userDeps.size()); - for (AppDependency dep : userDeps) { - userMap.put(dep.getArtifact().getKey(), dep.getArtifact()); + final Collection userDeps = curateOutcomeBuildItem.getApplicationModel() + .getRuntimeDependencies(); + final Map userMap = new HashMap<>(userDeps.size()); + for (ResolvedDependency dep : userDeps) { + userMap.put(dep.getKey(), dep); } try { for (IndexDependencyBuildItem indexDependencyBuildItem : indexDependencyBuildItems) { - final AppArtifactKey key = new AppArtifactKey(indexDependencyBuildItem.getGroupId(), + final ArtifactKey key = new GACT(indexDependencyBuildItem.getGroupId(), indexDependencyBuildItem.getArtifactId(), indexDependencyBuildItem.getClassifier(), - "jar"); - final AppArtifact artifact = userMap.get(key); + GACTV.TYPE_JAR); + final ResolvedDependency artifact = userMap.get(key); if (artifact == null) { + userMap.keySet().forEach(k -> System.out.println(" - " + k.getClass().getSimpleName() + " " + k)); throw new RuntimeException( "Could not resolve artifact " + key + " among the runtime dependencies of the application"); } - for (Path path : artifact.getPaths()) { + for (Path path : artifact.getResolvedPaths()) { if (!root.isExcludedFromIndexing(path) && !root.getPaths().contains(path) && indexedDeps.add(path)) { appArchives.add(createApplicationArchive(buildCloseables, classLoader, indexCache, path, key, removedResources)); @@ -179,12 +185,15 @@ public void addIndexDependencyPaths(List indexDependen private static ApplicationArchive createApplicationArchive(QuarkusBuildCloseablesBuildItem buildCloseables, ClassLoader classLoader, - IndexCache indexCache, Path dep, AppArtifactKey artifactKey, Map> removedResources) + IndexCache indexCache, Path dep, ArtifactKey artifactKey, Map> removedResources) throws IOException { - final FileSystem fs = Files.isDirectory(dep) ? null : buildCloseables.add(FileSystems.newFileSystem(dep, classLoader)); - Set removed = removedResources.get(artifactKey); - return new ApplicationArchiveImpl(indexPath(indexCache, dep, removed), - fs == null ? dep : fs.getRootDirectories().iterator().next(), fs, fs != null, dep, artifactKey); + Path rootDir = dep; + if (!Files.isDirectory(dep)) { + final FileSystem fs = buildCloseables.add(FileSystems.newFileSystem(dep, classLoader)); + rootDir = fs.getRootDirectories().iterator().next(); + } + final IndexView index = indexPath(indexCache, dep, removedResources.get(artifactKey)); + return new ApplicationArchiveImpl(index, rootDir, dep, artifactKey); } private static IndexView indexPath(IndexCache indexCache, Path dep, Set removed) throws IOException { @@ -195,10 +204,10 @@ private static IndexView indexPath(IndexCache indexCache, Path dep, Set private static void addMarkerFilePaths(Set applicationArchiveFiles, ArchiveRootBuildItem root, CurateOutcomeBuildItem curateOutcomeBuildItem, Set indexedPaths, List appArchives, QuarkusBuildCloseablesBuildItem buildCloseables, ClassLoader classLoader, - IndexCache indexCache, Map> removed) + IndexCache indexCache, Map> removed) throws IOException { - for (AppDependency dep : curateOutcomeBuildItem.getEffectiveModel().getUserDependencies()) { - final PathsCollection artifactPaths = dep.getArtifact().getPaths(); + for (ResolvedDependency dep : curateOutcomeBuildItem.getApplicationModel().getRuntimeDependencies()) { + final PathCollection artifactPaths = dep.getResolvedPaths(); boolean containsMarker = false; for (Path p : artifactPaths) { if (root.isExcludedFromIndexing(p)) { @@ -223,7 +232,7 @@ private static void addMarkerFilePaths(Set applicationArchiveFiles, } if (containsMarker) { - final PathsCollection.Builder rootDirs = PathsCollection.builder(); + final PathList.Builder rootDirs = PathList.builder(); final List indexes = new ArrayList<>(artifactPaths.size()); for (Path p : artifactPaths) { if (Files.isDirectory(p)) { @@ -232,14 +241,12 @@ private static void addMarkerFilePaths(Set applicationArchiveFiles, final FileSystem fs = buildCloseables.add(FileSystems.newFileSystem(p, classLoader)); fs.getRootDirectories().forEach(rootDirs::add); } - indexes.add( - indexPath(indexCache, p, removed.get(dep.getArtifact().getKey()))); - + indexes.add(indexPath(indexCache, p, removed.get(dep.getKey()))); indexedPaths.add(p); } appArchives .add(new ApplicationArchiveImpl(indexes.size() == 1 ? indexes.get(0) : CompositeIndex.create(indexes), - rootDirs.build(), artifactPaths, dep.getArtifact().getKey())); + rootDirs.build(), artifactPaths, dep.getKey())); } } } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/jbang/JBangAugmentorImpl.java b/core/deployment/src/main/java/io/quarkus/deployment/jbang/JBangAugmentorImpl.java index 02dd62fd04ab6..b49d007a01c75 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/jbang/JBangAugmentorImpl.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/jbang/JBangAugmentorImpl.java @@ -50,7 +50,7 @@ public void accept(CuratedApplication curatedApplication, Map re .setTargetDir(quarkusBootstrap.getTargetDirectory()) .setDeploymentClassLoader(curatedApplication.createDeploymentClassLoader()) .setBuildSystemProperties(quarkusBootstrap.getBuildSystemProperties()) - .setEffectiveModel(curatedApplication.getAppModel()); + .setEffectiveModel(curatedApplication.getApplicationModel()); if (quarkusBootstrap.getBaseName() != null) { builder.setBaseName(quarkusBootstrap.getBaseName()); } @@ -69,7 +69,7 @@ public void accept(CuratedApplication curatedApplication, Map re //but we only need to add it to the additional app archives //if it is forced as an app archive if (i.isForceApplicationArchive()) { - builder.addAdditionalApplicationArchive(i.getArchivePath()); + builder.addAdditionalApplicationArchive(i.getResolvedPaths()); } } builder.addBuildChainCustomizer(new Consumer() { @@ -122,7 +122,7 @@ public void accept(BuildChainBuilder builder) { } } resultMap.put("files", result); - List javaargs = new ArrayList(); + final List javaargs = new ArrayList<>(); javaargs.add("-Djava.util.logging.manager=org.jboss.logmanager.LogManager"); resultMap.put("java-args", javaargs); resultMap.put("main-class", buildResult.consume(MainClassBuildItem.class).getClassName()); diff --git a/core/deployment/src/main/java/io/quarkus/deployment/logging/LoggingResourceProcessor.java b/core/deployment/src/main/java/io/quarkus/deployment/logging/LoggingResourceProcessor.java index 0c1f2401644b7..ee3df692555a0 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/logging/LoggingResourceProcessor.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/logging/LoggingResourceProcessor.java @@ -212,7 +212,7 @@ public void run() { void setupStackTraceFormatter(ApplicationArchivesBuildItem item) { List indexList = new ArrayList<>(); for (ApplicationArchive i : item.getAllApplicationArchives()) { - if (Files.isDirectory(i.getArchiveLocation())) { + if (i.getResolvedPaths().isSinglePath() && Files.isDirectory(i.getResolvedPaths().getSinglePath())) { indexList.add(i.getIndex()); } } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/mutability/DevModeTask.java b/core/deployment/src/main/java/io/quarkus/deployment/mutability/DevModeTask.java index ca7c612bf518f..15df00956e5b3 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/mutability/DevModeTask.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/mutability/DevModeTask.java @@ -23,18 +23,19 @@ import io.quarkus.bootstrap.app.CuratedApplication; import io.quarkus.bootstrap.app.QuarkusBootstrap; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppArtifactKey; -import io.quarkus.bootstrap.model.AppDependency; -import io.quarkus.bootstrap.model.AppModel; -import io.quarkus.bootstrap.model.PersistentAppModel; +import io.quarkus.bootstrap.model.ApplicationModel; +import io.quarkus.bootstrap.model.MutableJarApplicationModel; import io.quarkus.bootstrap.util.IoUtils; import io.quarkus.deployment.dev.DevModeContext; import io.quarkus.deployment.dev.IsolatedDevModeMain; import io.quarkus.deployment.pkg.steps.JarResultBuildStep; import io.quarkus.dev.spi.DevModeType; +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.GACT; +import io.quarkus.maven.dependency.ResolvedArtifactDependency; +import io.quarkus.maven.dependency.ResolvedDependency; +import io.quarkus.paths.PathList; -@SuppressWarnings("Unused") public class DevModeTask { public static Closeable main(Path appRoot) throws Exception { @@ -47,9 +48,9 @@ public static Closeable main(Path appRoot) throws Exception { buildSystemProperties.load(buildIn); } - PersistentAppModel appModel = (PersistentAppModel) in.readObject(); + final MutableJarApplicationModel appModel = (MutableJarApplicationModel) in.readObject(); - AppModel existingModel = appModel.getAppModel(appRoot); + ApplicationModel existingModel = appModel.getAppModel(appRoot); DevModeContext context = createDevModeContext(appRoot, existingModel); CuratedApplication bootstrap = QuarkusBootstrap.builder() @@ -59,7 +60,7 @@ public static Closeable main(Path appRoot) throws Exception { .setMode(QuarkusBootstrap.Mode.REMOTE_DEV_SERVER) .setBuildSystemProperties(buildSystemProperties) .setBaseName(appModel.getBaseName()) - .setApplicationRoot(existingModel.getAppArtifact().getPath()) + .setApplicationRoot(existingModel.getAppArtifact().getResolvedPaths().getSinglePath()) .setTargetDirectory(appRoot.getParent()) .setBaseClassLoader(DevModeTask.class.getClassLoader()) .build().bootstrap(); @@ -73,14 +74,14 @@ public static Closeable main(Path appRoot) throws Exception { } } - private static DevModeContext createDevModeContext(Path appRoot, AppModel appModel) throws IOException { + private static DevModeContext createDevModeContext(Path appRoot, ApplicationModel appModel) throws IOException { DevModeContext context = new DevModeContext(); extractDevModeClasses(appRoot, appModel, new PostExtractAction() { @Override - public void run(AppArtifact dep, Path moduleClasses, boolean appArtifact) { + public void run(ResolvedDependency dep, Path moduleClasses, boolean appArtifact) { - dep.setPath(moduleClasses); - DevModeContext.ModuleInfo module = new DevModeContext.ModuleInfo.Builder().setAppArtifactKey(dep.getKey()) + ((ResolvedArtifactDependency) dep).setResolvedPaths(PathList.of(moduleClasses)); + DevModeContext.ModuleInfo module = new DevModeContext.ModuleInfo.Builder().setArtifactKey(dep.getKey()) .setName(dep.getArtifactId()) .setClassesPath(moduleClasses.toAbsolutePath().toString()) .setResourcesOutputPath(moduleClasses.toAbsolutePath().toString()) @@ -99,23 +100,25 @@ public void run(AppArtifact dep, Path moduleClasses, boolean appArtifact) { } - public static void extractDevModeClasses(Path appRoot, AppModel appModel, PostExtractAction postExtractAction) + public static void extractDevModeClasses(Path appRoot, ApplicationModel appModel, PostExtractAction postExtractAction) throws IOException { Path extracted = appRoot.resolve("dev"); Files.createDirectories(extracted); - Map userDependencies = new HashMap<>(); - for (AppDependency i : appModel.getUserDependencies()) { - userDependencies.put(i.getArtifact().getKey(), i.getArtifact()); + Map rtDependencies = new HashMap<>(); + for (ResolvedDependency i : appModel.getRuntimeDependencies()) { + rtDependencies.put(new GACT(i.getGroupId(), i.getArtifactId()), i); } //setup the classes that can be hot reloaded //this code needs to be kept in sync with the code in IsolatedRemoteDevModeMain //todo: look at a better way of doing this - for (AppArtifactKey i : appModel.getLocalProjectArtifacts()) { - boolean appArtifact = i.equals(appModel.getAppArtifact().getKey()); - AppArtifact dep = userDependencies.get(i); + for (ArtifactKey i : appModel.getReloadableWorkspaceDependencies()) { + boolean appArtifact = false; + ResolvedDependency dep = rtDependencies.get(i); Path moduleClasses = null; if (dep == null) { + appArtifact = i.getGroupId().equals(appModel.getAppArtifact().getGroupId()) + && i.getArtifactId().equals(appModel.getAppArtifact().getArtifactId()); //check if this is the application itself if (appArtifact) { dep = appModel.getAppArtifact(); @@ -129,7 +132,7 @@ public static void extractDevModeClasses(Path appRoot, AppModel appModel, PostEx continue; } IoUtils.createOrEmptyDir(moduleClasses); - for (Path p : dep.getPaths()) { + for (Path p : dep.getResolvedPaths()) { if (Files.isDirectory(p)) { Path moduleTarget = moduleClasses; Files.walkFileTree(p, new FileVisitor() { @@ -187,6 +190,6 @@ public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOEx } interface PostExtractAction { - void run(AppArtifact dep, Path moduleClasses, boolean appArtifact); + void run(ResolvedDependency dep, Path moduleClasses, boolean appArtifact); } } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/mutability/ReaugmentTask.java b/core/deployment/src/main/java/io/quarkus/deployment/mutability/ReaugmentTask.java index 264e8899dd859..c22d2b644ed01 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/mutability/ReaugmentTask.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/mutability/ReaugmentTask.java @@ -18,8 +18,8 @@ import io.quarkus.bootstrap.app.AdditionalDependency; import io.quarkus.bootstrap.app.CuratedApplication; import io.quarkus.bootstrap.app.QuarkusBootstrap; -import io.quarkus.bootstrap.model.AppModel; -import io.quarkus.bootstrap.model.PersistentAppModel; +import io.quarkus.bootstrap.model.ApplicationModel; +import io.quarkus.bootstrap.model.MutableJarApplicationModel; import io.quarkus.deployment.pkg.steps.JarResultBuildStep; public class ReaugmentTask { @@ -36,7 +36,7 @@ public static void main(Path appRoot) throws Exception { buildSystemProperties.load(buildIn); } - PersistentAppModel appModel = (PersistentAppModel) in.readObject(); + MutableJarApplicationModel appModel = (MutableJarApplicationModel) in.readObject(); List additional = new ArrayList<>(); if (appModel.getUserProvidersDirectory() != null) { @@ -53,7 +53,7 @@ public void accept(Path path) { } } - AppModel existingModel = appModel.getAppModel(appRoot); + final ApplicationModel existingModel = appModel.getAppModel(appRoot); System.setProperty("quarkus.package.type", "mutable-jar"); try (CuratedApplication bootstrap = QuarkusBootstrap.builder() .setAppArtifact(existingModel.getAppArtifact()) @@ -62,7 +62,7 @@ public void accept(Path path) { .setBuildSystemProperties(buildSystemProperties) .setBaseName(appModel.getBaseName()) .addAdditionalApplicationArchives(additional) - .setApplicationRoot(existingModel.getAppArtifact().getPath()) + .setApplicationRoot(existingModel.getAppArtifact().getResolvedPaths().getSinglePath()) .setTargetDirectory(appRoot.getParent()) .setBaseClassLoader(ReaugmentTask.class.getClassLoader()) .build().bootstrap()) { diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/builditem/CurateOutcomeBuildItem.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/builditem/CurateOutcomeBuildItem.java index d49e6b416c1a5..5b81bfd230a79 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/builditem/CurateOutcomeBuildItem.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/builditem/CurateOutcomeBuildItem.java @@ -1,17 +1,30 @@ package io.quarkus.deployment.pkg.builditem; import io.quarkus.bootstrap.model.AppModel; +import io.quarkus.bootstrap.model.ApplicationModel; +import io.quarkus.bootstrap.util.BootstrapUtils; import io.quarkus.builder.item.SimpleBuildItem; public final class CurateOutcomeBuildItem extends SimpleBuildItem { - private final AppModel effectiveModel; + private final ApplicationModel appModel; - public CurateOutcomeBuildItem(AppModel effectiveModel) { - this.effectiveModel = effectiveModel; + private AppModel effectiveModel; + + public CurateOutcomeBuildItem(ApplicationModel appModel) { + this.appModel = appModel; } + /** + * @deprecated in favor of {@link #getApplicationModel()} + * @return application model + */ + @Deprecated public AppModel getEffectiveModel() { - return effectiveModel; + return effectiveModel == null ? effectiveModel = BootstrapUtils.convert(appModel) : effectiveModel; + } + + public ApplicationModel getApplicationModel() { + return appModel; } } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/builditem/OutputTargetBuildItem.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/builditem/OutputTargetBuildItem.java index 0bbef34685cf4..24479c85b677c 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/builditem/OutputTargetBuildItem.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/builditem/OutputTargetBuildItem.java @@ -5,8 +5,8 @@ import java.util.Properties; import java.util.Set; -import io.quarkus.bootstrap.model.AppArtifactKey; import io.quarkus.builder.item.SimpleBuildItem; +import io.quarkus.maven.dependency.ArtifactKey; /** * The location that output artifacts should be created in @@ -19,10 +19,10 @@ public final class OutputTargetBuildItem extends SimpleBuildItem { private final String baseName; private final boolean rebuild; private final Properties buildSystemProperties; - private final Optional> includedOptionalDependencies; + private final Optional> includedOptionalDependencies; public OutputTargetBuildItem(Path outputDirectory, String baseName, boolean rebuild, Properties buildSystemProperties, - Optional> includedOptionalDependencies) { + Optional> includedOptionalDependencies) { this.outputDirectory = outputDirectory; this.baseName = baseName; this.rebuild = rebuild; @@ -46,7 +46,7 @@ public Properties getBuildSystemProperties() { return buildSystemProperties; } - public Optional> getIncludedOptionalDependencies() { + public Optional> getIncludedOptionalDependencies() { return includedOptionalDependencies; } } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/JarResultBuildStep.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/JarResultBuildStep.java index 255099175941c..2973aec54cbb2 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/JarResultBuildStep.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/JarResultBuildStep.java @@ -52,10 +52,7 @@ import org.apache.commons.lang3.SystemUtils; import org.jboss.logging.Logger; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppArtifactKey; -import io.quarkus.bootstrap.model.AppDependency; -import io.quarkus.bootstrap.model.PersistentAppModel; +import io.quarkus.bootstrap.model.MutableJarApplicationModel; import io.quarkus.bootstrap.runner.QuarkusEntryPoint; import io.quarkus.bootstrap.runner.SerializedApplication; import io.quarkus.bootstrap.util.IoUtils; @@ -84,6 +81,10 @@ import io.quarkus.deployment.pkg.builditem.UberJarMergedResourceBuildItem; import io.quarkus.deployment.pkg.builditem.UberJarRequiredBuildItem; import io.quarkus.deployment.util.FileUtil; +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.Dependency; +import io.quarkus.maven.dependency.GACT; +import io.quarkus.maven.dependency.ResolvedDependency; /** * This build step builds both the thin jars and uber jars. @@ -178,10 +179,10 @@ OutputTargetBuildItem outputTarget(BuildSystemTargetBuildItem bst, PackageConfig String name = packageConfig.outputName.orElseGet(bst::getBaseName); Path path = packageConfig.outputDirectory.map(s -> bst.getOutputDirectory().resolve(s)) .orElseGet(bst::getOutputDirectory); - Optional> includedOptionalDependencies; + Optional> includedOptionalDependencies; if (packageConfig.filterOptionalDependencies) { includedOptionalDependencies = Optional.of(packageConfig.includedOptionalDependencies - .map(set -> set.stream().map(AppArtifactKey::fromString).collect(Collectors.toSet())) + .map(set -> set.stream().map(s -> (ArtifactKey) GACT.fromString(s)).collect(Collectors.toSet())) .orElse(Collections.emptySet())); } else { includedOptionalDependencies = Optional.empty(); @@ -336,28 +337,28 @@ private void buildUberJar0(CurateOutcomeBuildItem curateOutcomeBuildItem, log.info("Building fat jar: " + runnerJar); final Map seen = new HashMap<>(); - final Map> duplicateCatcher = new HashMap<>(); + final Map> duplicateCatcher = new HashMap<>(); final Map> concatenatedEntries = new HashMap<>(); final Set mergeResourcePaths = mergedResources.stream() .map(UberJarMergedResourceBuildItem::getPath) .collect(Collectors.toSet()); - final Set removed = getRemovedKeys(classLoadingConfig); + final Set removed = getRemovedKeys(classLoadingConfig); Set finalIgnoredEntries = new HashSet<>(IGNORED_ENTRIES); packageConfig.userConfiguredIgnoredEntries.ifPresent(finalIgnoredEntries::addAll); ignoredResources.stream() .map(UberJarIgnoredResourceBuildItem::getPath) .forEach(finalIgnoredEntries::add); - final List appDeps = curateOutcomeBuildItem.getEffectiveModel().getUserDependencies(); + final Collection appDeps = curateOutcomeBuildItem.getApplicationModel() + .getRuntimeDependencies(); - AppArtifact appArtifact = curateOutcomeBuildItem.getEffectiveModel().getAppArtifact(); + ResolvedDependency appArtifact = curateOutcomeBuildItem.getApplicationModel().getAppArtifact(); // the manifest needs to be the first entry in the jar, otherwise JarInputStream does not work properly // see https://bugs.openjdk.java.net/browse/JDK-8031748 generateManifest(runnerZipFs, "", packageConfig, appArtifact, mainClassBuildItem.getClassName(), applicationInfo); - for (AppDependency appDep : appDeps) { - final AppArtifact depArtifact = appDep.getArtifact(); + for (ResolvedDependency appDep : appDeps) { // Exclude files that are not jars (typically, we can have XML files here, see https://github.com/quarkusio/quarkus/issues/2852) // and are not part of the optional dependencies to include @@ -365,7 +366,7 @@ private void buildUberJar0(CurateOutcomeBuildItem curateOutcomeBuildItem, continue; } - for (Path resolvedDep : depArtifact.getPaths()) { + for (Path resolvedDep : appDep.getResolvedPaths()) { Set existingEntries = new HashSet<>(); Set transformedFilesByJar = transformedClasses.getTransformedFilesByJar().get(resolvedDep); if (transformedFilesByJar != null) { @@ -389,8 +390,8 @@ private void buildUberJar0(CurateOutcomeBuildItem curateOutcomeBuildItem, } } } - Set> explained = new HashSet<>(); - for (Map.Entry> entry : duplicateCatcher.entrySet()) { + Set> explained = new HashSet<>(); + for (Map.Entry> entry : duplicateCatcher.entrySet()) { if (entry.getValue().size() > 1) { if (explained.add(entry.getValue())) { log.warn("Dependencies with duplicate files detected. The dependencies " + entry.getValue() @@ -438,24 +439,24 @@ private void buildUberJar0(CurateOutcomeBuildItem curateOutcomeBuildItem, * @param optionalDependencies the optional dependencies to include into the final package. * @return {@code true} if the dependency should be included, {@code false} otherwise. */ - private static boolean includeAppDep(AppDependency appDep, Optional> optionalDependencies, - Set removedArtifacts) { - if (!"jar".equals(appDep.getArtifact().getType())) { + private static boolean includeAppDep(ResolvedDependency appDep, Optional> optionalDependencies, + Set removedArtifacts) { + if (!"jar".equals(appDep.getType())) { return false; } if (appDep.isOptional()) { - return optionalDependencies.map(appArtifactKeys -> appArtifactKeys.contains(appDep.getArtifact().getKey())) + return optionalDependencies.map(appArtifactKeys -> appArtifactKeys.contains(appDep.getKey())) .orElse(true); } - if (removedArtifacts.contains(appDep.getArtifact().getKey())) { + if (removedArtifacts.contains(appDep.getKey())) { return false; } return true; } private void walkFileDependencyForDependency(Path root, FileSystem runnerZipFs, Map seen, - Map> duplicateCatcher, Map> concatenatedEntries, - Set finalIgnoredEntries, AppDependency appDep, Set existingEntries, + Map> duplicateCatcher, Map> concatenatedEntries, + Set finalIgnoredEntries, Dependency appDep, Set existingEntries, Set mergeResourcePaths) throws IOException { final Path metaInfDir = root.resolve("META-INF"); Files.walkFileTree(root, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, @@ -588,7 +589,7 @@ private JarBuildItem buildThinJar(CurateOutcomeBuildItem curateOutcomeBuildItem, } else { IoUtils.createOrEmptyDir(quarkus); } - Map> copiedArtifacts = new HashMap<>(); + Map> copiedArtifacts = new HashMap<>(); Path fernflowerJar = null; Path decompiledOutputDir = null; @@ -673,27 +674,27 @@ private JarBuildItem buildThinJar(CurateOutcomeBuildItem curateOutcomeBuildItem, Set finalIgnoredEntries = new HashSet<>(IGNORED_ENTRIES); packageConfig.userConfiguredIgnoredEntries.ifPresent(finalIgnoredEntries::addAll); try (FileSystem runnerZipFs = ZipUtils.newZip(runnerJar)) { - for (Path root : applicationArchivesBuildItem.getRootArchive().getRootDirs()) { + for (Path root : applicationArchivesBuildItem.getRootArchive().getRootDirectories()) { copyFiles(root, runnerZipFs, null, finalIgnoredEntries); } } } - final Set parentFirstKeys = getParentFirstKeys(curateOutcomeBuildItem, classLoadingConfig); + final Set parentFirstKeys = getParentFirstKeys(curateOutcomeBuildItem, classLoadingConfig); StringBuilder classPath = new StringBuilder(); - final Set removed = getRemovedKeys(classLoadingConfig); - for (AppDependency appDep : curateOutcomeBuildItem.getEffectiveModel().getUserDependencies()) { + final Set removed = getRemovedKeys(classLoadingConfig); + for (ResolvedDependency appDep : curateOutcomeBuildItem.getApplicationModel().getRuntimeDependencies()) { if (rebuild) { - jars.addAll(appDep.getArtifact().getPaths().toList()); + appDep.getResolvedPaths().forEach(jars::add); } else { copyDependency(parentFirstKeys, outputTargetBuildItem, copiedArtifacts, mainLib, baseLib, jars, true, classPath, appDep, transformedClasses, removed); } - if (parentFirstKeys.contains(appDep.getArtifact().getKey())) { - parentFirst.addAll(appDep.getArtifact().getPaths().toList()); + if (parentFirstKeys.contains(appDep.getKey())) { + appDep.getResolvedPaths().forEach(parentFirst::add); } } for (AdditionalApplicationArchiveBuildItem i : additionalApplicationArchiveBuildItems) { - for (Path path : i.getPaths()) { + for (Path path : i.getResolvedPaths()) { if (!path.getParent().equals(userProviders)) { throw new RuntimeException( "Additional application archives can only be provided from the user providers directory. " + path @@ -744,7 +745,7 @@ private JarBuildItem buildThinJar(CurateOutcomeBuildItem curateOutcomeBuildItem, } if (!rebuild) { try (FileSystem runnerZipFs = ZipUtils.newZip(initJar)) { - AppArtifact appArtifact = curateOutcomeBuildItem.getEffectiveModel().getAppArtifact(); + ResolvedDependency appArtifact = curateOutcomeBuildItem.getApplicationModel().getAppArtifact(); generateManifest(runnerZipFs, classPath.toString(), packageConfig, appArtifact, QuarkusEntryPoint.class.getName(), applicationInfo); @@ -755,14 +756,14 @@ private JarBuildItem buildThinJar(CurateOutcomeBuildItem curateOutcomeBuildItem, Path deploymentLib = libDir.resolve(DEPLOYMENT_LIB); Files.createDirectories(deploymentLib); - for (AppDependency appDep : curateOutcomeBuildItem.getEffectiveModel().getFullDeploymentDeps()) { + for (ResolvedDependency appDep : curateOutcomeBuildItem.getApplicationModel().getDependencies()) { copyDependency(parentFirstKeys, outputTargetBuildItem, copiedArtifacts, deploymentLib, baseLib, jars, false, classPath, appDep, new TransformedClassesBuildItem(Collections.emptyMap()), removed); //we don't care about transformation here, so just pass in an empty item } - Map> relativePaths = new HashMap<>(); - for (Map.Entry> e : copiedArtifacts.entrySet()) { + Map> relativePaths = new HashMap<>(); + for (Map.Entry> e : copiedArtifacts.entrySet()) { relativePaths.put(e.getKey(), e.getValue().stream().map(s -> buildDir.relativize(s).toString().replace('\\', '/')) .collect(Collectors.toList())); @@ -770,8 +771,9 @@ private JarBuildItem buildThinJar(CurateOutcomeBuildItem curateOutcomeBuildItem, //now we serialize the data needed to build up the reaugmentation class path //first the app model - PersistentAppModel model = new PersistentAppModel(outputTargetBuildItem.getBaseName(), relativePaths, - curateOutcomeBuildItem.getEffectiveModel(), + MutableJarApplicationModel model = new MutableJarApplicationModel(outputTargetBuildItem.getBaseName(), + relativePaths, + curateOutcomeBuildItem.getApplicationModel(), packageConfig.userProvidersDirectory.orElse(null), buildDir.relativize(runnerJar).toString()); Path appmodelDat = deploymentLib.resolve(APPMODEL_DAT); try (OutputStream out = Files.newOutputStream(appmodelDat)) { @@ -787,8 +789,8 @@ private JarBuildItem buildThinJar(CurateOutcomeBuildItem curateOutcomeBuildItem, try (OutputStream out = Files.newOutputStream(deploymentCp)) { ObjectOutputStream obj = new ObjectOutputStream(out); List paths = new ArrayList<>(); - for (AppDependency i : curateOutcomeBuildItem.getEffectiveModel().getFullDeploymentDeps()) { - final List list = relativePaths.get(i.getArtifact().getKey()); + for (ResolvedDependency i : curateOutcomeBuildItem.getApplicationModel().getDependencies()) { + final List list = relativePaths.get(i.getKey()); // some of the dependencies may have been filtered out if (list != null) { paths.addAll(list); @@ -802,8 +804,8 @@ private JarBuildItem buildThinJar(CurateOutcomeBuildItem curateOutcomeBuildItem, if (packageConfig.includeDependencyList) { Path deplist = buildDir.resolve(QUARKUS_APP_DEPS); List lines = new ArrayList<>(); - for (AppDependency i : curateOutcomeBuildItem.getEffectiveModel().getUserDependencies()) { - lines.add(i.getArtifact().toString()); + for (ResolvedDependency i : curateOutcomeBuildItem.getApplicationModel().getRuntimeDependencies()) { + lines.add(i.toGACTVString()); } lines.sort(Comparator.naturalOrder()); Files.write(deplist, lines); @@ -826,14 +828,14 @@ public void accept(Path path) { /** * @return a {@code Set} containing the key of the artifacts to load from the parent ClassLoader first. */ - private Set getParentFirstKeys(CurateOutcomeBuildItem curateOutcomeBuildItem, + private Set getParentFirstKeys(CurateOutcomeBuildItem curateOutcomeBuildItem, ClassLoadingConfig classLoadingConfig) { - final Set parentFirstKeys = new HashSet<>( - curateOutcomeBuildItem.getEffectiveModel().getRunnerParentFirstArtifacts()); + final Set parentFirstKeys = new HashSet<>( + curateOutcomeBuildItem.getApplicationModel().getRunnerParentFirst()); classLoadingConfig.parentFirstArtifacts.ifPresent( parentFirstArtifacts -> { for (String artifact : parentFirstArtifacts) { - parentFirstKeys.add(new AppArtifactKey(artifact.split(":"))); + parentFirstKeys.add(new GACT(artifact.split(":"))); } }); return parentFirstKeys; @@ -842,12 +844,12 @@ private Set getParentFirstKeys(CurateOutcomeBuildItem curateOutc /** * @return a {@code Set} containing the key of the artifacts to load from the parent ClassLoader first. */ - private Set getRemovedKeys(ClassLoadingConfig classLoadingConfig) { - final Set removed = new HashSet<>(); + private Set getRemovedKeys(ClassLoadingConfig classLoadingConfig) { + final Set removed = new HashSet<>(); classLoadingConfig.removedArtifacts.ifPresent( removedArtifacts -> { for (String artifact : removedArtifacts) { - removed.add(new AppArtifactKey(artifact.split(":"))); + removed.add(new GACT(artifact.split(":"))); } }); return removed; @@ -905,33 +907,32 @@ private boolean decompile(Path fernflowerJar, Path decompiledOutputDir, Path jar return true; } - private void copyDependency(Set parentFirstArtifacts, OutputTargetBuildItem outputTargetBuildItem, - Map> runtimeArtifacts, Path libDir, Path baseLib, List jars, - boolean allowParentFirst, StringBuilder classPath, AppDependency appDep, - TransformedClassesBuildItem transformedClasses, Set removedDeps) + private void copyDependency(Set parentFirstArtifacts, OutputTargetBuildItem outputTargetBuildItem, + Map> runtimeArtifacts, Path libDir, Path baseLib, List jars, + boolean allowParentFirst, StringBuilder classPath, ResolvedDependency appDep, + TransformedClassesBuildItem transformedClasses, Set removedDeps) throws IOException { - final AppArtifact depArtifact = appDep.getArtifact(); // Exclude files that are not jars (typically, we can have XML files here, see https://github.com/quarkusio/quarkus/issues/2852) // and are not part of the optional dependencies to include if (!includeAppDep(appDep, outputTargetBuildItem.getIncludedOptionalDependencies(), removedDeps)) { return; } - if (runtimeArtifacts.containsKey(depArtifact.getKey())) { + if (runtimeArtifacts.containsKey(appDep.getKey())) { return; } - for (Path resolvedDep : depArtifact.getPaths()) { - final String fileName = depArtifact.getGroupId() + "." + resolvedDep.getFileName(); + for (Path resolvedDep : appDep.getResolvedPaths()) { + final String fileName = appDep.getGroupId() + "." + resolvedDep.getFileName(); final Path targetPath; - if (allowParentFirst && parentFirstArtifacts.contains(depArtifact.getKey())) { + if (allowParentFirst && parentFirstArtifacts.contains(appDep.getKey())) { targetPath = baseLib.resolve(fileName); classPath.append(" ").append(LIB).append("/").append(BOOT_LIB).append("/").append(fileName); } else { targetPath = libDir.resolve(fileName); jars.add(targetPath); } - runtimeArtifacts.computeIfAbsent(depArtifact.getKey(), (s) -> new ArrayList<>(1)).add(targetPath); + runtimeArtifacts.computeIfAbsent(appDep.getKey(), (s) -> new ArrayList<>(1)).add(targetPath); if (Files.isDirectory(resolvedDep)) { // This case can happen when we are building a jar from inside the Quarkus repository @@ -1101,7 +1102,7 @@ private NativeImageSourceJarBuildItem buildNativeImageUberJar(CurateOutcomeBuild */ private void copyJsonConfigFiles(ApplicationArchivesBuildItem applicationArchivesBuildItem, Path thinJarDirectory) throws IOException { - for (Path root : applicationArchivesBuildItem.getRootArchive().getRootDirs()) { + for (Path root : applicationArchivesBuildItem.getRootArchive().getRootDirectories()) { try (Stream stream = Files.find(root, 1, IS_JSON_FILE_PREDICATE)) { stream.forEach(new Consumer() { @Override @@ -1136,15 +1137,16 @@ private void doLegacyThinJarGeneration(CurateOutcomeBuildItem curateOutcomeBuild final StringBuilder classPath = new StringBuilder(); final Map> services = new HashMap<>(); - final List appDeps = curateOutcomeBuildItem.getEffectiveModel().getUserDependencies(); + final Collection appDeps = curateOutcomeBuildItem.getApplicationModel() + .getRuntimeDependencies(); final Set finalIgnoredEntries = new HashSet<>(IGNORED_ENTRIES); packageConfig.userConfiguredIgnoredEntries.ifPresent(finalIgnoredEntries::addAll); - final Set removed = getRemovedKeys(classLoadingConfig); + final Set removed = getRemovedKeys(classLoadingConfig); copyLibraryJars(runnerZipFs, outputTargetBuildItem, transformedClasses, libDir, classPath, appDeps, services, finalIgnoredEntries, removed); - AppArtifact appArtifact = curateOutcomeBuildItem.getEffectiveModel().getAppArtifact(); + ResolvedDependency appArtifact = curateOutcomeBuildItem.getApplicationModel().getAppArtifact(); // the manifest needs to be the first entry in the jar, otherwise JarInputStream does not work properly // see https://bugs.openjdk.java.net/browse/JDK-8031748 generateManifest(runnerZipFs, classPath.toString(), packageConfig, appArtifact, mainClassBuildItem.getClassName(), @@ -1156,11 +1158,10 @@ private void doLegacyThinJarGeneration(CurateOutcomeBuildItem curateOutcomeBuild private void copyLibraryJars(FileSystem runnerZipFs, OutputTargetBuildItem outputTargetBuildItem, TransformedClassesBuildItem transformedClasses, Path libDir, - StringBuilder classPath, List appDeps, Map> services, - Set ignoredEntries, Set removedDependencies) throws IOException { + StringBuilder classPath, Collection appDeps, Map> services, + Set ignoredEntries, Set removedDependencies) throws IOException { - for (AppDependency appDep : appDeps) { - final AppArtifact depArtifact = appDep.getArtifact(); + for (ResolvedDependency appDep : appDeps) { // Exclude files that are not jars (typically, we can have XML files here, see https://github.com/quarkusio/quarkus/issues/2852) // and are not part of the optional dependencies to include @@ -1168,17 +1169,18 @@ private void copyLibraryJars(FileSystem runnerZipFs, OutputTargetBuildItem outpu continue; } - for (Path resolvedDep : depArtifact.getPaths()) { + for (Path resolvedDep : appDep.getResolvedPaths()) { if (!Files.isDirectory(resolvedDep)) { Set transformedFromThisArchive = transformedClasses.getTransformedFilesByJar().get(resolvedDep); if (transformedFromThisArchive == null || transformedFromThisArchive.isEmpty()) { - final String fileName = depArtifact.getGroupId() + "." + resolvedDep.getFileName(); + final String fileName = appDep.getGroupId() + "." + resolvedDep.getFileName(); final Path targetPath = libDir.resolve(fileName); Files.copy(resolvedDep, targetPath, StandardCopyOption.REPLACE_EXISTING); classPath.append(" lib/").append(fileName); } else { //we have transformed classes, we need to handle them correctly - final String fileName = "modified-" + depArtifact.getGroupId() + "." + resolvedDep.getFileName(); + final String fileName = "modified-" + appDep.getGroupId() + "." + + resolvedDep.getFileName(); final Path targetPath = libDir.resolve(fileName); classPath.append(" lib/").append(fileName); filterZipFile(resolvedDep, targetPath, transformedFromThisArchive); @@ -1270,7 +1272,7 @@ private void copyCommonContent(FileSystem runnerZipFs, Map> } } - for (Path root : appArchives.getRootArchive().getRootDirs()) { + for (Path root : appArchives.getRootArchive().getRootDirectories()) { copyFiles(root, runnerZipFs, concatenatedEntries, ignoredEntries); } @@ -1333,7 +1335,8 @@ private void filterZipFile(Path resolvedDep, Path targetPath, Set transf * BEWARE this method should be invoked after file copy from target/classes and so on. * Otherwise this manifest manipulation will be useless. */ - private void generateManifest(FileSystem runnerZipFs, final String classPath, PackageConfig config, AppArtifact appArtifact, + private void generateManifest(FileSystem runnerZipFs, final String classPath, PackageConfig config, + ResolvedDependency appArtifact, String mainClassName, ApplicationInfoBuildItem applicationInfo) throws IOException { @@ -1363,7 +1366,8 @@ private void generateManifest(FileSystem runnerZipFs, final String classPath, Pa } attributes.put(Attributes.Name.MAIN_CLASS, mainClassName); if (config.manifest.addImplementationEntries && !attributes.containsKey(Attributes.Name.IMPLEMENTATION_TITLE)) { - String name = ApplicationInfoBuildItem.UNSET_VALUE.equals(applicationInfo.getName()) ? appArtifact.getArtifactId() + String name = ApplicationInfoBuildItem.UNSET_VALUE.equals(applicationInfo.getName()) + ? appArtifact.getArtifactId() : applicationInfo.getName(); attributes.put(Attributes.Name.IMPLEMENTATION_TITLE, name); } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStep.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStep.java index 1eb6b48083755..e8185521e7f90 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStep.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStep.java @@ -22,8 +22,6 @@ import org.apache.commons.lang3.SystemUtils; import org.jboss.logging.Logger; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppDependency; import io.quarkus.bootstrap.util.IoUtils; import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.builditem.nativeimage.ExcludeConfigBuildItem; @@ -39,6 +37,8 @@ import io.quarkus.deployment.pkg.builditem.NativeImageSourceJarBuildItem; import io.quarkus.deployment.pkg.builditem.OutputTargetBuildItem; import io.quarkus.deployment.pkg.builditem.ProcessInheritIODisabled; +import io.quarkus.maven.dependency.GACTV; +import io.quarkus.maven.dependency.ResolvedDependency; public class NativeImageBuildStep { @@ -284,11 +284,9 @@ private void copyJarSourcesToLib(OutputTargetBuildItem outputTargetBuildItem, libDirFile.mkdirs(); } - final List appDeps = curateOutcomeBuildItem.getEffectiveModel().getUserDependencies(); - for (AppDependency appDep : appDeps) { - final AppArtifact depArtifact = appDep.getArtifact(); - if (depArtifact.getType().equals("jar")) { - for (Path resolvedDep : depArtifact.getPaths()) { + for (ResolvedDependency depArtifact : curateOutcomeBuildItem.getApplicationModel().getRuntimeDependencies()) { + if (depArtifact.getType().equals(GACTV.TYPE_JAR)) { + for (Path resolvedDep : depArtifact.getResolvedPaths()) { if (!Files.isDirectory(resolvedDep)) { // Do we need to handle transformed classes? // Their bytecode might have been modified but is there source for such modification? diff --git a/core/deployment/src/main/java/io/quarkus/deployment/steps/CapabilityAggregationStep.java b/core/deployment/src/main/java/io/quarkus/deployment/steps/CapabilityAggregationStep.java index 2b9d866363006..bca9c642c0d41 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/steps/CapabilityAggregationStep.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/steps/CapabilityAggregationStep.java @@ -5,9 +5,9 @@ import java.util.Map; import java.util.function.BooleanSupplier; -import io.quarkus.bootstrap.model.AppModel; -import io.quarkus.bootstrap.model.CapabilityContract; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.model.CapabilityErrors; +import io.quarkus.bootstrap.model.ExtensionCapabilities; import io.quarkus.deployment.BooleanSupplierFactoryBuildItem; import io.quarkus.deployment.Capabilities; import io.quarkus.deployment.annotations.BuildProducer; @@ -27,9 +27,9 @@ public class CapabilityAggregationStep { @BuildStep void provideCapabilities(BuildProducer producer, CurateOutcomeBuildItem curateOutcomeBuildItem, BooleanSupplierFactoryBuildItem supplierFactory) { - final AppModel appModel = curateOutcomeBuildItem.getEffectiveModel(); + final ApplicationModel appModel = curateOutcomeBuildItem.getApplicationModel(); - for (CapabilityContract contract : appModel.getCapabilityContracts().values()) { + for (ExtensionCapabilities contract : appModel.getExtensionCapabilities()) { final String provider = contract.getExtension(); for (String capability : contract.getProvidesCapabilities()) { int conditionIndex = capability.indexOf('?'); diff --git a/core/deployment/src/main/java/io/quarkus/deployment/steps/ClassTransformingBuildStep.java b/core/deployment/src/main/java/io/quarkus/deployment/steps/ClassTransformingBuildStep.java index f145ec439df6c..76b2f974ba843 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/steps/ClassTransformingBuildStep.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/steps/ClassTransformingBuildStep.java @@ -32,8 +32,6 @@ import io.quarkus.bootstrap.BootstrapDebug; import io.quarkus.bootstrap.classloading.ClassPathElement; import io.quarkus.bootstrap.classloading.QuarkusClassLoader; -import io.quarkus.bootstrap.model.AppArtifactKey; -import io.quarkus.bootstrap.model.AppDependency; import io.quarkus.deployment.QuarkusClassWriter; import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.builditem.ApplicationArchivesBuildItem; @@ -47,6 +45,9 @@ import io.quarkus.deployment.index.ConstPoolScanner; import io.quarkus.deployment.pkg.PackageConfig; import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem; +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.GACT; +import io.quarkus.maven.dependency.ResolvedDependency; import io.quarkus.runtime.LaunchMode; public class ClassTransformingBuildStep { @@ -132,7 +133,6 @@ public byte[] apply(String className, byte[] originalBytes) { List archives = cl.getElementsWithResource(classFileName); if (!archives.isEmpty()) { ClassPathElement classPathElement = archives.get(0); - Path jar = classPathElement.getRoot(); byte[] classData = classPathElement.getResource(classFileName).getData(); Set constValues = constScanning.get(className); if (constValues != null && !noConstScanning.contains(className)) { @@ -269,18 +269,18 @@ private void handleRemovedResources(ClassLoadingConfig classLoadingConfig, Curat Map> transformedClassesByJar, List removedResourceBuildItems) { //a little bit of a hack, but we use an empty transformed class to represent removed resources, as transforming a class removes it from the original archive - Map> removed = new HashMap<>(); + Map> removed = new HashMap<>(); for (Map.Entry> entry : classLoadingConfig.removedResources.entrySet()) { - removed.put(new AppArtifactKey(entry.getKey().split(":")), entry.getValue()); + removed.put(new GACT(entry.getKey().split(":")), entry.getValue()); } for (RemovedResourceBuildItem i : removedResourceBuildItems) { removed.computeIfAbsent(i.getArtifact(), k -> new HashSet<>()).addAll(i.getResources()); } if (!removed.isEmpty()) { - for (AppDependency i : curateOutcomeBuildItem.getEffectiveModel().getUserDependencies()) { - Set filtered = removed.remove(i.getArtifact().getKey()); + for (ResolvedDependency i : curateOutcomeBuildItem.getApplicationModel().getRuntimeDependencies()) { + Set filtered = removed.remove(i.getKey()); if (filtered != null) { - for (Path path : i.getArtifact().getPaths()) { + for (Path path : i.getResolvedPaths()) { transformedClassesByJar.computeIfAbsent(path, s -> new HashSet<>()) .addAll(filtered.stream() .map(file -> new TransformedClassesBuildItem.TransformedClass(null, null, file, false)) diff --git a/core/deployment/src/main/java/io/quarkus/deployment/util/ArtifactInfoUtil.java b/core/deployment/src/main/java/io/quarkus/deployment/util/ArtifactInfoUtil.java index 84f57bfed31bc..db2ef3ebfc141 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/util/ArtifactInfoUtil.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/util/ArtifactInfoUtil.java @@ -14,8 +14,8 @@ import java.util.Optional; import java.util.Properties; -import io.quarkus.bootstrap.model.AppDependency; import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem; +import io.quarkus.maven.dependency.ResolvedDependency; public final class ArtifactInfoUtil { @@ -56,22 +56,22 @@ public static Map.Entry groupIdAndArtifactId(Class clazz, } else if (curateOutcomeBuildItem != null) { // this is needed only for QuarkusDevModeTest inside Quarkus where the class is read from the corresponding directory Path path = Paths.get(codeLocation.toURI()); - for (AppDependency i : curateOutcomeBuildItem.getEffectiveModel().getFullDeploymentDeps()) { - for (Path p : i.getArtifact().getPaths()) { + for (ResolvedDependency i : curateOutcomeBuildItem.getApplicationModel().getDependencies()) { + for (Path p : i.getResolvedPaths()) { if (path.equals(p)) { - String artifactId = i.getArtifact().getArtifactId(); + String artifactId = i.getArtifactId(); if (artifactId.endsWith(DEPLOYMENT)) { artifactId = artifactId.substring(0, artifactId.length() - DEPLOYMENT.length()); } - return new AbstractMap.SimpleEntry<>(i.getArtifact().getGroupId(), artifactId); + return new AbstractMap.SimpleEntry<>(i.getGroupId(), artifactId); } } } return new AbstractMap.SimpleEntry<>("unspecified", "unspecified"); } else if ("file".equals(codeLocation.getProtocol())) { // E.g. /quarkus/extensions/arc/deployment/target/classes/io/quarkus/arc/deployment/devconsole - // This can happen if you run an example app in dev mode + // This can happen if you run an example app in dev mode // and this app is part of a multi-module project which also declares the extension // Just try to locate the pom.properties file in the target/maven-archiver directory // Note that this hack will not work if addMavenDescriptor=false or if the pomPropertiesFile is overriden diff --git a/core/deployment/src/main/java/io/quarkus/deployment/util/WebJarUtil.java b/core/deployment/src/main/java/io/quarkus/deployment/util/WebJarUtil.java index 94b686923613a..50fb048e1f0c4 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/util/WebJarUtil.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/util/WebJarUtil.java @@ -32,14 +32,13 @@ import org.eclipse.microprofile.config.ConfigProvider; import org.jboss.logging.Logger; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppDependency; -import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.bootstrap.util.IoUtils; import io.quarkus.builder.Version; import io.quarkus.deployment.builditem.LaunchModeBuildItem; import io.quarkus.deployment.builditem.LiveReloadBuildItem; import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem; +import io.quarkus.maven.dependency.ResolvedDependency; +import io.quarkus.paths.PathCollection; import io.quarkus.runtime.LaunchMode; import io.smallrye.common.io.jar.JarFiles; @@ -61,7 +60,7 @@ private WebJarUtil() { public static void hotReloadBrandingChanges(CurateOutcomeBuildItem curateOutcomeBuildItem, LaunchModeBuildItem launchMode, - AppArtifact resourcesArtifact, + ResolvedDependency resourcesArtifact, Set hotReloadChanges) throws IOException { hotReloadBrandingChanges(curateOutcomeBuildItem, launchMode, resourcesArtifact, hotReloadChanges, true); @@ -69,7 +68,7 @@ public static void hotReloadBrandingChanges(CurateOutcomeBuildItem curateOutcome public static void hotReloadBrandingChanges(CurateOutcomeBuildItem curateOutcomeBuildItem, LaunchModeBuildItem launchMode, - AppArtifact resourcesArtifact, + ResolvedDependency resourcesArtifact, Set hotReloadChanges, boolean useDefaultQuarkusBranding) throws IOException { @@ -78,16 +77,16 @@ public static void hotReloadBrandingChanges(CurateOutcomeBuildItem curateOutcome for (String changedResource : hotReloadChanges) { if (changedResource.startsWith(CUSTOM_MEDIA_FOLDER)) { ClassLoader classLoader = WebJarUtil.class.getClassLoader(); - AppArtifact userApplication = curateOutcomeBuildItem.getEffectiveModel().getAppArtifact(); + final ResolvedDependency userApplication = curateOutcomeBuildItem.getApplicationModel().getAppArtifact(); String fileName = changedResource.replace(CUSTOM_MEDIA_FOLDER, ""); // a branding file has changed ! String modulename = getModuleOverrideName(resourcesArtifact, fileName); if (IGNORE_LIST.contains(fileName) - && isOverride(userApplication.getPaths(), classLoader, fileName, modulename)) { + && isOverride(userApplication.getResolvedPaths(), classLoader, fileName, modulename)) { Path deploymentPath = createResourcesDirectory(userApplication, resourcesArtifact); Path filePath = deploymentPath.resolve(fileName); try (InputStream override = insertVariables(userApplication, - getOverride(userApplication.getPaths(), classLoader, + getOverride(userApplication.getResolvedPaths(), classLoader, fileName, modulename, useDefaultQuarkusBranding), fileName)) { if (override != null) { @@ -103,7 +102,7 @@ && isOverride(userApplication.getPaths(), classLoader, fileName, modulename)) { public static Path copyResourcesForDevOrTest(LiveReloadBuildItem liveReloadBuildItem, CurateOutcomeBuildItem curateOutcomeBuildItem, LaunchModeBuildItem launchMode, - AppArtifact resourcesArtifact, + ResolvedDependency resourcesArtifact, String rootFolderInJar) throws IOException { return copyResourcesForDevOrTest(liveReloadBuildItem, curateOutcomeBuildItem, launchMode, resourcesArtifact, @@ -113,13 +112,13 @@ public static Path copyResourcesForDevOrTest(LiveReloadBuildItem liveReloadBuild public static Path copyResourcesForDevOrTest(LiveReloadBuildItem liveReloadBuildItem, CurateOutcomeBuildItem curateOutcomeBuildItem, LaunchModeBuildItem launchMode, - AppArtifact resourcesArtifact, + ResolvedDependency resourcesArtifact, String rootFolderInJar, boolean useDefaultQuarkusBranding) throws IOException { rootFolderInJar = normalizeRootFolderInJar(rootFolderInJar); - AppArtifact userApplication = curateOutcomeBuildItem.getEffectiveModel().getAppArtifact(); + final ResolvedDependency userApplication = curateOutcomeBuildItem.getApplicationModel().getAppArtifact(); Path deploymentPath = createResourcesDirectory(userApplication, resourcesArtifact); @@ -133,7 +132,7 @@ public static Path copyResourcesForDevOrTest(LiveReloadBuildItem liveReloadBuild if (isEmpty(deploymentPath)) { ClassLoader classLoader = WebJarUtil.class.getClassLoader(); - for (Path p : resourcesArtifact.getPaths()) { + for (Path p : resourcesArtifact.getResolvedPaths()) { File artifactFile = p.toFile(); if (artifactFile.isFile()) { // case of a jar file @@ -151,9 +150,10 @@ public static Path copyResourcesForDevOrTest(LiveReloadBuildItem liveReloadBuild jarFile.getInputStream(entry), fileName)) { String modulename = getModuleOverrideName(resourcesArtifact, fileName); if (IGNORE_LIST.contains(fileName) - && isOverride(userApplication.getPaths(), classLoader, fileName, modulename)) { + && isOverride(userApplication.getResolvedPaths(), classLoader, fileName, + modulename)) { try (InputStream override = insertVariables(userApplication, - getOverride(userApplication.getPaths(), classLoader, + getOverride(userApplication.getResolvedPaths(), classLoader, fileName, modulename, useDefaultQuarkusBranding), fileName)) { if (override == null) { @@ -193,9 +193,9 @@ public FileVisitResult visitFile(final Path file, String modulename = getModuleOverrideName(resourcesArtifact, fileName); if (IGNORE_LIST.contains(fileName) - && isOverride(userApplication.getPaths(), classLoader, fileName, modulename)) { + && isOverride(userApplication.getResolvedPaths(), classLoader, fileName, modulename)) { try (InputStream override = insertVariables(userApplication, - getOverride(userApplication.getPaths(), classLoader, + getOverride(userApplication.getResolvedPaths(), classLoader, fileName, modulename, useDefaultQuarkusBranding), fileName)) { if (override == null) { @@ -218,17 +218,17 @@ && isOverride(userApplication.getPaths(), classLoader, fileName, modulename)) { } public static Map copyResourcesForProduction(CurateOutcomeBuildItem curateOutcomeBuildItem, - AppArtifact artifact, + ResolvedDependency artifact, String rootFolderInJar) throws IOException { return copyResourcesForProduction(curateOutcomeBuildItem, artifact, rootFolderInJar, true); } public static Map copyResourcesForProduction(CurateOutcomeBuildItem curateOutcomeBuildItem, - AppArtifact artifact, + ResolvedDependency artifact, String rootFolderInJar, boolean useDefaultQuarkusBranding) throws IOException { rootFolderInJar = normalizeRootFolderInJar(rootFolderInJar); - AppArtifact userApplication = curateOutcomeBuildItem.getEffectiveModel().getAppArtifact(); + final ResolvedDependency userApplication = curateOutcomeBuildItem.getApplicationModel().getAppArtifact(); Map map = new HashMap<>(); //we are including in a production artifact @@ -236,7 +236,7 @@ public static Map copyResourcesForProduction(CurateOutcomeBuildI //we could do this for dev mode as well but then we need to extract them every time ClassLoader classLoader = WebJarUtil.class.getClassLoader(); - for (Path p : artifact.getPaths()) { + for (Path p : artifact.getResolvedPaths()) { File artifactFile = p.toFile(); try (JarFile jarFile = JarFiles.create(artifactFile)) { Enumeration entries = jarFile.entries(); @@ -249,9 +249,9 @@ public static Map copyResourcesForProduction(CurateOutcomeBuildI byte[] content = null; String modulename = getModuleOverrideName(artifact, filename); if (IGNORE_LIST.contains(filename) - && isOverride(userApplication.getPaths(), classLoader, filename, modulename)) { + && isOverride(userApplication.getResolvedPaths(), classLoader, filename, modulename)) { try (InputStream resourceAsStream = insertVariables(userApplication, - getOverride(userApplication.getPaths(), classLoader, + getOverride(userApplication.getResolvedPaths(), classLoader, filename, modulename, useDefaultQuarkusBranding), filename)) { if (resourceAsStream != null) { @@ -300,30 +300,32 @@ public static String updateUrl(String original, String path, String lineStartsWi return original; } - public static AppArtifact getAppArtifact(CurateOutcomeBuildItem curateOutcomeBuildItem, String groupId, String artifactId) { - for (AppDependency dep : curateOutcomeBuildItem.getEffectiveModel().getFullDeploymentDeps()) { - if (dep.getArtifact().getArtifactId().equals(artifactId) - && dep.getArtifact().getGroupId().equals(groupId)) { - return dep.getArtifact(); + public static ResolvedDependency getAppArtifact(CurateOutcomeBuildItem curateOutcomeBuildItem, String groupId, + String artifactId) { + for (ResolvedDependency dep : curateOutcomeBuildItem.getApplicationModel().getDependencies()) { + if (dep.getArtifactId().equals(artifactId) + && dep.getGroupId().equals(groupId)) { + return dep; } } throw new RuntimeException("Could not find artifact " + groupId + ":" + artifactId + " among the application dependencies"); } - private static void copyFile(AppArtifact appArtifact, Path file, String fileName, Path targetFilePath) throws IOException { + private static void copyFile(ResolvedDependency appArtifact, Path file, String fileName, Path targetFilePath) + throws IOException { InputStream providedContent = pathToStream(file).orElse(null); if (providedContent != null) { Files.copy(insertVariables(appArtifact, providedContent, fileName), targetFilePath); } } - private static String getModuleOverrideName(AppArtifact artifact, String filename) { + private static String getModuleOverrideName(ResolvedDependency artifact, String filename) { String type = filename.substring(filename.lastIndexOf(".")); return artifact.getArtifactId() + type; } - private static InputStream getOverride(PathsCollection paths, ClassLoader classLoader, String filename, String modulename, + private static InputStream getOverride(PathCollection paths, ClassLoader classLoader, String filename, String modulename, boolean useDefaultQuarkusBranding) throws IOException { @@ -336,7 +338,8 @@ private static InputStream getOverride(PathsCollection paths, ClassLoader classL return overrideStream; } - private static InputStream insertVariables(AppArtifact appArtifact, InputStream is, String filename) throws IOException { + private static InputStream insertVariables(ResolvedDependency appArtifact, InputStream is, String filename) + throws IOException { // Allow replacement of certain values in css if (filename.endsWith(CSS)) { Config c = ConfigProvider.getConfig(); @@ -355,7 +358,7 @@ private static InputStream insertVariables(AppArtifact appArtifact, InputStream return is; } - private static InputStream getCustomOverride(PathsCollection paths, String filename, String modulename) { + private static InputStream getCustomOverride(PathCollection paths, String filename, String modulename) { // Check if the developer supplied the files Path customOverridePath = getCustomOverridePath(paths, filename, modulename); if (customOverridePath != null) { @@ -364,7 +367,7 @@ private static InputStream getCustomOverride(PathsCollection paths, String filen return null; } - private static Path getCustomOverridePath(PathsCollection paths, String filename, String modulename) { + private static Path getCustomOverridePath(PathCollection paths, String filename, String modulename) { // First check if the developer supplied the files Iterator iterator = paths.iterator(); @@ -395,7 +398,7 @@ private static InputStream getQuarkusOverride(ClassLoader classLoader, String fi return null; } - private static boolean isOverride(PathsCollection paths, ClassLoader classLoader, String filename, String modulename) { + private static boolean isOverride(PathCollection paths, ClassLoader classLoader, String filename, String modulename) { // Check if quarkus override this. return isQuarkusOverride(classLoader, filename, modulename) || isCustomOverride(paths, filename, modulename); } @@ -406,7 +409,7 @@ private static boolean isQuarkusOverride(ClassLoader classLoader, String filenam || fileExistInClasspath(classLoader, CUSTOM_MEDIA_FOLDER + filename); } - private static boolean isCustomOverride(PathsCollection paths, String filename, String modulename) { + private static boolean isCustomOverride(PathCollection paths, String filename, String modulename) { Iterator iterator = paths.iterator(); while (iterator.hasNext()) { Path root = iterator.next(); @@ -457,10 +460,11 @@ private static void createFile(InputStream source, Path targetFile) throws IOExc } } - public static Path createResourcesDirectory(AppArtifact userApplication, AppArtifact resourcesArtifact) { + public static Path createResourcesDirectory(ResolvedDependency userApplication, ResolvedDependency resourcesArtifact) { try { - Path path = Paths.get(TMP_DIR, "quarkus", userApplication.getGroupId(), userApplication.getArtifactId(), - resourcesArtifact.getGroupId(), resourcesArtifact.getArtifactId(), resourcesArtifact.getVersion()); + Path path = Paths.get(TMP_DIR, "quarkus", userApplication.getGroupId(), + userApplication.getArtifactId(), resourcesArtifact.getGroupId(), + resourcesArtifact.getArtifactId(), resourcesArtifact.getVersion()); if (!Files.exists(path)) { Files.createDirectories(path); diff --git a/core/deployment/src/main/java/io/quarkus/runner/bootstrap/AugmentActionImpl.java b/core/deployment/src/main/java/io/quarkus/runner/bootstrap/AugmentActionImpl.java index 9693eb1700819..966652ab95212 100644 --- a/core/deployment/src/main/java/io/quarkus/runner/bootstrap/AugmentActionImpl.java +++ b/core/deployment/src/main/java/io/quarkus/runner/bootstrap/AugmentActionImpl.java @@ -311,7 +311,7 @@ public BuildResult runCustomAction(Consumer chainBuild, Consu chainBuilder.setClassLoader(classLoader); ExtensionLoader.loadStepsFrom(classLoader, new Properties(), - curatedApplication.getAppModel(), launchMode, devModeType, null) + curatedApplication.getApplicationModel(), launchMode, devModeType, null) .accept(chainBuilder); chainBuilder.loadProviders(classLoader); @@ -375,7 +375,7 @@ private BuildResult runAugment(boolean firstRun, Set changedResources, .setTargetDir(quarkusBootstrap.getTargetDirectory()) .setDeploymentClassLoader(deploymentClassLoader) .setBuildSystemProperties(quarkusBootstrap.getBuildSystemProperties()) - .setEffectiveModel(curatedApplication.getAppModel()); + .setEffectiveModel(curatedApplication.getApplicationModel()); if (quarkusBootstrap.getBaseName() != null) { builder.setBaseName(quarkusBootstrap.getBaseName()); } @@ -401,7 +401,7 @@ private BuildResult runAugment(boolean firstRun, Set changedResources, //but we only need to add it to the additional app archives //if it is forced as an app archive if (i.isForceApplicationArchive()) { - builder.addAdditionalApplicationArchive(i.getArchivePath()); + builder.addAdditionalApplicationArchive(i.getResolvedPaths()); } } builder.excludeFromIndexing(quarkusBootstrap.getExcludeFromClassPath()); diff --git a/core/deployment/src/test/java/io/quarkus/deployment/conditionaldeps/CascadingConditionalDependenciesTest.java b/core/deployment/src/test/java/io/quarkus/deployment/conditionaldeps/CascadingConditionalDependenciesTest.java index 2ce27781e6820..b530e413a6a2e 100644 --- a/core/deployment/src/test/java/io/quarkus/deployment/conditionaldeps/CascadingConditionalDependenciesTest.java +++ b/core/deployment/src/test/java/io/quarkus/deployment/conditionaldeps/CascadingConditionalDependenciesTest.java @@ -3,14 +3,15 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.HashSet; -import java.util.List; import java.util.Set; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppDependency; import io.quarkus.bootstrap.resolver.TsArtifact; import io.quarkus.bootstrap.resolver.TsQuarkusExt; import io.quarkus.deployment.runnerjar.ExecutableOutputOutcomeTestBase; +import io.quarkus.maven.dependency.ArtifactDependency; +import io.quarkus.maven.dependency.Dependency; +import io.quarkus.maven.dependency.DependencyFlags; +import io.quarkus.maven.dependency.GACTV; public class CascadingConditionalDependenciesTest extends ExecutableOutputOutcomeTestBase { @@ -65,26 +66,26 @@ protected TsArtifact modelApp() { } @Override - protected void assertDeploymentDeps(List deploymentDeps) throws Exception { - final Set expected = new HashSet<>(); - expected.add(new AppDependency( - new AppArtifact(TsArtifact.DEFAULT_GROUP_ID, "ext-c-deployment", TsArtifact.DEFAULT_VERSION), "compile", - AppDependency.DEPLOYMENT_CP_FLAG)); - expected.add(new AppDependency( - new AppArtifact(TsArtifact.DEFAULT_GROUP_ID, "ext-a-deployment", TsArtifact.DEFAULT_VERSION), "compile", - AppDependency.DEPLOYMENT_CP_FLAG)); - expected.add(new AppDependency( - new AppArtifact(TsArtifact.DEFAULT_GROUP_ID, "ext-b-deployment", TsArtifact.DEFAULT_VERSION), "runtime", - AppDependency.DEPLOYMENT_CP_FLAG)); - expected.add(new AppDependency( - new AppArtifact(TsArtifact.DEFAULT_GROUP_ID, "ext-d-deployment", TsArtifact.DEFAULT_VERSION), "runtime", - AppDependency.DEPLOYMENT_CP_FLAG)); - expected.add(new AppDependency( - new AppArtifact(TsArtifact.DEFAULT_GROUP_ID, "ext-e-deployment", TsArtifact.DEFAULT_VERSION), "compile", - AppDependency.DEPLOYMENT_CP_FLAG)); - expected.add(new AppDependency( - new AppArtifact(TsArtifact.DEFAULT_GROUP_ID, "ext-f-deployment", TsArtifact.DEFAULT_VERSION), "runtime", - AppDependency.DEPLOYMENT_CP_FLAG)); - assertEquals(expected, new HashSet<>(deploymentDeps)); + protected void assertDeploymentDeps(Set deploymentDeps) throws Exception { + final Set expected = new HashSet<>(); + expected.add(new ArtifactDependency( + new GACTV(TsArtifact.DEFAULT_GROUP_ID, "ext-c-deployment", TsArtifact.DEFAULT_VERSION), "compile", + DependencyFlags.DEPLOYMENT_CP)); + expected.add(new ArtifactDependency( + new GACTV(TsArtifact.DEFAULT_GROUP_ID, "ext-a-deployment", TsArtifact.DEFAULT_VERSION), "compile", + DependencyFlags.DEPLOYMENT_CP)); + expected.add(new ArtifactDependency( + new GACTV(TsArtifact.DEFAULT_GROUP_ID, "ext-b-deployment", TsArtifact.DEFAULT_VERSION), "runtime", + DependencyFlags.DEPLOYMENT_CP)); + expected.add(new ArtifactDependency( + new GACTV(TsArtifact.DEFAULT_GROUP_ID, "ext-d-deployment", TsArtifact.DEFAULT_VERSION), "runtime", + DependencyFlags.DEPLOYMENT_CP)); + expected.add(new ArtifactDependency( + new GACTV(TsArtifact.DEFAULT_GROUP_ID, "ext-e-deployment", TsArtifact.DEFAULT_VERSION), "compile", + DependencyFlags.DEPLOYMENT_CP)); + expected.add(new ArtifactDependency( + new GACTV(TsArtifact.DEFAULT_GROUP_ID, "ext-f-deployment", TsArtifact.DEFAULT_VERSION), "runtime", + DependencyFlags.DEPLOYMENT_CP)); + assertEquals(expected, deploymentDeps); } } diff --git a/core/deployment/src/test/java/io/quarkus/deployment/conditionaldeps/ConditionalDependencyWithSingleConditionTest.java b/core/deployment/src/test/java/io/quarkus/deployment/conditionaldeps/ConditionalDependencyWithSingleConditionTest.java index edf1d892fb095..aaab4037b90a0 100644 --- a/core/deployment/src/test/java/io/quarkus/deployment/conditionaldeps/ConditionalDependencyWithSingleConditionTest.java +++ b/core/deployment/src/test/java/io/quarkus/deployment/conditionaldeps/ConditionalDependencyWithSingleConditionTest.java @@ -3,15 +3,17 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.HashSet; -import java.util.List; import java.util.Set; +import java.util.stream.Collectors; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppDependency; -import io.quarkus.bootstrap.model.AppModel; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.resolver.TsArtifact; import io.quarkus.bootstrap.resolver.TsQuarkusExt; import io.quarkus.deployment.runnerjar.ExecutableOutputOutcomeTestBase; +import io.quarkus.maven.dependency.ArtifactDependency; +import io.quarkus.maven.dependency.Dependency; +import io.quarkus.maven.dependency.DependencyFlags; +import io.quarkus.maven.dependency.GACTV; public class ConditionalDependencyWithSingleConditionTest extends ExecutableOutputOutcomeTestBase { @@ -39,18 +41,20 @@ protected TsArtifact modelApp() { } @Override - protected void assertAppModel(AppModel appModel) throws Exception { - final List deploymentDeps = appModel.getDeploymentDependencies(); - final Set expected = new HashSet<>(); - expected.add(new AppDependency( - new AppArtifact(TsArtifact.DEFAULT_GROUP_ID, "ext-c-deployment", TsArtifact.DEFAULT_VERSION), "compile", - AppDependency.DEPLOYMENT_CP_FLAG)); - expected.add(new AppDependency( - new AppArtifact(TsArtifact.DEFAULT_GROUP_ID, "ext-a-deployment", TsArtifact.DEFAULT_VERSION), "compile", - AppDependency.DEPLOYMENT_CP_FLAG)); - expected.add(new AppDependency( - new AppArtifact(TsArtifact.DEFAULT_GROUP_ID, "ext-b-deployment", TsArtifact.DEFAULT_VERSION), "runtime", - AppDependency.DEPLOYMENT_CP_FLAG)); - assertEquals(expected, new HashSet<>(deploymentDeps)); + protected void assertAppModel(ApplicationModel appModel) throws Exception { + final Set deploymentDeps = appModel.getDependencies().stream() + .filter(d -> d.isDeploymentCp() && !d.isRuntimeCp()).map(d -> new ArtifactDependency(d)) + .collect(Collectors.toSet()); + final Set expected = new HashSet<>(); + expected.add(new ArtifactDependency( + new GACTV(TsArtifact.DEFAULT_GROUP_ID, "ext-c-deployment", TsArtifact.DEFAULT_VERSION), "compile", + DependencyFlags.DEPLOYMENT_CP)); + expected.add(new ArtifactDependency( + new GACTV(TsArtifact.DEFAULT_GROUP_ID, "ext-a-deployment", TsArtifact.DEFAULT_VERSION), "compile", + DependencyFlags.DEPLOYMENT_CP)); + expected.add(new ArtifactDependency( + new GACTV(TsArtifact.DEFAULT_GROUP_ID, "ext-b-deployment", TsArtifact.DEFAULT_VERSION), "runtime", + DependencyFlags.DEPLOYMENT_CP)); + assertEquals(expected, deploymentDeps); } } diff --git a/core/deployment/src/test/java/io/quarkus/deployment/conditionaldeps/ConditionalDependencyWithTwoConditionsTest.java b/core/deployment/src/test/java/io/quarkus/deployment/conditionaldeps/ConditionalDependencyWithTwoConditionsTest.java index 413dd7c5f4622..3e0cc7c22774a 100644 --- a/core/deployment/src/test/java/io/quarkus/deployment/conditionaldeps/ConditionalDependencyWithTwoConditionsTest.java +++ b/core/deployment/src/test/java/io/quarkus/deployment/conditionaldeps/ConditionalDependencyWithTwoConditionsTest.java @@ -3,14 +3,15 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.HashSet; -import java.util.List; import java.util.Set; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppDependency; import io.quarkus.bootstrap.resolver.TsArtifact; import io.quarkus.bootstrap.resolver.TsQuarkusExt; import io.quarkus.deployment.runnerjar.ExecutableOutputOutcomeTestBase; +import io.quarkus.maven.dependency.ArtifactDependency; +import io.quarkus.maven.dependency.Dependency; +import io.quarkus.maven.dependency.DependencyFlags; +import io.quarkus.maven.dependency.GACTV; public class ConditionalDependencyWithTwoConditionsTest extends ExecutableOutputOutcomeTestBase { @@ -41,20 +42,20 @@ protected TsArtifact modelApp() { } @Override - protected void assertDeploymentDeps(List deploymentDeps) throws Exception { - final Set expected = new HashSet<>(); - expected.add(new AppDependency( - new AppArtifact(TsArtifact.DEFAULT_GROUP_ID, "ext-c-deployment", TsArtifact.DEFAULT_VERSION), "compile", - AppDependency.DEPLOYMENT_CP_FLAG)); - expected.add(new AppDependency( - new AppArtifact(TsArtifact.DEFAULT_GROUP_ID, "ext-a-deployment", TsArtifact.DEFAULT_VERSION), "compile", - AppDependency.DEPLOYMENT_CP_FLAG)); - expected.add(new AppDependency( - new AppArtifact(TsArtifact.DEFAULT_GROUP_ID, "ext-b-deployment", TsArtifact.DEFAULT_VERSION), "runtime", - AppDependency.DEPLOYMENT_CP_FLAG)); - expected.add(new AppDependency( - new AppArtifact(TsArtifact.DEFAULT_GROUP_ID, "ext-d-deployment", TsArtifact.DEFAULT_VERSION), "compile", - AppDependency.DEPLOYMENT_CP_FLAG)); - assertEquals(expected, new HashSet<>(deploymentDeps)); + protected void assertDeploymentDeps(Set deploymentDeps) throws Exception { + final Set expected = new HashSet<>(); + expected.add(new ArtifactDependency( + new GACTV(TsArtifact.DEFAULT_GROUP_ID, "ext-c-deployment", TsArtifact.DEFAULT_VERSION), "compile", + DependencyFlags.DEPLOYMENT_CP)); + expected.add(new ArtifactDependency( + new GACTV(TsArtifact.DEFAULT_GROUP_ID, "ext-a-deployment", TsArtifact.DEFAULT_VERSION), "compile", + DependencyFlags.DEPLOYMENT_CP)); + expected.add(new ArtifactDependency( + new GACTV(TsArtifact.DEFAULT_GROUP_ID, "ext-b-deployment", TsArtifact.DEFAULT_VERSION), "runtime", + DependencyFlags.DEPLOYMENT_CP)); + expected.add(new ArtifactDependency( + new GACTV(TsArtifact.DEFAULT_GROUP_ID, "ext-d-deployment", TsArtifact.DEFAULT_VERSION), "compile", + DependencyFlags.DEPLOYMENT_CP)); + assertEquals(expected, deploymentDeps); } } diff --git a/core/deployment/src/test/java/io/quarkus/deployment/conditionaldeps/UnsatisfiedConditionalDependencyWithTwoConditionsTest.java b/core/deployment/src/test/java/io/quarkus/deployment/conditionaldeps/UnsatisfiedConditionalDependencyWithTwoConditionsTest.java index bb95bab51d86f..ea93ac2ae9cb6 100644 --- a/core/deployment/src/test/java/io/quarkus/deployment/conditionaldeps/UnsatisfiedConditionalDependencyWithTwoConditionsTest.java +++ b/core/deployment/src/test/java/io/quarkus/deployment/conditionaldeps/UnsatisfiedConditionalDependencyWithTwoConditionsTest.java @@ -3,14 +3,15 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.HashSet; -import java.util.List; import java.util.Set; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppDependency; import io.quarkus.bootstrap.resolver.TsArtifact; import io.quarkus.bootstrap.resolver.TsQuarkusExt; import io.quarkus.deployment.runnerjar.ExecutableOutputOutcomeTestBase; +import io.quarkus.maven.dependency.ArtifactDependency; +import io.quarkus.maven.dependency.Dependency; +import io.quarkus.maven.dependency.DependencyFlags; +import io.quarkus.maven.dependency.GACTV; public class UnsatisfiedConditionalDependencyWithTwoConditionsTest extends ExecutableOutputOutcomeTestBase { @@ -38,14 +39,14 @@ protected TsArtifact modelApp() { } @Override - protected void assertDeploymentDeps(List deploymentDeps) throws Exception { - final Set expected = new HashSet<>(); - expected.add(new AppDependency( - new AppArtifact(TsArtifact.DEFAULT_GROUP_ID, "ext-c-deployment", TsArtifact.DEFAULT_VERSION), "compile", - AppDependency.DEPLOYMENT_CP_FLAG)); - expected.add(new AppDependency( - new AppArtifact(TsArtifact.DEFAULT_GROUP_ID, "ext-a-deployment", TsArtifact.DEFAULT_VERSION), "compile", - AppDependency.DEPLOYMENT_CP_FLAG)); - assertEquals(expected, new HashSet<>(deploymentDeps)); + protected void assertDeploymentDeps(Set deploymentDeps) throws Exception { + final Set expected = new HashSet<>(); + expected.add(new ArtifactDependency( + new GACTV(TsArtifact.DEFAULT_GROUP_ID, "ext-c-deployment", TsArtifact.DEFAULT_VERSION), "compile", + DependencyFlags.DEPLOYMENT_CP)); + expected.add(new ArtifactDependency( + new GACTV(TsArtifact.DEFAULT_GROUP_ID, "ext-a-deployment", TsArtifact.DEFAULT_VERSION), "compile", + DependencyFlags.DEPLOYMENT_CP)); + assertEquals(expected, deploymentDeps); } } diff --git a/core/deployment/src/test/java/io/quarkus/deployment/runnerjar/ExcludeExtensionDepsTest.java b/core/deployment/src/test/java/io/quarkus/deployment/runnerjar/ExcludeExtensionDepsTest.java index 634ef1ca41717..063733aa3f476 100644 --- a/core/deployment/src/test/java/io/quarkus/deployment/runnerjar/ExcludeExtensionDepsTest.java +++ b/core/deployment/src/test/java/io/quarkus/deployment/runnerjar/ExcludeExtensionDepsTest.java @@ -4,13 +4,16 @@ import java.util.HashSet; import java.util.Set; +import java.util.stream.Collectors; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppDependency; -import io.quarkus.bootstrap.model.AppModel; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.resolver.TsArtifact; import io.quarkus.bootstrap.resolver.TsDependency; import io.quarkus.bootstrap.resolver.TsQuarkusExt; +import io.quarkus.maven.dependency.ArtifactDependency; +import io.quarkus.maven.dependency.Dependency; +import io.quarkus.maven.dependency.DependencyFlags; +import io.quarkus.maven.dependency.GACTV; /** * The test allowing to make sure that if we exclude an extension from another extension, the @@ -66,30 +69,33 @@ protected TsArtifact modelApp() { } @Override - protected void assertAppModel(AppModel appModel) throws Exception { - final Set expectedDeployDeps = new HashSet<>(); + protected void assertAppModel(ApplicationModel appModel) throws Exception { + final Set expectedDeployDeps = new HashSet<>(); expectedDeployDeps - .add(new AppDependency(new AppArtifact("io.quarkus.bootstrap.test", "ext-b-deployment", "1"), "compile", - AppDependency.DEPLOYMENT_CP_FLAG)); - assertEquals(expectedDeployDeps, new HashSet<>(appModel.getDeploymentDependencies())); - final Set expectedRuntimeDeps = new HashSet<>(); - expectedRuntimeDeps.add(new AppDependency(new AppArtifact("io.quarkus.bootstrap.test", "ext-b", "1"), "compile", - AppDependency.DIRECT_FLAG, AppDependency.RUNTIME_EXTENSION_ARTIFACT_FLAG, AppDependency.RUNTIME_CP_FLAG, - AppDependency.DEPLOYMENT_CP_FLAG)); - expectedRuntimeDeps.add(new AppDependency(new AppArtifact("io.quarkus.bootstrap.test", "ext-b-dep-1", "1"), "compile", - AppDependency.RUNTIME_CP_FLAG, AppDependency.DEPLOYMENT_CP_FLAG)); - expectedRuntimeDeps.add(new AppDependency(new AppArtifact("io.quarkus.bootstrap.test", "ext-b-dep-2", "1"), "compile", - AppDependency.RUNTIME_CP_FLAG, AppDependency.DEPLOYMENT_CP_FLAG)); + .add(new ArtifactDependency(new GACTV("io.quarkus.bootstrap.test", "ext-b-deployment", "1"), "compile", + DependencyFlags.DEPLOYMENT_CP)); + assertEquals(expectedDeployDeps, appModel.getDependencies().stream().filter(d -> d.isDeploymentCp() && !d.isRuntimeCp()) + .map(d -> new ArtifactDependency(d)).collect(Collectors.toSet())); + final Set expectedRuntimeDeps = new HashSet<>(); + expectedRuntimeDeps.add(new ArtifactDependency(new GACTV("io.quarkus.bootstrap.test", "ext-b", "1"), "compile", + DependencyFlags.DIRECT, DependencyFlags.RUNTIME_EXTENSION_ARTIFACT, DependencyFlags.RUNTIME_CP, + DependencyFlags.DEPLOYMENT_CP)); + expectedRuntimeDeps.add(new ArtifactDependency(new GACTV("io.quarkus.bootstrap.test", "ext-b-dep-1", "1"), "compile", + DependencyFlags.RUNTIME_CP, DependencyFlags.DEPLOYMENT_CP)); + expectedRuntimeDeps.add(new ArtifactDependency(new GACTV("io.quarkus.bootstrap.test", "ext-b-dep-2", "1"), "compile", + DependencyFlags.RUNTIME_CP, DependencyFlags.DEPLOYMENT_CP)); expectedRuntimeDeps - .add(new AppDependency(new AppArtifact("io.quarkus.bootstrap.test", "ext-b-dep-trans-1", "1"), "compile", - AppDependency.RUNTIME_CP_FLAG, AppDependency.DEPLOYMENT_CP_FLAG)); + .add(new ArtifactDependency(new GACTV("io.quarkus.bootstrap.test", "ext-b-dep-trans-1", "1"), "compile", + DependencyFlags.RUNTIME_CP, DependencyFlags.DEPLOYMENT_CP)); expectedRuntimeDeps - .add(new AppDependency(new AppArtifact("io.quarkus.bootstrap.test", "ext-b-dep-trans-2", "1"), "compile", - AppDependency.RUNTIME_CP_FLAG, AppDependency.DEPLOYMENT_CP_FLAG)); - assertEquals(expectedRuntimeDeps, new HashSet<>(appModel.getUserDependencies())); - final Set expectedFullDeps = new HashSet<>(); + .add(new ArtifactDependency(new GACTV("io.quarkus.bootstrap.test", "ext-b-dep-trans-2", "1"), "compile", + DependencyFlags.RUNTIME_CP, DependencyFlags.DEPLOYMENT_CP)); + assertEquals(expectedRuntimeDeps, + appModel.getRuntimeDependencies().stream().map(d -> new ArtifactDependency(d)).collect(Collectors.toSet())); + final Set expectedFullDeps = new HashSet<>(); expectedFullDeps.addAll(expectedDeployDeps); expectedFullDeps.addAll(expectedRuntimeDeps); - assertEquals(expectedFullDeps, new HashSet<>(appModel.getFullDeploymentDeps())); + assertEquals(expectedFullDeps, + appModel.getDependencies().stream().map(d -> new ArtifactDependency(d)).collect(Collectors.toSet())); } } diff --git a/core/deployment/src/test/java/io/quarkus/deployment/runnerjar/ExcludeLibDepsTest.java b/core/deployment/src/test/java/io/quarkus/deployment/runnerjar/ExcludeLibDepsTest.java index 80537c2dd27ea..a02a07168b39a 100644 --- a/core/deployment/src/test/java/io/quarkus/deployment/runnerjar/ExcludeLibDepsTest.java +++ b/core/deployment/src/test/java/io/quarkus/deployment/runnerjar/ExcludeLibDepsTest.java @@ -4,13 +4,16 @@ import java.util.HashSet; import java.util.Set; +import java.util.stream.Collectors; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppDependency; -import io.quarkus.bootstrap.model.AppModel; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.resolver.TsArtifact; import io.quarkus.bootstrap.resolver.TsDependency; import io.quarkus.bootstrap.resolver.TsQuarkusExt; +import io.quarkus.maven.dependency.ArtifactDependency; +import io.quarkus.maven.dependency.Dependency; +import io.quarkus.maven.dependency.DependencyFlags; +import io.quarkus.maven.dependency.GACTV; /** * The test allowing to make sure that if we exclude a library from an extension, the @@ -58,30 +61,33 @@ protected TsArtifact modelApp() { } @Override - protected void assertAppModel(AppModel appModel) throws Exception { - final Set expectedDeployDeps = new HashSet<>(); + protected void assertAppModel(ApplicationModel appModel) throws Exception { + final Set expectedDeployDeps = new HashSet<>(); expectedDeployDeps - .add(new AppDependency(new AppArtifact("io.quarkus.bootstrap.test", "ext-a-deployment", "1"), "compile", - AppDependency.DEPLOYMENT_CP_FLAG)); - assertEquals(expectedDeployDeps, new HashSet<>(appModel.getDeploymentDependencies())); - final Set expectedRuntimeDeps = new HashSet<>(); - expectedRuntimeDeps.add(new AppDependency(new AppArtifact("io.quarkus.bootstrap.test", "ext-a", "1"), "compile", - AppDependency.DIRECT_FLAG, AppDependency.RUNTIME_EXTENSION_ARTIFACT_FLAG, AppDependency.RUNTIME_CP_FLAG, - AppDependency.DEPLOYMENT_CP_FLAG)); - expectedRuntimeDeps.add(new AppDependency(new AppArtifact("io.quarkus.bootstrap.test", "ext-a-dep-1", "1"), "compile", - AppDependency.RUNTIME_CP_FLAG, AppDependency.DEPLOYMENT_CP_FLAG)); - expectedRuntimeDeps.add(new AppDependency(new AppArtifact("io.quarkus.bootstrap.test", "ext-a-dep-2", "1"), "compile", - AppDependency.RUNTIME_CP_FLAG, AppDependency.DEPLOYMENT_CP_FLAG)); + .add(new ArtifactDependency(new GACTV("io.quarkus.bootstrap.test", "ext-a-deployment", "1"), "compile", + DependencyFlags.DEPLOYMENT_CP)); + assertEquals(expectedDeployDeps, appModel.getDependencies().stream().filter(d -> d.isDeploymentCp() && !d.isRuntimeCp()) + .map(d -> new ArtifactDependency(d)).collect(Collectors.toSet())); + final Set expectedRuntimeDeps = new HashSet<>(); + expectedRuntimeDeps.add(new ArtifactDependency(new GACTV("io.quarkus.bootstrap.test", "ext-a", "1"), "compile", + DependencyFlags.DIRECT, DependencyFlags.RUNTIME_EXTENSION_ARTIFACT, DependencyFlags.RUNTIME_CP, + DependencyFlags.DEPLOYMENT_CP)); + expectedRuntimeDeps.add(new ArtifactDependency(new GACTV("io.quarkus.bootstrap.test", "ext-a-dep-1", "1"), "compile", + DependencyFlags.RUNTIME_CP, DependencyFlags.DEPLOYMENT_CP)); + expectedRuntimeDeps.add(new ArtifactDependency(new GACTV("io.quarkus.bootstrap.test", "ext-a-dep-2", "1"), "compile", + DependencyFlags.RUNTIME_CP, DependencyFlags.DEPLOYMENT_CP)); expectedRuntimeDeps - .add(new AppDependency(new AppArtifact("io.quarkus.bootstrap.test", "ext-a-dep-trans-1", "1"), "compile", - AppDependency.RUNTIME_CP_FLAG, AppDependency.DEPLOYMENT_CP_FLAG)); + .add(new ArtifactDependency(new GACTV("io.quarkus.bootstrap.test", "ext-a-dep-trans-1", "1"), "compile", + DependencyFlags.RUNTIME_CP, DependencyFlags.DEPLOYMENT_CP)); expectedRuntimeDeps - .add(new AppDependency(new AppArtifact("io.quarkus.bootstrap.test", "ext-a-dep-trans-2", "1"), "compile", - AppDependency.RUNTIME_CP_FLAG, AppDependency.DEPLOYMENT_CP_FLAG)); - assertEquals(expectedRuntimeDeps, new HashSet<>(appModel.getUserDependencies())); - final Set expectedFullDeps = new HashSet<>(); + .add(new ArtifactDependency(new GACTV("io.quarkus.bootstrap.test", "ext-a-dep-trans-2", "1"), "compile", + DependencyFlags.RUNTIME_CP, DependencyFlags.DEPLOYMENT_CP)); + assertEquals(expectedRuntimeDeps, + appModel.getRuntimeDependencies().stream().map(d -> new ArtifactDependency(d)).collect(Collectors.toSet())); + final Set expectedFullDeps = new HashSet<>(); expectedFullDeps.addAll(expectedDeployDeps); expectedFullDeps.addAll(expectedRuntimeDeps); - assertEquals(expectedFullDeps, new HashSet<>(appModel.getFullDeploymentDeps())); + assertEquals(expectedFullDeps, + appModel.getDependencies().stream().map(d -> new ArtifactDependency(d)).collect(Collectors.toSet())); } } diff --git a/core/deployment/src/test/java/io/quarkus/deployment/runnerjar/ExecutableOutputOutcomeTestBase.java b/core/deployment/src/test/java/io/quarkus/deployment/runnerjar/ExecutableOutputOutcomeTestBase.java index fdb2ebe7b8737..afc35d87a2359 100644 --- a/core/deployment/src/test/java/io/quarkus/deployment/runnerjar/ExecutableOutputOutcomeTestBase.java +++ b/core/deployment/src/test/java/io/quarkus/deployment/runnerjar/ExecutableOutputOutcomeTestBase.java @@ -12,6 +12,7 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; @@ -20,6 +21,7 @@ import java.util.Set; import java.util.jar.Attributes; import java.util.jar.JarFile; +import java.util.stream.Collectors; import java.util.stream.Stream; import io.quarkus.bootstrap.BootstrapConstants; @@ -27,13 +29,14 @@ import io.quarkus.bootstrap.app.AugmentResult; import io.quarkus.bootstrap.app.CuratedApplication; import io.quarkus.bootstrap.app.QuarkusBootstrap; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppDependency; -import io.quarkus.bootstrap.model.AppModel; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.resolver.TsArtifact; import io.quarkus.bootstrap.resolver.TsArtifact.ContentProvider; import io.quarkus.bootstrap.resolver.TsDependency; import io.quarkus.bootstrap.resolver.update.CreatorOutcomeTestBase; +import io.quarkus.maven.dependency.ArtifactDependency; +import io.quarkus.maven.dependency.Dependency; +import io.quarkus.maven.dependency.ResolvedDependency; public abstract class ExecutableOutputOutcomeTestBase extends CreatorOutcomeTestBase { @@ -48,10 +51,10 @@ protected void addToExpectedLib(TsArtifact entry) { expectedLib.add(entry.getGroupId() + '.' + entry.getArtifactId() + '-' + entry.getVersion() + '.' + entry.getType()); } - protected void assertDeploymentDeps(List deploymentDeps) throws Exception { + protected void assertDeploymentDeps(Set deploymentDeps) throws Exception { } - protected void assertAppModel(AppModel appModel) throws Exception { + protected void assertAppModel(ApplicationModel appModel) throws Exception { } protected String[] expectedExtensionDependencies() { @@ -110,18 +113,19 @@ public Path getPath(Path workDir) throws IOException { return platformPropsDep; } - @SuppressWarnings("deprecation") @Override protected void testCreator(QuarkusBootstrap creator) throws Exception { System.setProperty("quarkus.package.type", "legacy-jar"); try { CuratedApplication curated = creator.bootstrap(); - assertAppModel(curated.getAppModel()); + assertAppModel(curated.getApplicationModel()); final String[] expectedExtensions = expectedExtensionDependencies(); if (expectedExtensions != null) { - assertExtensionDependencies(curated.getAppModel(), expectedExtensions); + assertExtensionDependencies(curated.getApplicationModel(), expectedExtensions); } - assertDeploymentDeps(curated.getAppModel().getDeploymentDependencies()); + assertDeploymentDeps( + curated.getApplicationModel().getDependencies().stream().filter(d -> d.isDeploymentCp() && !d.isRuntimeCp()) + .map(d -> new ArtifactDependency(d)).collect(Collectors.toSet())); AugmentAction action = curated.createAugmentor(); AugmentResult outcome = action.createProductionApplication(); @@ -194,24 +198,28 @@ protected void testCreator(QuarkusBootstrap creator) throws Exception { } } - @SuppressWarnings("deprecation") - private static void assertExtensionDependencies(AppModel appModel, String[] expectedExtensions) { - final Set expectedRuntime = new HashSet<>(expectedExtensions.length); - final Set expectedDeployment = new HashSet<>(expectedExtensions.length); + private static void assertExtensionDependencies(ApplicationModel appModel, String[] expectedExtensions) { + final Set expectedRuntime = new HashSet<>(expectedExtensions.length); + final Set expectedDeployment = new HashSet<>(expectedExtensions.length); for (String rtId : expectedExtensions) { - expectedRuntime.add(new AppArtifact(TsArtifact.DEFAULT_GROUP_ID, rtId, TsArtifact.DEFAULT_VERSION)); + expectedRuntime.add(TsArtifact.DEFAULT_GROUP_ID + ":" + rtId + "::jar:" + TsArtifact.DEFAULT_VERSION); expectedDeployment - .add(new AppArtifact(TsArtifact.DEFAULT_GROUP_ID, rtId + "-deployment", TsArtifact.DEFAULT_VERSION)); + .add(TsArtifact.DEFAULT_GROUP_ID + ":" + rtId + "-deployment" + "::jar:" + TsArtifact.DEFAULT_VERSION); } - for (AppDependency dep : appModel.getUserDependencies()) { - assertTrue(expectedRuntime.contains(dep.getArtifact()), dep.getArtifact().toString()); + final Collection rtDeps = appModel.getRuntimeDependencies(); + for (Dependency dep : rtDeps) { + final String coords = dep.toGACTVString(); + assertTrue(expectedRuntime.contains(coords), coords); } - assertEquals(expectedExtensions.length, appModel.getUserDependencies().size()); + assertEquals(expectedExtensions.length, rtDeps.size()); - for (AppDependency dep : appModel.getDeploymentDependencies()) { - assertTrue(expectedDeployment.contains(dep.getArtifact())); + final List deploymentOnly = appModel.getDependencies().stream() + .filter(d -> d.isDeploymentCp() && !d.isRuntimeCp()).collect(Collectors.toList()); + for (Dependency dep : deploymentOnly) { + final String coords = dep.toGACTVString(); + assertTrue(expectedDeployment.contains(coords), coords); } - assertEquals(expectedExtensions.length, appModel.getDeploymentDependencies().size()); + assertEquals(expectedExtensions.length, deploymentOnly.size()); } } diff --git a/core/deployment/src/test/java/io/quarkus/deployment/runnerjar/OptionalDepsTest.java b/core/deployment/src/test/java/io/quarkus/deployment/runnerjar/OptionalDepsTest.java index d3fbaca4ef03a..8aced19be0e78 100644 --- a/core/deployment/src/test/java/io/quarkus/deployment/runnerjar/OptionalDepsTest.java +++ b/core/deployment/src/test/java/io/quarkus/deployment/runnerjar/OptionalDepsTest.java @@ -3,14 +3,15 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.HashSet; -import java.util.List; import java.util.Set; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppDependency; import io.quarkus.bootstrap.resolver.TsArtifact; import io.quarkus.bootstrap.resolver.TsDependency; import io.quarkus.bootstrap.resolver.TsQuarkusExt; +import io.quarkus.maven.dependency.ArtifactDependency; +import io.quarkus.maven.dependency.Dependency; +import io.quarkus.maven.dependency.DependencyFlags; +import io.quarkus.maven.dependency.GACTV; public class OptionalDepsTest extends ExecutableOutputOutcomeTestBase { @@ -66,18 +67,19 @@ protected TsArtifact modelApp() { } @Override - protected void assertDeploymentDeps(List deploymentDeps) throws Exception { - final Set expected = new HashSet<>(); - expected.add(new AppDependency(new AppArtifact("io.quarkus.bootstrap.test", "ext-a-deployment", "1"), "compile", true, - AppDependency.DEPLOYMENT_CP_FLAG)); - expected.add( - new AppDependency(new AppArtifact("io.quarkus.bootstrap.test", "ext-b-deployment-dep", "1"), "compile", true, - AppDependency.DEPLOYMENT_CP_FLAG)); - expected.add(new AppDependency(new AppArtifact("io.quarkus.bootstrap.test", "ext-b-deployment", "1"), "compile", true, - AppDependency.DEPLOYMENT_CP_FLAG)); - expected.add( - new AppDependency(new AppArtifact("io.quarkus.bootstrap.test", "ext-d-deployment", "1"), "compile", false, - AppDependency.DEPLOYMENT_CP_FLAG)); - assertEquals(expected, new HashSet<>(deploymentDeps)); + protected void assertDeploymentDeps(Set deploymentDeps) throws Exception { + final Set expected = new HashSet<>(); + expected.add(new ArtifactDependency(new GACTV("io.quarkus.bootstrap.test", "ext-a-deployment", "1"), "compile", + DependencyFlags.OPTIONAL, + DependencyFlags.DEPLOYMENT_CP)); + expected.add(new ArtifactDependency(new GACTV("io.quarkus.bootstrap.test", "ext-b-deployment-dep", "1"), "compile", + DependencyFlags.OPTIONAL, + DependencyFlags.DEPLOYMENT_CP)); + expected.add(new ArtifactDependency(new GACTV("io.quarkus.bootstrap.test", "ext-b-deployment", "1"), "compile", + DependencyFlags.OPTIONAL, + DependencyFlags.DEPLOYMENT_CP)); + expected.add(new ArtifactDependency(new GACTV("io.quarkus.bootstrap.test", "ext-d-deployment", "1"), "compile", + DependencyFlags.DEPLOYMENT_CP)); + assertEquals(expected, deploymentDeps); } } diff --git a/core/deployment/src/test/java/io/quarkus/deployment/runnerjar/ProvidedExtensionDepsTest.java b/core/deployment/src/test/java/io/quarkus/deployment/runnerjar/ProvidedExtensionDepsTest.java index 86ab3e41fb15b..bad9b791d832c 100644 --- a/core/deployment/src/test/java/io/quarkus/deployment/runnerjar/ProvidedExtensionDepsTest.java +++ b/core/deployment/src/test/java/io/quarkus/deployment/runnerjar/ProvidedExtensionDepsTest.java @@ -3,14 +3,15 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.HashSet; -import java.util.List; import java.util.Set; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppDependency; import io.quarkus.bootstrap.resolver.TsArtifact; import io.quarkus.bootstrap.resolver.TsDependency; import io.quarkus.bootstrap.resolver.TsQuarkusExt; +import io.quarkus.maven.dependency.ArtifactDependency; +import io.quarkus.maven.dependency.Dependency; +import io.quarkus.maven.dependency.DependencyFlags; +import io.quarkus.maven.dependency.GACTV; public class ProvidedExtensionDepsTest extends ExecutableOutputOutcomeTestBase { @@ -41,12 +42,12 @@ protected TsArtifact modelApp() { } @Override - protected void assertDeploymentDeps(List deploymentDeps) throws Exception { - final Set expected = new HashSet<>(); - expected.add(new AppDependency(new AppArtifact("io.quarkus.bootstrap.test", "ext-a-deployment", "1"), "compile", - AppDependency.DEPLOYMENT_CP_FLAG)); - expected.add(new AppDependency(new AppArtifact("io.quarkus.bootstrap.test", "ext-a-deployment-dep", "1"), "compile", - AppDependency.DEPLOYMENT_CP_FLAG)); - assertEquals(expected, new HashSet<>(deploymentDeps)); + protected void assertDeploymentDeps(Set deploymentDeps) throws Exception { + final Set expected = new HashSet<>(); + expected.add(new ArtifactDependency(new GACTV("io.quarkus.bootstrap.test", "ext-a-deployment", "1"), "compile", + DependencyFlags.DEPLOYMENT_CP)); + expected.add(new ArtifactDependency(new GACTV("io.quarkus.bootstrap.test", "ext-a-deployment-dep", "1"), "compile", + DependencyFlags.DEPLOYMENT_CP)); + assertEquals(expected, deploymentDeps); } } diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/AppModelGradleResolver.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/AppModelGradleResolver.java index 0e1ccd52c6f43..9520b0404a920 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/AppModelGradleResolver.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/AppModelGradleResolver.java @@ -1,6 +1,7 @@ package io.quarkus.gradle; import java.nio.file.Path; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Set; @@ -13,74 +14,86 @@ import org.gradle.api.internal.artifacts.dependencies.DefaultDependencyArtifact; import org.gradle.api.internal.artifacts.dependencies.DefaultExternalModuleDependency; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppArtifactKey; -import io.quarkus.bootstrap.model.AppDependency; -import io.quarkus.bootstrap.model.AppModel; -import io.quarkus.bootstrap.model.gradle.QuarkusModel; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.resolver.AppModelResolver; import io.quarkus.bootstrap.resolver.AppModelResolverException; -import io.quarkus.bootstrap.util.QuarkusModelHelper; +import io.quarkus.maven.dependency.ArtifactCoords; +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.Dependency; +import io.quarkus.maven.dependency.GACTV; +import io.quarkus.maven.dependency.ResolvedArtifactDependency; +import io.quarkus.maven.dependency.ResolvedDependency; public class AppModelGradleResolver implements AppModelResolver { - private AppModel appModel; private final Project project; - private final QuarkusModel model; + private final ApplicationModel model; - public AppModelGradleResolver(Project project, QuarkusModel model) { + public AppModelGradleResolver(Project project, ApplicationModel model) { this.model = model; this.project = project; } @Override - public String getLatestVersion(AppArtifact appArtifact, String upToVersion, boolean inclusive) + public String getLatestVersion(ArtifactCoords appArtifact, String upToVersion, + boolean inclusive) throws AppModelResolverException { try { - return resolveArtifact(new AppArtifact(appArtifact.getGroupId(), appArtifact.getArtifactId(), - appArtifact.getClassifier(), appArtifact.getType(), - "[" + appArtifact.getVersion() + "," + upToVersion + (inclusive ? "]" : ")"))).getVersion(); + return resolveArtifact( + new GACTV(appArtifact.getGroupId(), appArtifact.getArtifactId(), + appArtifact.getClassifier(), appArtifact.getType(), + "[" + appArtifact.getVersion() + "," + upToVersion + (inclusive ? "]" : ")"))) + .getVersion(); } catch (AppModelResolverException e) { return null; } } @Override - public String getLatestVersionFromRange(AppArtifact appArtifact, String range) throws AppModelResolverException { + public String getLatestVersionFromRange(ArtifactCoords appArtifact, String range) + throws AppModelResolverException { try { - return resolveArtifact(new AppArtifact(appArtifact.getGroupId(), appArtifact.getArtifactId(), - appArtifact.getClassifier(), appArtifact.getType(), range)).getVersion(); + return resolveArtifact( + new GACTV(appArtifact.getGroupId(), appArtifact.getArtifactId(), + appArtifact.getClassifier(), appArtifact.getType(), range)).getVersion(); } catch (AppModelResolverException e) { return null; } } @Override - public String getNextVersion(AppArtifact appArtifact, String fromVersion, boolean fromVersionIncluded, String upToVersion, + public String getNextVersion(ArtifactCoords appArtifact, String fromVersion, + boolean fromVersionIncluded, String upToVersion, boolean upToVersionIncluded) throws AppModelResolverException { throw new UnsupportedOperationException(); } @Override - public List listLaterVersions(AppArtifact appArtifact, String upToVersion, boolean inclusive) + public List listLaterVersions(ArtifactCoords appArtifact, String upToVersion, + boolean inclusive) throws AppModelResolverException { throw new UnsupportedOperationException(); } @Override - public void relink(AppArtifact appArtifact, Path localPath) throws AppModelResolverException { + public void relink(ArtifactCoords artifact, Path localPath) + throws AppModelResolverException { } @Override - public Path resolve(AppArtifact appArtifact) throws AppModelResolverException { - return resolveArtifact(appArtifact).getPaths().getSinglePath(); + public ResolvedDependency resolve(ArtifactCoords appArtifact) throws AppModelResolverException { + return resolveArtifact(appArtifact); } - private AppArtifact resolveArtifact(AppArtifact appArtifact) throws AppModelResolverException { - if (appArtifact.isResolved()) { - return appArtifact; + private ResolvedDependency resolveArtifact( + ArtifactCoords appArtifact) throws AppModelResolverException { + if (ResolvedDependency.class.isAssignableFrom(appArtifact.getClass())) { + final ResolvedDependency resolved = (ResolvedDependency) appArtifact; + if (resolved.isResolved()) { + return resolved; + } } final DefaultDependencyArtifact dep = new DefaultDependencyArtifact(); dep.setExtension(appArtifact.getType()); @@ -108,48 +121,43 @@ private AppArtifact resolveArtifact(AppArtifact appArtifact) throws AppModelReso && (a.getClassifier() == null ? appArtifact.getClassifier() == null : a.getClassifier().equals(appArtifact.getClassifier())) && appArtifact.getGroupId().equals(a.getModuleVersion().getId().getGroup())) { - if (!appArtifact.getVersion().equals(a.getModuleVersion().getId().getVersion())) { - appArtifact = new AppArtifact(appArtifact.getGroupId(), appArtifact.getArtifactId(), - appArtifact.getClassifier(), appArtifact.getType(), a.getModuleVersion().getId().getVersion()); - } - appArtifact.setPath(a.getFile().toPath()); - break; + final String version = appArtifact.getVersion().equals(a.getModuleVersion().getId().getVersion()) + ? appArtifact.getVersion() + : a.getModuleVersion().getId().getVersion(); + return new ResolvedArtifactDependency(appArtifact.getGroupId(), appArtifact.getArtifactId(), + appArtifact.getClassifier(), appArtifact.getType(), version, a.getFile().toPath()); } } - - if (!appArtifact.isResolved()) { - throw new AppModelResolverException("Failed to resolve " + appArtifact); - } - return appArtifact; + throw new AppModelResolverException("Failed to resolve " + appArtifact); } @Override - public List resolveUserDependencies(AppArtifact appArtifact, List directDeps) { + public Collection resolveUserDependencies(ArtifactCoords appArtifact, + Collection directDeps) { return Collections.emptyList(); } @Override - public AppModel resolveModel(AppArtifact appArtifact) throws AppModelResolverException { - if (appModel != null) { - if (appModel.getAppArtifact().equals(appArtifact)) { - return appModel; - } else { - throw new AppModelResolverException( - "Requested artifact : " + appArtifact + ", does not match loaded model " + appModel.getAppArtifact()); - } + public ApplicationModel resolveModel(ArtifactCoords appArtifact) + throws AppModelResolverException { + if (model.getAppArtifact().toGACTVString().equals(appArtifact.toGACTVString())) { + return model; } - appModel = QuarkusModelHelper.convert(model, appArtifact); - return appModel; + throw new AppModelResolverException( + "Requested artifact " + appArtifact + " does not match loaded model " + model.getAppArtifact()); } @Override - public AppModel resolveModel(AppArtifact root, List deps) throws AppModelResolverException { + public ApplicationModel resolveModel(ArtifactCoords root, Collection deps) + throws AppModelResolverException { throw new UnsupportedOperationException(); } @Override - public AppModel resolveManagedModel(AppArtifact appArtifact, List directDeps, AppArtifact managingProject, - Set localProjects) + public ApplicationModel resolveManagedModel(ArtifactCoords appArtifact, + Collection directDeps, + ArtifactCoords managingProject, + Set localProjects) throws AppModelResolverException { return resolveModel(appArtifact); } diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/QuarkusPlugin.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/QuarkusPlugin.java index f30598226d53b..3429ca47f573a 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/QuarkusPlugin.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/QuarkusPlugin.java @@ -30,7 +30,7 @@ import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry; import org.gradle.util.GradleVersion; -import io.quarkus.gradle.builder.QuarkusModelBuilder; +import io.quarkus.gradle.builder.GradleApplicationModelBuilder; import io.quarkus.gradle.dependency.ApplicationDeploymentClasspathBuilder; import io.quarkus.gradle.dependency.ConditionalDependenciesEnabler; import io.quarkus.gradle.dependency.ExtensionDependency; @@ -267,7 +267,7 @@ private Set getSourcesParents(SourceSet mainSourceSet) { } private void registerModel() { - registry.register(new QuarkusModelBuilder()); + registry.register(new GradleApplicationModelBuilder()); } private void verifyGradleVersion() { diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/builder/GradleApplicationModelBuilder.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/builder/GradleApplicationModelBuilder.java new file mode 100644 index 0000000000000..1d2b9ac22531f --- /dev/null +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/builder/GradleApplicationModelBuilder.java @@ -0,0 +1,640 @@ +package io.quarkus.gradle.builder; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import org.gradle.api.GradleException; +import org.gradle.api.Project; +import org.gradle.api.artifacts.Configuration; +import org.gradle.api.artifacts.ResolvedArtifact; +import org.gradle.api.artifacts.ResolvedConfiguration; +import org.gradle.api.artifacts.component.ProjectComponentIdentifier; +import org.gradle.api.initialization.IncludedBuild; +import org.gradle.api.internal.artifacts.dependencies.DefaultDependencyArtifact; +import org.gradle.api.internal.artifacts.dependencies.DefaultExternalModuleDependency; +import org.gradle.api.plugins.JavaPlugin; +import org.gradle.api.plugins.JavaPluginConvention; +import org.gradle.api.tasks.SourceSet; +import org.gradle.api.tasks.TaskCollection; +import org.gradle.api.tasks.compile.AbstractCompile; +import org.gradle.language.jvm.tasks.ProcessResources; +import org.gradle.tooling.provider.model.ParameterizedToolingModelBuilder; + +import io.quarkus.bootstrap.BootstrapConstants; +import io.quarkus.bootstrap.model.ApplicationModel; +import io.quarkus.bootstrap.model.ApplicationModelBuilder; +import io.quarkus.bootstrap.model.CapabilityContract; +import io.quarkus.bootstrap.model.PlatformImports; +import io.quarkus.bootstrap.model.PlatformImportsImpl; +import io.quarkus.bootstrap.model.gradle.ModelParameter; +import io.quarkus.bootstrap.model.gradle.impl.ModelParameterImpl; +import io.quarkus.bootstrap.resolver.AppModelResolverException; +import io.quarkus.bootstrap.workspace.DefaultProcessedSources; +import io.quarkus.bootstrap.workspace.DefaultWorkspaceModule; +import io.quarkus.bootstrap.workspace.ProcessedSources; +import io.quarkus.gradle.QuarkusPlugin; +import io.quarkus.gradle.dependency.ApplicationDeploymentClasspathBuilder; +import io.quarkus.gradle.dependency.DependencyUtils; +import io.quarkus.maven.dependency.ArtifactCoords; +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.GACT; +import io.quarkus.maven.dependency.GACTV; +import io.quarkus.maven.dependency.GAV; +import io.quarkus.maven.dependency.ResolvedDependency; +import io.quarkus.maven.dependency.ResolvedDependencyBuilder; +import io.quarkus.paths.PathCollection; +import io.quarkus.paths.PathList; +import io.quarkus.runtime.LaunchMode; +import io.quarkus.runtime.util.HashUtil; + +public class GradleApplicationModelBuilder implements ParameterizedToolingModelBuilder { + + private static final String MAIN_RESOURCES_OUTPUT = "build/resources/main"; + private static final String CLASSES_OUTPUT = "build/classes"; + private static final String DEPLOYMENT_CONFIGURATION = "quarkusDeploymentConfiguration"; + private static final String CLASSPATH_CONFIGURATION = "quarkusClasspathConfiguration"; + + private static Configuration classpathConfig(Project project, LaunchMode mode) { + if (LaunchMode.TEST.equals(mode)) { + return project.getConfigurations().getByName(JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME); + } + if (LaunchMode.DEVELOPMENT.equals(mode)) { + Configuration classpathConfiguration = project.getConfigurations().findByName(CLASSPATH_CONFIGURATION); + if (classpathConfiguration != null) { + project.getConfigurations().remove(classpathConfiguration); + } + + return project.getConfigurations().create(CLASSPATH_CONFIGURATION).extendsFrom( + project.getConfigurations().getByName(QuarkusPlugin.DEV_MODE_CONFIGURATION_NAME), + project.getConfigurations().getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME), + project.getConfigurations().getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME)); + } + return project.getConfigurations().getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME); + } + + private static Configuration deploymentClasspathConfig(Project project, LaunchMode mode, + Collection platforms) { + + Configuration deploymentConfiguration = project.getConfigurations().findByName(DEPLOYMENT_CONFIGURATION); + if (deploymentConfiguration != null) { + project.getConfigurations().remove(deploymentConfiguration); + } + + deploymentConfiguration = project.getConfigurations().create(DEPLOYMENT_CONFIGURATION) + .withDependencies(ds -> ds.addAll(platforms)); + Configuration implementationDeployment = project.getConfigurations().findByName(ApplicationDeploymentClasspathBuilder + .toDeploymentConfigurationName(JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME)); + if (implementationDeployment != null) { + deploymentConfiguration.extendsFrom(implementationDeployment); + } + + if (LaunchMode.TEST.equals(mode)) { + Configuration testDeploymentConfiguration = project.getConfigurations() + .findByName(ApplicationDeploymentClasspathBuilder + .toDeploymentConfigurationName(JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME)); + if (testDeploymentConfiguration != null) { + deploymentConfiguration.extendsFrom(testDeploymentConfiguration); + } + } + if (LaunchMode.DEVELOPMENT.equals(mode)) { + Configuration devDeploymentConfiguration = project.getConfigurations() + .findByName(ApplicationDeploymentClasspathBuilder + .toDeploymentConfigurationName(QuarkusPlugin.DEV_MODE_CONFIGURATION_NAME)); + if (devDeploymentConfiguration != null) { + deploymentConfiguration.extendsFrom(devDeploymentConfiguration); + } + + } + return deploymentConfiguration; + } + + @Override + public boolean canBuild(String modelName) { + return modelName.equals(ApplicationModel.class.getName()); + } + + @Override + public Class getParameterType() { + return ModelParameter.class; + } + + @Override + public Object buildAll(String modelName, Project project) { + final ModelParameterImpl modelParameter = new ModelParameterImpl(); + modelParameter.setMode(LaunchMode.DEVELOPMENT.toString()); + return buildAll(modelName, modelParameter, project); + } + + @Override + public Object buildAll(String modelName, ModelParameter parameter, Project project) { + final LaunchMode mode = LaunchMode.valueOf(parameter.getMode()); + + final List deploymentDeps = DependencyUtils.getEnforcedPlatforms(project); + final PlatformImports platformImports = resolvePlatformImports(project, deploymentDeps); + + final ResolvedDependency appArtifact = getProjectArtifact(project, mode); + final ApplicationModelBuilder modelBuilder = new ApplicationModelBuilder() + .setAppArtifact(appArtifact) + .addReloadableWorkspaceModule(new GACT(appArtifact.getGroupId(), appArtifact.getArtifactId())) + .setPlatformImports(platformImports); + + final Map appDependencies = new LinkedHashMap<>(); + Configuration classpathConfig = classpathConfig(project, mode); + collectDependencies(classpathConfig.getResolvedConfiguration(), mode, project, appDependencies, modelBuilder); + + Configuration deploymentConfig = deploymentClasspathConfig(project, mode, deploymentDeps); + collectExtensionDependencies(deploymentConfig, appDependencies, modelBuilder); + + for (ResolvedDependencyBuilder d : appDependencies.values()) { + modelBuilder.addDependency(d.build()); + } + return modelBuilder.build(); + } + + public static ResolvedDependency getProjectArtifact(Project project, LaunchMode mode) { + final ResolvedDependencyBuilder appArtifact = ResolvedDependencyBuilder.newInstance() + .setGroupId(project.getGroup().toString()) + .setArtifactId(project.getName()) + .setVersion(project.getVersion().toString()); + + final JavaPluginConvention javaConvention = project.getConvention().findPlugin(JavaPluginConvention.class); + if (javaConvention == null) { + throw new GradleException("Failed to locate Java plugin extension in " + project.getPath()); + } + final DefaultWorkspaceModule mainModule = new DefaultWorkspaceModule( + new GAV(appArtifact.getGroupId(), appArtifact.getArtifactId(), appArtifact.getVersion()), + project.getProjectDir(), project.getBuildDir()); + + initProjectModule(project, mainModule, javaConvention.getSourceSets().findByName(SourceSet.MAIN_SOURCE_SET_NAME), + false); + if (mode.equals(LaunchMode.TEST)) { + initProjectModule(project, mainModule, javaConvention.getSourceSets().findByName(SourceSet.TEST_SOURCE_SET_NAME), + true); + } + + final PathList.Builder paths = PathList.builder(); + mainModule.getMainSources().forEach(src -> { + collectDestinationDirs(src, paths); + }); + mainModule.getMainResources().forEach(src -> { + collectDestinationDirs(src, paths); + }); + + return appArtifact.setWorkspaceModule(mainModule).setResolvedPaths(paths.build()).build(); + } + + private static void collectDestinationDirs(ProcessedSources src, final PathList.Builder paths) { + if (!src.getDestinationDir().exists()) { + return; + } + final Path path = src.getDestinationDir().toPath(); + if (paths.contains(path)) { + return; + } + paths.add(path); + } + + private static void processQuarkusDir(ResolvedDependencyBuilder artifactBuilder, Path quarkusDir, + ApplicationModelBuilder modelBuilder) { + if (!Files.exists(quarkusDir)) { + return; + } + final Path quarkusDescr = quarkusDir.resolve(BootstrapConstants.DESCRIPTOR_FILE_NAME); + if (!Files.exists(quarkusDescr)) { + return; + } + final Properties extProps = readDescriptor(quarkusDescr); + if (extProps == null) { + return; + } + artifactBuilder.setRuntimeExtensionArtifact(); + final String extensionCoords = artifactBuilder.toGACTVString(); + modelBuilder.handleExtensionProperties(extProps, extensionCoords); + + final String providesCapabilities = extProps.getProperty(BootstrapConstants.PROP_PROVIDES_CAPABILITIES); + if (providesCapabilities != null) { + modelBuilder + .addExtensionCapabilities(CapabilityContract.providesCapabilities(extensionCoords, providesCapabilities)); + } + } + + private static Properties readDescriptor(final Path path) { + final Properties rtProps; + if (!Files.exists(path)) { + // not a platform artifact + return null; + } + rtProps = new Properties(); + try (BufferedReader reader = Files.newBufferedReader(path)) { + rtProps.load(reader); + } catch (IOException e) { + throw new UncheckedIOException("Failed to load extension description " + path, e); + } + return rtProps; + } + + private PlatformImports resolvePlatformImports(Project project, + List deploymentDeps) { + final Configuration boms = project.getConfigurations() + .detachedConfiguration(deploymentDeps.toArray(new org.gradle.api.artifacts.Dependency[0])); + final PlatformImportsImpl platformImports = new PlatformImportsImpl(); + boms.getResolutionStrategy().eachDependency(d -> { + final String group = d.getTarget().getGroup(); + final String name = d.getTarget().getName(); + if (name.endsWith(BootstrapConstants.PLATFORM_DESCRIPTOR_ARTIFACT_ID_SUFFIX)) { + platformImports.addPlatformDescriptor(group, name, d.getTarget().getVersion(), "json", + d.getTarget().getVersion()); + } else if (name.endsWith(BootstrapConstants.PLATFORM_PROPERTIES_ARTIFACT_ID_SUFFIX)) { + final DefaultDependencyArtifact dep = new DefaultDependencyArtifact(); + dep.setExtension("properties"); + dep.setType("properties"); + dep.setName(name); + + final DefaultExternalModuleDependency gradleDep = new DefaultExternalModuleDependency( + group, name, d.getTarget().getVersion(), null); + gradleDep.addArtifact(dep); + + for (ResolvedArtifact a : project.getConfigurations().detachedConfiguration(gradleDep) + .getResolvedConfiguration().getResolvedArtifacts()) { + if (a.getName().equals(name)) { + try { + platformImports.addPlatformProperties(group, name, null, "properties", d.getTarget().getVersion(), + a.getFile().toPath()); + } catch (AppModelResolverException e) { + throw new GradleException("Failed to import platform properties " + a.getFile(), e); + } + break; + } + } + } + + }); + boms.getResolvedConfiguration(); + return platformImports; + } + + private void collectExtensionDependencies(Configuration deploymentConfiguration, + Map appDependencies, ApplicationModelBuilder modelBuilder) { + final ResolvedConfiguration rc = deploymentConfiguration.getResolvedConfiguration(); + for (ResolvedArtifact a : rc.getResolvedArtifacts()) { + if (isDependency(a)) { + final ResolvedDependencyBuilder dep = appDependencies.computeIfAbsent( + toAppDependenciesKey(a.getModuleVersion().getId().getGroup(), a.getName(), a.getClassifier()), + k -> { + return toDependency(a); + }); + dep.setDeploymentCp(); + } + } + } + + private void collectDependencies(ResolvedConfiguration configuration, + LaunchMode mode, Project project, Map appDependencies, + ApplicationModelBuilder modelBuilder) { + + final Set resolvedArtifacts = configuration.getResolvedArtifacts(); + // if the number of artifacts is less than the number of files then probably + // the project includes direct file dependencies + final Set artifactFiles = resolvedArtifacts.size() < configuration.getFiles().size() + ? new HashSet<>(resolvedArtifacts.size()) + : null; + + configuration.getFirstLevelModuleDependencies() + .forEach(d -> collectDependencies(d, mode, project, appDependencies, artifactFiles, new HashSet<>(), + modelBuilder)); + + if (artifactFiles != null) { + // detect FS paths that aren't provided by the resolved artifacts + for (File f : configuration.getFiles()) { + if (artifactFiles.contains(f)) { + continue; + } + // here we are trying to represent a direct FS path dependency + // as an artifact dependency + // SHA1 hash is used to avoid long file names in the lib dir + final String parentPath = f.getParent(); + final String group = HashUtil.sha1(parentPath == null ? f.getName() : parentPath); + String name = f.getName(); + String type = "jar"; + if (!f.isDirectory()) { + final int dot = f.getName().lastIndexOf('.'); + if (dot > 0) { + name = f.getName().substring(0, dot); + type = f.getName().substring(dot + 1); + } + } + // hash could be a better way to represent the version + final String version = String.valueOf(f.lastModified()); + final ResolvedDependencyBuilder artifactBuilder = ResolvedDependencyBuilder.newInstance() + .setGroupId(group) + .setArtifactId(name) + .setType(type) + .setVersion(version) + .setResolvedPath(f.toPath()) + .setDirect(true) + .setRuntimeCp(); + processQuarkusDependency(artifactBuilder, modelBuilder); + appDependencies.put(artifactBuilder.getKey(), artifactBuilder); + } + } + } + + private void collectDependencies(org.gradle.api.artifacts.ResolvedDependency resolvedDep, LaunchMode mode, Project project, + Map appDependencies, Set artifactFiles, + Set processedModules, ApplicationModelBuilder modelBuilder) { + + for (ResolvedArtifact a : resolvedDep.getModuleArtifacts()) { + final ArtifactKey artifactKey = toAppDependenciesKey(a.getModuleVersion().getId().getGroup(), a.getName(), + a.getClassifier()); + if (!isDependency(a) || appDependencies.containsKey(artifactKey)) { + continue; + } + final ResolvedDependencyBuilder depBuilder = ResolvedDependencyBuilder.newInstance() + .setCoords(toArtifactCoords(a)) + .setDirect(processedModules.isEmpty()) + .setRuntimeCp(); + + DefaultWorkspaceModule projectModule = null; + PathCollection paths = null; + if ((LaunchMode.DEVELOPMENT.equals(mode) || LaunchMode.TEST.equals(mode)) && + a.getId().getComponentIdentifier() instanceof ProjectComponentIdentifier) { + + final Project projectDep = project.getRootProject().findProject( + ((ProjectComponentIdentifier) a.getId().getComponentIdentifier()).getProjectPath()); + final JavaPluginConvention javaExtension = projectDep == null ? null + : projectDep.getConvention().findPlugin(JavaPluginConvention.class); + + final String classifier = a.getClassifier(); + if (classifier == null || classifier.isEmpty()) { + final IncludedBuild includedBuild = DependencyUtils.includedBuild(project.getRootProject(), a.getName()); + if (includedBuild != null) { + final PathList.Builder pathBuilder = PathList.builder(); + addSubstitutedProject(pathBuilder, includedBuild.getProjectDir()); + paths = pathBuilder.build(); + } else if (javaExtension != null) { + final PathList.Builder pathBuilder = PathList.builder(); + projectModule = initProjectModuleAndBuildPaths(projectDep, a, modelBuilder, depBuilder, + javaExtension, pathBuilder, SourceSet.MAIN_SOURCE_SET_NAME, false); + paths = pathBuilder.build(); + } + } else if (javaExtension != null) { + if ("test".equals(classifier)) { + final PathList.Builder pathBuilder = PathList.builder(); + projectModule = initProjectModuleAndBuildPaths(projectDep, a, modelBuilder, depBuilder, + javaExtension, pathBuilder, SourceSet.TEST_SOURCE_SET_NAME, true); + paths = pathBuilder.build(); + } else if ("test-fixtures".equals(classifier)) { + final PathList.Builder pathBuilder = PathList.builder(); + projectModule = initProjectModuleAndBuildPaths(projectDep, a, modelBuilder, depBuilder, + javaExtension, pathBuilder, "testFixtures", true); + paths = pathBuilder.build(); + } + } + } + + final ResolvedDependencyBuilder artifactBuilder = depBuilder + .setResolvedPaths(paths == null ? PathList.of(a.getFile().toPath()) : paths) + .setWorkspaceModule(projectModule); + processQuarkusDependency(artifactBuilder, modelBuilder); + appDependencies.put(artifactBuilder.getKey(), artifactBuilder); + + if (artifactFiles != null) { + artifactFiles.add(a.getFile()); + } + } + + processedModules.add(new GACT(resolvedDep.getModuleGroup(), resolvedDep.getModuleName())); + for (org.gradle.api.artifacts.ResolvedDependency child : resolvedDep.getChildren()) { + if (!processedModules.contains(new GACT(child.getModuleGroup(), child.getModuleName()))) { + collectDependencies(child, mode, project, appDependencies, artifactFiles, processedModules, modelBuilder); + } + } + } + + private DefaultWorkspaceModule initProjectModuleAndBuildPaths(final Project project, + ResolvedArtifact resolvedArtifact, ApplicationModelBuilder appModel, final ResolvedDependencyBuilder appDep, + final JavaPluginConvention javaExt, PathList.Builder buildPaths, String sourceName, boolean test) { + + appDep.setWorkspaceModule().setReloadable(); + + final DefaultWorkspaceModule projectModule = appModel.getOrCreateProjectModule( + new GAV(resolvedArtifact.getModuleVersion().getId().getGroup(), resolvedArtifact.getName(), + resolvedArtifact.getModuleVersion().getId().getVersion()), + project.getProjectDir(), + project.getBuildDir()); + + initProjectModule(project, projectModule, javaExt.getSourceSets().findByName(sourceName), test); + + if (test) { + projectModule.getTestSources().forEach(src -> { + collectDestinationDirs(src, buildPaths); + }); + projectModule.getTestResources().forEach(src -> { + collectDestinationDirs(src, buildPaths); + }); + } else { + projectModule.getMainSources().forEach(src -> { + collectDestinationDirs(src, buildPaths); + }); + projectModule.getMainResources().forEach(src -> { + collectDestinationDirs(src, buildPaths); + }); + } + + appModel.addReloadableWorkspaceModule( + new GACT(resolvedArtifact.getModuleVersion().getId().getGroup(), resolvedArtifact.getName())); + return projectModule; + } + + private void processQuarkusDependency(ResolvedDependencyBuilder artifactBuilder, ApplicationModelBuilder modelBuilder) { + artifactBuilder.getResolvedPaths().forEach(artifactPath -> { + if (!Files.exists(artifactPath) || !artifactBuilder.getType().equals(GACTV.TYPE_JAR)) { + return; + } + if (Files.isDirectory(artifactPath)) { + processQuarkusDir(artifactBuilder, artifactPath.resolve(BootstrapConstants.META_INF), modelBuilder); + } else { + try (FileSystem artifactFs = FileSystems.newFileSystem(artifactPath, null)) { + processQuarkusDir(artifactBuilder, artifactFs.getPath(BootstrapConstants.META_INF), modelBuilder); + } catch (IOException e) { + throw new RuntimeException("Failed to process " + artifactPath, e); + } + } + }); + } + + private static void initProjectModule(Project project, DefaultWorkspaceModule module, SourceSet sourceSet, boolean test) { + + module.setBuildFiles(PathList.of(project.getBuildFile().toPath())); + final List allJavaDirs = new ArrayList<>(2); + sourceSet.getAllJava().getSourceDirectories().forEach(f -> { + if (f.exists()) { + allJavaDirs.add(f.toPath()); + } + }); + + if (!allJavaDirs.isEmpty()) { + final TaskCollection compileTasks = project.getTasks().withType(AbstractCompile.class); + compileTasks.forEach(t -> { + String compiler = t.getName(); + if (compiler.startsWith("compile")) { + compiler = compiler.substring("compile".length()).toLowerCase(); + } + + final File destDir = t.getDestinationDirectory().getAsFile().get(); + + final List srcDirs = new ArrayList<>(1); + for (File f : t.getSource().getFiles()) { + if (!f.exists()) { + return; + } + final Path p = f.toPath(); + int i = 0; + while (i < srcDirs.size()) { + if (p.startsWith(srcDirs.get(i))) { + break; + } + ++i; + } + if (i < srcDirs.size()) { + continue; + } + for (Path srcDir : allJavaDirs) { + if (p.startsWith(srcDir)) { + srcDirs.add(srcDir); + DefaultProcessedSources sources = new DefaultProcessedSources(srcDir.toFile(), destDir, + Collections.singletonMap("compiler", compiler)); + if (test) { + module.addTestSources(sources); + } else { + module.addMainSources(sources); + } + break; + } + } + } + }); + } + + final List allResourcesDirs = new ArrayList<>(1); + final List addedSrcDirs = new ArrayList<>(1); + final File outputDir = sourceSet.getOutput().getResourcesDir(); + for (File resourcesDir : sourceSet.getResources().getSourceDirectories()) { + allResourcesDirs.add(resourcesDir.toPath()); + addResources(module, resourcesDir, outputDir, test, addedSrcDirs); + } + + if (!allResourcesDirs.isEmpty()) { + final TaskCollection resources = project.getTasks().withType(ProcessResources.class); + resources.forEach(t -> { + final File destDir = t.getDestinationDir(); + for (File f : t.getSource().getFiles()) { + if (!f.exists()) { + return; + } + final Path p = f.toPath(); + int i = 0; + while (i < addedSrcDirs.size()) { + if (p.startsWith(addedSrcDirs.get(i))) { + break; + } + ++i; + } + if (i < addedSrcDirs.size()) { + continue; + } + for (Path srcDir : allResourcesDirs) { + if (p.startsWith(srcDir)) { + addResources(module, srcDir.toFile(), destDir, test, addedSrcDirs); + break; + } + } + } + }); + } + } + + private static void addResources(DefaultWorkspaceModule module, File srcDir, final File destDir, boolean test, + Collection addedSrcDirs) { + final DefaultProcessedSources resrc = new DefaultProcessedSources(srcDir, destDir); + if (test) { + module.addTestResources(resrc); + } else { + module.addMainResources(resrc); + } + addedSrcDirs.add(srcDir.toPath()); + } + + private void addSubstitutedProject(PathList.Builder paths, File projectFile) { + File mainResourceDirectory = new File(projectFile, MAIN_RESOURCES_OUTPUT); + if (mainResourceDirectory.exists()) { + paths.add(mainResourceDirectory.toPath()); + } + File classesOutput = new File(projectFile, CLASSES_OUTPUT); + File[] languageDirectories = classesOutput.listFiles(); + if (languageDirectories == null) { + throw new GradleException( + "The project does not contain a class output directory. " + classesOutput.getPath() + " must exist."); + } + for (File languageDirectory : languageDirectories) { + if (languageDirectory.isDirectory()) { + for (File sourceSet : languageDirectory.listFiles()) { + if (sourceSet.isDirectory() && sourceSet.getName().equals(SourceSet.MAIN_SOURCE_SET_NAME)) { + paths.add(sourceSet.toPath()); + } + } + } + } + } + + private static boolean isDependency(ResolvedArtifact a) { + return ArtifactCoords.TYPE_JAR.equalsIgnoreCase(a.getExtension()) || "exe".equalsIgnoreCase(a.getExtension()) || + a.getFile().isDirectory(); + } + + /** + * Creates an instance of Dependency and associates it with the ResolvedArtifact's path + */ + static ResolvedDependencyBuilder toDependency(ResolvedArtifact a, int... flags) { + return toDependency(a, PathList.of(a.getFile().toPath()), null, flags); + } + + static ResolvedDependencyBuilder toDependency(ResolvedArtifact a, PathCollection paths, DefaultWorkspaceModule module, + int... flags) { + int allFlags = 0; + for (int f : flags) { + allFlags |= f; + } + return ResolvedDependencyBuilder.newInstance() + .setCoords(toArtifactCoords(a)) + .setResolvedPaths(paths) + .setWorkspaceModule(module) + .setFlags(allFlags); + } + + private static ArtifactCoords toArtifactCoords(ResolvedArtifact a) { + final String[] split = a.getModuleVersion().toString().split(":"); + return new GACTV(split[0], split[1], a.getClassifier(), a.getType(), split.length > 2 ? split[2] : null); + } + + private static ArtifactKey toAppDependenciesKey(String groupId, String artifactId, String classifier) { + // Default classifier is empty string and not null value, lets keep it that way + classifier = classifier == null ? "" : classifier; + return new GACT(groupId, artifactId, classifier, ArtifactCoords.TYPE_JAR); + } +} diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/builder/QuarkusModelBuilder.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/builder/QuarkusModelBuilder.java deleted file mode 100644 index 1be45e0690719..0000000000000 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/builder/QuarkusModelBuilder.java +++ /dev/null @@ -1,443 +0,0 @@ -package io.quarkus.gradle.builder; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.gradle.api.GradleException; -import org.gradle.api.Project; -import org.gradle.api.Task; -import org.gradle.api.artifacts.Configuration; -import org.gradle.api.artifacts.ResolvedArtifact; -import org.gradle.api.artifacts.ResolvedConfiguration; -import org.gradle.api.artifacts.ResolvedDependency; -import org.gradle.api.artifacts.component.ProjectComponentIdentifier; -import org.gradle.api.initialization.IncludedBuild; -import org.gradle.api.internal.artifacts.dependencies.DefaultDependencyArtifact; -import org.gradle.api.internal.artifacts.dependencies.DefaultExternalModuleDependency; -import org.gradle.api.plugins.Convention; -import org.gradle.api.plugins.JavaPlugin; -import org.gradle.api.plugins.JavaPluginConvention; -import org.gradle.api.tasks.SourceSet; -import org.gradle.tooling.provider.model.ParameterizedToolingModelBuilder; - -import io.quarkus.bootstrap.BootstrapConstants; -import io.quarkus.bootstrap.model.AppArtifactKey; -import io.quarkus.bootstrap.model.AppDependency; -import io.quarkus.bootstrap.model.PlatformImports; -import io.quarkus.bootstrap.model.PlatformImportsImpl; -import io.quarkus.bootstrap.model.gradle.ArtifactCoords; -import io.quarkus.bootstrap.model.gradle.ModelParameter; -import io.quarkus.bootstrap.model.gradle.QuarkusModel; -import io.quarkus.bootstrap.model.gradle.WorkspaceModule; -import io.quarkus.bootstrap.model.gradle.impl.ArtifactCoordsImpl; -import io.quarkus.bootstrap.model.gradle.impl.DependencyImpl; -import io.quarkus.bootstrap.model.gradle.impl.ModelParameterImpl; -import io.quarkus.bootstrap.model.gradle.impl.QuarkusModelImpl; -import io.quarkus.bootstrap.model.gradle.impl.SourceSetImpl; -import io.quarkus.bootstrap.model.gradle.impl.WorkspaceImpl; -import io.quarkus.bootstrap.model.gradle.impl.WorkspaceModuleImpl; -import io.quarkus.bootstrap.resolver.AppModelResolverException; -import io.quarkus.gradle.QuarkusPlugin; -import io.quarkus.gradle.dependency.ApplicationDeploymentClasspathBuilder; -import io.quarkus.gradle.dependency.DependencyUtils; -import io.quarkus.gradle.tasks.QuarkusGradleUtils; -import io.quarkus.runtime.LaunchMode; -import io.quarkus.runtime.util.HashUtil; - -public class QuarkusModelBuilder implements ParameterizedToolingModelBuilder { - - private static final String MAIN_RESOURCES_OUTPUT = "build/resources/main"; - private static final String CLASSES_OUTPUT = "build/classes"; - private static final String DEPLOYMENT_CONFIGURATION = "quarkusDeploymentConfiguration"; - private static final String CLASSPATH_CONFIGURATION = "quarkusClasspathConfiguration"; - - private static Configuration classpathConfig(Project project, LaunchMode mode) { - if (LaunchMode.TEST.equals(mode)) { - return project.getConfigurations().getByName(JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME); - } - if (LaunchMode.DEVELOPMENT.equals(mode)) { - Configuration classpathConfiguration = project.getConfigurations().findByName(CLASSPATH_CONFIGURATION); - if (classpathConfiguration != null) { - project.getConfigurations().remove(classpathConfiguration); - } - - return project.getConfigurations().create(CLASSPATH_CONFIGURATION).extendsFrom( - project.getConfigurations().getByName(QuarkusPlugin.DEV_MODE_CONFIGURATION_NAME), - project.getConfigurations().getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME), - project.getConfigurations().getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME)); - } - return project.getConfigurations().getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME); - } - - private static Configuration deploymentClasspathConfig(Project project, LaunchMode mode, - Collection platforms) { - - Configuration deploymentConfiguration = project.getConfigurations().findByName(DEPLOYMENT_CONFIGURATION); - if (deploymentConfiguration != null) { - project.getConfigurations().remove(deploymentConfiguration); - } - - deploymentConfiguration = project.getConfigurations().create(DEPLOYMENT_CONFIGURATION) - .withDependencies(ds -> ds.addAll(platforms)); - Configuration implementationDeployment = project.getConfigurations().findByName(ApplicationDeploymentClasspathBuilder - .toDeploymentConfigurationName(JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME)); - if (implementationDeployment != null) { - deploymentConfiguration.extendsFrom(implementationDeployment); - } - - if (LaunchMode.TEST.equals(mode)) { - Configuration testDeploymentConfiguration = project.getConfigurations() - .findByName(ApplicationDeploymentClasspathBuilder - .toDeploymentConfigurationName(JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME)); - if (testDeploymentConfiguration != null) { - deploymentConfiguration.extendsFrom(testDeploymentConfiguration); - } - } - if (LaunchMode.DEVELOPMENT.equals(mode)) { - Configuration devDeploymentConfiguration = project.getConfigurations() - .findByName(ApplicationDeploymentClasspathBuilder - .toDeploymentConfigurationName(QuarkusPlugin.DEV_MODE_CONFIGURATION_NAME)); - if (devDeploymentConfiguration != null) { - deploymentConfiguration.extendsFrom(devDeploymentConfiguration); - } - - } - return deploymentConfiguration; - } - - @Override - public boolean canBuild(String modelName) { - return modelName.equals(QuarkusModel.class.getName()); - } - - @Override - public Class getParameterType() { - return ModelParameter.class; - } - - @Override - public Object buildAll(String modelName, Project project) { - final ModelParameterImpl modelParameter = new ModelParameterImpl(); - modelParameter.setMode(LaunchMode.DEVELOPMENT.toString()); - return buildAll(modelName, modelParameter, project); - } - - @Override - public Object buildAll(String modelName, ModelParameter parameter, Project project) { - LaunchMode mode = LaunchMode.valueOf(parameter.getMode()); - - final List deploymentDeps = DependencyUtils.getEnforcedPlatforms(project); - final PlatformImports platformImports = resolvePlatformImports(project, deploymentDeps); - - final Map appDependencies = new LinkedHashMap<>(); - Configuration classpathConfig = classpathConfig(project, mode); - final ResolvedConfiguration resolvedConfiguration = classpathConfig.getResolvedConfiguration(); - collectDependencies(resolvedConfiguration, mode, project, appDependencies); - - Configuration deploymentConfig = deploymentClasspathConfig(project, mode, deploymentDeps); - collectExtensionDependencies(deploymentConfig, appDependencies); - - ArtifactCoords appArtifactCoords = new ArtifactCoordsImpl(project.getGroup().toString(), project.getName(), - project.getVersion().toString()); - - return new QuarkusModelImpl( - new WorkspaceImpl(appArtifactCoords, getWorkspace(project.getRootProject(), mode, appArtifactCoords)), - new ArrayList<>(appDependencies.values()), - platformImports); - } - - private PlatformImports resolvePlatformImports(Project project, - List deploymentDeps) { - final Configuration boms = project.getConfigurations() - .detachedConfiguration(deploymentDeps.toArray(new org.gradle.api.artifacts.Dependency[0])); - final PlatformImportsImpl platformImports = new PlatformImportsImpl(); - boms.getResolutionStrategy().eachDependency(d -> { - final String group = d.getTarget().getGroup(); - final String name = d.getTarget().getName(); - if (name.endsWith(BootstrapConstants.PLATFORM_DESCRIPTOR_ARTIFACT_ID_SUFFIX)) { - platformImports.addPlatformDescriptor(group, name, d.getTarget().getVersion(), "json", - d.getTarget().getVersion()); - } else if (name.endsWith(BootstrapConstants.PLATFORM_PROPERTIES_ARTIFACT_ID_SUFFIX)) { - final DefaultDependencyArtifact dep = new DefaultDependencyArtifact(); - dep.setExtension("properties"); - dep.setType("properties"); - dep.setName(name); - - final DefaultExternalModuleDependency gradleDep = new DefaultExternalModuleDependency( - group, name, d.getTarget().getVersion(), null); - gradleDep.addArtifact(dep); - - for (ResolvedArtifact a : project.getConfigurations().detachedConfiguration(gradleDep) - .getResolvedConfiguration().getResolvedArtifacts()) { - if (a.getName().equals(name)) { - try { - platformImports.addPlatformProperties(group, name, null, "properties", d.getTarget().getVersion(), - a.getFile().toPath()); - } catch (AppModelResolverException e) { - throw new GradleException("Failed to import platform properties " + a.getFile(), e); - } - break; - } - } - } - - }); - boms.getResolvedConfiguration(); - return platformImports; - } - - public Set getWorkspace(Project project, LaunchMode mode, ArtifactCoords mainModuleCoord) { - Set modules = new HashSet<>(); - for (Project subproject : project.getAllprojects()) { - final Convention convention = subproject.getConvention(); - JavaPluginConvention javaConvention = convention.findPlugin(JavaPluginConvention.class); - if (javaConvention == null || !javaConvention.getSourceSets().getNames().contains(SourceSet.MAIN_SOURCE_SET_NAME)) { - continue; - } - if (subproject.getName().equals(mainModuleCoord.getArtifactId()) - && subproject.getGroup().equals(mainModuleCoord.getGroupId())) { - modules.add(getWorkspaceModule(subproject, mode, true)); - } else { - modules.add(getWorkspaceModule(subproject, mode, false)); - } - - } - return modules; - } - - private WorkspaceModule getWorkspaceModule(Project project, LaunchMode mode, boolean isMainModule) { - ArtifactCoords appArtifactCoords = new ArtifactCoordsImpl(project.getGroup().toString(), project.getName(), - project.getVersion().toString()); - final SourceSet mainSourceSet = QuarkusGradleUtils.getSourceSet(project, SourceSet.MAIN_SOURCE_SET_NAME); - final SourceSetImpl modelSourceSet; - if (isMainModule && mode == LaunchMode.TEST) { - final SourceSet testSourceSet = QuarkusGradleUtils.getSourceSet(project, SourceSet.TEST_SOURCE_SET_NAME); - modelSourceSet = convert(mainSourceSet, testSourceSet.getOutput().getClassesDirs().getFiles()); - } else { - modelSourceSet = convert(mainSourceSet, Collections.emptySet()); - } - return new WorkspaceModuleImpl(appArtifactCoords, - project.getProjectDir().getAbsoluteFile(), - project.getBuildDir().getAbsoluteFile(), getSourceSourceSet(mainSourceSet), modelSourceSet); - } - - private void collectExtensionDependencies(Configuration deploymentConfiguration, - Map appDependencies) { - final ResolvedConfiguration rc = deploymentConfiguration.getResolvedConfiguration(); - for (ResolvedArtifact a : rc.getResolvedArtifacts()) { - if (isDependency(a)) { - DependencyImpl dep = appDependencies.computeIfAbsent( - toAppDependenciesKey(a.getModuleVersion().getId().getGroup(), a.getName(), a.getClassifier()), - k -> toDependency(a, AppDependency.DEPLOYMENT_CP_FLAG)); - dep.setFlag(AppDependency.DEPLOYMENT_CP_FLAG); - } - } - } - - private void collectDependencies(ResolvedConfiguration configuration, - LaunchMode mode, Project project, Map appDependencies) { - - final Set resolvedArtifacts = configuration.getResolvedArtifacts(); - // if the number of artifacts is less than the number of files then probably - // the project includes direct file dependencies - final Set artifactFiles = resolvedArtifacts.size() < configuration.getFiles().size() - ? new HashSet<>(resolvedArtifacts.size()) - : null; - - configuration.getFirstLevelModuleDependencies() - .forEach(d -> collectDependencies(d, mode, project, appDependencies, artifactFiles, new HashSet<>())); - - if (artifactFiles != null) { - // detect FS paths that aren't provided by the resolved artifacts - for (File f : configuration.getFiles()) { - if (artifactFiles.contains(f)) { - continue; - } - // here we are trying to represent a direct FS path dependency - // as an artifact dependency - // SHA1 hash is used to avoid long file names in the lib dir - final String parentPath = f.getParent(); - final String group = HashUtil.sha1(parentPath == null ? f.getName() : parentPath); - String name = f.getName(); - String type = "jar"; - if (!f.isDirectory()) { - final int dot = f.getName().lastIndexOf('.'); - if (dot > 0) { - name = f.getName().substring(0, dot); - type = f.getName().substring(dot + 1); - } - } - // hash could be a better way to represent the version - final String version = String.valueOf(f.lastModified()); - final DependencyImpl dep = new DependencyImpl(name, group, version, "compile", type, null, - AppDependency.DIRECT_FLAG, AppDependency.RUNTIME_CP_FLAG); - dep.addPath(f); - final ArtifactCoords key = toAppDependenciesKey(group, name, ""); - appDependencies.put(key, dep); - } - } - } - - private void collectDependencies(ResolvedDependency resolvedDep, LaunchMode mode, Project project, - Map appDependencies, Set artifactFiles, - Set processedModules) { - - for (ResolvedArtifact a : resolvedDep.getModuleArtifacts()) { - final ArtifactCoords artifactKey = toAppDependenciesKey(a.getModuleVersion().getId().getGroup(), a.getName(), - a.getClassifier()); - if (!isDependency(a) || appDependencies.containsKey(artifactKey)) { - continue; - } - final DependencyImpl dep = initDependency(a, processedModules.isEmpty() ? AppDependency.DIRECT_FLAG : 0, - AppDependency.RUNTIME_CP_FLAG); - if ((LaunchMode.DEVELOPMENT.equals(mode) || LaunchMode.TEST.equals(mode)) && - a.getId().getComponentIdentifier() instanceof ProjectComponentIdentifier) { - if ("test-fixtures".equals(a.getClassifier()) || "test".equals(a.getClassifier())) { - //TODO: test-fixtures are broken under the new ClassLoading model - dep.addPath(a.getFile()); - } else { - IncludedBuild includedBuild = DependencyUtils.includedBuild(project.getRootProject(), a.getName()); - if (includedBuild != null) { - addSubstitutedProject(dep, includedBuild.getProjectDir()); - } else { - Project projectDep = project.getRootProject() - .findProject( - ((ProjectComponentIdentifier) a.getId().getComponentIdentifier()).getProjectPath()); - if (projectDep != null) { - addDevModePaths(dep, a, projectDep); - } else { - dep.addPath(a.getFile()); - } - } - } - } else { - dep.addPath(a.getFile()); - } - appDependencies.put(artifactKey, dep); - if (artifactFiles != null) { - artifactFiles.add(a.getFile()); - } - } - - processedModules.add(new AppArtifactKey(resolvedDep.getModuleGroup(), resolvedDep.getModuleName())); - for (ResolvedDependency child : resolvedDep.getChildren()) { - if (!processedModules.contains(new AppArtifactKey(child.getModuleGroup(), child.getModuleName()))) { - collectDependencies(child, mode, project, appDependencies, artifactFiles, processedModules); - } - } - } - - private void addDevModePaths(final DependencyImpl dep, ResolvedArtifact a, Project project) { - final JavaPluginConvention javaConvention = project.getConvention().findPlugin(JavaPluginConvention.class); - if (javaConvention == null) { - dep.addPath(a.getFile()); - return; - } - final SourceSet mainSourceSet = javaConvention.getSourceSets().findByName(SourceSet.MAIN_SOURCE_SET_NAME); - if (mainSourceSet == null) { - dep.addPath(a.getFile()); - return; - } - final String classes = QuarkusGradleUtils.getClassesDir(mainSourceSet, project.getBuildDir(), false); - if (classes == null) { - dep.addPath(a.getFile()); - } else { - final File classesDir = new File(classes); - if (classesDir.exists()) { - dep.addPath(classesDir); - } else { - dep.addPath(a.getFile()); - } - } - for (File resourcesDir : mainSourceSet.getResources().getSourceDirectories()) { - if (resourcesDir.exists()) { - dep.addPath(resourcesDir); - } - } - final Task resourcesTask = project.getTasks().findByName(JavaPlugin.PROCESS_RESOURCES_TASK_NAME); - for (File outputDir : resourcesTask.getOutputs().getFiles()) { - if (outputDir.exists()) { - dep.addPath(outputDir); - } - } - } - - private void addSubstitutedProject(final DependencyImpl dep, File projectFile) { - File mainResourceDirectory = new File(projectFile, MAIN_RESOURCES_OUTPUT); - if (mainResourceDirectory.exists()) { - dep.addPath(mainResourceDirectory); - } - File classesOutput = new File(projectFile, CLASSES_OUTPUT); - File[] languageDirectories = classesOutput.listFiles(); - if (languageDirectories == null) { - throw new GradleException( - "The project does not contain a class output directory. " + classesOutput.getPath() + " must exist."); - } - for (File languageDirectory : languageDirectories) { - if (languageDirectory.isDirectory()) { - for (File sourceSet : languageDirectory.listFiles()) { - if (sourceSet.isDirectory() && sourceSet.getName().equals(SourceSet.MAIN_SOURCE_SET_NAME)) { - dep.addPath(sourceSet); - } - } - } - } - } - - private SourceSetImpl convert(SourceSet sourceSet, Set additionalSourceDirs) { - Set existingSrcDirs = new HashSet<>(); - for (File srcDir : sourceSet.getOutput().getClassesDirs().getFiles()) { - if (srcDir.exists()) { - existingSrcDirs.add(srcDir); - } - } - existingSrcDirs.addAll(additionalSourceDirs); - if (sourceSet.getOutput().getResourcesDir().exists()) { - return new SourceSetImpl( - existingSrcDirs, - Collections.singleton(sourceSet.getOutput().getResourcesDir())); - } - return new SourceSetImpl(existingSrcDirs); - } - - private io.quarkus.bootstrap.model.gradle.SourceSet getSourceSourceSet(SourceSet sourceSet) { - return new SourceSetImpl(sourceSet.getAllJava().getSrcDirs(), - sourceSet.getResources().getSourceDirectories().getFiles()); - } - - private static boolean isDependency(ResolvedArtifact a) { - return BootstrapConstants.JAR.equalsIgnoreCase(a.getExtension()) || "exe".equalsIgnoreCase(a.getExtension()) || - a.getFile().isDirectory(); - } - - /** - * Creates an instance of Dependency and associates it with the ResolvedArtifact's path - */ - static DependencyImpl toDependency(ResolvedArtifact a, int... flags) { - final DependencyImpl dependency = initDependency(a, flags); - dependency.addPath(a.getFile()); - return dependency; - } - - /** - * Creates an instance of DependencyImpl but does not associates it with a path - */ - private static DependencyImpl initDependency(ResolvedArtifact a, int... flags) { - final String[] split = a.getModuleVersion().toString().split(":"); - return new DependencyImpl(split[1], split[0], split.length > 2 ? split[2] : null, - "compile", a.getType(), a.getClassifier(), flags); - } - - private static ArtifactCoords toAppDependenciesKey(String groupId, String artifactId, String classifier) { - // Default classifier is empty string and not null value, lets keep it that way - classifier = classifier == null ? "" : classifier; - return new ArtifactCoordsImpl(groupId, artifactId, classifier, "", ArtifactCoordsImpl.TYPE_JAR); - } -} diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/dependency/DependencyUtils.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/dependency/DependencyUtils.java index b5bc96a08637d..11c93080539c1 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/dependency/DependencyUtils.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/dependency/DependencyUtils.java @@ -30,9 +30,10 @@ import io.quarkus.bootstrap.BootstrapConstants; import io.quarkus.bootstrap.model.AppArtifactCoords; -import io.quarkus.bootstrap.model.AppArtifactKey; import io.quarkus.bootstrap.util.BootstrapUtils; import io.quarkus.bootstrap.util.ZipUtils; +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.GACT; public class DependencyUtils { @@ -71,10 +72,10 @@ public static Dependency create(DependencyHandler dependencies, String condition dependencyCoords.getVersion())); } - public static boolean exist(Set runtimeArtifacts, List dependencies) { - final Set rtKeys = new HashSet<>(runtimeArtifacts.size()); + public static boolean exist(Set runtimeArtifacts, List dependencies) { + final Set rtKeys = new HashSet<>(runtimeArtifacts.size()); runtimeArtifacts.forEach(r -> rtKeys.add( - new AppArtifactKey(r.getModuleVersion().getId().getGroup(), r.getName(), r.getClassifier(), r.getExtension()))); + new GACT(r.getModuleVersion().getId().getGroup(), r.getName(), r.getClassifier(), r.getExtension()))); return rtKeys.containsAll(dependencies); } @@ -199,7 +200,7 @@ private static ExtensionDependency loadExtensionInfo(Project project, Path descr conditionalDependencies = Collections.emptyList(); } - final AppArtifactKey[] constraints = BootstrapUtils + final ArtifactKey[] constraints = BootstrapUtils .parseDependencyCondition(extensionProperties.getProperty(BootstrapConstants.DEPENDENCY_CONDITION)); return new ExtensionDependency(exentionId, deploymentModule, conditionalDependencies, constraints == null ? Collections.emptyList() : Arrays.asList(constraints)); diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/dependency/ExtensionDependency.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/dependency/ExtensionDependency.java index 5ee873aab14d2..6b81a29873673 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/dependency/ExtensionDependency.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/dependency/ExtensionDependency.java @@ -11,18 +11,18 @@ import org.gradle.api.artifacts.dsl.DependencyHandler; import io.quarkus.bootstrap.model.AppArtifactCoords; -import io.quarkus.bootstrap.model.AppArtifactKey; +import io.quarkus.maven.dependency.ArtifactKey; public class ExtensionDependency { ModuleVersionIdentifier extensionId; AppArtifactCoords deploymentModule; List conditionalDependencies; - List dependencyConditions; + List dependencyConditions; ExtensionDependency(ModuleVersionIdentifier extensionId, AppArtifactCoords deploymentModule, List conditionalDependencies, - List dependencyConditions) { + List dependencyConditions) { this.extensionId = extensionId; this.deploymentModule = deploymentModule; this.conditionalDependencies = conditionalDependencies; diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/extension/QuarkusPluginExtension.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/extension/QuarkusPluginExtension.java index 87af073fb1d0d..64f22b5da429f 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/extension/QuarkusPluginExtension.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/extension/QuarkusPluginExtension.java @@ -14,7 +14,6 @@ import org.gradle.api.Project; import org.gradle.api.file.FileCollection; import org.gradle.api.file.RegularFile; -import org.gradle.api.plugins.Convention; import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.JavaPluginConvention; import org.gradle.api.provider.Provider; @@ -24,14 +23,12 @@ import org.gradle.jvm.tasks.Jar; import io.quarkus.bootstrap.BootstrapConstants; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppModel; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.model.gradle.ModelParameter; -import io.quarkus.bootstrap.model.gradle.QuarkusModel; import io.quarkus.bootstrap.model.gradle.impl.ModelParameterImpl; import io.quarkus.bootstrap.resolver.AppModelResolver; import io.quarkus.gradle.AppModelGradleResolver; -import io.quarkus.gradle.builder.QuarkusModelBuilder; +import io.quarkus.gradle.builder.GradleApplicationModelBuilder; import io.quarkus.gradle.tasks.QuarkusGradleUtils; import io.quarkus.runtime.LaunchMode; @@ -60,8 +57,7 @@ public void beforeTest(Test task) { try { final Map props = task.getSystemProperties(); - final AppModel appModel = getAppModelResolver(LaunchMode.TEST) - .resolveModel(getAppArtifact()); + final ApplicationModel appModel = getApplicationModel(LaunchMode.TEST); final Path serializedModel = QuarkusGradleUtils.serializeAppModel(appModel, task, true); props.put(BootstrapConstants.SERIALIZED_TEST_APP_MODEL, serializedModel.toString()); @@ -108,10 +104,8 @@ public Path appJarOrClasses() { } } if (classesDir == null) { - final Convention convention = project.getConvention(); - JavaPluginConvention javaConvention = convention.findPlugin(JavaPluginConvention.class); - if (javaConvention != null) { - final SourceSet mainSourceSet = javaConvention.getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME); + final SourceSet mainSourceSet = getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME); + if (mainSourceSet != null) { final String classesPath = QuarkusGradleUtils.getClassesDir(mainSourceSet, jarTask.getTemporaryDir(), false); if (classesPath != null) { classesDir = Paths.get(classesPath); @@ -201,32 +195,27 @@ public Set combinedOutputSourceDirs() { return sourcesDirs; } - public AppArtifact getAppArtifact() { - return new AppArtifact(project.getGroup().toString(), project.getName(), - project.getVersion().toString()); - } - public AppModelResolver getAppModelResolver() { return getAppModelResolver(LaunchMode.NORMAL); } public AppModelResolver getAppModelResolver(LaunchMode mode) { - return new AppModelGradleResolver(project, getQuarkusModel(mode)); + return new AppModelGradleResolver(project, getApplicationModel(mode)); } - public QuarkusModel getQuarkusModel() { - return getQuarkusModel(LaunchMode.NORMAL); + public ApplicationModel getApplicationModel() { + return getApplicationModel(LaunchMode.NORMAL); } - public QuarkusModel getQuarkusModel(LaunchMode mode) { + public ApplicationModel getApplicationModel(LaunchMode mode) { return create(project, mode); } - private QuarkusModel create(Project project, LaunchMode mode) { - QuarkusModelBuilder builder = new QuarkusModelBuilder(); - ModelParameter params = new ModelParameterImpl(); + private ApplicationModel create(Project project, LaunchMode mode) { + final ModelParameter params = new ModelParameterImpl(); params.setMode(mode.toString()); - return (QuarkusModel) builder.buildAll(QuarkusModel.class.getName(), params, project); + return (ApplicationModel) new GradleApplicationModelBuilder().buildAll(ApplicationModel.class.getName(), params, + project); } /** @@ -251,5 +240,4 @@ private File getLastFile(FileCollection fileCollection) { private SourceSetContainer getSourceSets() { return project.getConvention().getPlugin(JavaPluginConvention.class).getSourceSets(); } - } diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusBuild.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusBuild.java index 76e7231fab909..919cc3a23cf4b 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusBuild.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusBuild.java @@ -24,8 +24,7 @@ import io.quarkus.bootstrap.BootstrapException; import io.quarkus.bootstrap.app.CuratedApplication; import io.quarkus.bootstrap.app.QuarkusBootstrap; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.resolver.AppModelResolver; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.runtime.util.StringUtil; public class QuarkusBuild extends QuarkusTask { @@ -109,22 +108,20 @@ public File getFastJar() { public void buildQuarkus() { getLogger().lifecycle("building quarkus jar"); - final AppArtifact appArtifact = extension().getAppArtifact(); - appArtifact.setPaths(QuarkusGradleUtils.getOutputPaths(getProject())); - final AppModelResolver modelResolver = extension().getAppModelResolver(); + final ApplicationModel appModel = extension().getApplicationModel(); - final Properties effectiveProperties = getBuildSystemProperties(appArtifact); + final Properties effectiveProperties = getBuildSystemProperties(appModel.getAppArtifact()); if (ignoredEntries != null && ignoredEntries.size() > 0) { String joinedEntries = String.join(",", ignoredEntries); effectiveProperties.setProperty("quarkus.package.user-configured-ignored-entries", joinedEntries); } try (CuratedApplication appCreationContext = QuarkusBootstrap.builder() .setBaseClassLoader(getClass().getClassLoader()) - .setAppModelResolver(modelResolver) + .setExistingModel(appModel) .setTargetDirectory(getProject().getBuildDir().toPath()) .setBaseName(extension().finalName()) .setBuildSystemProperties(effectiveProperties) - .setAppArtifact(appArtifact) + .setAppArtifact(appModel.getAppArtifact()) .setLocalProjectDiscovery(false) .setIsolateDeployment(true) .build().bootstrap()) { diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusDev.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusDev.java index 90ed99514f073..78659fa4b591d 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusDev.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusDev.java @@ -43,15 +43,11 @@ import org.gradle.util.GradleVersion; import io.quarkus.bootstrap.BootstrapConstants; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppArtifactKey; -import io.quarkus.bootstrap.model.AppDependency; -import io.quarkus.bootstrap.model.AppModel; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.model.PathsCollection; -import io.quarkus.bootstrap.resolver.AppModelResolver; -import io.quarkus.bootstrap.resolver.AppModelResolverException; import io.quarkus.deployment.dev.DevModeContext; import io.quarkus.deployment.dev.QuarkusDevModeLauncher; +import io.quarkus.maven.dependency.GACT; import io.quarkus.runtime.LaunchMode; public class QuarkusDev extends QuarkusTask { @@ -258,31 +254,22 @@ private QuarkusDevModeLauncher newLauncher() throws Exception { builder.sourceEncoding(getSourceEncoding()); - final AppModel appModel; - final AppModelResolver modelResolver = extension().getAppModelResolver(LaunchMode.DEVELOPMENT); - try { - final AppArtifact appArtifact = extension().getAppArtifact(); - appArtifact.setPaths(QuarkusGradleUtils.getOutputPaths(project)); - appModel = modelResolver.resolveModel(appArtifact); - } catch (AppModelResolverException e) { - throw new GradleException("Failed to resolve application model " + extension().getAppArtifact() + " dependencies", - e); - } - - final Set projectDependencies = new HashSet<>(); + final ApplicationModel appModel = extension().getApplicationModel(LaunchMode.DEVELOPMENT); + final Set projectDependencies = new HashSet<>(); addSelfWithLocalDeps(project, builder, new HashSet<>(), projectDependencies, true); - for (AppDependency appDependency : appModel.getFullDeploymentDeps()) { - final AppArtifact appArtifact = appDependency.getArtifact(); + for (io.quarkus.maven.dependency.ResolvedDependency artifact : appModel.getDependencies()) { //we only use the launcher for launching from the IDE, we need to exclude it - if (appArtifact.getGroupId().equals("io.quarkus") && appArtifact.getGroupId().equals("quarkus-ide-launcher")) { + if (artifact.getGroupId().equals("io.quarkus") + && artifact.getArtifactId().equals("quarkus-ide-launcher")) { continue; } - if (!projectDependencies.contains(new AppArtifactKey(appArtifact.getGroupId(), appArtifact.getArtifactId()))) { - appArtifact.getPaths().forEach(p -> { + if (!projectDependencies + .contains(new GACT(artifact.getGroupId(), artifact.getArtifactId()))) { + artifact.getResolvedPaths().forEach(p -> { if (Files.exists(p)) { - if (appArtifact.getGroupId().equals("io.quarkus") - && appArtifact.getArtifactId().equals("quarkus-class-change-agent")) { + if (artifact.getGroupId().equals("io.quarkus") + && artifact.getArtifactId().equals("quarkus-class-change-agent")) { builder.jvmArgs("-javaagent:" + p.toFile().getAbsolutePath()); } else { addToClassPaths(builder, p.toFile()); @@ -298,7 +285,7 @@ private QuarkusDevModeLauncher newLauncher() throws Exception { //to the runner jar addGradlePluginDeps(builder); - JavaPluginConvention javaPluginConvention = project.getConvention().findPlugin(JavaPluginConvention.class); + final JavaPluginConvention javaPluginConvention = project.getConvention().findPlugin(JavaPluginConvention.class); if (javaPluginConvention != null) { builder.sourceJavaVersion(javaPluginConvention.getSourceCompatibility().toString()); builder.targetJavaVersion(javaPluginConvention.getTargetCompatibility().toString()); @@ -318,17 +305,7 @@ private QuarkusDevModeLauncher newLauncher() throws Exception { serializedModel.toFile().deleteOnExit(); builder.jvmArgs("-D" + BootstrapConstants.SERIALIZED_APP_MODEL + "=" + serializedModel.toAbsolutePath()); - final AppModel testAppModel; - final AppModelResolver testModelResolver = extension().getAppModelResolver(LaunchMode.TEST); - try { - final AppArtifact appArtifact = extension().getAppArtifact(); - appArtifact.setPaths(QuarkusGradleUtils.getOutputPaths(project)); - testAppModel = testModelResolver.resolveModel(appArtifact); - } catch (AppModelResolverException e) { - throw new GradleException( - "Failed to resolve application model " + extension().getAppArtifact() + " dependencies", - e); - } + final ApplicationModel testAppModel = extension().getApplicationModel(LaunchMode.TEST); final Path serializedTestModel = QuarkusGradleUtils.serializeAppModel(testAppModel, this, true); serializedTestModel.toFile().deleteOnExit(); builder.jvmArgs("-D" + BootstrapConstants.SERIALIZED_TEST_APP_MODEL + "=" + serializedTestModel.toAbsolutePath()); @@ -347,7 +324,7 @@ protected void modifyDevModeContext(GradleDevModeLauncher.Builder builder) { } private void addSelfWithLocalDeps(Project project, GradleDevModeLauncher.Builder builder, Set visited, - Set addedDeps, boolean root) { + Set addedDeps, boolean root) { if (!visited.add(project.getPath())) { return; } @@ -363,9 +340,8 @@ private void addSelfWithLocalDeps(Project project, GradleDevModeLauncher.Builder addLocalProject(project, builder, addedDeps, root); } - private void addLocalProject(Project project, GradleDevModeLauncher.Builder builder, Set addeDeps, - boolean root) { - final AppArtifactKey key = new AppArtifactKey(project.getGroup().toString(), project.getName()); + private void addLocalProject(Project project, GradleDevModeLauncher.Builder builder, Set addeDeps, boolean root) { + final GACT key = new GACT(project.getGroup().toString(), project.getName()); if (addeDeps.contains(key)) { return; } @@ -421,7 +397,8 @@ private void addLocalProject(Project project, GradleDevModeLauncher.Builder buil resourcesOutputPath = classesDir; } - DevModeContext.ModuleInfo.Builder moduleBuilder = new DevModeContext.ModuleInfo.Builder().setAppArtifactKey(key) + DevModeContext.ModuleInfo.Builder moduleBuilder = new DevModeContext.ModuleInfo.Builder() + .setArtifactKey(new GACT(key.getGroupId(), key.getArtifactId())) .setName(project.getName()) .setProjectDirectory(project.getProjectDir().getAbsolutePath()) .setSourcePaths(PathsCollection.from(sourcePaths)) @@ -475,8 +452,7 @@ private void addLocalProject(Project project, GradleDevModeLauncher.Builder buil } } } - DevModeContext.ModuleInfo wsModuleInfo = moduleBuilder - .build(); + DevModeContext.ModuleInfo wsModuleInfo = moduleBuilder.build(); if (root) { builder.mainModule(wsModuleInfo); diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGenerateCode.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGenerateCode.java index c37c75ba9a5ff..58f67b79518df 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGenerateCode.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGenerateCode.java @@ -16,7 +16,6 @@ import org.gradle.api.GradleException; import org.gradle.api.file.FileCollection; -import org.gradle.api.plugins.Convention; import org.gradle.api.plugins.JavaPluginConvention; import org.gradle.api.tasks.CompileClasspath; import org.gradle.api.tasks.InputFiles; @@ -28,10 +27,10 @@ import io.quarkus.bootstrap.app.CuratedApplication; import io.quarkus.bootstrap.app.QuarkusBootstrap; import io.quarkus.bootstrap.classloading.QuarkusClassLoader; -import io.quarkus.bootstrap.model.AppArtifact; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.model.PathsCollection; -import io.quarkus.bootstrap.resolver.AppModelResolver; import io.quarkus.deployment.CodeGenerator; +import io.quarkus.runtime.LaunchMode; public class QuarkusGenerateCode extends QuarkusTask { @@ -89,26 +88,22 @@ public File getGeneratedOutputDirectory() { public void prepareQuarkus() { getLogger().lifecycle("preparing quarkus application"); - final AppArtifact appArtifact = extension().getAppArtifact(); - appArtifact.setPaths(QuarkusGradleUtils.getOutputPaths(getProject())); - - final AppModelResolver modelResolver = extension().getAppModelResolver(); - final Properties realProperties = getBuildSystemProperties(appArtifact); + final ApplicationModel appModel = extension().getApplicationModel(test ? LaunchMode.TEST : LaunchMode.NORMAL); + final Properties realProperties = getBuildSystemProperties(appModel.getAppArtifact()); Path buildDir = getProject().getBuildDir().toPath(); try (CuratedApplication appCreationContext = QuarkusBootstrap.builder() .setBaseClassLoader(getClass().getClassLoader()) - .setAppModelResolver(modelResolver) + .setExistingModel(appModel) .setTargetDirectory(buildDir) .setBaseName(extension().finalName()) .setBuildSystemProperties(realProperties) - .setAppArtifact(appArtifact) + .setAppArtifact(appModel.getAppArtifact()) .setLocalProjectDiscovery(false) .setIsolateDeployment(true) .build().bootstrap()) { - final Convention convention = getProject().getConvention(); - JavaPluginConvention javaConvention = convention.findPlugin(JavaPluginConvention.class); + final JavaPluginConvention javaConvention = getProject().getConvention().findPlugin(JavaPluginConvention.class); if (javaConvention != null) { final String generateSourcesDir = test ? QUARKUS_TEST_GENERATED_SOURCES : QUARKUS_GENERATED_SOURCES; final SourceSet generatedSources = javaConvention.getSourceSets().findByName(generateSourcesDir); @@ -132,12 +127,13 @@ public void prepareQuarkus() { if (!initAndRun.isPresent()) { throw new GradleException("Failed to find " + INIT_AND_RUN + " method in " + CodeGenerator.class.getName()); } + initAndRun.get().invoke(null, deploymentClassLoader, PathsCollection.from(sourcesDirectories), - paths.iterator().next(), + paths.get(0), buildDir, sourceRegistrar, - appCreationContext.getAppModel(), + appCreationContext.getApplicationModel(), realProperties); } diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGenerateConfig.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGenerateConfig.java index 73a4764e7b64f..f19b2ecbdb059 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGenerateConfig.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGenerateConfig.java @@ -15,8 +15,7 @@ import io.quarkus.bootstrap.BootstrapException; import io.quarkus.bootstrap.app.CuratedApplication; import io.quarkus.bootstrap.app.QuarkusBootstrap; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.resolver.AppModelResolver; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.runner.bootstrap.GenerateConfigTask; public class QuarkusGenerateConfig extends QuarkusTask { @@ -52,9 +51,7 @@ public void setFile(String file) { public void buildQuarkus() { getLogger().lifecycle("generating example config"); - final AppArtifact appArtifact = extension().getAppArtifact(); - appArtifact.setPaths(QuarkusGradleUtils.getOutputPaths(getProject())); - final AppModelResolver modelResolver = extension().getAppModelResolver(); + final ApplicationModel appModel = extension().getApplicationModel(); if (extension().resourcesDir().isEmpty()) { throw new GradleException("No resources directory, cannot create application.properties"); } @@ -66,10 +63,10 @@ public void buildQuarkus() { } try (CuratedApplication bootstrap = QuarkusBootstrap.builder() .setBaseClassLoader(getClass().getClassLoader()) - .setAppModelResolver(modelResolver) + .setExistingModel(appModel) .setTargetDirectory(getProject().getBuildDir().toPath()) .setBaseName(extension().finalName()) - .setAppArtifact(appArtifact) + .setAppArtifact(appModel.getAppArtifact()) .setLocalProjectDiscovery(false) .setIsolateDeployment(true) .build().bootstrap()) { diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGradleUtils.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGradleUtils.java index b83875b915ccd..3019061530229 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGradleUtils.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGradleUtils.java @@ -12,11 +12,10 @@ import org.gradle.api.Project; import org.gradle.api.Task; import org.gradle.api.file.FileCollection; -import org.gradle.api.plugins.Convention; import org.gradle.api.plugins.JavaPluginConvention; import org.gradle.api.tasks.SourceSet; -import io.quarkus.bootstrap.model.AppModel; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.bootstrap.util.IoUtils; @@ -24,7 +23,7 @@ public class QuarkusGradleUtils { private static final String ERROR_COLLECTING_PROJECT_CLASSES = "Failed to collect project's classes in a temporary dir"; - public static Path serializeAppModel(final AppModel appModel, Task context, boolean test) throws IOException { + public static Path serializeAppModel(ApplicationModel appModel, Task context, boolean test) throws IOException { final Path serializedModel = context.getTemporaryDir().toPath() .resolve("quarkus-app" + (test ? "-test" : "") + "-model.dat"); try (ObjectOutputStream out = new ObjectOutputStream(Files.newOutputStream(serializedModel))) { @@ -34,8 +33,7 @@ public static Path serializeAppModel(final AppModel appModel, Task context, bool } public static SourceSet getSourceSet(Project project, String sourceSetName) { - final Convention convention = project.getConvention(); - JavaPluginConvention javaConvention = convention.findPlugin(JavaPluginConvention.class); + final JavaPluginConvention javaConvention = project.getConvention().findPlugin(JavaPluginConvention.class); if (javaConvention == null) { throw new IllegalArgumentException("The project does not include the Java plugin"); } diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusPlatformTask.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusPlatformTask.java index 20ebaff3816ba..7372ac3a10de2 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusPlatformTask.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusPlatformTask.java @@ -18,7 +18,6 @@ import org.gradle.api.plugins.JavaPlugin; import io.quarkus.bootstrap.BootstrapConstants; -import io.quarkus.bootstrap.model.AppArtifactKey; import io.quarkus.devtools.messagewriter.MessageWriter; import io.quarkus.devtools.project.QuarkusProject; import io.quarkus.devtools.project.QuarkusProjectHelper; @@ -26,6 +25,8 @@ import io.quarkus.devtools.project.buildfile.GradleGroovyProjectBuildFile; import io.quarkus.devtools.project.buildfile.GradleKotlinProjectBuildFile; import io.quarkus.maven.ArtifactCoords; +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.GACT; import io.quarkus.platform.tools.ToolsUtils; import io.quarkus.registry.ExtensionCatalogResolver; import io.quarkus.registry.RegistryResolutionException; @@ -65,12 +66,12 @@ protected List importedPlatforms() { final Configuration boms = getProject().getConfigurations() .detachedConfiguration(bomDeps.toArray(new org.gradle.api.artifacts.Dependency[0])); - final Set processedKeys = new HashSet<>(1); + final Set processedKeys = new HashSet<>(1); List platforms = new ArrayList<>(); boms.getResolutionStrategy().eachDependency(d -> { if (!d.getTarget().getName().endsWith(BootstrapConstants.PLATFORM_DESCRIPTOR_ARTIFACT_ID_SUFFIX) - || !processedKeys.add(new AppArtifactKey(d.getTarget().getGroup(), d.getTarget().getName()))) { + || !processedKeys.add(new GACT(d.getTarget().getGroup(), d.getTarget().getName()))) { return; } final ArtifactCoords platform = new ArtifactCoords(d.getTarget().getGroup(), d.getTarget().getName(), diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusTask.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusTask.java index 257ce171183a4..41600035f4b47 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusTask.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusTask.java @@ -5,8 +5,8 @@ import org.gradle.api.DefaultTask; -import io.quarkus.bootstrap.model.AppArtifact; import io.quarkus.gradle.extension.QuarkusPluginExtension; +import io.quarkus.maven.dependency.ResolvedDependency; public abstract class QuarkusTask extends DefaultTask { @@ -26,7 +26,7 @@ QuarkusPluginExtension extension() { return extension; } - protected Properties getBuildSystemProperties(AppArtifact appArtifact) { + protected Properties getBuildSystemProperties(ResolvedDependency appArtifact) { final Map properties = getProject().getProperties(); final Properties realProperties = new Properties(); for (Map.Entry entry : properties.entrySet()) { diff --git a/devtools/gradle/gradle-application-plugin/src/test/java/io/quarkus/gradle/builder/QuarkusModelBuilderTest.java b/devtools/gradle/gradle-application-plugin/src/test/java/io/quarkus/gradle/builder/QuarkusModelBuilderTest.java index 044f7b410f131..ea81d7e889998 100644 --- a/devtools/gradle/gradle-application-plugin/src/test/java/io/quarkus/gradle/builder/QuarkusModelBuilderTest.java +++ b/devtools/gradle/gradle-application-plugin/src/test/java/io/quarkus/gradle/builder/QuarkusModelBuilderTest.java @@ -18,6 +18,6 @@ void testToAppDependency() { when(version.toString()).thenReturn(":commons-lang3-3.9:"); when(artifact.getModuleVersion()).thenReturn(version); when(artifact.getFile()).thenReturn(Files.currentFolder()); - assertThatCode(() -> QuarkusModelBuilder.toDependency(artifact)).doesNotThrowAnyException(); + assertThatCode(() -> GradleApplicationModelBuilder.toDependency(artifact)).doesNotThrowAnyException(); } } diff --git a/devtools/gradle/gradle-extension-plugin/src/main/java/io/quarkus/extension/gradle/tasks/ExtensionDescriptorTask.java b/devtools/gradle/gradle-extension-plugin/src/main/java/io/quarkus/extension/gradle/tasks/ExtensionDescriptorTask.java index 4f9d639c2695c..1dece3505367e 100644 --- a/devtools/gradle/gradle-extension-plugin/src/main/java/io/quarkus/extension/gradle/tasks/ExtensionDescriptorTask.java +++ b/devtools/gradle/gradle-extension-plugin/src/main/java/io/quarkus/extension/gradle/tasks/ExtensionDescriptorTask.java @@ -14,9 +14,9 @@ import io.quarkus.bootstrap.BootstrapConstants; import io.quarkus.bootstrap.model.AppArtifactCoords; -import io.quarkus.bootstrap.model.AppArtifactKey; import io.quarkus.bootstrap.model.AppModel; import io.quarkus.extension.gradle.QuarkusExtensionConfiguration; +import io.quarkus.maven.dependency.GACT; /** * Task that generates extension descriptor files. @@ -67,9 +67,9 @@ private void generateQuarkusExtensionProperties(File outputDir) { if (dependencyConditions != null && !dependencyConditions.isEmpty()) { final StringBuilder buf = new StringBuilder(); int i = 0; - buf.append(AppArtifactKey.fromString(dependencyConditions.get(i++)).toGacString()); + buf.append(GACT.fromString(dependencyConditions.get(i++)).toGacString()); while (i < dependencyConditions.size()) { - buf.append(' ').append(AppArtifactKey.fromString(dependencyConditions.get(i++)).toGacString()); + buf.append(' ').append(GACT.fromString(dependencyConditions.get(i++)).toGacString()); } props.setProperty(BootstrapConstants.DEPENDENCY_CONDITION, buf.toString()); } diff --git a/devtools/maven/src/main/java/io/quarkus/maven/DependencyTreeMojo.java b/devtools/maven/src/main/java/io/quarkus/maven/DependencyTreeMojo.java index 760bc863f6ea6..49f330da42709 100644 --- a/devtools/maven/src/main/java/io/quarkus/maven/DependencyTreeMojo.java +++ b/devtools/maven/src/main/java/io/quarkus/maven/DependencyTreeMojo.java @@ -13,10 +13,10 @@ import org.apache.maven.project.MavenProject; import org.eclipse.aether.repository.RemoteRepository; -import io.quarkus.bootstrap.model.AppArtifact; import io.quarkus.bootstrap.resolver.BootstrapAppModelResolver; import io.quarkus.bootstrap.resolver.maven.BootstrapMavenException; import io.quarkus.bootstrap.resolver.maven.MavenArtifactResolver; +import io.quarkus.maven.dependency.GACTV; /** * Displays Quarkus application build dependency tree including the deployment ones. @@ -48,8 +48,7 @@ public void execute() throws MojoExecutionException, MojoFailureException { String buf = "Quarkus application " + mode.toUpperCase() + " mode build dependency tree:"; getLog().info(buf); - final AppArtifact appArtifact = new AppArtifact(project.getGroupId(), project.getArtifactId(), null, "pom", - project.getVersion()); + final GACTV appArtifact = new GACTV(project.getGroupId(), project.getArtifactId(), null, "pom", project.getVersion()); final BootstrapAppModelResolver modelResolver; try { modelResolver = new BootstrapAppModelResolver(resolver()); diff --git a/devtools/maven/src/main/java/io/quarkus/maven/DevMojo.java b/devtools/maven/src/main/java/io/quarkus/maven/DevMojo.java index 54df7df8f1641..6f5ebef76c8ac 100644 --- a/devtools/maven/src/main/java/io/quarkus/maven/DevMojo.java +++ b/devtools/maven/src/main/java/io/quarkus/maven/DevMojo.java @@ -65,6 +65,7 @@ import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.artifact.DefaultArtifact; import org.eclipse.aether.collection.CollectRequest; +import org.eclipse.aether.impl.RemoteRepositoryManager; import org.eclipse.aether.repository.RemoteRepository; import org.eclipse.aether.repository.WorkspaceReader; import org.eclipse.aether.resolution.ArtifactRequest; @@ -77,17 +78,24 @@ import org.fusesource.jansi.internal.Kernel32; import org.fusesource.jansi.internal.WindowsSupport; +import io.quarkus.bootstrap.BootstrapConstants; import io.quarkus.bootstrap.devmode.DependenciesFilter; import io.quarkus.bootstrap.model.AppArtifactKey; -import io.quarkus.bootstrap.model.AppModel; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.model.PathsCollection; +import io.quarkus.bootstrap.resolver.BootstrapAppModelResolver; +import io.quarkus.bootstrap.resolver.maven.MavenArtifactResolver; import io.quarkus.bootstrap.resolver.maven.options.BootstrapMavenOptions; -import io.quarkus.bootstrap.resolver.maven.workspace.LocalProject; +import io.quarkus.bootstrap.util.BootstrapUtils; +import io.quarkus.bootstrap.workspace.WorkspaceModule; import io.quarkus.deployment.dev.DevModeContext; import io.quarkus.deployment.dev.DevModeMain; import io.quarkus.deployment.dev.QuarkusDevModeLauncher; import io.quarkus.maven.MavenDevModeLauncher.Builder; import io.quarkus.maven.components.MavenVersionEnforcer; +import io.quarkus.maven.dependency.GACT; +import io.quarkus.maven.dependency.GACTV; +import io.quarkus.runtime.LaunchMode; /** * The dev mojo, that runs a quarkus app in a forked process. A background compilation process is launched and any changes are @@ -254,6 +262,9 @@ public class DevMojo extends AbstractMojo { @Component private RepositorySystem repoSystem; + @Component + RemoteRepositoryManager remoteRepositoryManager; + @Parameter(defaultValue = "${repositorySystemSession}", readonly = true) private RepositorySystemSession repoSession; @@ -316,6 +327,9 @@ public class DevMojo extends AbstractMojo { private Map pluginMap; + @Component + protected QuarkusBootstrapProvider bootstrapProvider; + /** * console attributes, used to restore the console state */ @@ -499,12 +513,13 @@ private void handleAutoCompile() throws MojoExecutionException { } private void initToolchain() throws MojoExecutionException { - executeIfConfigured(ORG_APACHE_MAVEN_PLUGINS, MAVEN_TOOLCHAINS_PLUGIN, "toolchain"); + executeIfConfigured(ORG_APACHE_MAVEN_PLUGINS, MAVEN_TOOLCHAINS_PLUGIN, "toolchain", Collections.emptyMap()); } private void triggerPrepare() throws MojoExecutionException { final PluginDescriptor pluginDescr = getPluginDescriptor(); - executeIfConfigured(pluginDescr.getGroupId(), pluginDescr.getArtifactId(), QUARKUS_GENERATE_CODE_GOAL); + executeIfConfigured(pluginDescr.getGroupId(), pluginDescr.getArtifactId(), QUARKUS_GENERATE_CODE_GOAL, + Collections.singletonMap("mode", LaunchMode.DEVELOPMENT.name())); } private PluginDescriptor getPluginDescriptor() { @@ -515,10 +530,12 @@ private void triggerCompile(boolean test) throws MojoExecutionException { handleResources(test); // compile the Kotlin sources if needed - executeIfConfigured(ORG_JETBRAINS_KOTLIN, KOTLIN_MAVEN_PLUGIN, test ? "test-compile" : "compile"); + executeIfConfigured(ORG_JETBRAINS_KOTLIN, KOTLIN_MAVEN_PLUGIN, test ? "test-compile" : "compile", + Collections.emptyMap()); // Compile the Java sources if needed - executeIfConfigured(ORG_APACHE_MAVEN_PLUGINS, MAVEN_COMPILER_PLUGIN, test ? "testCompile" : "compile"); + executeIfConfigured(ORG_APACHE_MAVEN_PLUGINS, MAVEN_COMPILER_PLUGIN, test ? "testCompile" : "compile", + Collections.emptyMap()); } /** @@ -529,16 +546,18 @@ private void handleResources(boolean test) throws MojoExecutionException { if (resources.isEmpty()) { return; } - executeIfConfigured(ORG_APACHE_MAVEN_PLUGINS, MAVEN_RESOURCES_PLUGIN, test ? "testResources" : "resources"); + executeIfConfigured(ORG_APACHE_MAVEN_PLUGINS, MAVEN_RESOURCES_PLUGIN, test ? "testResources" : "resources", + Collections.emptyMap()); } - private void executeIfConfigured(String pluginGroupId, String pluginArtifactId, String goal) throws MojoExecutionException { + private void executeIfConfigured(String pluginGroupId, String pluginArtifactId, String goal, Map params) + throws MojoExecutionException { final Plugin plugin = getConfiguredPluginOrNull(pluginGroupId, pluginArtifactId); if (!isGoalConfigured(plugin, goal)) { return; } getLog().info("Invoking " + plugin.getGroupId() + ":" + plugin.getArtifactId() + ":" + plugin.getVersion() + ":" + goal - + " @ " + project.getArtifactId()); + + ") @ " + project.getArtifactId()); executeMojo( plugin( groupId(pluginGroupId), @@ -546,7 +565,7 @@ private void executeIfConfigured(String pluginGroupId, String pluginArtifactId, version(plugin.getVersion()), plugin.getDependencies()), goal(goal), - getPluginConfig(plugin, goal), + getPluginConfig(plugin, goal, params), executionEnvironment( project, session, @@ -565,7 +584,7 @@ public boolean isGoalConfigured(Plugin plugin, String goal) { return false; } - private Xpp3Dom getPluginConfig(Plugin plugin, String goal) throws MojoExecutionException { + private Xpp3Dom getPluginConfig(Plugin plugin, String goal, Map params) throws MojoExecutionException { Xpp3Dom mergedConfig = null; if (!plugin.getExecutions().isEmpty()) { for (PluginExecution exec : plugin.getExecutions()) { @@ -598,6 +617,12 @@ private Xpp3Dom getPluginConfig(Plugin plugin, String goal) throws MojoExecution } } + for (Map.Entry param : params.entrySet()) { + final Xpp3Dom p = new Xpp3Dom(param.getKey()); + p.setValue(param.getValue()); + configuration.addChild(p); + } + return configuration; } @@ -637,7 +662,7 @@ private String getSourceEncoding() { return null; } - private void addProject(MavenDevModeLauncher.Builder builder, LocalProject localProject, boolean root) throws Exception { + private void addProject(MavenDevModeLauncher.Builder builder, WorkspaceModule module, boolean root) throws Exception { String projectDirectory; Set sourcePaths; @@ -649,13 +674,14 @@ private void addProject(MavenDevModeLauncher.Builder builder, LocalProject local List activeProfiles = Collections.emptyList(); final MavenProject mavenProject = session.getProjectMap().get( - String.format("%s:%s:%s", localProject.getGroupId(), localProject.getArtifactId(), localProject.getVersion())); + String.format("%s:%s:%s", module.getId().getGroupId(), module.getId().getArtifactId(), + module.getId().getVersion())); if (mavenProject == null) { - projectDirectory = localProject.getDir().toAbsolutePath().toString(); - Path sourcePath = localProject.getSourcesSourcesDir().toAbsolutePath(); - sourcePaths = Collections.singleton(sourcePath); - Path testSourcePath = localProject.getTestSourcesSourcesDir().toAbsolutePath(); - testSourcePaths = Collections.singleton(testSourcePath); + projectDirectory = module.getModuleDir().getAbsolutePath(); + sourcePaths = module.getMainSources().stream().map(src -> src.getSourceDir().toPath().toAbsolutePath()) + .collect(Collectors.toCollection(LinkedHashSet::new)); + testSourcePaths = module.getTestSources().stream().map(src -> src.getSourceDir().toPath().toAbsolutePath()) + .collect(Collectors.toCollection(LinkedHashSet::new)); } else { projectDirectory = mavenProject.getBasedir().getPath(); sourcePaths = mavenProject.getCompileSourceRoots().stream() @@ -668,19 +694,27 @@ private void addProject(MavenDevModeLauncher.Builder builder, LocalProject local .collect(Collectors.toCollection(LinkedHashSet::new)); activeProfiles = mavenProject.getActiveProfiles(); } - Path sourceParent = localProject.getSourcesDir().toAbsolutePath(); - Path classesDir = localProject.getClassesDir(); + final Path sourceParent; + if (module.getMainSources().isEmpty()) { + if (module.getMainResources().isEmpty()) { + throw new MojoExecutionException("The project does not appear to contain any sources or resources"); + } + sourceParent = module.getMainResources().iterator().next().getSourceDir().toPath().toAbsolutePath().getParent(); + } else { + sourceParent = module.getMainSources().iterator().next().getSourceDir().toPath().toAbsolutePath().getParent(); + } + + Path classesDir = module.getMainResources().iterator().next().getDestinationDir().toPath().toAbsolutePath(); if (Files.isDirectory(classesDir)) { - classesPath = classesDir.toAbsolutePath().toString(); + classesPath = classesDir.toString(); } - Path testClassesDir = localProject.getTestClassesDir(); - testClassesPath = testClassesDir.toAbsolutePath().toString(); - resourcePaths = localProject.getResourcesSourcesDirs().toList().stream() - .map(Path::toAbsolutePath) + Path testClassesDir = module.getTestSources().iterator().next().getDestinationDir().toPath().toAbsolutePath(); + testClassesPath = testClassesDir.toString(); + + resourcePaths = module.getMainResources().stream().map(src -> src.getSourceDir().toPath().toAbsolutePath()) .collect(Collectors.toCollection(LinkedHashSet::new)); - testResourcePaths = localProject.getTestResourcesSourcesDirs().toList().stream() - .map(Path::toAbsolutePath) + testResourcePaths = module.getTestResources().stream().map(src -> src.getSourceDir().toPath().toAbsolutePath()) .collect(Collectors.toCollection(LinkedHashSet::new)); // Add the resources and test resources from the profiles for (Profile profile : activeProfiles) { @@ -689,27 +723,28 @@ private void addProject(MavenDevModeLauncher.Builder builder, LocalProject local resourcePaths.addAll( build.getResources().stream() .map(Resource::getDirectory) - .map(localProject::resolveRelativeToBaseDir) + .map(Paths::get) .map(Path::toAbsolutePath) .collect(Collectors.toList())); testResourcePaths.addAll( build.getTestResources().stream() .map(Resource::getDirectory) - .map(localProject::resolveRelativeToBaseDir) + .map(Paths::get) .map(Path::toAbsolutePath) .collect(Collectors.toList())); } } if (classesPath == null && (!sourcePaths.isEmpty() || !resourcePaths.isEmpty())) { - throw new MojoExecutionException("Hot reloadable dependency " + localProject.getAppArtifact() + throw new MojoExecutionException("Hot reloadable dependency " + module.getId() + " has not been compiled yet (the classes directory " + classesDir + " does not exist)"); } Path targetDir = Paths.get(project.getBuild().getDirectory()); - DevModeContext.ModuleInfo moduleInfo = new DevModeContext.ModuleInfo.Builder().setAppArtifactKey(localProject.getKey()) - .setName(localProject.getArtifactId()) + DevModeContext.ModuleInfo moduleInfo = new DevModeContext.ModuleInfo.Builder() + .setArtifactKey(new GACT(module.getId().getGroupId(), module.getId().getArtifactId())) + .setName(module.getId().getArtifactId()) .setProjectDirectory(projectDirectory) .setSourcePaths(PathsCollection.from(sourcePaths)) .setClassesPath(classesPath) @@ -865,18 +900,50 @@ private QuarkusDevModeLauncher newLauncher() throws Exception { } setKotlinSpecificFlags(builder); + + // path to the serialized application model + final Path appModelLocation = resolveSerializedModelLocation(); + + ApplicationModel appModel = bootstrapProvider + .getResolvedApplicationModel(QuarkusBootstrapProvider.getProjectId(project), LaunchMode.DEVELOPMENT); + if (appModel != null) { + bootstrapProvider.close(); + } else { + final MavenArtifactResolver.Builder resolverBuilder = MavenArtifactResolver.builder() + .setRepositorySystem(repoSystem) + .setRemoteRepositories(repos) + .setRemoteRepositoryManager(remoteRepositoryManager) + .setWorkspaceDiscovery(true); + + // if it already exists, it may be a reload triggered by a change in a POM + // in which case we should not be using the original Maven session + boolean reinitializeMavenSession = Files.exists(appModelLocation); + if (reinitializeMavenSession) { + Files.delete(appModelLocation); + } else { + // we can re-use the original Maven session + resolverBuilder.setRepositorySystemSession(repoSession); + } + + appModel = new BootstrapAppModelResolver(resolverBuilder.build()) + .setDevMode(true) + .setCollectReloadableDependencies(!noDeps) + .resolveModel(new GACTV(project.getGroupId(), project.getArtifactId(), null, "jar", project.getVersion())); + } + + // serialize the app model to avoid re-resolving it in the dev process + BootstrapUtils.serializeAppModel(appModel, appModelLocation); + builder.jvmArgs("-D" + BootstrapConstants.SERIALIZED_APP_MODEL + "=" + appModelLocation); + if (noDeps) { - final LocalProject localProject = LocalProject.load(project.getModel().getPomFile().toPath()); - addProject(builder, localProject, true); - builder.watchedBuildFile(localProject.getRawModel().getPomFile().toPath()); - builder.localArtifact(new AppArtifactKey(localProject.getGroupId(), localProject.getArtifactId(), null, "jar")); + addProject(builder, appModel.getApplicationModule(), true); + appModel.getApplicationModule().getBuildFiles().forEach(p -> builder.watchedBuildFile(p)); + builder.localArtifact(new AppArtifactKey(project.getGroupId(), project.getArtifactId())); } else { - final LocalProject localProject = LocalProject.loadWorkspace(project.getModel().getPomFile().toPath()); - for (LocalProject project : DependenciesFilter.filterNotReloadableDependencies(localProject, - this.project.getArtifacts(), repoSystem, repoSession, repos)) { - addProject(builder, project, project == localProject); - builder.watchedBuildFile(project.getRawModel().getPomFile().toPath()); - builder.localArtifact(new AppArtifactKey(project.getGroupId(), project.getArtifactId(), null, "jar")); + for (WorkspaceModule project : DependenciesFilter.getReloadableModules(appModel)) { + addProject(builder, project, project == appModel.getApplicationModule()); + project.getBuildFiles().forEach(p -> builder.watchedBuildFile(p)); + builder.localArtifact(new AppArtifactKey(project.getId().getGroupId(), project.getId().getArtifactId())); } } @@ -894,7 +961,7 @@ private QuarkusDevModeLauncher newLauncher() throws Exception { Properties p = new Properties(); try (InputStream inputStream = file.getInputStream(entry)) { p.load(inputStream); - String parentFirst = p.getProperty(AppModel.PARENT_FIRST_ARTIFACTS); + String parentFirst = p.getProperty(ApplicationModel.PARENT_FIRST_ARTIFACTS); if (parentFirst != null) { String[] artifacts = parentFirst.split(","); for (String artifact : artifacts) { @@ -1077,4 +1144,10 @@ private Optional findCompilerPluginConfiguration() { } return Optional.empty(); } + + private Path resolveSerializedModelLocation() { + final Path p = BootstrapUtils.resolveSerializedAppModelPath(Paths.get(project.getBuild().getDirectory())); + p.toFile().deleteOnExit(); + return p; + } } diff --git a/devtools/maven/src/main/java/io/quarkus/maven/GenerateCodeMojo.java b/devtools/maven/src/main/java/io/quarkus/maven/GenerateCodeMojo.java index cd72420cce4eb..d233f5881ed5d 100644 --- a/devtools/maven/src/main/java/io/quarkus/maven/GenerateCodeMojo.java +++ b/devtools/maven/src/main/java/io/quarkus/maven/GenerateCodeMojo.java @@ -15,8 +15,9 @@ import io.quarkus.bootstrap.app.CuratedApplication; import io.quarkus.bootstrap.classloading.QuarkusClassLoader; -import io.quarkus.bootstrap.model.AppModel; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.model.PathsCollection; +import io.quarkus.runtime.LaunchMode; @Mojo(name = "generate-code", defaultPhase = LifecyclePhase.GENERATE_SOURCES, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, threadSafe = true) public class GenerateCodeMojo extends QuarkusBootstrapMojo { @@ -27,6 +28,9 @@ public class GenerateCodeMojo extends QuarkusBootstrapMojo { @Parameter(defaultValue = "false", property = "quarkus.generate-code.skip", alias = "quarkus.prepare.skip") private boolean skipSourceGeneration = false; + @Parameter(defaultValue = "NORMAL", property = "launchMode") + String mode; + @Override protected boolean beforeExecute() throws MojoExecutionException, MojoFailureException { if (mavenProject().getPackaging().equals("pom")) { @@ -51,10 +55,15 @@ void generateCode(Path sourcesDir, Consumer sourceRegistrar, boolean test) throws MojoFailureException, MojoExecutionException { + final LaunchMode launchMode = test ? LaunchMode.TEST : LaunchMode.valueOf(mode); + if (getLog().isDebugEnabled()) { + getLog().debug("Bootstrapping Quarkus application in mode " + launchMode); + } + ClassLoader originalTccl = Thread.currentThread().getContextClassLoader(); try { - final CuratedApplication curatedApplication = bootstrapApplication(); + final CuratedApplication curatedApplication = bootstrapApplication(launchMode); QuarkusClassLoader deploymentClassLoader = curatedApplication.createDeploymentClassLoader(); Thread.currentThread().setContextClassLoader(deploymentClassLoader); @@ -63,13 +72,13 @@ void generateCode(Path sourcesDir, final Method initAndRun = codeGenerator.getMethod("initAndRun", ClassLoader.class, PathsCollection.class, Path.class, Path.class, - Consumer.class, AppModel.class, Map.class); + Consumer.class, ApplicationModel.class, Map.class); initAndRun.invoke(null, deploymentClassLoader, PathsCollection.of(sourcesDir), generatedSourcesDir(test), buildDir().toPath(), sourceRegistrar, - curatedApplication.getAppModel(), + curatedApplication.getApplicationModel(), mavenProject().getProperties()); } catch (Exception any) { throw new MojoExecutionException("Quarkus code generation phase has failed", any); diff --git a/devtools/maven/src/main/java/io/quarkus/maven/GenerateConfigMojo.java b/devtools/maven/src/main/java/io/quarkus/maven/GenerateConfigMojo.java index cadf0c0b1e755..c6608f63a00e5 100644 --- a/devtools/maven/src/main/java/io/quarkus/maven/GenerateConfigMojo.java +++ b/devtools/maven/src/main/java/io/quarkus/maven/GenerateConfigMojo.java @@ -27,8 +27,8 @@ import io.quarkus.bootstrap.app.CuratedApplication; import io.quarkus.bootstrap.app.QuarkusBootstrap; -import io.quarkus.bootstrap.model.AppArtifact; import io.quarkus.bootstrap.resolver.maven.MavenArtifactResolver; +import io.quarkus.maven.dependency.ResolvedArtifactDependency; import io.quarkus.runner.bootstrap.GenerateConfigTask; /** @@ -125,10 +125,10 @@ public void execute() throws MojoExecutionException { .build(); final Artifact projectArtifact = project.getArtifact(); - final AppArtifact appArtifact = new AppArtifact(projectArtifact.getGroupId(), projectArtifact.getArtifactId(), + final ResolvedArtifactDependency appArtifact = new ResolvedArtifactDependency(projectArtifact.getGroupId(), + projectArtifact.getArtifactId(), projectArtifact.getClassifier(), projectArtifact.getArtifactHandler().getExtension(), - projectArtifact.getVersion()); - appArtifact.setPath(classesDir); + projectArtifact.getVersion(), classesDir); try (CuratedApplication curatedApplication = QuarkusBootstrap .builder() diff --git a/devtools/maven/src/main/java/io/quarkus/maven/QuarkusBootstrapMojo.java b/devtools/maven/src/main/java/io/quarkus/maven/QuarkusBootstrapMojo.java index 79fc3d69493fe..95c36a7715b42 100644 --- a/devtools/maven/src/main/java/io/quarkus/maven/QuarkusBootstrapMojo.java +++ b/devtools/maven/src/main/java/io/quarkus/maven/QuarkusBootstrapMojo.java @@ -20,10 +20,8 @@ import org.eclipse.aether.repository.RemoteRepository; import io.quarkus.bootstrap.app.CuratedApplication; -import io.quarkus.bootstrap.app.QuarkusBootstrap; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppArtifactKey; -import io.quarkus.bootstrap.resolver.maven.MavenArtifactResolver; +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.runtime.LaunchMode; public abstract class QuarkusBootstrapMojo extends AbstractMojo { @@ -115,7 +113,7 @@ public abstract class QuarkusBootstrapMojo extends AbstractMojo { @Parameter(defaultValue = "${mojoExecution}", readonly = true, required = true) private MojoExecution mojoExecution; - private AppArtifactKey projectId; + private ArtifactKey projectId; @Override public void execute() throws MojoExecutionException, MojoFailureException { @@ -200,25 +198,15 @@ protected String executionId() { return mojoExecution.getExecutionId(); } - protected AppArtifactKey projectId() { - return projectId == null ? projectId = new AppArtifactKey(project.getGroupId(), project.getArtifactId()) : projectId; + protected ArtifactKey projectId() { + return projectId == null ? projectId = QuarkusBootstrapProvider.getProjectId(project) : projectId; } - // @deprecated in 1.14.0.Final - @Deprecated - protected AppArtifact projectArtifact() throws MojoExecutionException { - return bootstrapProvider.projectArtifact(this); - } - - protected MavenArtifactResolver artifactResolver() throws MojoExecutionException { - return bootstrapProvider.artifactResolver(this); - } - - protected QuarkusBootstrap bootstrapQuarkus() throws MojoExecutionException { - return bootstrapProvider.bootstrapQuarkus(this); + protected CuratedApplication bootstrapApplication() throws MojoExecutionException { + return bootstrapApplication(LaunchMode.NORMAL); } - protected CuratedApplication bootstrapApplication() throws MojoExecutionException { - return bootstrapProvider.bootstrapApplication(this); + protected CuratedApplication bootstrapApplication(LaunchMode mode) throws MojoExecutionException { + return bootstrapProvider.bootstrapApplication(this, mode); } } diff --git a/devtools/maven/src/main/java/io/quarkus/maven/QuarkusBootstrapProvider.java b/devtools/maven/src/main/java/io/quarkus/maven/QuarkusBootstrapProvider.java index 1ce97e18e35f8..8e587e88f8808 100644 --- a/devtools/maven/src/main/java/io/quarkus/maven/QuarkusBootstrapProvider.java +++ b/devtools/maven/src/main/java/io/quarkus/maven/QuarkusBootstrapProvider.java @@ -6,7 +6,12 @@ import java.io.Closeable; import java.io.File; import java.io.IOException; +import java.nio.file.Path; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; import java.util.Properties; +import java.util.Set; import java.util.concurrent.ExecutionException; import org.apache.maven.artifact.Artifact; @@ -15,7 +20,6 @@ import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Requirement; import org.eclipse.aether.RepositorySystem; -import org.eclipse.aether.artifact.DefaultArtifact; import org.eclipse.aether.impl.RemoteRepositoryManager; import com.google.common.cache.Cache; @@ -24,11 +28,17 @@ import io.quarkus.bootstrap.BootstrapException; import io.quarkus.bootstrap.app.CuratedApplication; import io.quarkus.bootstrap.app.QuarkusBootstrap; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppArtifactKey; -import io.quarkus.bootstrap.model.PathsCollection; +import io.quarkus.bootstrap.model.ApplicationModel; +import io.quarkus.bootstrap.resolver.AppModelResolverException; +import io.quarkus.bootstrap.resolver.BootstrapAppModelResolver; import io.quarkus.bootstrap.resolver.maven.BootstrapMavenException; import io.quarkus.bootstrap.resolver.maven.MavenArtifactResolver; +import io.quarkus.maven.dependency.ArtifactCoords; +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.GACT; +import io.quarkus.maven.dependency.GACTV; +import io.quarkus.maven.dependency.ResolvedArtifactDependency; +import io.quarkus.runtime.LaunchMode; import io.smallrye.common.expression.Expression; @Component(role = QuarkusBootstrapProvider.class, instantiationStrategy = "singleton") @@ -43,6 +53,10 @@ public class QuarkusBootstrapProvider implements Closeable { private final Cache appBootstrapProviders = CacheBuilder.newBuilder() .concurrencyLevel(4).softValues().initialCapacity(10).build(); + static ArtifactKey getProjectId(MavenProject project) { + return new GACT(project.getGroupId(), project.getArtifactId()); + } + public RepositorySystem repositorySystem() { return repoSystem; } @@ -51,7 +65,7 @@ public RemoteRepositoryManager remoteRepositoryManager() { return remoteRepoManager; } - private QuarkusAppBootstrapProvider provider(AppArtifactKey projectId, String executionId) { + private QuarkusAppBootstrapProvider provider(ArtifactKey projectId, String executionId) { try { return appBootstrapProviders.get(String.format("%s-%s", projectId, executionId), QuarkusAppBootstrapProvider::new); } catch (ExecutionException e) { @@ -60,26 +74,26 @@ private QuarkusAppBootstrapProvider provider(AppArtifactKey projectId, String ex } } - public MavenArtifactResolver artifactResolver(QuarkusBootstrapMojo mojo) - throws MojoExecutionException { - return provider(mojo.projectId(), mojo.executionId()).artifactResolver(mojo); - } - - // @deprecated in 1.14.0.Final - @Deprecated - public AppArtifact projectArtifact(QuarkusBootstrapMojo mojo) - throws MojoExecutionException { - return provider(mojo.projectId(), mojo.executionId()).appArtifact(mojo); - } - - public QuarkusBootstrap bootstrapQuarkus(QuarkusBootstrapMojo mojo) + public CuratedApplication bootstrapApplication(QuarkusBootstrapMojo mojo, LaunchMode mode) throws MojoExecutionException { - return provider(mojo.projectId(), mojo.executionId()).bootstrapQuarkus(mojo); + return provider(mojo.projectId(), mojo.executionId()).bootstrapApplication(mojo, mode); } - public CuratedApplication bootstrapApplication(QuarkusBootstrapMojo mojo) - throws MojoExecutionException { - return provider(mojo.projectId(), mojo.executionId()).curateApplication(mojo); + public ApplicationModel getResolvedApplicationModel(ArtifactKey projectId, LaunchMode mode) { + if (appBootstrapProviders.size() == 0) { + return null; + } + final QuarkusAppBootstrapProvider provider = appBootstrapProviders.getIfPresent(projectId + "-null"); + if (provider == null) { + return null; + } + if (mode == LaunchMode.DEVELOPMENT) { + return provider.devApp == null ? null : provider.devApp.getApplicationModel(); + } + if (mode == LaunchMode.TEST) { + return provider.testApp == null ? null : provider.testApp.getApplicationModel(); + } + return provider.prodApp == null ? null : provider.prodApp.getApplicationModel(); } @Override @@ -98,19 +112,16 @@ public void close() throws IOException { private class QuarkusAppBootstrapProvider implements Closeable { - private AppArtifact appArtifact; - private MavenArtifactResolver artifactResolver; - private QuarkusBootstrap quarkusBootstrap; - private CuratedApplication curatedApp; + private CuratedApplication prodApp; + private CuratedApplication devApp; + private CuratedApplication testApp; - private MavenArtifactResolver artifactResolver(QuarkusBootstrapMojo mojo) + private MavenArtifactResolver artifactResolver(QuarkusBootstrapMojo mojo, LaunchMode mode) throws MojoExecutionException { - if (artifactResolver != null) { - return artifactResolver; - } try { - return artifactResolver = MavenArtifactResolver.builder() - .setWorkspaceDiscovery(false) + return MavenArtifactResolver.builder() + .setWorkspaceDiscovery(mode == LaunchMode.DEVELOPMENT || mode == LaunchMode.TEST) + .setPreferPomsFromWorkspace(mode == LaunchMode.DEVELOPMENT || mode == LaunchMode.TEST) .setRepositorySystem(repoSystem) .setRepositorySystemSession(mojo.repositorySystemSession()) .setRemoteRepositories(mojo.remoteRepositories()) @@ -121,11 +132,8 @@ private MavenArtifactResolver artifactResolver(QuarkusBootstrapMojo mojo) } } - protected QuarkusBootstrap bootstrapQuarkus(QuarkusBootstrapMojo mojo) throws MojoExecutionException { - if (quarkusBootstrap != null) { - return quarkusBootstrap; - } - + protected CuratedApplication doBootstrap(QuarkusBootstrapMojo mojo, LaunchMode mode) + throws MojoExecutionException { final Properties projectProperties = mojo.mavenProject().getProperties(); final Properties effectiveProperties = new Properties(); // quarkus. properties > ignoredEntries in pom.xml @@ -161,60 +169,69 @@ protected QuarkusBootstrap bootstrapQuarkus(QuarkusBootstrapMojo mojo) throws Mo } } + final BootstrapAppModelResolver modelResolver = new BootstrapAppModelResolver(artifactResolver(mojo, mode)) + .setDevMode(mode == LaunchMode.DEVELOPMENT) + .setTest(mode == LaunchMode.TEST); + + final List localProjects = mojo.mavenProject().getCollectedProjects(); + final Set reloadableModules = new HashSet<>(localProjects.size() + 1); + final ArtifactCoords artifactCoords = appArtifact(mojo); + reloadableModules.add(new GACT(artifactCoords.getGroupId(), artifactCoords.getArtifactId())); + for (MavenProject project : localProjects) { + reloadableModules.add(new GACT(project.getGroupId(), project.getArtifactId())); + } + + final ApplicationModel appModel; + try { + appModel = modelResolver.resolveManagedModel(artifactCoords, Collections.emptyList(), managingProject(mojo), + reloadableModules); + } catch (AppModelResolverException e) { + throw new MojoExecutionException("Failed to bootstrap application in " + mode + " mode", e); + } + QuarkusBootstrap.Builder builder = QuarkusBootstrap.builder() - .setAppArtifact(appArtifact(mojo)) - .setManagingProject(managingProject(mojo)) - .setMavenArtifactResolver(artifactResolver(mojo)) + .setAppArtifact(appModel.getAppArtifact()) + .setExistingModel(appModel) .setIsolateDeployment(true) .setBaseClassLoader(getClass().getClassLoader()) .setBuildSystemProperties(effectiveProperties) - .setLocalProjectDiscovery(false) .setProjectRoot(mojo.baseDir().toPath()) .setBaseName(mojo.finalName()) .setTargetDirectory(mojo.buildDir().toPath()); - for (MavenProject project : mojo.mavenProject().getCollectedProjects()) { - builder.addLocalArtifact(new AppArtifactKey(project.getGroupId(), project.getArtifactId(), null, - project.getArtifact().getArtifactHandler().getExtension())); + try { + return builder.build().bootstrap(); + } catch (BootstrapException e) { + throw new MojoExecutionException("Failed to bootstrap the application", e); } - - return quarkusBootstrap = builder.build(); } - protected CuratedApplication curateApplication(QuarkusBootstrapMojo mojo) throws MojoExecutionException { - if (curatedApp != null) { - return curatedApp; + protected CuratedApplication bootstrapApplication(QuarkusBootstrapMojo mojo, LaunchMode mode) + throws MojoExecutionException { + if (mode == LaunchMode.DEVELOPMENT) { + return devApp == null ? devApp = doBootstrap(mojo, mode) : devApp; } - try { - return curatedApp = bootstrapQuarkus(mojo).bootstrap(); - } catch (MojoExecutionException e) { - throw e; - } catch (BootstrapException e) { - throw new MojoExecutionException("Failed to bootstrap the application", e); + if (mode == LaunchMode.TEST) { + return testApp == null ? testApp = doBootstrap(mojo, mode) : testApp; } + return prodApp == null ? prodApp = doBootstrap(mojo, mode) : prodApp; } - protected AppArtifact managingProject(QuarkusBootstrapMojo mojo) { + protected GACTV managingProject(QuarkusBootstrapMojo mojo) { if (mojo.appArtifactCoords() == null) { return null; } final Artifact artifact = mojo.mavenProject().getArtifact(); - return new AppArtifact(artifact.getGroupId(), artifact.getArtifactId(), + return new GACTV(artifact.getGroupId(), artifact.getArtifactId(), artifact.getClassifier(), artifact.getArtifactHandler().getExtension(), artifact.getVersion()); } - private AppArtifact appArtifact(QuarkusBootstrapMojo mojo) throws MojoExecutionException { - return appArtifact == null ? appArtifact = initAppArtifact(mojo) : appArtifact; - } - - private AppArtifact initAppArtifact(QuarkusBootstrapMojo mojo) throws MojoExecutionException { + private ArtifactCoords appArtifact(QuarkusBootstrapMojo mojo) + throws MojoExecutionException { String appArtifactCoords = mojo.appArtifactCoords(); if (appArtifactCoords == null) { final Artifact projectArtifact = mojo.mavenProject().getArtifact(); - final AppArtifact appArtifact = new AppArtifact(projectArtifact.getGroupId(), projectArtifact.getArtifactId(), - projectArtifact.getClassifier(), projectArtifact.getArtifactHandler().getExtension(), - projectArtifact.getVersion()); File projectFile = projectArtifact.getFile(); if (projectFile == null) { @@ -231,8 +248,9 @@ private AppArtifact initAppArtifact(QuarkusBootstrapMojo mojo) throws MojoExecut } } } - appArtifact.setPaths(PathsCollection.of(projectFile.toPath())); - return appArtifact; + return new ResolvedArtifactDependency(projectArtifact.getGroupId(), projectArtifact.getArtifactId(), + projectArtifact.getClassifier(), projectArtifact.getArtifactHandler().getExtension(), + projectArtifact.getVersion(), projectFile.toPath()); } final String[] coordsArr = appArtifactCoords.split(":"); @@ -244,7 +262,7 @@ private AppArtifact initAppArtifact(QuarkusBootstrapMojo mojo) throws MojoExecut final String groupId = coordsArr[0]; final String artifactId = coordsArr[1]; String classifier = ""; - String type = "jar"; + String type = GACTV.TYPE_JAR; String version = null; if (coordsArr.length == 3) { version = coordsArr[2]; @@ -255,57 +273,43 @@ private AppArtifact initAppArtifact(QuarkusBootstrapMojo mojo) throws MojoExecut version = coordsArr[4]; } } + Path path = null; if (version == null) { for (Artifact dep : mojo.mavenProject().getArtifacts()) { if (dep.getArtifactId().equals(artifactId) && dep.getGroupId().equals(groupId) && dep.getClassifier().equals(classifier) && dep.getType().equals(type)) { - return new AppArtifact(dep.getGroupId(), - dep.getArtifactId(), - dep.getClassifier(), - dep.getArtifactHandler().getExtension(), - dep.getVersion()); + version = dep.getVersion(); + if (dep.getFile() != null) { + path = dep.getFile().toPath(); + } + break; } } - throw new IllegalStateException("Failed to locate " + appArtifactCoords + " among the project dependencies"); + if (version == null) { + throw new IllegalStateException( + "Failed to locate " + appArtifactCoords + " among the project dependencies"); + } } - final AppArtifact appArtifact = new AppArtifact(groupId, artifactId, classifier, type, version); - try { - appArtifact.setPath( - artifactResolver(mojo).resolve(new DefaultArtifact(groupId, artifactId, classifier, type, version)) - .getArtifact().getFile().toPath()); - } catch (MojoExecutionException e) { - throw e; - } catch (Exception e) { - throw new MojoExecutionException("Failed to resolve " + appArtifact, e); - } - return appArtifact; + return new GACTV(groupId, artifactId, classifier, type, version); } @Override public void close() { - if (curatedApp != null) { - curatedApp.close(); - curatedApp = null; + if (prodApp != null) { + prodApp.close(); + prodApp = null; + } + if (devApp != null) { + devApp.close(); + devApp = null; + } + if (testApp != null) { + testApp.close(); + testApp = null; } - appArtifact = null; - quarkusBootstrap = null; } } - - /* - * private static boolean hasSources(MavenProject project) { - * if (new File(project.getBuild().getSourceDirectory()).exists()) { - * return true; - * } - * for (Resource r : project.getBuild().getResources()) { - * if (new File(r.getDirectory()).exists()) { - * return true; - * } - * } - * return false; - * } - */ } diff --git a/devtools/maven/src/main/java/io/quarkus/maven/QuarkusMavenWorkspaceBuilder.java b/devtools/maven/src/main/java/io/quarkus/maven/QuarkusMavenWorkspaceBuilder.java new file mode 100644 index 0000000000000..64d4917608d87 --- /dev/null +++ b/devtools/maven/src/main/java/io/quarkus/maven/QuarkusMavenWorkspaceBuilder.java @@ -0,0 +1,52 @@ +package io.quarkus.maven; + +import java.io.File; + +import org.apache.maven.model.Build; +import org.apache.maven.model.Resource; +import org.apache.maven.project.MavenProject; + +import io.quarkus.bootstrap.model.ApplicationModelBuilder; +import io.quarkus.bootstrap.workspace.DefaultProcessedSources; +import io.quarkus.bootstrap.workspace.DefaultWorkspaceModule; +import io.quarkus.bootstrap.workspace.WorkspaceModule; +import io.quarkus.bootstrap.workspace.WorkspaceModuleId; +import io.quarkus.maven.dependency.GAV; +import io.quarkus.paths.PathList; + +class QuarkusMavenWorkspaceBuilder { + + static void loadModules(MavenProject project, ApplicationModelBuilder modelBuilder) { + } + + static WorkspaceModule toProjectModule(MavenProject project) { + final Build build = project.getBuild(); + final DefaultWorkspaceModule module = new DefaultWorkspaceModule(getId(project), project.getBasedir(), + new File(build.getDirectory())); + + final File classesDir = new File(build.getOutputDirectory()); + project.getCompileSourceRoots() + .forEach(s -> module.addMainSources(new DefaultProcessedSources(new File(s), classesDir))); + final File testClassesDir = new File(build.getTestOutputDirectory()); + project.getTestCompileSourceRoots() + .forEach(s -> module.addTestSources(new DefaultProcessedSources(new File(s), testClassesDir))); + + for (Resource r : build.getResources()) { + module.addMainResources(new DefaultProcessedSources(new File(r.getDirectory()), + r.getTargetPath() == null ? classesDir : new File(r.getTargetPath()))); + } + + for (Resource r : build.getTestResources()) { + module.addTestResources(new DefaultProcessedSources(new File(r.getDirectory()), + r.getTargetPath() == null ? testClassesDir : new File(r.getTargetPath()))); + } + + module.setBuildFiles(PathList.of(project.getFile().toPath())); + + return module; + } + + private static WorkspaceModuleId getId(MavenProject project) { + return new GAV(project.getGroupId(), project.getArtifactId(), project.getVersion()); + } +} diff --git a/devtools/platform-descriptor-json-plugin/src/main/java/io/quarkus/maven/GeneratePlatformDescriptorJsonMojo.java b/devtools/platform-descriptor-json-plugin/src/main/java/io/quarkus/maven/GeneratePlatformDescriptorJsonMojo.java deleted file mode 100644 index ac00e34916d24..0000000000000 --- a/devtools/platform-descriptor-json-plugin/src/main/java/io/quarkus/maven/GeneratePlatformDescriptorJsonMojo.java +++ /dev/null @@ -1,687 +0,0 @@ -package io.quarkus.maven; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.FileSystem; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -import org.apache.maven.model.Model; -import org.apache.maven.plugin.AbstractMojo; -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.Component; -import org.apache.maven.plugins.annotations.Mojo; -import org.apache.maven.plugins.annotations.Parameter; -import org.apache.maven.project.MavenProject; -import org.apache.maven.project.MavenProjectHelper; -import org.eclipse.aether.RepositorySystem; -import org.eclipse.aether.RepositorySystemSession; -import org.eclipse.aether.artifact.Artifact; -import org.eclipse.aether.artifact.DefaultArtifact; -import org.eclipse.aether.graph.Dependency; -import org.eclipse.aether.impl.RemoteRepositoryManager; -import org.eclipse.aether.repository.RemoteRepository; -import org.eclipse.aether.resolution.ArtifactDescriptorException; -import org.eclipse.aether.resolution.ArtifactDescriptorRequest; -import org.eclipse.aether.resolution.ArtifactRequest; -import org.eclipse.aether.resolution.ArtifactResolutionException; -import org.eclipse.aether.resolution.ArtifactResult; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; - -import io.quarkus.bootstrap.BootstrapConstants; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.resolver.AppModelResolverException; -import io.quarkus.bootstrap.resolver.BootstrapAppModelResolver; -import io.quarkus.bootstrap.resolver.maven.BootstrapMavenException; -import io.quarkus.bootstrap.resolver.maven.MavenArtifactResolver; -import io.quarkus.bootstrap.resolver.maven.workspace.LocalWorkspace; -import io.quarkus.bootstrap.resolver.maven.workspace.ModelUtils; -import io.quarkus.bootstrap.util.IoUtils; -import io.quarkus.bootstrap.util.ZipUtils; -import io.quarkus.platform.descriptor.ProjectPlatformDescriptorJsonUtil; -import io.quarkus.platform.tools.ToolsConstants; -import io.quarkus.registry.catalog.Category; -import io.quarkus.registry.catalog.Extension; -import io.quarkus.registry.catalog.ExtensionOrigin; -import io.quarkus.registry.catalog.json.JsonCatalogMapperHelper; -import io.quarkus.registry.catalog.json.JsonCategory; -import io.quarkus.registry.catalog.json.JsonExtension; -import io.quarkus.registry.catalog.json.JsonExtensionCatalog; - -/** - * This goal generates a platform JSON descriptor for a given platform BOM. - * - * @deprecated in favor of io.quarkus:quarkus-platform-bom-maven-plugin:generate-platform-descriptor - */ -@Deprecated -@Mojo(name = "generate-platform-descriptor-json", threadSafe = true) -public class GeneratePlatformDescriptorJsonMojo extends AbstractMojo { - - @Parameter(property = "quarkusCoreGroupId", defaultValue = ToolsConstants.QUARKUS_CORE_GROUP_ID) - private String quarkusCoreGroupId; - - @Parameter(property = "quarkusCoreArtifactId", defaultValue = ToolsConstants.QUARKUS_CORE_ARTIFACT_ID) - private String quarkusCoreArtifactId; - - @Parameter(property = "bomGroupId", defaultValue = "${project.groupId}") - private String bomGroupId; - - @Parameter(property = "bomArtifactId", defaultValue = "${project.artifactId}") - private String bomArtifactId; - - @Parameter(property = "bomVersion", defaultValue = "${project.version}") - private String bomVersion; - - /** file used for overrides - overridesFiles takes precedence over this file. **/ - @Parameter(property = "overridesFile", defaultValue = "${project.basedir}/src/main/resources/extensions-overrides.json") - private String overridesFile; - - @Parameter(property = "outputFile", defaultValue = "${project.build.directory}/${project.artifactId}-${project.version}-${project.version}.json") - private File outputFile; - - @Component - private RepositorySystem repoSystem; - - @Component - RemoteRepositoryManager remoteRepoManager; - - @Parameter(defaultValue = "${repositorySystemSession}", readonly = true) - private RepositorySystemSession repoSession; - - @Parameter(defaultValue = "${project.remoteProjectRepositories}", readonly = true, required = true) - private List repos; - - @Component - private MavenProject project; - @Component - private MavenProjectHelper projectHelper; - - /** - * A set of artifact group ID's that should be excluded from of the BOM and the descriptor. - * This can speed up the process by preventing the download of artifacts that are not required. - */ - @Parameter - private Set ignoredGroupIds = new HashSet<>(0); - - /** - * A set of group IDs artifacts of which should be checked to be extensions and if so, included into the - * generated descriptor. If this parameter is configured, artifacts with group IDs that aren't found - * among the configured set will be ignored. However, this will not prevent extensions that are inherited - * from parent platforms with different group IDs to be included into the generated descriptor. - */ - @Parameter - private Set processGroupIds = new HashSet<>(1); - - /** - * Skips the check for the descriptor's artifactId naming convention - */ - @Parameter - private boolean skipArtifactIdCheck; - - /** - * Skips the check for the BOM to contain the generated platform JSON descriptor - */ - @Parameter(property = "skipBomCheck") - private boolean skipBomCheck; - - /** - * Skips the check for categories referenced from the extensions to be listed in the generated descriptor - */ - @Parameter(property = "skipCategoryCheck") - boolean skipCategoryCheck; - - @Parameter(property = "resolveDependencyManagement") - boolean resolveDependencyManagement; - - @Parameter(required = false) - String quarkusCoreVersion; - - @Override - public void execute() throws MojoExecutionException, MojoFailureException { - - final Artifact jsonArtifact = new DefaultArtifact(project.getGroupId(), project.getArtifactId(), project.getVersion(), - "json", project.getVersion()); - if (!skipArtifactIdCheck) { - final String expectedArtifactId = bomArtifactId + BootstrapConstants.PLATFORM_DESCRIPTOR_ARTIFACT_ID_SUFFIX; - if (!jsonArtifact.getArtifactId().equals(expectedArtifactId)) { - throw new MojoExecutionException( - "The project's artifactId " + project.getArtifactId() + " is expected to be " + expectedArtifactId); - } - if (!jsonArtifact.getGroupId().equals(bomGroupId)) { - throw new MojoExecutionException("The project's groupId " + project.getGroupId() - + " is expected to match the groupId of the BOM which is " + bomGroupId); - } - if (!jsonArtifact.getVersion().equals(bomVersion)) { - throw new MojoExecutionException("The project's version " + project.getVersion() - + " is expected to match the version of the BOM which is " + bomVersion); - } - } - - // Get the BOM artifact - final DefaultArtifact bomArtifact = new DefaultArtifact(bomGroupId, bomArtifactId, "", "pom", bomVersion); - info("Generating catalog of extensions for %s", bomArtifact); - - // if the BOM is generated and has replaced the original one, to pick up the generated content - // we should read the dependencyManagement from the generated pom.xml - List deps; - if (resolveDependencyManagement) { - getLog().debug("Resolving dependencyManagement from the artifact descriptor"); - deps = dependencyManagementFromDescriptor(bomArtifact); - } else { - deps = dependencyManagementFromProject(); - if (deps == null) { - deps = dependencyManagementFromResolvedPom(bomArtifact); - } - } - if (deps.isEmpty()) { - getLog().warn("BOM " + bomArtifact + " does not include any dependency"); - return; - } - - List allOverrides = new ArrayList<>(); - for (String path : overridesFile.split(",")) { - OverrideInfo overrideInfo = getOverrideInfo(new File(path.trim())); - if (overrideInfo != null) { - allOverrides.add(overrideInfo); - } - } - - final JsonExtensionCatalog platformJson = new JsonExtensionCatalog(); - final String platformId = jsonArtifact.getGroupId() + ":" + jsonArtifact.getArtifactId() + ":" - + jsonArtifact.getClassifier() - + ":" + jsonArtifact.getExtension() + ":" + jsonArtifact.getVersion(); - platformJson.setId(platformId); - platformJson.setBom(ArtifactCoords.pom(bomGroupId, bomArtifactId, bomVersion)); - platformJson.setPlatform(true); - - final List importedDescriptors = deps.stream().filter( - d -> d.getArtifact().getArtifactId().endsWith(BootstrapConstants.PLATFORM_DESCRIPTOR_ARTIFACT_ID_SUFFIX) - && d.getArtifact().getExtension().equals("json") - && !(d.getArtifact().getArtifactId().equals(jsonArtifact.getArtifactId()) - && d.getArtifact().getGroupId().equals(jsonArtifact.getGroupId()))) - .map(d -> new AppArtifact(d.getArtifact().getGroupId(), d.getArtifact().getArtifactId(), - d.getArtifact().getClassifier(), d.getArtifact().getExtension(), d.getArtifact().getVersion())) - .collect(Collectors.toList()); - - Map inheritedExtensions = Collections.emptyMap(); - if (!importedDescriptors.isEmpty()) { - final MavenArtifactResolver mvnResolver; - try { - mvnResolver = MavenArtifactResolver.builder() - .setRepositorySystem(repoSystem) - .setRemoteRepositoryManager(remoteRepoManager) - .setRepositorySystemSession(repoSession) - .setRemoteRepositories(repos) - .setWorkspaceDiscovery(false) - .build(); - } catch (BootstrapMavenException e) { - throw new MojoExecutionException("Failed to initialize Maven artifact resolver", e); - } - final JsonExtensionCatalog baseCatalog; - try { - baseCatalog = ProjectPlatformDescriptorJsonUtil - .resolveCatalog(new BootstrapAppModelResolver(mvnResolver), importedDescriptors); - } catch (AppModelResolverException e) { - throw new MojoExecutionException("Failed to resolver inherited platform descriptor", e); - } - platformJson.setDerivedFrom(baseCatalog.getDerivedFrom()); - platformJson.setCategories(baseCatalog.getCategories()); - - final List extensions = baseCatalog.getExtensions(); - if (!extensions.isEmpty()) { - inheritedExtensions = new HashMap<>(extensions.size()); - for (Extension e : extensions) { - inheritedExtensions.put(e.getArtifact().getKey(), e); - } - } - - platformJson.setMetadata(baseCatalog.getMetadata()); - } - - // Create a JSON array of extension descriptors - final Set referencedCategories = new HashSet<>(); - final List extListJson = new ArrayList<>(); - platformJson.setExtensions(extListJson); - boolean jsonFoundInBom = false; - for (Dependency dep : deps) { - final Artifact artifact = dep.getArtifact(); - - // checking whether the descriptor is present in the BOM - if (!skipBomCheck && !jsonFoundInBom) { - jsonFoundInBom = artifact.getArtifactId().equals(jsonArtifact.getArtifactId()) - && artifact.getGroupId().equals(jsonArtifact.getGroupId()) - && artifact.getExtension().equals(jsonArtifact.getExtension()) - && artifact.getClassifier().equals(jsonArtifact.getClassifier()) - && artifact.getVersion().equals(jsonArtifact.getVersion()); - } - - // filtering non jar artifacts - if (!artifact.getExtension().equals("jar") - || "javadoc".equals(artifact.getClassifier()) - || "tests".equals(artifact.getClassifier()) - || "sources".equals(artifact.getClassifier()) - || artifact.getArtifactId().endsWith("-deployment")) { - continue; - } - - if (processGroupIds.isEmpty()) { - if (ignoredGroupIds.contains(artifact.getGroupId())) { - continue; - } - } else if (!processGroupIds.contains(artifact.getGroupId())) { - continue; - } - - if (quarkusCoreVersion == null && artifact.getArtifactId().equals(quarkusCoreArtifactId) - && artifact.getGroupId().equals(quarkusCoreGroupId)) { - quarkusCoreVersion = artifact.getVersion(); - } - ArtifactResult resolved = null; - JsonExtension extension = null; - try { - resolved = repoSystem.resolveArtifact(repoSession, - new ArtifactRequest().setRepositories(repos).setArtifact(artifact)); - extension = processDependency(resolved.getArtifact()); - } catch (ArtifactResolutionException e) { - // there are some parent poms that appear as jars for some reason - debug("Failed to resolve dependency %s defined in %s", artifact, bomArtifact); - } catch (IOException e) { - throw new MojoExecutionException("Failed to process dependency " + artifact, e); - } - - if (extension == null) { - continue; - } - - Extension inherited = inheritedExtensions.get(extension.getArtifact().getKey()); - final List origins; - if (inherited != null) { - origins = new ArrayList<>(inherited.getOrigins().size() + 1); - origins.addAll(inherited.getOrigins()); - origins.add(platformJson); - } else { - origins = Arrays.asList(platformJson); - } - extension.setOrigins(origins); - String key = extensionId(extension); - for (OverrideInfo info : allOverrides) { - io.quarkus.registry.catalog.Extension extOverride = info.getExtOverrides().get(key); - if (extOverride != null) { - extension = mergeObject(extension, extOverride); - } - } - extListJson.add(extension); - - if (!skipCategoryCheck) { - try { - @SuppressWarnings("unchecked") - final Collection extCategories = (Collection) extension.getMetadata() - .get("categories"); - if (extCategories != null) { - referencedCategories.addAll(extCategories); - } - } catch (ClassCastException e) { - getLog().warn("Failed to cast the extension categories list to java.util.Collection", e); - } - } - } - - if (!skipBomCheck && !jsonFoundInBom) { - throw new MojoExecutionException( - "Failed to locate " + jsonArtifact + " in the dependencyManagement section of " + bomArtifact); - } - if (quarkusCoreVersion == null) { - throw new MojoExecutionException("Failed to determine the Quarkus Core version for " + bomArtifact); - } - platformJson.setQuarkusCoreVersion(quarkusCoreVersion); - - for (OverrideInfo info : allOverrides) { - if (info.getTheRest() != null) { - if (!info.getTheRest().getCategories().isEmpty()) { - if (platformJson.getCategories().isEmpty()) { - platformJson.setCategories(info.getTheRest().getCategories()); - } else { - info.getTheRest().getCategories().stream().forEach(c -> { - boolean found = false; - for (Category platformC : platformJson.getCategories()) { - if (platformC.getId().equals(c.getId())) { - found = true; - JsonCategory jsonC = (JsonCategory) platformC; - if (c.getDescription() != null) { - jsonC.setDescription(c.getDescription()); - } - if (!c.getMetadata().isEmpty()) { - if (jsonC.getMetadata().isEmpty()) { - jsonC.setMetadata(c.getMetadata()); - } else { - jsonC.getMetadata().putAll(c.getMetadata()); - } - } - if (c.getName() != null) { - jsonC.setName(c.getName()); - } - } - break; - } - if (!found) { - platformJson.getCategories().add(c); - } - }); - } - } - } - if (!info.getTheRest().getMetadata().isEmpty()) { - if (platformJson.getMetadata().isEmpty()) { - platformJson.setMetadata(info.getTheRest().getMetadata()); - } else { - platformJson.getMetadata().putAll(info.getTheRest().getMetadata()); - } - } - } - - // make sure all the categories referenced by extensions are actually present in - // the platform descriptor - if (!skipCategoryCheck) { - final Set catalogCategories = platformJson.getCategories().stream().map(c -> c.getId()) - .collect(Collectors.toSet()); - if (!catalogCategories.containsAll(referencedCategories)) { - final List missing = referencedCategories.stream().filter(c -> !catalogCategories.contains(c)) - .collect(Collectors.toList()); - final StringBuilder buf = new StringBuilder(); - buf.append( - "The following categories referenced from extensions are missing from the generated catalog: "); - buf.append(missing.get(0)); - for (int i = 1; i < missing.size(); ++i) { - buf.append(", ").append(missing.get(i)); - } - throw new MojoExecutionException(buf.toString()); - } - } - - // Write the JSON to the output file - final File outputDir = outputFile.getParentFile(); - if (outputFile.exists()) { - outputFile.delete(); - } else if (!outputDir.exists()) { - if (!outputDir.mkdirs()) { - throw new MojoExecutionException("Failed to create output directory " + outputDir); - } - } - try { - JsonCatalogMapperHelper.serialize(platformJson, outputFile.toPath().getParent().resolve(outputFile.getName())); - } catch (IOException e) { - throw new MojoExecutionException("Failed to persist the platform descriptor", e); - } - info("Extensions file written to %s", outputFile); - - // this is necessary to sometimes be able to resolve the artifacts from the workspace - final File published = new File(project.getBuild().getDirectory(), LocalWorkspace.getFileName(jsonArtifact)); - if (!outputDir.equals(published)) { - try { - IoUtils.copy(outputFile.toPath(), published.toPath()); - } catch (IOException e) { - throw new MojoExecutionException("Failed to copy " + outputFile + " to " + published); - } - } - projectHelper.attachArtifact(project, jsonArtifact.getExtension(), jsonArtifact.getClassifier(), published); - } - - private List dependencyManagementFromDescriptor(Artifact bomArtifact) throws MojoExecutionException { - try { - return repoSystem - .readArtifactDescriptor(repoSession, - new ArtifactDescriptorRequest().setRepositories(repos).setArtifact(bomArtifact)) - .getManagedDependencies(); - } catch (ArtifactDescriptorException e) { - throw new MojoExecutionException("Failed to read descriptor of " + bomArtifact, e); - } - } - - private List dependencyManagementFromResolvedPom(Artifact bomArtifact) throws MojoExecutionException { - final Path pomXml; - try { - pomXml = repoSystem - .resolveArtifact(repoSession, new ArtifactRequest().setArtifact(bomArtifact).setRepositories(repos)) - .getArtifact().getFile().toPath(); - } catch (ArtifactResolutionException e) { - throw new MojoExecutionException("Failed to resolve " + bomArtifact, e); - } - return readDependencyManagement(pomXml); - } - - private List dependencyManagementFromProject() throws MojoExecutionException { - // if the configured BOM coordinates are not matching the current project - // the current project's POM isn't the right source - if (!project.getArtifact().getArtifactId().equals(bomArtifactId) - || !project.getArtifact().getVersion().equals(bomVersion) - || !project.getArtifact().getGroupId().equals(bomGroupId) - || !project.getFile().exists()) { - return null; - } - return readDependencyManagement(project.getFile().toPath()); - } - - private List readDependencyManagement(Path pomXml) throws MojoExecutionException { - if (getLog().isDebugEnabled()) { - getLog().debug("Reading dependencyManagement from " + pomXml); - } - final Model bomModel; - try { - bomModel = ModelUtils.readModel(pomXml); - } catch (IOException e) { - throw new MojoExecutionException("Failed to parse " + project.getFile(), e); - } - - // if the POM has a parent then we better resolve the descriptor - if (bomModel.getParent() != null) { - throw new MojoExecutionException(pomXml - + " has a parent, in which case it is recommended to set 'resolveDependencyManagement' parameter to true"); - } - - if (bomModel.getDependencyManagement() == null) { - return Collections.emptyList(); - } - final List modelDeps = bomModel.getDependencyManagement().getDependencies(); - if (modelDeps.isEmpty()) { - return Collections.emptyList(); - } - - final List deps = new ArrayList<>(modelDeps.size()); - for (org.apache.maven.model.Dependency modelDep : modelDeps) { - final Artifact artifact = new DefaultArtifact(modelDep.getGroupId(), modelDep.getArtifactId(), - modelDep.getClassifier(), modelDep.getType(), modelDep.getVersion()); - // exclusions aren't relevant in this context - deps.add(new Dependency(artifact, modelDep.getScope(), modelDep.isOptional(), Collections.emptyList())); - } - return deps; - } - - private JsonExtension processDependency(Artifact artifact) throws IOException { - final Path path = artifact.getFile().toPath(); - if (Files.isDirectory(path)) { - return processMetaInfDir(artifact, path.resolve(BootstrapConstants.META_INF)); - } else { - try (FileSystem artifactFs = ZipUtils.newFileSystem(path)) { - return processMetaInfDir(artifact, artifactFs.getPath(BootstrapConstants.META_INF)); - } - } - } - - /** - * Load and return javax.jsonObject based on yaml, json or properties file. - * - * @param artifact - * @param metaInfDir - * @return - * @throws IOException - */ - private JsonExtension processMetaInfDir(Artifact artifact, Path metaInfDir) - throws IOException { - - ObjectMapper mapper = null; - - if (!Files.exists(metaInfDir)) { - return null; - } - - Path yaml = metaInfDir.resolve(BootstrapConstants.QUARKUS_EXTENSION_FILE_NAME); - if (Files.exists(yaml)) { - mapper = getMapper(true); - return processPlatformArtifact(artifact, yaml, mapper); - } - - JsonExtension e = null; - mapper = getMapper(false); - Path json = metaInfDir.resolve(BootstrapConstants.EXTENSION_PROPS_JSON_FILE_NAME); - if (!Files.exists(json)) { - final Path props = metaInfDir.resolve(BootstrapConstants.DESCRIPTOR_FILE_NAME); - if (Files.exists(props)) { - e = new JsonExtension(); - e.setArtifact(new ArtifactCoords(artifact.getGroupId(), artifact.getArtifactId(), - artifact.getClassifier(), artifact.getExtension(), artifact.getVersion())); - e.setName(artifact.getArtifactId()); - } - } else { - e = processPlatformArtifact(artifact, json, mapper); - } - return e; - } - - private JsonExtension processPlatformArtifact(Artifact artifact, Path descriptor, ObjectMapper mapper) - throws IOException { - try (InputStream is = Files.newInputStream(descriptor)) { - JsonExtension legacy = mapper.readValue(is, JsonExtension.class); - JsonExtension object = transformLegacyToNew(legacy); - debug("Adding Quarkus extension %s", object.getArtifact()); - return object; - } catch (IOException io) { - throw new IOException("Failed to parse " + descriptor, io); - } - } - - private ObjectMapper getMapper(boolean yaml) { - - if (yaml) { - YAMLFactory yf = new YAMLFactory(); - return JsonCatalogMapperHelper.initMapper(new ObjectMapper(yf)); - } else { - return JsonCatalogMapperHelper.mapper(); - } - } - - private String extensionId(io.quarkus.registry.catalog.Extension extObject) { - return extObject.getArtifact().getGroupId() + ":" + extObject.getArtifact().getArtifactId(); - } - - private JsonExtension mergeObject(JsonExtension extObject, io.quarkus.registry.catalog.Extension extOverride) { - if (extOverride.getArtifact() != null) { - extObject.setArtifact(extOverride.getArtifact()); - } - if (!extOverride.getMetadata().isEmpty()) { - if (extObject.getMetadata().isEmpty()) { - extObject.setMetadata(extOverride.getMetadata()); - } else { - extObject.getMetadata().putAll(extOverride.getMetadata()); - } - } - if (extOverride.getName() != null) { - extObject.setName(extOverride.getName()); - } - if (!extOverride.getOrigins().isEmpty()) { - extObject.setOrigins(extOverride.getOrigins()); - } - return extObject; - } - - private void info(String msg, Object... args) { - if (!getLog().isInfoEnabled()) { - return; - } - if (args.length == 0) { - getLog().info(msg); - return; - } - getLog().info(String.format(msg, args)); - } - - private void debug(String msg, Object... args) { - if (!getLog().isDebugEnabled()) { - return; - } - if (args.length == 0) { - getLog().debug(msg); - return; - } - getLog().debug(String.format(msg, args)); - } - - private JsonExtension transformLegacyToNew(JsonExtension extObject) { - final Map metadata = extObject.getMetadata(); - final Object labels = metadata.get("labels"); - if (labels != null) { - metadata.put("keywords", labels); - metadata.remove("labels"); - } - return extObject; - } - - public OverrideInfo getOverrideInfo(File overridesFile) throws MojoExecutionException { - // Read the overrides file for the extensions (if it exists) - HashMap extOverrides = new HashMap<>(); - JsonExtensionCatalog theRest = null; - if (overridesFile.isFile()) { - info("Found overrides file %s", overridesFile); - try { - JsonExtensionCatalog overridesObject = JsonCatalogMapperHelper.deserialize(overridesFile.toPath(), - JsonExtensionCatalog.class); - List extensionsOverrides = overridesObject.getExtensions(); - if (!extensionsOverrides.isEmpty()) { - // Put the extension overrides into a map keyed to their GAV - for (io.quarkus.registry.catalog.Extension extOverride : extensionsOverrides) { - String key = extensionId(extOverride); - extOverrides.put(key, extOverride); - } - } - - theRest = overridesObject; - } catch (IOException e) { - throw new MojoExecutionException("Failed to read " + overridesFile, e); - } - return new OverrideInfo(extOverrides, theRest); - } - return null; - } - - private static class OverrideInfo { - private Map extOverrides; - private JsonExtensionCatalog theRest; - - public OverrideInfo(Map extOverrides, - JsonExtensionCatalog theRest) { - this.extOverrides = extOverrides; - this.theRest = theRest; - } - - public Map getExtOverrides() { - return extOverrides; - } - - public JsonExtensionCatalog getTheRest() { - return theRest; - } - } -} diff --git a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/BeanArchiveProcessor.java b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/BeanArchiveProcessor.java index 8133de96db552..9fb74040f7b84 100644 --- a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/BeanArchiveProcessor.java +++ b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/BeanArchiveProcessor.java @@ -21,7 +21,6 @@ import io.quarkus.arc.processor.BeanDefiningAnnotation; import io.quarkus.arc.processor.BeanDeployment; import io.quarkus.arc.processor.DotNames; -import io.quarkus.bootstrap.model.AppArtifactKey; import io.quarkus.deployment.ApplicationArchive; import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; @@ -32,6 +31,7 @@ import io.quarkus.deployment.index.IndexDependencyConfig; import io.quarkus.deployment.index.IndexingUtil; import io.quarkus.deployment.index.PersistentClassIndex; +import io.quarkus.maven.dependency.ArtifactKey; public class BeanArchiveProcessor { @@ -154,8 +154,8 @@ private boolean isAdditionalBeanArchive(ApplicationArchive archive, private boolean isApplicationArchiveExcluded(ArcConfig config, List excludeDependencyBuildItems, ApplicationArchive archive) { - if (archive.getArtifactKey() != null) { - AppArtifactKey key = archive.getArtifactKey(); + if (archive.getKey() != null) { + final ArtifactKey key = archive.getKey(); for (IndexDependencyConfig excludeDependency : config.excludeDependency.values()) { if (archiveMatches(key, excludeDependency.groupId, excludeDependency.artifactId, excludeDependency.classifier)) { @@ -174,7 +174,7 @@ private boolean isApplicationArchiveExcluded(ArcConfig config, List classifier) { + public static boolean archiveMatches(ArtifactKey key, String groupId, String artifactId, Optional classifier) { if (Objects.equal(key.getArtifactId(), artifactId) && Objects.equal(key.getGroupId(), groupId)) { diff --git a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/SplitPackageProcessor.java b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/SplitPackageProcessor.java index 1e1e11cedf062..3e2bb3a37b39b 100644 --- a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/SplitPackageProcessor.java +++ b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/SplitPackageProcessor.java @@ -17,11 +17,11 @@ import org.jboss.logging.Logger; import io.quarkus.arc.processor.DotNames; -import io.quarkus.bootstrap.model.AppArtifactKey; import io.quarkus.deployment.ApplicationArchive; import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.builditem.ApplicationArchivesBuildItem; +import io.quarkus.maven.dependency.ArtifactKey; /** * Split package (same package coming from multiple app archives) is considered a bad practice and @@ -107,8 +107,8 @@ void splitPackageDetection(ApplicationArchivesBuildItem archivesBuildItem, Iterator iterator = applicationArchives.iterator(); Set splitPackages = new TreeSet<>(); while (iterator.hasNext()) { - ApplicationArchive next = iterator.next(); - AppArtifactKey a = next.getArtifactKey(); + final ApplicationArchive next = iterator.next(); + final ArtifactKey a = next.getKey(); // can be null for instance in test mode where all application classes go under target/classes if (a == null) { if (archivesBuildItem.getRootArchive().equals(next)) { @@ -116,7 +116,7 @@ void splitPackageDetection(ApplicationArchivesBuildItem archivesBuildItem, splitPackages.add("application classes"); } else { // as next best effort, we try to take first path from archive paths collection - Iterator pathIterator = next.getPaths().iterator(); + Iterator pathIterator = next.getResolvedPaths().iterator(); if (pathIterator.hasNext()) { splitPackages.add(pathIterator.next().toString()); } else { diff --git a/extensions/arc/deployment/src/test/java/io/quarkus/arc/test/deployment/TestArchiveMatching.java b/extensions/arc/deployment/src/test/java/io/quarkus/arc/test/deployment/TestArchiveMatching.java index 6375e4148d081..d4edff3b07ca2 100644 --- a/extensions/arc/deployment/src/test/java/io/quarkus/arc/test/deployment/TestArchiveMatching.java +++ b/extensions/arc/deployment/src/test/java/io/quarkus/arc/test/deployment/TestArchiveMatching.java @@ -7,7 +7,8 @@ import org.junit.jupiter.api.Test; -import io.quarkus.bootstrap.model.AppArtifactKey; +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.GACT; public class TestArchiveMatching { @@ -18,8 +19,8 @@ public class TestArchiveMatching { @Test public void testMatch() { - AppArtifactKey key = AppArtifactKey.fromString(GROUP_ID + ":" + ARTIFACT_ID); - AppArtifactKey keyWithClassifier = AppArtifactKey.fromString(GROUP_ID + ":" + ARTIFACT_ID + ":" + CLASSIFIER); + ArtifactKey key = GACT.fromString(GROUP_ID + ":" + ARTIFACT_ID); + ArtifactKey keyWithClassifier = GACT.fromString(GROUP_ID + ":" + ARTIFACT_ID + ":" + CLASSIFIER); assertTrue(archiveMatches(key, GROUP_ID, ARTIFACT_ID, Optional.empty())); assertFalse(archiveMatches(key, GROUP_ID, ARTIFACT_ID, Optional.of(CLASSIFIER))); diff --git a/extensions/container-image/container-image-jib/deployment/src/main/java/io/quarkus/container/image/jib/deployment/JibProcessor.java b/extensions/container-image/container-image-jib/deployment/src/main/java/io/quarkus/container/image/jib/deployment/JibProcessor.java index 910bc79d776cc..ab11cca3cf94c 100644 --- a/extensions/container-image/container-image-jib/deployment/src/main/java/io/quarkus/container/image/jib/deployment/JibProcessor.java +++ b/extensions/container-image/container-image-jib/deployment/src/main/java/io/quarkus/container/image/jib/deployment/JibProcessor.java @@ -42,8 +42,6 @@ import com.google.cloud.tools.jib.api.buildplan.Port; import com.google.cloud.tools.jib.frontend.CredentialRetrieverFactory; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppDependency; import io.quarkus.bootstrap.util.ZipUtils; import io.quarkus.builder.Version; import io.quarkus.container.image.deployment.ContainerImageConfig; @@ -68,6 +66,7 @@ import io.quarkus.deployment.pkg.builditem.OutputTargetBuildItem; import io.quarkus.deployment.pkg.steps.JarResultBuildStep; import io.quarkus.deployment.pkg.steps.NativeBuild; +import io.quarkus.maven.dependency.ResolvedDependency; public class JibProcessor { @@ -302,10 +301,9 @@ private JibContainerBuilder createContainerBuilderFromFastJar(JibConfig jibConfi entrypoint.add(JarResultBuildStep.QUARKUS_RUN_JAR); } - List fastChangingLibs = new ArrayList<>(); - List userDependencies = curateOutcome.getEffectiveModel().getUserDependencies(); - for (AppDependency dep : userDependencies) { - AppArtifact artifact = dep.getArtifact(); + List fastChangingLibs = new ArrayList<>(); + Collection userDependencies = curateOutcome.getApplicationModel().getRuntimeDependencies(); + for (ResolvedDependency artifact : userDependencies) { if (artifact == null) { continue; } @@ -330,9 +328,9 @@ private JibContainerBuilder createContainerBuilderFromFastJar(JibConfig jibConfi throw new UncheckedIOException(e); } List libFileNames = new ArrayList<>(libNameToPath.keySet()); - for (AppArtifact appArtifact : fastChangingLibs) { + for (ResolvedDependency appArtifact : fastChangingLibs) { String matchingLibDirFileName = null; - for (Path appArtifactPath : appArtifact.getPaths()) { + for (Path appArtifactPath : appArtifact.getResolvedPaths()) { for (String libFileName : libFileNames) { if (libFileName.contains(appArtifact.getGroupId()) && libFileName.contains(appArtifactPath.getFileName().toString())) { diff --git a/extensions/container-image/container-image-s2i/deployment/src/main/java/io/quarkus/container/image/s2i/deployment/S2iProcessor.java b/extensions/container-image/container-image-s2i/deployment/src/main/java/io/quarkus/container/image/s2i/deployment/S2iProcessor.java index fb9aff6596f06..ad4d2f9add5ff 100644 --- a/extensions/container-image/container-image-s2i/deployment/src/main/java/io/quarkus/container/image/s2i/deployment/S2iProcessor.java +++ b/extensions/container-image/container-image-s2i/deployment/src/main/java/io/quarkus/container/image/s2i/deployment/S2iProcessor.java @@ -39,7 +39,6 @@ import io.fabric8.openshift.api.model.BuildConfig; import io.fabric8.openshift.api.model.ImageStream; import io.fabric8.openshift.client.OpenShiftClient; -import io.quarkus.bootstrap.model.AppDependency; import io.quarkus.container.image.deployment.ContainerImageConfig; import io.quarkus.container.image.deployment.util.ImageUtil; import io.quarkus.container.spi.AvailableContainerImageExtensionBuildItem; @@ -63,6 +62,7 @@ import io.quarkus.kubernetes.client.spi.KubernetesClientBuildItem; import io.quarkus.kubernetes.spi.KubernetesCommandBuildItem; import io.quarkus.kubernetes.spi.KubernetesEnvBuildItem; +import io.quarkus.maven.dependency.ResolvedDependency; public class S2iProcessor { @@ -88,10 +88,12 @@ public void s2iRequirementsJvm(S2iConfig s2iConfig, BuildProducer builderImageProducer, BuildProducer commandProducer) { - final List appDeps = curateOutcomeBuildItem.getEffectiveModel().getUserDependencies(); + final Collection appDeps = curateOutcomeBuildItem.getApplicationModel() + .getRuntimeDependencies(); String outputJarFileName = jarBuildItem.getPath().getFileName().toString(); String classpath = appDeps.stream() - .map(d -> d.getArtifact().getGroupId() + "." + d.getArtifact().getPath().getFileName()) + .map(d -> d.getGroupId() + "." + + d.getResolvedPaths().getSinglePath().getFileName()) .map(s -> concatUnixPaths(s2iConfig.jarDirectory, "lib", s)) .collect(Collectors.joining(":")); diff --git a/extensions/datasource/deployment-spi/src/main/java/io/quarkus/datasource/deployment/spi/DefaultDataSourceDbKindBuildItem.java b/extensions/datasource/deployment-spi/src/main/java/io/quarkus/datasource/deployment/spi/DefaultDataSourceDbKindBuildItem.java index 8d2ecc29f7fe9..7360a8304a1e6 100644 --- a/extensions/datasource/deployment-spi/src/main/java/io/quarkus/datasource/deployment/spi/DefaultDataSourceDbKindBuildItem.java +++ b/extensions/datasource/deployment-spi/src/main/java/io/quarkus/datasource/deployment/spi/DefaultDataSourceDbKindBuildItem.java @@ -4,11 +4,11 @@ import java.util.Map; import java.util.Optional; -import io.quarkus.bootstrap.model.AppDependency; import io.quarkus.builder.item.MultiBuildItem; import io.quarkus.datasource.common.runtime.DatabaseKind; import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem; import io.quarkus.deployment.util.ArtifactInfoUtil; +import io.quarkus.maven.dependency.ResolvedDependency; /** * A build item that represents the "quarkus.datasource.db-kind" value. @@ -40,9 +40,9 @@ public String getDbKind() { public String getScope(CurateOutcomeBuildItem curateOutcomeBuildItem) { if (scope == null) { Map.Entry artifact = ArtifactInfoUtil.groupIdAndArtifactId(callerClass, curateOutcomeBuildItem); - for (AppDependency i : curateOutcomeBuildItem.getEffectiveModel().getFullDeploymentDeps()) { - if (i.getArtifact().getArtifactId().equals(artifact.getValue()) - && i.getArtifact().getGroupId().equals(artifact.getKey())) { + for (ResolvedDependency i : curateOutcomeBuildItem.getApplicationModel().getDependencies()) { + if (i.getArtifactId().equals(artifact.getValue()) + && i.getGroupId().equals(artifact.getKey())) { scope = i.getScope(); break; } diff --git a/extensions/grpc/codegen/src/main/java/io/quarkus/grpc/deployment/GrpcCodeGen.java b/extensions/grpc/codegen/src/main/java/io/quarkus/grpc/deployment/GrpcCodeGen.java index 91439bc10b1b0..4501a69d09398 100644 --- a/extensions/grpc/codegen/src/main/java/io/quarkus/grpc/deployment/GrpcCodeGen.java +++ b/extensions/grpc/codegen/src/main/java/io/quarkus/grpc/deployment/GrpcCodeGen.java @@ -27,14 +27,13 @@ import org.codehaus.plexus.util.io.RawInputStreamFacade; import org.jboss.logging.Logger; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppDependency; -import io.quarkus.bootstrap.model.AppModel; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.prebuild.CodeGenException; import io.quarkus.bootstrap.prebuild.CodeGenFailureException; import io.quarkus.deployment.CodeGenContext; import io.quarkus.deployment.CodeGenProvider; import io.quarkus.deployment.util.ProcessUtil; +import io.quarkus.maven.dependency.ResolvedDependency; import io.quarkus.runtime.util.HashUtil; import io.quarkus.utilities.JavaBinFinder; import io.quarkus.utilities.OS; @@ -89,7 +88,7 @@ public boolean trigger(CodeGenContext context) throws CodeGenException { .map(this::escapeWhitespace) .collect(Collectors.toList()); if (!protoFiles.isEmpty()) { - initExecutables(workDir, context.appModel()); + initExecutables(workDir, context.applicationModel()); Collection protosToImport = gatherImports(workDir.resolve("protoc-dependencies"), context); @@ -139,12 +138,12 @@ private Collection gatherImports(Path workDir, CodeGenContext context) t List dependenciesToScan = Arrays.asList(scanForImports.split(",")); Set importDirectories = new HashSet<>(); - AppModel appModel = context.appModel(); - for (AppDependency dependency : appModel.getUserDependencies()) { - AppArtifact artifact = dependency.getArtifact(); + ApplicationModel appModel = context.applicationModel(); + for (ResolvedDependency artifact : appModel.getRuntimeDependencies()) { if (scanAll - || dependenciesToScan.contains(String.format("%s:%s", artifact.getGroupId(), artifact.getArtifactId()))) { - for (Path path : artifact.getPaths()) { + || dependenciesToScan.contains( + String.format("%s:%s", artifact.getGroupId(), artifact.getArtifactId()))) { + for (Path path : artifact.getResolvedPaths()) { Path jarName = path.getFileName(); if (jarName.toString().endsWith(".jar")) { final JarFile jar; @@ -195,7 +194,7 @@ private String escapeWhitespace(String path) { } } - private void initExecutables(Path workDir, AppModel model) throws CodeGenException { + private void initExecutables(Path workDir, ApplicationModel model) throws CodeGenException { if (executables == null) { Path protocPath; String protocPathProperty = System.getProperty("quarkus.grpc.protoc-path"); @@ -216,7 +215,7 @@ private void initExecutables(Path workDir, AppModel model) throws CodeGenExcepti } } - private Path prepareExecutable(Path buildDir, AppModel model, + private Path prepareExecutable(Path buildDir, ApplicationModel model, String groupId, String artifactId, String classifier, String packaging) throws CodeGenException { Path artifactPath = findArtifactPath(model, groupId, artifactId, classifier, packaging); @@ -247,17 +246,16 @@ private Path makeExecutableFromPath(Path buildDir, String groupId, String artifa return exe; } - private static Path findArtifactPath(AppModel model, String groupId, String artifactId, String classifier, + private static Path findArtifactPath(ApplicationModel model, String groupId, String artifactId, String classifier, String packaging) { Path artifactPath = null; - for (AppDependency dep : model.getFullDeploymentDeps()) { - AppArtifact artifact = dep.getArtifact(); + for (ResolvedDependency artifact : model.getDependencies()) { if (groupId.equals(artifact.getGroupId()) && artifactId.equals(artifact.getArtifactId()) && classifier.equals(artifact.getClassifier()) && packaging.equals(artifact.getType())) { - artifactPath = artifact.getPaths().getSinglePath(); + artifactPath = artifact.getResolvedPaths().getSinglePath(); } } return artifactPath; @@ -278,7 +276,7 @@ private String osClassifier() throws CodeGenException { } } - private static Path prepareQuarkusGrpcExecutable(AppModel appModel, Path buildDir) throws CodeGenException { + private static Path prepareQuarkusGrpcExecutable(ApplicationModel appModel, Path buildDir) throws CodeGenException { Path pluginPath = findArtifactPath(appModel, "io.quarkus", "quarkus-grpc-protoc-plugin", "shaded", "jar"); if (pluginPath == null) { throw new CodeGenException("Failed to find Quarkus gRPC protoc plugin among dependencies"); diff --git a/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java b/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java index f2e341003a5e1..9225b41cd8817 100644 --- a/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java +++ b/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java @@ -1071,7 +1071,7 @@ void collectTemplates(ApplicationArchivesBuildItem applicationArchivesBuildItem, ApplicationArchive applicationArchive = applicationArchivesBuildItem.getRootArchive(); String basePath = "templates"; Path templatesPath = null; - for (Path rootDir : applicationArchive.getRootDirs()) { + for (Path rootDir : applicationArchive.getRootDirectories()) { // Note that we cannot use ApplicationArchive.getChildPath(String) here because we would not be able to detect // a wrong directory name on case-insensitive file systems templatesPath = Files.list(rootDir).filter(p -> p.getFileName().toString().equals(basePath)).findFirst() diff --git a/extensions/smallrye-graphql/deployment/src/main/java/io/quarkus/smallrye/graphql/deployment/SmallRyeGraphQLProcessor.java b/extensions/smallrye-graphql/deployment/src/main/java/io/quarkus/smallrye/graphql/deployment/SmallRyeGraphQLProcessor.java index 0721b153785cb..41e3249dd6bee 100644 --- a/extensions/smallrye-graphql/deployment/src/main/java/io/quarkus/smallrye/graphql/deployment/SmallRyeGraphQLProcessor.java +++ b/extensions/smallrye-graphql/deployment/src/main/java/io/quarkus/smallrye/graphql/deployment/SmallRyeGraphQLProcessor.java @@ -22,7 +22,6 @@ import io.quarkus.arc.deployment.BeanContainerBuildItem; import io.quarkus.arc.deployment.BeanDefiningAnnotationBuildItem; import io.quarkus.arc.deployment.UnremovableBeanBuildItem; -import io.quarkus.bootstrap.model.AppArtifact; import io.quarkus.deployment.Capabilities; import io.quarkus.deployment.Capability; import io.quarkus.deployment.Feature; @@ -49,6 +48,7 @@ import io.quarkus.deployment.metrics.MetricsCapabilityBuildItem; import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem; import io.quarkus.deployment.util.WebJarUtil; +import io.quarkus.maven.dependency.ResolvedDependency; import io.quarkus.runtime.LaunchMode; import io.quarkus.runtime.RuntimeValue; import io.quarkus.smallrye.graphql.runtime.SmallRyeGraphQLRecorder; @@ -528,7 +528,7 @@ void getGraphqlUiFinalDestination( String graphQLPath = httpRootPath.resolvePath(graphQLConfig.rootPath); String graphQLUiPath = nonApplicationRootPathBuildItem.resolvePath(graphQLConfig.ui.rootPath); - AppArtifact artifact = WebJarUtil.getAppArtifact(curateOutcomeBuildItem, GRAPHQL_UI_WEBJAR_GROUP_ID, + ResolvedDependency artifact = WebJarUtil.getAppArtifact(curateOutcomeBuildItem, GRAPHQL_UI_WEBJAR_GROUP_ID, GRAPHQL_UI_WEBJAR_ARTIFACT_ID); if (launchMode.getLaunchMode().isDevOrTest()) { Path tempPath = WebJarUtil.copyResourcesForDevOrTest(liveReloadBuildItem, curateOutcomeBuildItem, launchMode, diff --git a/extensions/smallrye-health/deployment/src/main/java/io/quarkus/smallrye/health/deployment/SmallRyeHealthProcessor.java b/extensions/smallrye-health/deployment/src/main/java/io/quarkus/smallrye/health/deployment/SmallRyeHealthProcessor.java index 4e29352c89188..cf0bac7224575 100644 --- a/extensions/smallrye-health/deployment/src/main/java/io/quarkus/smallrye/health/deployment/SmallRyeHealthProcessor.java +++ b/extensions/smallrye-health/deployment/src/main/java/io/quarkus/smallrye/health/deployment/SmallRyeHealthProcessor.java @@ -38,7 +38,6 @@ import io.quarkus.arc.processor.AnnotationsTransformer; import io.quarkus.arc.processor.BuiltinScope; import io.quarkus.arc.processor.DotNames; -import io.quarkus.bootstrap.model.AppArtifact; import io.quarkus.deployment.Capabilities; import io.quarkus.deployment.Capability; import io.quarkus.deployment.Feature; @@ -61,6 +60,7 @@ import io.quarkus.kubernetes.spi.KubernetesHealthLivenessPathBuildItem; import io.quarkus.kubernetes.spi.KubernetesHealthReadinessPathBuildItem; import io.quarkus.kubernetes.spi.KubernetesHealthStartupPathBuildItem; +import io.quarkus.maven.dependency.ResolvedDependency; import io.quarkus.smallrye.health.deployment.spi.HealthBuildItem; import io.quarkus.smallrye.health.runtime.QuarkusAsyncHealthCheckFactory; import io.quarkus.smallrye.health.runtime.ShutdownReadinessListener; @@ -426,7 +426,7 @@ void registerUiExtension( String healthPath = nonApplicationRootPathBuildItem.resolvePath(healthConfig.rootPath); String healthUiPath = nonApplicationRootPathBuildItem.resolvePath(healthConfig.ui.rootPath); - AppArtifact artifact = WebJarUtil.getAppArtifact(curateOutcomeBuildItem, HEALTH_UI_WEBJAR_GROUP_ID, + ResolvedDependency artifact = WebJarUtil.getAppArtifact(curateOutcomeBuildItem, HEALTH_UI_WEBJAR_GROUP_ID, HEALTH_UI_WEBJAR_ARTIFACT_ID); if (launchMode.getLaunchMode().isDevOrTest()) { diff --git a/extensions/swagger-ui/deployment/src/main/java/io/quarkus/swaggerui/deployment/SwaggerUiProcessor.java b/extensions/swagger-ui/deployment/src/main/java/io/quarkus/swaggerui/deployment/SwaggerUiProcessor.java index 797293ba16f0a..38dc3c10b9d97 100644 --- a/extensions/swagger-ui/deployment/src/main/java/io/quarkus/swaggerui/deployment/SwaggerUiProcessor.java +++ b/extensions/swagger-ui/deployment/src/main/java/io/quarkus/swaggerui/deployment/SwaggerUiProcessor.java @@ -9,7 +9,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import io.quarkus.bootstrap.model.AppArtifact; import io.quarkus.builder.Version; import io.quarkus.deployment.Feature; import io.quarkus.deployment.annotations.BuildProducer; @@ -26,6 +25,7 @@ import io.quarkus.deployment.configuration.ConfigurationError; import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem; import io.quarkus.deployment.util.WebJarUtil; +import io.quarkus.maven.dependency.ResolvedDependency; import io.quarkus.smallrye.openapi.common.deployment.SmallRyeOpenApiConfig; import io.quarkus.swaggerui.runtime.SwaggerUiRecorder; import io.quarkus.swaggerui.runtime.SwaggerUiRuntimeConfig; @@ -117,7 +117,7 @@ public void getSwaggerUiFinalDestination( String openApiPath = nonApplicationRootPathBuildItem.resolvePath(openapi.path); String swaggerUiPath = nonApplicationRootPathBuildItem.resolvePath(swaggerUiConfig.path); - AppArtifact artifact = WebJarUtil.getAppArtifact(curateOutcomeBuildItem, SWAGGER_UI_WEBJAR_GROUP_ID, + ResolvedDependency artifact = WebJarUtil.getAppArtifact(curateOutcomeBuildItem, SWAGGER_UI_WEBJAR_GROUP_ID, SWAGGER_UI_WEBJAR_ARTIFACT_ID); if (launchMode.getLaunchMode().isDevOrTest()) { diff --git a/extensions/undertow/deployment/src/main/java/io/quarkus/undertow/deployment/UndertowBuildStep.java b/extensions/undertow/deployment/src/main/java/io/quarkus/undertow/deployment/UndertowBuildStep.java index c07101bef3fe1..173a534149274 100644 --- a/extensions/undertow/deployment/src/main/java/io/quarkus/undertow/deployment/UndertowBuildStep.java +++ b/extensions/undertow/deployment/src/main/java/io/quarkus/undertow/deployment/UndertowBuildStep.java @@ -84,7 +84,6 @@ import io.quarkus.arc.deployment.ContextRegistrationPhaseBuildItem.ContextConfiguratorBuildItem; import io.quarkus.arc.deployment.CustomScopeBuildItem; import io.quarkus.arc.deployment.SyntheticBeanBuildItem; -import io.quarkus.bootstrap.model.AppDependency; import io.quarkus.deployment.Capabilities; import io.quarkus.deployment.Capability; import io.quarkus.deployment.Feature; @@ -106,6 +105,7 @@ import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem; import io.quarkus.deployment.recording.RecorderContext; import io.quarkus.deployment.util.ServiceUtil; +import io.quarkus.maven.dependency.ResolvedDependency; import io.quarkus.runtime.RuntimeValue; import io.quarkus.undertow.runtime.HttpSessionContext; import io.quarkus.undertow.runtime.ServletHttpSecurityPolicy; @@ -163,8 +163,8 @@ void build(CurateOutcomeBuildItem curateOutcomeBuildItem, } private boolean jacksonOnClasspath(CurateOutcomeBuildItem curateOutcomeBuildItem) { - for (AppDependency appDep : curateOutcomeBuildItem.getEffectiveModel().getUserDependencies()) { - if (appDep.getArtifact().getArtifactId().equals("jackson-core")) { + for (ResolvedDependency appDep : curateOutcomeBuildItem.getApplicationModel().getRuntimeDependencies()) { + if (appDep.getArtifactId().equals("jackson-core")) { return true; } } diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsole.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsole.java index 3959b4769f957..7d21ba9b94e44 100644 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsole.java +++ b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsole.java @@ -18,9 +18,9 @@ import org.yaml.snakeyaml.Yaml; import io.netty.handler.codec.http.HttpHeaderNames; -import io.quarkus.bootstrap.model.AppArtifactCoords; import io.quarkus.builder.Version; import io.quarkus.devconsole.runtime.spi.FlashScopeUtil; +import io.quarkus.maven.dependency.GACTV; import io.quarkus.qute.Engine; import io.quarkus.qute.Template; import io.quarkus.qute.TemplateInstance; @@ -213,7 +213,7 @@ private static String getExtensionNamespace(Map metadata) { "Failed to locate 'artifact' or 'group-id' and 'artifact-id' among metadata keys " + metadata.keySet()); } } else { - final AppArtifactCoords coords = AppArtifactCoords.fromString(artifact); + final GACTV coords = GACTV.fromString(artifact); groupId = coords.getGroupId(); artifactId = coords.getArtifactId(); } diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsoleProcessor.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsoleProcessor.java index 922e5d303e1d1..3c80e3c10f3f3 100644 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsoleProcessor.java +++ b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsoleProcessor.java @@ -43,7 +43,6 @@ import io.netty.channel.ChannelInitializer; import io.netty.handler.codec.http.HttpHeaderNames; import io.quarkus.bootstrap.classloading.QuarkusClassLoader; -import io.quarkus.bootstrap.model.AppArtifact; import io.quarkus.builder.item.SimpleBuildItem; import io.quarkus.deployment.IsDevelopment; import io.quarkus.deployment.annotations.BuildProducer; @@ -72,6 +71,7 @@ import io.quarkus.devconsole.spi.DevConsoleRouteBuildItem; import io.quarkus.devconsole.spi.DevConsoleRuntimeTemplateInfoBuildItem; import io.quarkus.devconsole.spi.DevConsoleTemplateInfoBuildItem; +import io.quarkus.maven.dependency.ResolvedDependency; import io.quarkus.netty.runtime.virtual.VirtualChannel; import io.quarkus.netty.runtime.virtual.VirtualServerChannel; import io.quarkus.qute.Engine; @@ -399,7 +399,7 @@ public void setupDevConsoleRoutes( } // Add the static resources - AppArtifact devConsoleResourcesArtifact = WebJarUtil.getAppArtifact(curateOutcomeBuildItem, "io.quarkus", + ResolvedDependency devConsoleResourcesArtifact = WebJarUtil.getAppArtifact(curateOutcomeBuildItem, "io.quarkus", "quarkus-vertx-http-deployment"); Path devConsoleStaticResourcesDeploymentPath = WebJarUtil.copyResourcesForDevOrTest(liveReloadBuildItem, @@ -640,7 +640,7 @@ public String map(Object result, Expression expression) { } private Map getDefaultValues(List configDescriptionBuildItems) { - Map defaultValues = new HashMap(); + Map defaultValues = new HashMap<>(); for (ConfigDescriptionBuildItem configDescriptionBuildItem : configDescriptionBuildItems) { if (configDescriptionBuildItem.getDefaultValue() != null) { diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/BootstrapConstants.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/BootstrapConstants.java index 6aa4e545952d4..9d0a77e3aad46 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/BootstrapConstants.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/BootstrapConstants.java @@ -1,7 +1,5 @@ package io.quarkus.bootstrap; -import io.quarkus.bootstrap.model.AppArtifactCoords; - /** * * @author Alexey Loubyansky @@ -38,8 +36,6 @@ public interface BootstrapConstants { String LESSER_PRIORITY_ARTIFACTS = "lesser-priority-artifacts"; String EMPTY = ""; - String JAR = AppArtifactCoords.TYPE_JAR; - String POM = AppArtifactCoords.TYPE_POM; String PLATFORM_DESCRIPTOR_ARTIFACT_ID_SUFFIX = "-quarkus-platform-descriptor"; String PLATFORM_PROPERTIES_ARTIFACT_ID_SUFFIX = "-quarkus-platform-properties"; diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppArtifact.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppArtifact.java index 264ebd9ec2b69..85772f31fc45d 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppArtifact.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppArtifact.java @@ -1,5 +1,9 @@ package io.quarkus.bootstrap.model; +import io.quarkus.bootstrap.workspace.WorkspaceModule; +import io.quarkus.maven.dependency.ResolvedDependency; +import io.quarkus.paths.PathCollection; +import io.quarkus.paths.PathList; import java.io.Serializable; import java.nio.file.Path; @@ -8,24 +12,46 @@ * * @author Alexey Loubyansky */ -public class AppArtifact extends AppArtifactCoords implements Serializable { +public class AppArtifact extends AppArtifactCoords implements ResolvedDependency, Serializable { protected PathsCollection paths; + private final WorkspaceModule module; + private final String scope; + private final int flags; public AppArtifact(AppArtifactCoords coords) { - this(coords.getGroupId(), coords.getArtifactId(), coords.getClassifier(), coords.getType(), coords.getVersion()); + this(coords, null); + } + + public AppArtifact(AppArtifactCoords coords, WorkspaceModule module) { + this(coords.getGroupId(), coords.getArtifactId(), coords.getClassifier(), coords.getType(), coords.getVersion(), + module, "compile", 0); } public AppArtifact(String groupId, String artifactId, String version) { super(groupId, artifactId, version); + module = null; + scope = "compile"; + flags = 0; } public AppArtifact(String groupId, String artifactId, String classifier, String type, String version) { super(groupId, artifactId, classifier, type, version); + module = null; + scope = "compile"; + flags = 0; + } + + public AppArtifact(String groupId, String artifactId, String classifier, String type, String version, + WorkspaceModule module, String scope, int flags) { + super(groupId, artifactId, classifier, type, version); + this.module = module; + this.scope = scope; + this.flags = flags; } /** - * @deprecated in favor of {@link #getPaths()} + * @deprecated in favor of {@link #getResolvedPaths()} */ @Deprecated public Path getPath() { @@ -68,7 +94,28 @@ public void setPaths(PathsCollection paths) { * * @return true if the artifact has been resolved, otherwise - false */ + @Override public boolean isResolved() { return paths != null && !paths.isEmpty(); } + + @Override + public PathCollection getResolvedPaths() { + return paths == null ? null : PathList.from(paths); + } + + @Override + public WorkspaceModule getWorkspaceModule() { + return module; + } + + @Override + public String getScope() { + return scope; + } + + @Override + public int getFlags() { + return flags; + } } diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppArtifactCoords.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppArtifactCoords.java index 1e737e7b6fef5..a26c660c48742 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppArtifactCoords.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppArtifactCoords.java @@ -2,6 +2,7 @@ import static java.util.Objects.requireNonNull; +import io.quarkus.maven.dependency.ArtifactCoords; import java.io.Serializable; import java.util.Objects; @@ -10,7 +11,7 @@ * * @author Alexey Loubyansky */ -public class AppArtifactCoords implements Serializable { +public class AppArtifactCoords implements ArtifactCoords, Serializable { public static final String TYPE_JAR = "jar"; public static final String TYPE_POM = "pom"; diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppArtifactKey.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppArtifactKey.java index f31fc5d09b7fc..c3d4e1fa6d4b2 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppArtifactKey.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppArtifactKey.java @@ -1,5 +1,6 @@ package io.quarkus.bootstrap.model; +import io.quarkus.maven.dependency.ArtifactKey; import java.io.Serializable; /** @@ -7,7 +8,7 @@ * * @author Alexey Loubyansky */ -public class AppArtifactKey implements Serializable { +public class AppArtifactKey implements ArtifactKey, Serializable { public static AppArtifactKey fromString(String str) { return new AppArtifactKey(split(str, new String[4], str.length())); diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppDependency.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppDependency.java index 3fc311d513e42..4199d3eb0143e 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppDependency.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppDependency.java @@ -1,19 +1,17 @@ package io.quarkus.bootstrap.model; +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.DependencyFlags; +import io.quarkus.maven.dependency.ResolvedDependency; +import io.quarkus.paths.PathCollection; import java.io.Serializable; import java.util.Objects; -public class AppDependency implements Serializable { - - public static final int OPTIONAL_FLAG = 0b000001; - public static final int DIRECT_FLAG = 0b000010; - public static final int RUNTIME_CP_FLAG = 0b000100; - public static final int DEPLOYMENT_CP_FLAG = 0b001000; - public static final int RUNTIME_EXTENSION_ARTIFACT_FLAG = 0b010000; +public class AppDependency implements ResolvedDependency, Serializable { private final AppArtifact artifact; private final String scope; - private final int flags; + private int flags; public AppDependency(AppArtifact artifact, String scope, int... flags) { this(artifact, scope, false, flags); @@ -22,7 +20,7 @@ public AppDependency(AppArtifact artifact, String scope, int... flags) { public AppDependency(AppArtifact artifact, String scope, boolean optional, int... flags) { this.artifact = artifact; this.scope = scope; - int tmpFlags = optional ? OPTIONAL_FLAG : 0; + int tmpFlags = optional ? DependencyFlags.OPTIONAL : 0; for (int f : flags) { tmpFlags |= f; } @@ -33,38 +31,22 @@ public AppArtifact getArtifact() { return artifact; } + @Override public String getScope() { return scope; } - public boolean isOptional() { - return isFlagSet(OPTIONAL_FLAG); - } - - public boolean isDirect() { - return isFlagSet(DIRECT_FLAG); - } - - public boolean isRuntimeExtensionArtifact() { - return isFlagSet(RUNTIME_EXTENSION_ARTIFACT_FLAG); - } - - public boolean isRuntimeCp() { - return isFlagSet(RUNTIME_CP_FLAG); - } - - public boolean isDeploymentCp() { - return isFlagSet(DEPLOYMENT_CP_FLAG); - } - - public boolean isFlagSet(int flag) { - return (flags & flag) > 0; - } - + @Override public int getFlags() { return flags; } + public void clearFlag(int flag) { + if ((flags & flag) > 0) { + flags ^= flag; + } + } + @Override public int hashCode() { return Objects.hash(artifact, flags, scope); @@ -92,6 +74,9 @@ public String toString() { if (isOptional()) { buf.append("optional "); } + if (isWorkspacetModule()) { + buf.append("local "); + } if (isRuntimeExtensionArtifact()) { buf.append("extension "); } @@ -103,4 +88,39 @@ public String toString() { } return buf.append(scope).append(')').toString(); } + + @Override + public String getGroupId() { + return artifact.getGroupId(); + } + + @Override + public String getArtifactId() { + return artifact.getArtifactId(); + } + + @Override + public String getClassifier() { + return artifact.getClassifier(); + } + + @Override + public String getType() { + return artifact.getType(); + } + + @Override + public String getVersion() { + return artifact.getVersion(); + } + + @Override + public ArtifactKey getKey() { + return artifact.getKey(); + } + + @Override + public PathCollection getResolvedPaths() { + return artifact.getResolvedPaths(); + } } diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppModel.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppModel.java index ebd5ac9dc4d59..f69b7ccd2364d 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppModel.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppModel.java @@ -1,10 +1,13 @@ package io.quarkus.bootstrap.model; +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.ResolvedDependency; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Properties; @@ -16,16 +19,12 @@ /** * A representation of the Quarkus dependency model for a given application. * - * Changes made to this class should also be reflected in {@link PersistentAppModel} + * Changes made to this class should also be reflected in {@link MutableJarApplicationModel} * - * @author Alexey Loubyansky + * @deprecated in favor of {@link ApplicationModel} */ -public class AppModel implements Serializable { - - public static final String PARENT_FIRST_ARTIFACTS = "parent-first-artifacts"; - public static final String RUNNER_PARENT_FIRST_ARTIFACTS = "runner-parent-first-artifacts"; - public static final String EXCLUDED_ARTIFACTS = "excluded-artifacts"; - public static final String LESSER_PRIORITY_ARTIFACTS = "lesser-priority-artifacts"; +@Deprecated +public class AppModel implements ApplicationModel, Serializable { private static final Logger log = Logger.getLogger(AppModel.class); @@ -69,7 +68,7 @@ public class AppModel implements Serializable { private AppModel(Builder builder) { this.appArtifact = builder.appArtifact; - this.dependencies = builder.filter(builder.dependencies); + this.dependencies = builder.filter(builder.dependencies.values()); this.parentFirstArtifacts = builder.parentFirstArtifacts; this.runnerParentFirstArtifacts = builder.runnerParentFirstArtifacts; this.lesserPriorityArtifacts = builder.lesserPriorityArtifacts; @@ -149,7 +148,7 @@ public static class Builder { private AppArtifact appArtifact; - private final List dependencies = new ArrayList<>(); + private final Map dependencies = new LinkedHashMap<>(); private final Set parentFirstArtifacts = new HashSet<>(); private final Set runnerParentFirstArtifacts = new HashSet<>(); private final Set excludedArtifacts = new HashSet<>(); @@ -176,12 +175,16 @@ public Builder setCapabilitiesContracts(Map capabili } public Builder addDependency(AppDependency dep) { - dependencies.add(dep); + dependencies.put(dep.getArtifact().getKey(), dep); return this; } + public AppDependency getDependency(ArtifactKey key) { + return dependencies.get(key); + } + public Builder addDependencies(Collection deps) { - dependencies.addAll(deps); + deps.forEach(d -> addDependency(d)); return this; } @@ -317,7 +320,7 @@ private Predicate dependencyPredicate() { return depPredicate; } - private List filter(List deps) { + private List filter(Collection deps) { return deps.stream().filter(dependencyPredicate()).collect(Collectors.toList()); } @@ -325,4 +328,34 @@ public AppModel build() { return new AppModel(this); } } + + @Override + public Collection getDependencies() { + return new ArrayList<>(dependencies); + } + + @Override + public Collection getExtensionCapabilities() { + return new ArrayList<>(capabilitiesContracts.values()); + } + + @Override + public Set getParentFirst() { + return new HashSet<>(parentFirstArtifacts); + } + + @Override + public Set getRunnerParentFirst() { + return new HashSet<>(runnerParentFirstArtifacts); + } + + @Override + public Set getLowerPriorityArtifacts() { + return new HashSet<>(lesserPriorityArtifacts); + } + + @Override + public Set getReloadableWorkspaceDependencies() { + return new HashSet<>(localProjectArtifacts); + } } diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/ApplicationModel.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/ApplicationModel.java new file mode 100644 index 0000000000000..ccf853fa8d938 --- /dev/null +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/ApplicationModel.java @@ -0,0 +1,61 @@ +package io.quarkus.bootstrap.model; + +import io.quarkus.bootstrap.workspace.WorkspaceModule; +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.Dependency; +import io.quarkus.maven.dependency.ResolvedDependency; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +public interface ApplicationModel { + + String PARENT_FIRST_ARTIFACTS = "parent-first-artifacts"; + String RUNNER_PARENT_FIRST_ARTIFACTS = "runner-parent-first-artifacts"; + String EXCLUDED_ARTIFACTS = "excluded-artifacts"; + String LESSER_PRIORITY_ARTIFACTS = "lesser-priority-artifacts"; + + ResolvedDependency getAppArtifact(); + + Collection getDependencies(); + + default Collection getRuntimeDependencies() { + return getDependencies().stream().filter(Dependency::isRuntimeCp).collect(Collectors.toList()); + } + + PlatformImports getPlatforms(); + + default Map getPlatformProperties() { + final PlatformImports platformImports = getPlatforms(); + return platformImports == null ? Collections.emptyMap() : platformImports.getPlatformProperties(); + } + + Collection getExtensionCapabilities(); + + Set getParentFirst(); + + Set getRunnerParentFirst(); + + Set getLowerPriorityArtifacts(); + + Set getReloadableWorkspaceDependencies(); + + default WorkspaceModule getApplicationModule() { + return getAppArtifact().getWorkspaceModule(); + } + + default Collection getWorkspaceModules() { + final List modules = new ArrayList<>(); + for (ResolvedDependency d : getDependencies()) { + final WorkspaceModule module = d.getWorkspaceModule(); + if (module != null) { + modules.add(module); + } + } + return modules; + } +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/ApplicationModelBuilder.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/ApplicationModelBuilder.java new file mode 100644 index 0000000000000..6e2badaeb9b7f --- /dev/null +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/ApplicationModelBuilder.java @@ -0,0 +1,188 @@ +package io.quarkus.bootstrap.model; + +import io.quarkus.bootstrap.workspace.DefaultWorkspaceModule; +import io.quarkus.bootstrap.workspace.WorkspaceModuleId; +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.Dependency; +import io.quarkus.maven.dependency.GACT; +import io.quarkus.maven.dependency.ResolvedDependency; +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import org.jboss.logging.Logger; + +public class ApplicationModelBuilder { + + public static final String PARENT_FIRST_ARTIFACTS = "parent-first-artifacts"; + public static final String RUNNER_PARENT_FIRST_ARTIFACTS = "runner-parent-first-artifacts"; + public static final String EXCLUDED_ARTIFACTS = "excluded-artifacts"; + public static final String LESSER_PRIORITY_ARTIFACTS = "lesser-priority-artifacts"; + + private static final Logger log = Logger.getLogger(ApplicationModelBuilder.class); + + ResolvedDependency appArtifact; + + final Map dependencies = new LinkedHashMap<>(); + final Set parentFirstArtifacts = new HashSet<>(); + final Set runnerParentFirstArtifacts = new HashSet<>(); + final Set excludedArtifacts = new HashSet<>(); + final Set lesserPriorityArtifacts = new HashSet<>(); + final Set reloadableWorkspaceModules = new HashSet<>(); + final List extensionCapabilities = new ArrayList<>(); + PlatformImports platformImports; + final Map projectModules = new HashMap<>(); + + private Predicate depPredicate; + + public ApplicationModelBuilder setAppArtifact(ResolvedDependency appArtifact) { + this.appArtifact = appArtifact; + return this; + } + + public ApplicationModelBuilder setPlatformImports(PlatformImports platformImports) { + this.platformImports = platformImports; + return this; + } + + public ApplicationModelBuilder addExtensionCapabilities(ExtensionCapabilities extensionCapabilities) { + this.extensionCapabilities.add(extensionCapabilities); + return this; + } + + public ApplicationModelBuilder addDependency(ResolvedDependency dep) { + dependencies.put(dep.getKey(), dep); + return this; + } + + public ApplicationModelBuilder addDependencies(Collection deps) { + deps.forEach(d -> addDependency(d)); + return this; + } + + public Dependency getDependency(ArtifactKey key) { + return dependencies.get(key); + } + + public ApplicationModelBuilder addParentFirstArtifact(ArtifactKey deps) { + this.parentFirstArtifacts.add(deps); + return this; + } + + public ApplicationModelBuilder addParentFirstArtifacts(List deps) { + this.parentFirstArtifacts.addAll(deps); + return this; + } + + public ApplicationModelBuilder addRunnerParentFirstArtifact(ArtifactKey deps) { + this.runnerParentFirstArtifacts.add(deps); + return this; + } + + public ApplicationModelBuilder addRunnerParentFirstArtifacts(List deps) { + this.runnerParentFirstArtifacts.addAll(deps); + return this; + } + + public ApplicationModelBuilder addExcludedArtifact(ArtifactKey deps) { + this.excludedArtifacts.add(deps); + return this; + } + + public ApplicationModelBuilder addExcludedArtifacts(List deps) { + this.excludedArtifacts.addAll(deps); + return this; + } + + public ApplicationModelBuilder addLesserPriorityArtifact(ArtifactKey deps) { + this.lesserPriorityArtifacts.add(deps); + return this; + } + + public ApplicationModelBuilder addReloadableWorkspaceModule(ArtifactKey key) { + this.reloadableWorkspaceModules.add(key); + return this; + } + + public ApplicationModelBuilder addReloadableWorkspaceModules(Collection key) { + this.reloadableWorkspaceModules.addAll(key); + return this; + } + + public ApplicationModelBuilder addLesserPriorityArtifacts(List deps) { + this.lesserPriorityArtifacts.addAll(deps); + return this; + } + + public DefaultWorkspaceModule getOrCreateProjectModule(WorkspaceModuleId id, File moduleDir, File buildDir) { + return projectModules.computeIfAbsent(id, k -> new DefaultWorkspaceModule(id, moduleDir, buildDir)); + } + + /** + * Sets the parent first and excluded artifacts from a descriptor properties file + * + * @param props The quarkus-extension.properties file + */ + public void handleExtensionProperties(Properties props, String extension) { + String parentFirst = props.getProperty(PARENT_FIRST_ARTIFACTS); + if (parentFirst != null) { + String[] artifacts = parentFirst.split(","); + for (String artifact : artifacts) { + parentFirstArtifacts.add(new GACT(artifact.split(":"))); + } + } + String runnerParentFirst = props.getProperty(RUNNER_PARENT_FIRST_ARTIFACTS); + if (runnerParentFirst != null) { + String[] artifacts = runnerParentFirst.split(","); + for (String artifact : artifacts) { + runnerParentFirstArtifacts.add(new GACT(artifact.split(":"))); + } + } + String excluded = props.getProperty(EXCLUDED_ARTIFACTS); + if (excluded != null) { + String[] artifacts = excluded.split(","); + for (String artifact : artifacts) { + excludedArtifacts.add(new GACT(artifact.split(":"))); + log.debugf("Extension %s is excluding %s", extension, artifact); + } + } + String lesserPriority = props.getProperty(LESSER_PRIORITY_ARTIFACTS); + if (lesserPriority != null) { + String[] artifacts = lesserPriority.split(","); + for (String artifact : artifacts) { + lesserPriorityArtifacts.add(new GACT(artifact.split(":"))); + log.debugf("Extension %s is making %s a lesser priority artifact", extension, artifact); + } + } + } + + private Predicate dependencyPredicate() { + if (depPredicate == null) { + depPredicate = s -> { + // we never include the ide launcher in the final app model + if (s.getGroupId().equals("io.quarkus") + && s.getArtifactId().equals("quarkus-ide-launcher")) { + return false; + } + return !excludedArtifacts.contains(s.getKey()); + }; + } + return depPredicate; + } + + List filter(Collection deps) { + return deps.stream().filter(dependencyPredicate()).collect(Collectors.toList()); + } + + public DefaultApplicationModel build() { + return new DefaultApplicationModel(this); + } +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/CapabilityContract.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/CapabilityContract.java index fc01e1a0f0fd7..65c02474d487c 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/CapabilityContract.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/CapabilityContract.java @@ -5,7 +5,7 @@ import java.util.List; import java.util.Objects; -public class CapabilityContract implements Serializable { +public class CapabilityContract implements ExtensionCapabilities, Serializable { public static CapabilityContract providesCapabilities(String extension, String commaSeparatedList) { final List list = Arrays.asList(commaSeparatedList.split("\\s*,\\s*")); @@ -26,10 +26,12 @@ public CapabilityContract(String extension, List providesCapabilities) { this.providesCapabilities = Objects.requireNonNull(providesCapabilities, "providesCapabilities can't be null"); } + @Override public String getExtension() { return extension; } + @Override public List getProvidesCapabilities() { return providesCapabilities; } diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/DefaultApplicationModel.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/DefaultApplicationModel.java new file mode 100644 index 0000000000000..2f9f067110b1d --- /dev/null +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/DefaultApplicationModel.java @@ -0,0 +1,71 @@ +package io.quarkus.bootstrap.model; + +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.ResolvedDependency; +import java.io.Serializable; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +public class DefaultApplicationModel implements ApplicationModel, Serializable { + + private final ResolvedDependency appArtifact; + private final List dependencies; + private final PlatformImports platformImports; + private final List capabilityContracts; + private final Set parentFirstArtifacts; + private final Set runnerParentFirstArtifacts; + private final Set lesserPriorityArtifacts; + private final Set localProjectArtifacts; + + public DefaultApplicationModel(ApplicationModelBuilder builder) { + this.appArtifact = builder.appArtifact; + this.dependencies = builder.filter(builder.dependencies.values()); + this.platformImports = builder.platformImports; + this.capabilityContracts = builder.extensionCapabilities; + this.parentFirstArtifacts = builder.parentFirstArtifacts; + this.runnerParentFirstArtifacts = builder.runnerParentFirstArtifacts; + this.lesserPriorityArtifacts = builder.lesserPriorityArtifacts; + this.localProjectArtifacts = builder.reloadableWorkspaceModules; + } + + @Override + public ResolvedDependency getAppArtifact() { + return appArtifact; + } + + @Override + public Collection getDependencies() { + return dependencies; + } + + @Override + public PlatformImports getPlatforms() { + return platformImports; + } + + @Override + public Collection getExtensionCapabilities() { + return capabilityContracts; + } + + @Override + public Set getParentFirst() { + return parentFirstArtifacts; + } + + @Override + public Set getRunnerParentFirst() { + return runnerParentFirstArtifacts; + } + + @Override + public Set getLowerPriorityArtifacts() { + return lesserPriorityArtifacts; + } + + @Override + public Set getReloadableWorkspaceDependencies() { + return localProjectArtifacts; + } +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/ExtensionCapabilities.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/ExtensionCapabilities.java new file mode 100644 index 0000000000000..47cdfc2dd3fab --- /dev/null +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/ExtensionCapabilities.java @@ -0,0 +1,10 @@ +package io.quarkus.bootstrap.model; + +import java.util.Collection; + +public interface ExtensionCapabilities { + + String getExtension(); + + Collection getProvidesCapabilities(); +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/MutableJarApplicationModel.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/MutableJarApplicationModel.java new file mode 100644 index 0000000000000..dd81c97d8b0be --- /dev/null +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/MutableJarApplicationModel.java @@ -0,0 +1,122 @@ +package io.quarkus.bootstrap.model; + +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.GACTV; +import io.quarkus.maven.dependency.ResolvedDependency; +import io.quarkus.maven.dependency.ResolvedDependencyBuilder; +import io.quarkus.paths.PathList; +import java.io.Serializable; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * A representation of AppModel, that has been serialized to disk for an existing application. + *

+ * This needs a slightly different representation than AppModel + */ +public class MutableJarApplicationModel implements Serializable { + + private final String baseName; + private final SerializedDep appArtifact; + + private List dependencies; + private Set parentFirstArtifacts; + private Set runnerParentFirstArtifacts; + private Set lesserPriorityArtifacts; + private Set localProjectArtifacts; + private Collection capabilitiesContracts; + private PlatformImports platformImports; + private String userProvidersDirectory; + + public MutableJarApplicationModel(String baseName, Map> paths, ApplicationModel appModel, + String userProvidersDirectory, String appArchivePath) { + this.baseName = baseName; + this.userProvidersDirectory = userProvidersDirectory; + appArtifact = new SerializedDep(appModel.getAppArtifact(), paths, 0); + appArtifact.paths = Collections.singletonList(appArchivePath.replace('\\', '/')); + dependencies = new ArrayList<>(appModel.getDependencies().size()); + for (ResolvedDependency i : appModel.getDependencies()) { + dependencies.add(new SerializedDep(i, paths, i.getFlags())); + } + localProjectArtifacts = new HashSet<>(appModel.getReloadableWorkspaceDependencies()); + parentFirstArtifacts = new HashSet<>(appModel.getParentFirst()); + runnerParentFirstArtifacts = new HashSet<>(appModel.getRunnerParentFirst()); + lesserPriorityArtifacts = new HashSet<>(appModel.getLowerPriorityArtifacts()); + capabilitiesContracts = new ArrayList<>(appModel.getExtensionCapabilities()); + this.platformImports = appModel.getPlatforms(); + } + + public String getUserProvidersDirectory() { + return userProvidersDirectory; + } + + public ApplicationModel getAppModel(Path root) { + final ApplicationModelBuilder model = new ApplicationModelBuilder(); + model.setAppArtifact(appArtifact.getDep(root)); + for (SerializedDep i : dependencies) { + model.addDependency(i.getDep(root)); + } + for (ArtifactKey i : parentFirstArtifacts) { + model.addParentFirstArtifact(i); + } + for (ArtifactKey i : runnerParentFirstArtifacts) { + model.addRunnerParentFirstArtifact(i); + } + for (ArtifactKey i : lesserPriorityArtifacts) { + model.addLesserPriorityArtifact(i); + } + for (ArtifactKey i : localProjectArtifacts) { + model.addReloadableWorkspaceModule(i); + } + for (ExtensionCapabilities ec : capabilitiesContracts) { + model.addExtensionCapabilities(ec); + } + model.setPlatformImports(platformImports); + return model.build(); + } + + public String getBaseName() { + return baseName; + } + + private static class SerializedDep extends GACTV { + + private List paths; + private final int flags; + + public SerializedDep(ResolvedDependency dependency, Map> paths, int flags) { + super(dependency.getGroupId(), dependency.getArtifactId(), + dependency.getClassifier(), dependency.getType(), + dependency.getVersion()); + List pathList = paths.get(dependency.getKey()); + if (pathList == null) { + pathList = Collections.emptyList(); + } + this.paths = pathList.stream().map(s -> s.replace('\\', '/')).collect(Collectors.toList()); + this.flags = flags; + } + + public ResolvedDependency getDep(Path root) { + final PathList.Builder builder = PathList.builder(); + for (String i : paths) { + builder.add(root.resolve(i)); + } + final ResolvedDependency d = ResolvedDependencyBuilder.newInstance() + .setGroupId(getGroupId()) + .setArtifactId(getArtifactId()) + .setClassifier(getClassifier()) + .setVersion(getVersion()) + .setResolvedPaths(builder.build()) + .setFlags(flags) + .build(); + return d; + } + } +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/PathsCollection.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/PathsCollection.java index 5dd33eabf04a6..eef4447449aa6 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/PathsCollection.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/PathsCollection.java @@ -1,5 +1,6 @@ package io.quarkus.bootstrap.model; +import io.quarkus.paths.PathCollection; import java.io.IOException; import java.io.Serializable; import java.nio.file.Files; @@ -12,7 +13,7 @@ import java.util.Iterator; import java.util.List; -public class PathsCollection implements Iterable, Serializable { +public class PathsCollection implements PathCollection, Serializable { public static PathsCollection from(Iterable paths) { final List list = new ArrayList<>(); @@ -54,34 +55,32 @@ private PathsCollection(List paths) { this.paths = Collections.unmodifiableList(paths); } + @Override public boolean isEmpty() { return paths.isEmpty(); } + @Override public int size() { return paths.size(); } + @Override public boolean isSinglePath() { return paths.size() == 1; } - public Path getSinglePath() { - if (paths.size() != 1) { - throw new IllegalStateException("Paths collection expected to contain a single path but contains " + paths.size()); - } - return paths.get(0); - } - @Override public Iterator iterator() { return paths.iterator(); } + @Override public boolean contains(Path path) { return paths.contains(path); } + @Override public PathsCollection add(Path... paths) { final List list = new ArrayList<>(this.paths.size() + paths.length); list.addAll(this.paths); @@ -91,6 +90,7 @@ public PathsCollection add(Path... paths) { return new PathsCollection(list); } + @Override public PathsCollection addFirst(Path... paths) { final List list = new ArrayList<>(this.paths.size() + paths.length); for (int i = 0; i < paths.length; ++i) { @@ -100,6 +100,7 @@ public PathsCollection addFirst(Path... paths) { return new PathsCollection(list); } + @Override public PathsCollection addAllFirst(Iterable i) { final List list = new ArrayList<>(); i.forEach(list::add); @@ -107,6 +108,7 @@ public PathsCollection addAllFirst(Iterable i) { return new PathsCollection(list); } + @Override public Path resolveExistingOrNull(String path) { for (Path p : paths) { final Path resolved = p.resolve(path); @@ -144,4 +146,4 @@ private void readObject(java.io.ObjectInputStream in) throws IOException, ClassN public Collection toList() { return new ArrayList<>(paths); } -} \ No newline at end of file +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/PersistentAppModel.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/PersistentAppModel.java deleted file mode 100644 index 7e2762c82adc7..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/PersistentAppModel.java +++ /dev/null @@ -1,116 +0,0 @@ -package io.quarkus.bootstrap.model; - -import java.io.Serializable; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -/** - * A representation of AppModel, that has been serialized to disk for an existing application. - *

- * This needs a slightly different representation than AppModel - */ -public class PersistentAppModel implements Serializable { - - private final String baseName; - private final SerializedDep appArtifact; - - private List dependencies; - private Set parentFirstArtifacts; - private Set runnerParentFirstArtifacts; - private Set lesserPriorityArtifacts; - private Set localProjectArtifacts; - private Map platformProperties; - private Map capabilitiesContracts; - private String userProvidersDirectory; - - public PersistentAppModel(String baseName, Map> paths, AppModel appModel, - String userProvidersDirectory, String appArchivePath) { - this.baseName = baseName; - this.userProvidersDirectory = userProvidersDirectory; - appArtifact = new SerializedDep(appModel.getAppArtifact(), paths, 0); - appArtifact.paths = Collections.singletonList(appArchivePath.replace('\\', '/')); - dependencies = new ArrayList<>(appModel.getFullDeploymentDeps().size()); - for (AppDependency i : appModel.getFullDeploymentDeps()) { - dependencies.add(new SerializedDep(i, paths, i.getFlags())); - } - platformProperties = new HashMap<>(appModel.getPlatformProperties()); - localProjectArtifacts = new HashSet<>(appModel.getLocalProjectArtifacts()); - parentFirstArtifacts = new HashSet<>(appModel.getParentFirstArtifacts()); - runnerParentFirstArtifacts = new HashSet<>(appModel.getRunnerParentFirstArtifacts()); - lesserPriorityArtifacts = new HashSet<>(appModel.getLesserPriorityArtifacts()); - capabilitiesContracts = new HashMap<>(appModel.getCapabilityContracts()); - } - - public String getUserProvidersDirectory() { - return userProvidersDirectory; - } - - public AppModel getAppModel(Path root) { - AppModel.Builder model = new AppModel.Builder(); - model.setAppArtifact(appArtifact.getDep(root).getArtifact()); - for (SerializedDep i : dependencies) { - model.addDependency(i.getDep(root)); - } - for (AppArtifactKey i : parentFirstArtifacts) { - model.addParentFirstArtifact(i); - } - for (AppArtifactKey i : runnerParentFirstArtifacts) { - model.addRunnerParentFirstArtifact(i); - } - for (AppArtifactKey i : lesserPriorityArtifacts) { - model.addLesserPriorityArtifact(i); - } - for (AppArtifactKey i : localProjectArtifacts) { - model.addLocalProjectArtifact(i); - } - model.setCapabilitiesContracts(capabilitiesContracts); - final PlatformImportsImpl pi = new PlatformImportsImpl(); - pi.setPlatformProperties(platformProperties); - model.setPlatformImports(pi); - return model.build(); - } - - public String getBaseName() { - return baseName; - } - - private static class SerializedDep extends AppArtifactCoords { - - private List paths; - private final int flags; - - public SerializedDep(AppArtifact dependency, Map> paths, int flags) { - super(dependency.getGroupId(), dependency.getArtifactId(), - dependency.getClassifier(), dependency.getType(), - dependency.getVersion()); - List pathList = paths.get(dependency.getKey()); - if (pathList == null) { - pathList = Collections.emptyList(); - } - this.paths = pathList.stream().map(s -> s.replace('\\', '/')).collect(Collectors.toList()); - this.flags = flags; - } - - public SerializedDep(AppDependency dependency, Map> paths, int flags) { - this(dependency.getArtifact(), paths, flags); - } - - public AppDependency getDep(Path root) { - PathsCollection.Builder builder = PathsCollection.builder(); - for (String i : paths) { - builder.add(root.resolve(i)); - } - - AppArtifact appArtifact = new AppArtifact(getGroupId(), getArtifactId(), getClassifier(), getType(), getVersion()); - appArtifact.setPaths(builder.build()); - return new AppDependency(appArtifact, "compile", flags); //we don't care about scope at this point - } - } -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/PlatformImports.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/PlatformImports.java index 7114363a228cf..5022cebd04442 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/PlatformImports.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/PlatformImports.java @@ -1,5 +1,6 @@ package io.quarkus.bootstrap.model; +import io.quarkus.maven.dependency.ArtifactCoords; import java.util.Collection; import java.util.Map; @@ -24,7 +25,7 @@ public interface PlatformImports { * * @return all the Quarkus platform BOMs imported by an application */ - Collection getImportedPlatformBoms(); + Collection getImportedPlatformBoms(); /** * In case Quarkus platform member BOM imports were misaligned this method diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/PlatformImportsImpl.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/PlatformImportsImpl.java index 8db44fde9de36..a09b04f8c0b92 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/PlatformImportsImpl.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/PlatformImportsImpl.java @@ -2,6 +2,8 @@ import io.quarkus.bootstrap.BootstrapConstants; import io.quarkus.bootstrap.resolver.AppModelResolverException; +import io.quarkus.maven.dependency.ArtifactCoords; +import io.quarkus.maven.dependency.GACTV; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; @@ -38,12 +40,12 @@ public static boolean isPlatformReleaseInfo(String s) { // metadata for each found platform release by platform key private final Map allPlatformInfo = new HashMap<>(); // imported platform BOMs by platform keys (groupId) - private final Map> importedPlatformBoms = new HashMap<>(); + private final Map> importedPlatformBoms = new HashMap<>(); - private final Map platformImports = new HashMap<>(); + private final Map platformImports = new HashMap<>(); final Map collectedProps = new HashMap(); - private final Collection platformBoms = new ArrayList<>(); + private final Collection platformBoms = new ArrayList<>(); private final Collection platformReleaseInfo = new ArrayList<>(); public PlatformImportsImpl() { @@ -53,7 +55,7 @@ public Collection getPlatformReleaseInfo() { return platformReleaseInfo; } - public Collection getImportedPlatformBoms() { + public Collection getImportedPlatformBoms() { return platformBoms; } @@ -74,7 +76,7 @@ void addPlatformRelease(String propertyName, String propertyValue) { } public void addPlatformDescriptor(String groupId, String artifactId, String classifier, String type, String version) { - final AppArtifactCoords bomCoords = new AppArtifactCoords(groupId, + final ArtifactCoords bomCoords = new GACTV(groupId, artifactId.substring(0, artifactId.length() - BootstrapConstants.PLATFORM_DESCRIPTOR_ARTIFACT_ID_SUFFIX.length()), null, "pom", @@ -85,7 +87,7 @@ public void addPlatformDescriptor(String groupId, String artifactId, String clas public void addPlatformProperties(String groupId, String artifactId, String classifier, String type, String version, Path propsPath) throws AppModelResolverException { - final AppArtifactCoords bomCoords = new AppArtifactCoords(groupId, + final ArtifactCoords bomCoords = new GACTV(groupId, artifactId.substring(0, artifactId.length() - BootstrapConstants.PLATFORM_PROPERTIES_ARTIFACT_ID_SUFFIX.length()), null, "pom", @@ -123,7 +125,7 @@ public Map getPlatformProperties() { @Override public String getMisalignmentReport() { StringWriter error = null; - for (Map.Entry pi : platformImports.entrySet()) { + for (Map.Entry pi : platformImports.entrySet()) { if (!pi.getValue().descriptorFound) { if (error == null) { error = new StringWriter(); @@ -173,13 +175,13 @@ public boolean isAligned() { return isAligned(importedPlatformBoms); } - boolean isAligned(Map> importedPlatformBoms) { - for (Map.Entry pi : platformImports.entrySet()) { + boolean isAligned(Map> importedPlatformBoms) { + for (Map.Entry pi : platformImports.entrySet()) { if (!pi.getValue().descriptorFound) { return false; } } - for (Map.Entry> platformImportedBoms : importedPlatformBoms.entrySet()) { + for (Map.Entry> platformImportedBoms : importedPlatformBoms.entrySet()) { final PlatformInfo platformInfo = allPlatformInfo.get(platformImportedBoms.getKey()); if (platformInfo != null && !platformInfo.isAligned(platformImportedBoms.getValue())) { return false; @@ -189,9 +191,9 @@ boolean isAligned(Map> importedPlatformBom } private Map>> getPossibleAlignemnts( - Map> importedPlatformBoms) { + Map> importedPlatformBoms) { final Map>> alignments = new HashMap<>(importedPlatformBoms.size()); - for (Map.Entry> platformImportedBoms : importedPlatformBoms.entrySet()) { + for (Map.Entry> platformImportedBoms : importedPlatformBoms.entrySet()) { final PlatformInfo platformInfo = allPlatformInfo.get(platformImportedBoms.getKey()); if (platformInfo == null || platformInfo.isAligned(platformImportedBoms.getValue())) { continue; diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/PlatformInfo.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/PlatformInfo.java index 348a9771f14cc..82758d2d1a219 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/PlatformInfo.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/PlatformInfo.java @@ -1,5 +1,6 @@ package io.quarkus.bootstrap.model; +import io.quarkus.maven.dependency.ArtifactCoords; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; @@ -19,7 +20,7 @@ public String getPlatformKey() { return key; } - boolean isAligned(Collection importedBoms) { + boolean isAligned(Collection importedBoms) { if (streams.isEmpty()) { return true; } @@ -29,11 +30,11 @@ boolean isAligned(Collection importedBoms) { return streams.get(0).isAligned(importedBoms); } - List> getPossibleAlignments(Collection importedPlatformBoms) { + List> getPossibleAlignments(Collection importedPlatformBoms) { if (streams.size() > 1) { final StringBuilder buf = new StringBuilder(); buf.append("Imported BOMs "); - final Iterator it = importedPlatformBoms.iterator(); + final Iterator it = importedPlatformBoms.iterator(); if (it.hasNext()) { buf.append(it.next()); while (it.hasNext()) { @@ -70,4 +71,4 @@ PlatformStreamInfo getStream(String stream) { } return null; } -} \ No newline at end of file +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/PlatformReleaseInfo.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/PlatformReleaseInfo.java index f316e8eaf62dc..99c7b655c9384 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/PlatformReleaseInfo.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/PlatformReleaseInfo.java @@ -1,5 +1,7 @@ package io.quarkus.bootstrap.model; +import io.quarkus.maven.dependency.ArtifactCoords; +import io.quarkus.maven.dependency.GACTV; import java.io.Serializable; import java.util.ArrayList; import java.util.List; @@ -13,7 +15,7 @@ public class PlatformReleaseInfo implements Serializable { private final String platformKey; private final String stream; private final String version; - private final List boms; + private final List boms; public PlatformReleaseInfo(String platformKey, String stream, String version, String boms) { this.platformKey = platformKey; @@ -22,7 +24,7 @@ public PlatformReleaseInfo(String platformKey, String stream, String version, St final String[] bomCoords = boms.split(","); this.boms = new ArrayList<>(bomCoords.length); for (String s : bomCoords) { - this.boms.add(AppArtifactCoords.fromString(s)); + this.boms.add(GACTV.fromString(s)); } } @@ -58,7 +60,7 @@ public String getVersion() { * * @return member BOM coordinates */ - public List getBoms() { + public List getBoms() { return boms; } @@ -73,7 +75,7 @@ String getPropertyName() { String getPropertyValue() { final StringBuilder buf = new StringBuilder(); - final List boms = getBoms(); + final List boms = getBoms(); if (!boms.isEmpty()) { buf.append(boms.get(0).toString()); for (int i = 1; i < boms.size(); ++i) { diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/PlatformStreamInfo.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/PlatformStreamInfo.java index 1cdf6c9f10cc6..2f5991d85995f 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/PlatformStreamInfo.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/PlatformStreamInfo.java @@ -1,5 +1,7 @@ package io.quarkus.bootstrap.model; +import io.quarkus.maven.dependency.ArtifactCoords; +import io.quarkus.maven.dependency.ArtifactKey; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; @@ -21,7 +23,7 @@ public String getId() { return id; } - boolean isAligned(Collection importedBoms) { + boolean isAligned(Collection importedBoms) { if (releases.isEmpty()) { return true; } @@ -33,22 +35,22 @@ boolean isAligned(Collection importedBoms) { return false; } - List> getPossibleAlignemnts(Collection importedPlatformBoms) { - final Map importedKeys = new HashMap<>(importedPlatformBoms.size()); - for (AppArtifactCoords bom : importedPlatformBoms) { + List> getPossibleAlignemnts(Collection importedPlatformBoms) { + final Map importedKeys = new HashMap<>(importedPlatformBoms.size()); + for (ArtifactCoords bom : importedPlatformBoms) { importedKeys.put(bom.getKey(), bom.getVersion()); } final List> suggestions = new ArrayList<>(); for (PlatformReleaseInfo release : releases.values()) { - final Map stackBoms = new HashMap<>(release.getBoms().size()); - for (AppArtifactCoords bom : release.getBoms()) { + final Map stackBoms = new HashMap<>(release.getBoms().size()); + for (ArtifactCoords bom : release.getBoms()) { stackBoms.put(bom.getKey(), bom); } if (stackBoms.keySet().containsAll(importedKeys.keySet())) { final List suggestion = new ArrayList<>(importedPlatformBoms.size()); suggestions.add(suggestion); - for (Map.Entry bomKey : importedKeys.entrySet()) { - final AppArtifactCoords stackBom = stackBoms.get(bomKey.getKey()); + for (Map.Entry bomKey : importedKeys.entrySet()) { + final ArtifactCoords stackBom = stackBoms.get(bomKey.getKey()); if (!bomKey.getValue().equals(stackBom.getVersion())) { suggestion.add(bomKey.getKey().getGroupId() + ":" + bomKey.getKey().getArtifactId() + ":" + bomKey.getValue() + " -> " + stackBom.getVersion()); @@ -75,4 +77,4 @@ Collection getReleases() { PlatformReleaseInfo getRelease(String version) { return releases.get(version); } -} \ No newline at end of file +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/ArtifactCoords.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/ArtifactCoords.java deleted file mode 100644 index 08f903903dde5..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/ArtifactCoords.java +++ /dev/null @@ -1,14 +0,0 @@ -package io.quarkus.bootstrap.model.gradle; - -public interface ArtifactCoords { - - String getGroupId(); - - String getArtifactId(); - - String getClassifier(); - - String getVersion(); - - String getType(); -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/Dependency.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/Dependency.java deleted file mode 100644 index c0ac1a241e5e0..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/Dependency.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.quarkus.bootstrap.model.gradle; - -import java.io.File; -import java.util.Set; - -public interface Dependency { - - String getName(); - - String getGroupId(); - - String getVersion(); - - String getClassifier(); - - Set getPaths(); - - String getType(); - - String getScope(); - - int getFlags(); -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/QuarkusModel.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/QuarkusModel.java deleted file mode 100644 index f93eb75207af1..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/QuarkusModel.java +++ /dev/null @@ -1,13 +0,0 @@ -package io.quarkus.bootstrap.model.gradle; - -import io.quarkus.bootstrap.model.PlatformImports; -import java.util.List; - -public interface QuarkusModel { - - Workspace getWorkspace(); - - List getDependencies(); - - PlatformImports getPlatformImports(); -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/SourceSet.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/SourceSet.java deleted file mode 100644 index ddb6cb24965de..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/SourceSet.java +++ /dev/null @@ -1,11 +0,0 @@ -package io.quarkus.bootstrap.model.gradle; - -import java.io.File; -import java.util.Set; - -public interface SourceSet { - - Set getSourceDirectories(); - - Set getResourceDirectories(); -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/Workspace.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/Workspace.java deleted file mode 100644 index 75b2166398944..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/Workspace.java +++ /dev/null @@ -1,13 +0,0 @@ -package io.quarkus.bootstrap.model.gradle; - -import java.util.Collection; - -public interface Workspace { - - WorkspaceModule getMainModule(); - - Collection getAllModules(); - - WorkspaceModule getModule(ArtifactCoords key); - -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/WorkspaceModule.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/WorkspaceModule.java deleted file mode 100644 index 8ec440b8e58ea..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/WorkspaceModule.java +++ /dev/null @@ -1,16 +0,0 @@ -package io.quarkus.bootstrap.model.gradle; - -import java.io.File; - -public interface WorkspaceModule { - - ArtifactCoords getArtifactCoords(); - - File getProjectRoot(); - - File getBuildDir(); - - SourceSet getSourceSet(); - - SourceSet getSourceSourceSet(); -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/impl/ArtifactCoordsImpl.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/impl/ArtifactCoordsImpl.java deleted file mode 100644 index 784437f750d64..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/impl/ArtifactCoordsImpl.java +++ /dev/null @@ -1,72 +0,0 @@ -package io.quarkus.bootstrap.model.gradle.impl; - -import io.quarkus.bootstrap.model.gradle.ArtifactCoords; -import java.io.Serializable; -import java.util.Objects; - -public class ArtifactCoordsImpl implements ArtifactCoords, Serializable { - - public static final String TYPE_JAR = "jar"; - - private final String groupId; - private final String artifactId; - private final String classifier; - private final String version; - private final String type; - - public ArtifactCoordsImpl(String groupId, String artifactId, String version) { - this(groupId, artifactId, "", version, TYPE_JAR); - } - - public ArtifactCoordsImpl(String groupId, String artifactId, String classifier, String version, String type) { - this.groupId = groupId; - this.artifactId = artifactId; - this.classifier = classifier; - this.version = version; - this.type = type; - } - - @Override - public String getGroupId() { - return groupId; - } - - @Override - public String getArtifactId() { - return artifactId; - } - - @Override - public String getClassifier() { - return classifier; - } - - @Override - public String getVersion() { - return version; - } - - @Override - public String getType() { - return type; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - ArtifactCoordsImpl that = (ArtifactCoordsImpl) o; - return Objects.equals(groupId, that.groupId) && - Objects.equals(artifactId, that.artifactId) && - Objects.equals(classifier, that.classifier) && - Objects.equals(version, that.version) && - Objects.equals(type, that.type); - } - - @Override - public int hashCode() { - return Objects.hash(groupId, artifactId, classifier, version, type); - } -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/impl/DependencyImpl.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/impl/DependencyImpl.java deleted file mode 100644 index 74f1b74086550..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/impl/DependencyImpl.java +++ /dev/null @@ -1,126 +0,0 @@ -package io.quarkus.bootstrap.model.gradle.impl; - -import io.quarkus.bootstrap.model.gradle.Dependency; -import java.io.File; -import java.io.Serializable; -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; - -public class DependencyImpl implements Dependency, Serializable { - - private final String name; - private final String groupId; - private final String version; - private final String classifier; - private final Set paths = new HashSet<>(); - private final String scope; - private final String type; - private int flags; - - public DependencyImpl(String name, String groupId, String version, File path, String scope, String type, - String classifier, int... flags) { - this(name, groupId, version, scope, type, classifier, flags); - this.paths.add(path); - } - - public DependencyImpl(String name, String groupId, String version, String scope, String type, String classifier, - int... flags) { - this.name = name; - this.groupId = groupId; - this.version = version; - this.scope = scope; - this.type = type; - this.classifier = classifier; - int allFlags = 0; - for (int flag : flags) { - allFlags |= flag; - } - this.flags = allFlags; - } - - @Override - public String getName() { - return name; - } - - @Override - public String getGroupId() { - return groupId; - } - - @Override - public String getVersion() { - return version; - } - - @Override - public String getType() { - return type; - } - - @Override - public String getClassifier() { - return classifier; - } - - @Override - public Set getPaths() { - return paths; - } - - public void addPath(File path) { - this.paths.add(path); - } - - @Override - public String getScope() { - return scope; - } - - @Override - public int getFlags() { - return flags; - } - - public void setFlag(int flag) { - flags |= flag; - } - - public boolean isFlagSet(int flag) { - return (flags & flag) > 0; - } - - @Override - public String toString() { - return "DependencyImpl{" + - "name='" + name + '\'' + - ", groupId='" + groupId + '\'' + - ", version='" + version + '\'' + - ", type='" + type + '\'' + - ", path=" + paths + - ", classifier= " + classifier + - ", scope='" + scope + '\'' + - '}'; - } - - @Override - public int hashCode() { - return Objects.hash(classifier, flags, groupId, name, paths, scope, type, version); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - DependencyImpl other = (DependencyImpl) obj; - return Objects.equals(classifier, other.classifier) && flags == other.flags - && Objects.equals(groupId, other.groupId) && Objects.equals(name, other.name) - && Objects.equals(paths, other.paths) && Objects.equals(scope, other.scope) - && Objects.equals(type, other.type) && Objects.equals(version, other.version); - } -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/impl/QuarkusModelImpl.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/impl/QuarkusModelImpl.java deleted file mode 100644 index 81eb45cf3ad91..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/impl/QuarkusModelImpl.java +++ /dev/null @@ -1,38 +0,0 @@ -package io.quarkus.bootstrap.model.gradle.impl; - -import io.quarkus.bootstrap.model.PlatformImports; -import io.quarkus.bootstrap.model.gradle.Dependency; -import io.quarkus.bootstrap.model.gradle.QuarkusModel; -import io.quarkus.bootstrap.model.gradle.Workspace; -import java.io.Serializable; -import java.util.List; - -public class QuarkusModelImpl implements QuarkusModel, Serializable { - - private final Workspace workspace; - private final List dependencies; - private final PlatformImports platformImports; - - public QuarkusModelImpl(Workspace workspace, - List dependencies, - PlatformImports platformImports) { - this.workspace = workspace; - this.dependencies = dependencies; - this.platformImports = platformImports; - } - - @Override - public Workspace getWorkspace() { - return workspace; - } - - @Override - public List getDependencies() { - return dependencies; - } - - @Override - public PlatformImports getPlatformImports() { - return platformImports; - } -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/impl/SourceSetImpl.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/impl/SourceSetImpl.java deleted file mode 100644 index c10232672df48..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/impl/SourceSetImpl.java +++ /dev/null @@ -1,43 +0,0 @@ -package io.quarkus.bootstrap.model.gradle.impl; - -import io.quarkus.bootstrap.model.gradle.SourceSet; -import java.io.File; -import java.io.Serializable; -import java.util.Collections; -import java.util.Set; -import java.util.stream.Collectors; - -public class SourceSetImpl implements SourceSet, Serializable { - - private final Set sourceDirectories; - private final Set resourceDirectories; - - public SourceSetImpl(Set sourceDirectories, Set resourceDirectories) { - this.sourceDirectories = sourceDirectories; - this.resourceDirectories = resourceDirectories; - } - - public SourceSetImpl(Set sourceDirectories) { - this(sourceDirectories, Collections.emptySet()); - } - - @Override - public Set getSourceDirectories() { - return sourceDirectories; - } - - @Override - public Set getResourceDirectories() { - return resourceDirectories; - } - - @Override - public String toString() { - return "SourceSetImpl{" + - "sourceDirectories=" + sourceDirectories.stream().map(File::toString).collect(Collectors.joining(":")) - + - ", resourceDirectories=" - + resourceDirectories.stream().map(File::toString).collect(Collectors.joining(":")) + - '}'; - } -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/impl/WorkspaceImpl.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/impl/WorkspaceImpl.java deleted file mode 100644 index f12a6429c61ed..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/impl/WorkspaceImpl.java +++ /dev/null @@ -1,39 +0,0 @@ -package io.quarkus.bootstrap.model.gradle.impl; - -import io.quarkus.bootstrap.model.gradle.ArtifactCoords; -import io.quarkus.bootstrap.model.gradle.Workspace; -import io.quarkus.bootstrap.model.gradle.WorkspaceModule; -import java.io.Serializable; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -public class WorkspaceImpl implements Workspace, Serializable { - - public ArtifactCoords mainModuleKey; - public Map modules = new HashMap<>(); - - public WorkspaceImpl(ArtifactCoords mainModuleKey, Set workspaceModules) { - this.mainModuleKey = mainModuleKey; - for (WorkspaceModule module : workspaceModules) { - modules.put(module.getArtifactCoords(), module); - } - } - - @Override - public WorkspaceModule getMainModule() { - return modules.get(mainModuleKey); - } - - @Override - public Collection getAllModules() { - return modules.values(); - } - - @Override - public WorkspaceModule getModule(ArtifactCoords key) { - return modules.get(key); - } - -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/impl/WorkspaceModuleImpl.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/impl/WorkspaceModuleImpl.java deleted file mode 100644 index b80e372515f46..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/gradle/impl/WorkspaceModuleImpl.java +++ /dev/null @@ -1,70 +0,0 @@ -package io.quarkus.bootstrap.model.gradle.impl; - -import io.quarkus.bootstrap.model.gradle.ArtifactCoords; -import io.quarkus.bootstrap.model.gradle.SourceSet; -import io.quarkus.bootstrap.model.gradle.WorkspaceModule; -import java.io.File; -import java.io.Serializable; -import java.util.Objects; - -public class WorkspaceModuleImpl implements WorkspaceModule, Serializable { - - private final ArtifactCoords artifactCoords; - private final File projectRoot; - private final File buildDir; - private final SourceSet sourceSourceSet; - private final SourceSet sourceSet; - - public WorkspaceModuleImpl(ArtifactCoords artifactCoords, File projectRoot, File buildDir, SourceSet sourceSourceSet, - SourceSet sourceSet) { - this.artifactCoords = artifactCoords; - this.projectRoot = projectRoot; - this.buildDir = buildDir; - this.sourceSourceSet = sourceSourceSet; - this.sourceSet = sourceSet; - } - - @Override - public ArtifactCoords getArtifactCoords() { - return artifactCoords; - } - - @Override - public File getProjectRoot() { - return projectRoot; - } - - @Override - public File getBuildDir() { - return buildDir; - } - - @Override - public SourceSet getSourceSet() { - return sourceSet; - } - - @Override - public SourceSet getSourceSourceSet() { - return sourceSourceSet; - } - - public boolean equals(Object object) { - if (this == object) - return true; - if (object == null || getClass() != object.getClass()) - return false; - if (!super.equals(object)) - return false; - WorkspaceModuleImpl that = (WorkspaceModuleImpl) object; - return java.util.Objects.equals(artifactCoords, that.artifactCoords) && - java.util.Objects.equals(projectRoot, that.projectRoot) && - java.util.Objects.equals(buildDir, that.buildDir) && - java.util.Objects.equals(sourceSourceSet, that.sourceSourceSet) && - java.util.Objects.equals(sourceSet, that.sourceSet); - } - - public int hashCode() { - return Objects.hash(super.hashCode(), artifactCoords, projectRoot, buildDir, sourceSourceSet, sourceSet); - } -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/resolver/AppModelResolver.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/resolver/AppModelResolver.java index 644abea0fcd2f..a7bb1703663eb 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/resolver/AppModelResolver.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/resolver/AppModelResolver.java @@ -1,10 +1,12 @@ package io.quarkus.bootstrap.resolver; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppArtifactKey; -import io.quarkus.bootstrap.model.AppDependency; -import io.quarkus.bootstrap.model.AppModel; +import io.quarkus.bootstrap.model.ApplicationModel; +import io.quarkus.maven.dependency.ArtifactCoords; +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.Dependency; +import io.quarkus.maven.dependency.ResolvedDependency; import java.nio.file.Path; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Set; @@ -19,20 +21,20 @@ public interface AppModelResolver { /** * (Re-)links an artifact to a path. * - * @param appArtifact an artifact to (re-)link to the path + * @param artifact an artifact to (re-)link to the path * @param localPath local path to the artifact * @throws AppModelResolverException in case of a failure */ - void relink(AppArtifact appArtifact, Path localPath) throws AppModelResolverException; + void relink(ArtifactCoords artifact, Path localPath) throws AppModelResolverException; /** * Resolves an artifact. * * @param artifact artifact to resolve - * @return local path + * @return resolved artifact * @throws AppModelResolverException in case of a failure */ - Path resolve(AppArtifact artifact) throws AppModelResolverException; + ResolvedDependency resolve(ArtifactCoords artifact) throws AppModelResolverException; /** * Resolve application direct and transitive dependencies configured by the user. @@ -43,7 +45,7 @@ public interface AppModelResolver { * @return the list of dependencies configured by the user * @throws AppModelResolverException in case of a failure */ - default List resolveUserDependencies(AppArtifact artifact) throws AppModelResolverException { + default Collection resolveUserDependencies(ArtifactCoords artifact) throws AppModelResolverException { return resolveUserDependencies(artifact, Collections.emptyList()); } @@ -58,7 +60,7 @@ default List resolveUserDependencies(AppArtifact artifact) throws * @return the list of dependencies configured by the user * @throws AppModelResolverException in case of a failure */ - List resolveUserDependencies(AppArtifact artifact, List deps) + Collection resolveUserDependencies(ArtifactCoords artifact, Collection deps) throws AppModelResolverException; /** @@ -68,7 +70,7 @@ List resolveUserDependencies(AppArtifact artifact, List resolveUserDependencies(AppArtifact artifact, List deps) throws AppModelResolverException; + ApplicationModel resolveModel(ArtifactCoords root, Collection deps) throws AppModelResolverException; - AppModel resolveManagedModel(AppArtifact appArtifact, List directDeps, AppArtifact managingProject, - Set localProjects) + ApplicationModel resolveManagedModel(ArtifactCoords appArtifact, Collection directDeps, + ArtifactCoords managingProject, + Set localProjects) throws AppModelResolverException; /** @@ -92,7 +95,7 @@ AppModel resolveManagedModel(AppArtifact appArtifact, List direct * @return the list of versions released later than the version of the artifact * @throws AppModelResolverException in case of a failure */ - List listLaterVersions(AppArtifact artifact, String upToVersion, boolean inclusive) + List listLaterVersions(ArtifactCoords artifact, String upToVersion, boolean inclusive) throws AppModelResolverException; /** @@ -107,7 +110,7 @@ List listLaterVersions(AppArtifact artifact, String upToVersion, boolean * @return the next version from the specified range or null if the next version is not available * @throws AppModelResolverException in case of a failure */ - String getNextVersion(AppArtifact artifact, String fromVersion, boolean fromVersionIncluded, String upToVersion, + String getNextVersion(ArtifactCoords artifact, String fromVersion, boolean fromVersionIncluded, String upToVersion, boolean upToVersionIncluded) throws AppModelResolverException; /** @@ -120,7 +123,7 @@ String getNextVersion(AppArtifact artifact, String fromVersion, boolean fromVers * @return the latest version up to specified boundary * @throws AppModelResolverException in case of a failure */ - String getLatestVersion(AppArtifact artifact, String upToVersion, boolean inclusive) throws AppModelResolverException; + String getLatestVersion(ArtifactCoords artifact, String upToVersion, boolean inclusive) throws AppModelResolverException; /** * Resolves the latest version from the specified range. The version of the artifact is ignored. @@ -130,5 +133,5 @@ String getNextVersion(AppArtifact artifact, String fromVersion, boolean fromVers * @return the latest version of the artifact from the range or null, if no version was found for the specified range * @throws AppModelResolverException in case of a failure */ - String getLatestVersionFromRange(AppArtifact appArtifact, String range) throws AppModelResolverException; + String getLatestVersionFromRange(ArtifactCoords appArtifact, String range) throws AppModelResolverException; } diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/resolver/workspace/BuildOutput.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/resolver/workspace/BuildOutput.java deleted file mode 100644 index 247bf8ef1dad6..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/resolver/workspace/BuildOutput.java +++ /dev/null @@ -1,16 +0,0 @@ -package io.quarkus.bootstrap.resolver.workspace; - -import io.quarkus.bootstrap.model.PathsCollection; -import java.nio.file.Path; - -/** - * Represents an outcome of the build for a specific set of sources and resources. - */ -public interface BuildOutput { - - Path getOutputDir(); - - PathsCollection getSourcesDirs(); - - PathsCollection getResourcesDirs(); -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/resolver/workspace/Workspace.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/resolver/workspace/Workspace.java deleted file mode 100644 index a30391262ddc9..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/resolver/workspace/Workspace.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.quarkus.bootstrap.resolver.workspace; - -import io.quarkus.bootstrap.model.AppArtifactKey; -import java.util.Collection; - -public interface Workspace { - - default M getProject(String groupId, String artifactId) { - return getProject(new AppArtifactKey(groupId, artifactId)); - } - - M getProject(AppArtifactKey key); - - Collection getAllProjects(); -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/resolver/workspace/WorkspaceProject.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/resolver/workspace/WorkspaceProject.java deleted file mode 100644 index 363baecaf36ff..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/resolver/workspace/WorkspaceProject.java +++ /dev/null @@ -1,56 +0,0 @@ -package io.quarkus.bootstrap.resolver.workspace; - -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppArtifactKey; -import java.nio.file.Path; -import java.util.Collection; - -/** - * Represents a project in a workspace - */ -public interface WorkspaceProject { - - String getGroupId(); - - String getArtifactId(); - - String getVersion(); - - /** - * Project location on the filesystem - * - * @return project location - */ - Path getDir(); - - /** - * Project's key consisting of its group and artifact IDs - * - * @return project's key - */ - AppArtifactKey getKey(); - - /** - * Where the main build output can be located and from which - * sources and resources it was produced - * - * @return main build output - */ - Collection getMainOutput(); - - /** - * Where the test build output can be located and from which - * sources and resources it was produced - * - * @return test build output - */ - Collection getTestOutput(); - - default AppArtifact getAppArtifact(String extension) { - return getAppArtifact("", extension); - } - - default AppArtifact getAppArtifact(String classifier, String extension) { - return new AppArtifact(getGroupId(), getArtifactId(), classifier, extension, getVersion()); - } -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/util/BootstrapUtils.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/util/BootstrapUtils.java index cbd1fb039aa3f..b45657b176003 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/util/BootstrapUtils.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/util/BootstrapUtils.java @@ -1,7 +1,28 @@ package io.quarkus.bootstrap.util; +import io.quarkus.bootstrap.BootstrapConstants; +import io.quarkus.bootstrap.model.AppArtifact; import io.quarkus.bootstrap.model.AppArtifactKey; +import io.quarkus.bootstrap.model.AppDependency; +import io.quarkus.bootstrap.model.AppModel; +import io.quarkus.bootstrap.model.ApplicationModel; +import io.quarkus.bootstrap.model.CapabilityContract; +import io.quarkus.bootstrap.model.PathsCollection; +import io.quarkus.bootstrap.resolver.AppModelResolverException; +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.GACT; +import io.quarkus.maven.dependency.ResolvedDependency; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.function.Function; import java.util.regex.Pattern; +import java.util.stream.Collectors; public class BootstrapUtils { @@ -17,15 +38,97 @@ public static String[] splitByWhitespace(String s) { return splitByWs.split(s); } - public static AppArtifactKey[] parseDependencyCondition(String s) { + public static ArtifactKey[] parseDependencyCondition(String s) { final String[] strArr = splitByWhitespace(s); if (strArr == null) { return null; } - final AppArtifactKey[] keys = new AppArtifactKey[strArr.length]; + final ArtifactKey[] keys = new ArtifactKey[strArr.length]; for (int i = 0; i < strArr.length; ++i) { - keys[i] = AppArtifactKey.fromString(strArr[i]); + keys[i] = GACT.fromString(strArr[i]); } return keys; } + + public static AppModel convert(ApplicationModel appModel) { + if (appModel instanceof AppModel) { + return (AppModel) appModel; + } + final AppModel.Builder builder = new AppModel.Builder(); + final ResolvedDependency resolvedArtifact = appModel.getAppArtifact(); + final AppArtifact appArtifact = new AppArtifact(resolvedArtifact.getGroupId(), resolvedArtifact.getArtifactId(), + resolvedArtifact.getClassifier(), + resolvedArtifact.getType(), resolvedArtifact.getVersion(), appModel.getApplicationModule(), + resolvedArtifact.getScope(), resolvedArtifact.getFlags()); + if (appModel.getAppArtifact().isResolved()) { + appArtifact.setPaths(PathsCollection.from(appModel.getAppArtifact().getResolvedPaths())); + } + builder.setAppArtifact(appArtifact); + builder.setCapabilitiesContracts(appModel.getExtensionCapabilities().stream() + .map(c -> new CapabilityContract(c.getExtension(), new ArrayList<>(c.getProvidesCapabilities()))) + .collect(Collectors.toMap(CapabilityContract::getExtension, Function.identity()))); + builder.setPlatformImports(appModel.getPlatforms()); + appModel.getDependencies().forEach(d -> { + final AppArtifact a = new AppArtifact(d.getGroupId(), d.getArtifactId(), d.getClassifier(), d.getType(), + d.getVersion(), d.getWorkspaceModule(), d.getScope(), d.getFlags()); + a.setPaths(d.getResolvedPaths() == null ? PathsCollection.of() + : PathsCollection.from(d.getResolvedPaths())); + builder.addDependency(new AppDependency(a, d.getScope(), d.getFlags())); + }); + appModel.getLowerPriorityArtifacts().forEach(k -> builder.addLesserPriorityArtifact( + new AppArtifactKey(k.getGroupId(), k.getArtifactId(), k.getClassifier(), k.getType()))); + appModel.getParentFirst().forEach(k -> builder + .addParentFirstArtifact(new AppArtifactKey(k.getGroupId(), k.getArtifactId(), k.getClassifier(), k.getType()))); + appModel.getRunnerParentFirst().forEach(k -> builder.addRunnerParentFirstArtifact( + new AppArtifactKey(k.getGroupId(), k.getArtifactId(), k.getClassifier(), k.getType()))); + + appModel.getReloadableWorkspaceDependencies().forEach(k -> builder.addLocalProjectArtifact( + new AppArtifactKey(k.getGroupId(), k.getArtifactId()))); + + return builder.build(); + } + + public static void exportModel(ApplicationModel model, boolean test) throws AppModelResolverException, IOException { + Path serializedModel = serializeAppModel(model, test); + System.setProperty(test ? BootstrapConstants.SERIALIZED_TEST_APP_MODEL : BootstrapConstants.SERIALIZED_APP_MODEL, + serializedModel.toString()); + } + + public static Path serializeAppModel(ApplicationModel model, boolean test) throws AppModelResolverException, IOException { + final Path serializedModel = File.createTempFile("quarkus-" + (test ? "test-" : "") + "app-model", ".dat").toPath(); + serializeAppModel(model, serializedModel); + return serializedModel; + } + + public static void serializeAppModel(ApplicationModel model, final Path serializedModel) + throws IOException { + Files.createDirectories(serializedModel.getParent()); + try (ObjectOutputStream out = new ObjectOutputStream(Files.newOutputStream(serializedModel))) { + out.writeObject(model); + } + } + + public static Path serializeQuarkusModel(ApplicationModel model) throws IOException { + final Path serializedModel = File.createTempFile("quarkus-model", ".dat").toPath(); + serializeAppModel(model, serializedModel); + return serializedModel; + } + + public static ApplicationModel deserializeQuarkusModel(Path modelPath) throws AppModelResolverException { + if (Files.exists(modelPath)) { + try (InputStream existing = Files.newInputStream(modelPath); + ObjectInputStream object = new ObjectInputStream(existing)) { + ApplicationModel model = (ApplicationModel) object.readObject(); + IoUtils.recursiveDelete(modelPath); + return model; + } catch (IOException | ClassNotFoundException e) { + throw new AppModelResolverException("Failed to deserialize quarkus model", e); + } + } + throw new AppModelResolverException("Unable to locate quarkus model"); + } + + public static Path resolveSerializedAppModelPath(Path projectBuildDir) { + return projectBuildDir.resolve("quarkus").resolve("bootstrap").resolve("dev-app-model.dat"); + } } diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/DefaultProcessedSources.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/DefaultProcessedSources.java new file mode 100644 index 0000000000000..e5171b4767690 --- /dev/null +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/DefaultProcessedSources.java @@ -0,0 +1,74 @@ +package io.quarkus.bootstrap.workspace; + +import java.io.File; +import java.io.Serializable; +import java.util.Collections; +import java.util.Iterator; +import java.util.Map; +import java.util.Objects; + +public class DefaultProcessedSources implements ProcessedSources, Serializable { + + private final File srcDir; + private final File destinationDir; + private final Map data; + + public DefaultProcessedSources(File srcDir, File destinationDir) { + this(srcDir, destinationDir, Collections.emptyMap()); + } + + public DefaultProcessedSources(File srcDir, File destinationDir, Map data) { + this.srcDir = srcDir; + this.destinationDir = destinationDir; + this.data = data; + } + + @Override + public File getSourceDir() { + return srcDir; + } + + @Override + public File getDestinationDir() { + return destinationDir; + } + + public T getValue(Object key, Class type) { + final Object o = data.get(key); + return o == null ? null : type.cast(o); + } + + @Override + public int hashCode() { + return Objects.hash(data, destinationDir, srcDir); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + DefaultProcessedSources other = (DefaultProcessedSources) obj; + return Objects.equals(data, other.data) && Objects.equals(destinationDir, other.destinationDir) + && Objects.equals(srcDir, other.srcDir); + } + + @Override + public String toString() { + final StringBuilder buf = new StringBuilder(); + buf.append(srcDir).append(" -> ").append(destinationDir); + if (!data.isEmpty()) { + final Iterator> i = data.entrySet().iterator(); + Map.Entry e = i.next(); + buf.append(" ").append(e.getKey()).append("=").append(e.getValue()); + while (i.hasNext()) { + e = i.next(); + buf.append(",").append(e.getKey()).append("=").append(e.getValue()); + } + } + return buf.toString(); + } +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/DefaultWorkspaceModule.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/DefaultWorkspaceModule.java new file mode 100644 index 0000000000000..6377863c7c3ec --- /dev/null +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/DefaultWorkspaceModule.java @@ -0,0 +1,112 @@ +package io.quarkus.bootstrap.workspace; + +import io.quarkus.paths.PathCollection; +import io.quarkus.paths.PathList; +import java.io.File; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +public class DefaultWorkspaceModule implements WorkspaceModule, Serializable { + + private final WorkspaceModuleId id; + private final File moduleDir; + private final File buildDir; + private final Collection mainSources = new ArrayList<>(1); + private final Collection mainResources = new ArrayList<>(1); + private final Collection testSources = new ArrayList<>(1); + private final Collection testResources = new ArrayList<>(1); + private PathCollection buildFiles; + + public DefaultWorkspaceModule(WorkspaceModuleId id, File moduleDir, File buildDir) { + super(); + this.id = id; + this.moduleDir = moduleDir; + this.buildDir = buildDir; + } + + @Override + public WorkspaceModuleId getId() { + return id; + } + + @Override + public File getModuleDir() { + return moduleDir; + } + + @Override + public File getBuildDir() { + return buildDir; + } + + @Override + public Collection getMainSources() { + return mainSources; + } + + public void addMainSources(ProcessedSources mainSources) { + this.mainSources.add(mainSources); + } + + @Override + public Collection getMainResources() { + return mainResources; + } + + public void addMainResources(ProcessedSources mainResources) { + this.mainResources.add(mainResources); + } + + @Override + public Collection getTestSources() { + return testSources; + } + + public void addTestSources(ProcessedSources testSources) { + this.testSources.add(testSources); + } + + @Override + public Collection getTestResources() { + return testResources; + } + + public void addTestResources(ProcessedSources testResources) { + this.testResources.add(testResources); + } + + public void setBuildFiles(PathCollection buildFiles) { + this.buildFiles = buildFiles; + } + + @Override + public PathCollection getBuildFiles() { + return buildFiles == null ? PathList.empty() : buildFiles; + } + + @Override + public String toString() { + final StringBuilder buf = new StringBuilder(); + buf.append(id); + buf.append(" ").append(moduleDir); + appendSources(buf, "sources", getMainSources()); + appendSources(buf, "resources", getMainResources()); + appendSources(buf, "test-sources", getTestSources()); + appendSources(buf, "test-resources", getTestResources()); + return buf.toString(); + } + + private void appendSources(StringBuilder buf, String name, Collection sources) { + if (!sources.isEmpty()) { + buf.append(" ").append(name).append("["); + final Iterator i = sources.iterator(); + buf.append(i.next()); + while (i.hasNext()) { + buf.append(";").append(i.next()); + } + buf.append("]"); + } + } +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/ProcessedSources.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/ProcessedSources.java new file mode 100644 index 0000000000000..1ff2191407cf0 --- /dev/null +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/ProcessedSources.java @@ -0,0 +1,14 @@ +package io.quarkus.bootstrap.workspace; + +import java.io.File; + +public interface ProcessedSources { + + File getSourceDir(); + + File getDestinationDir(); + + default T getValue(Object key, Class type) { + return null; + } +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/WorkspaceModule.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/WorkspaceModule.java new file mode 100644 index 0000000000000..42e8f02154885 --- /dev/null +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/WorkspaceModule.java @@ -0,0 +1,24 @@ +package io.quarkus.bootstrap.workspace; + +import io.quarkus.paths.PathCollection; +import java.io.File; +import java.util.Collection; + +public interface WorkspaceModule { + + WorkspaceModuleId getId(); + + File getModuleDir(); + + File getBuildDir(); + + Collection getMainSources(); + + Collection getMainResources(); + + Collection getTestSources(); + + Collection getTestResources(); + + PathCollection getBuildFiles(); +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/WorkspaceModuleId.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/WorkspaceModuleId.java new file mode 100644 index 0000000000000..c0fd64df1e85e --- /dev/null +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/WorkspaceModuleId.java @@ -0,0 +1,10 @@ +package io.quarkus.bootstrap.workspace; + +public interface WorkspaceModuleId { + + String getGroupId(); + + String getArtifactId(); + + String getVersion(); +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ArtifactCoords.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ArtifactCoords.java new file mode 100644 index 0000000000000..829558519d0a0 --- /dev/null +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ArtifactCoords.java @@ -0,0 +1,23 @@ +package io.quarkus.maven.dependency; + +public interface ArtifactCoords { + + String TYPE_JAR = "jar"; + String TYPE_POM = "pom"; + + String getGroupId(); + + String getArtifactId(); + + String getClassifier(); + + String getType(); + + String getVersion(); + + ArtifactKey getKey(); + + default String toGACTVString() { + return getGroupId() + ":" + getArtifactId() + ":" + getClassifier() + ":" + getType() + ":" + getVersion(); + } +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ArtifactDependency.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ArtifactDependency.java new file mode 100644 index 0000000000000..368913b4acc6b --- /dev/null +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ArtifactDependency.java @@ -0,0 +1,88 @@ +package io.quarkus.maven.dependency; + +import java.io.Serializable; +import java.util.Objects; + +public class ArtifactDependency extends GACTV implements Dependency, Serializable { + + private final String scope; + private int flags; + + public ArtifactDependency(String groupId, String artifactId, String classifier, String type, String version) { + super(groupId, artifactId, classifier, type, version); + this.scope = "copmpile"; + flags = 0; + } + + public ArtifactDependency(ArtifactCoords coords, int... flags) { + this(coords, "compile", flags); + } + + public ArtifactDependency(ArtifactCoords coords, String scope, int... flags) { + super(coords.getGroupId(), coords.getArtifactId(), coords.getClassifier(), coords.getType(), + coords.getVersion()); + this.scope = scope; + int allFlags = 0; + for (int f : flags) { + allFlags |= f; + } + this.flags = allFlags; + } + + public ArtifactDependency(Dependency d) { + super(d.getGroupId(), d.getArtifactId(), d.getClassifier(), d.getType(), d.getVersion()); + this.scope = d.getScope(); + this.flags = d.getFlags(); + } + + public ArtifactDependency(AbstractDependencyBuilder builder) { + super(builder.getGroupId(), builder.getArtifactId(), builder.getClassifier(), builder.getType(), builder.getVersion()); + this.scope = builder.getScope(); + this.flags = builder.getFlags(); + } + + @Override + public String getScope() { + return scope; + } + + @Override + public int getFlags() { + return flags; + } + + public void setFlag(int flag) { + flags |= flag; + } + + public void clearFlag(int flag) { + if ((flags & flag) > 0) { + flags ^= flag; + } + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + Objects.hash(flags, scope); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + ArtifactDependency other = (ArtifactDependency) obj; + return flags == other.flags && Objects.equals(scope, other.scope); + } + + @Override + public String toString() { + return "[" + toGACTVString() + " " + scope + "]"; + } +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ArtifactDependencyBuilder.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ArtifactDependencyBuilder.java new file mode 100644 index 0000000000000..818ae0108a3b6 --- /dev/null +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ArtifactDependencyBuilder.java @@ -0,0 +1,160 @@ +package io.quarkus.maven.dependency; + +abstract class AbstractDependencyBuilder, T> { + + String groupId; + String artifactId; + String classifier = ""; + String type = GACTV.TYPE_JAR; + String version; + String scope = "compile"; + int flags; + + @SuppressWarnings("unchecked") + public B setCoords(ArtifactCoords coords) { + this.groupId = coords.getGroupId(); + this.artifactId = coords.getArtifactId(); + this.classifier = coords.getClassifier(); + this.type = coords.getType(); + this.version = coords.getVersion(); + return (B) this; + } + + @SuppressWarnings("unchecked") + public B setGroupId(String groupId) { + this.groupId = groupId; + return (B) this; + } + + @SuppressWarnings("unchecked") + public B setArtifactId(String artifactId) { + this.artifactId = artifactId; + return (B) this; + } + + @SuppressWarnings("unchecked") + public B setClassifier(String classifier) { + this.classifier = classifier; + return (B) this; + } + + @SuppressWarnings("unchecked") + public B setType(String type) { + this.type = type; + return (B) this; + } + + @SuppressWarnings("unchecked") + public B setVersion(String version) { + this.version = version; + return (B) this; + } + + @SuppressWarnings("unchecked") + public B setScope(String scope) { + this.scope = scope; + return (B) this; + } + + @SuppressWarnings("unchecked") + public B setOptional(boolean optional) { + if (optional) { + setFlags(DependencyFlags.OPTIONAL); + } else { + clearFlag(DependencyFlags.OPTIONAL); + } + return (B) this; + } + + @SuppressWarnings("unchecked") + public B setDeploymentCp() { + setFlags(DependencyFlags.DEPLOYMENT_CP); + return (B) this; + } + + @SuppressWarnings("unchecked") + public B setRuntimeCp() { + setFlags(DependencyFlags.RUNTIME_CP); + return (B) this; + } + + @SuppressWarnings("unchecked") + public B setWorkspaceModule() { + setFlags(DependencyFlags.WORKSPACE_MODULE); + return (B) this; + } + + @SuppressWarnings("unchecked") + public B setDirect(boolean direct) { + if (direct) { + setFlags(DependencyFlags.DIRECT); + } + return (B) this; + } + + @SuppressWarnings("unchecked") + public B setReloadable() { + setFlags(DependencyFlags.RELOADABLE); + return (B) this; + } + + @SuppressWarnings("unchecked") + public B setRuntimeExtensionArtifact() { + setFlags(DependencyFlags.RUNTIME_EXTENSION_ARTIFACT); + return (B) this; + } + + @SuppressWarnings("unchecked") + public B setFlags(int flag) { + this.flags |= flag; + return (B) this; + } + + public int getFlags() { + return flags; + } + + public boolean isFlagSet(int flag) { + return (flags & flag) > 0; + } + + public void clearFlag(int flag) { + if ((flags & flag) > 0) { + flags ^= flag; + } + } + + public String getGroupId() { + return groupId; + } + + public String getArtifactId() { + return artifactId; + } + + public String getClassifier() { + return classifier; + } + + public String getType() { + return type; + } + + public String getVersion() { + return version; + } + + public String getScope() { + return scope; + } + + public String toGACTVString() { + return getGroupId() + ":" + getArtifactId() + ":" + getClassifier() + ":" + getType() + ":" + getVersion(); + } + + public ArtifactKey getKey() { + return new GACT(groupId, artifactId, classifier, type); + } + + public abstract T build(); +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ArtifactKey.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ArtifactKey.java new file mode 100644 index 0000000000000..e039f76666545 --- /dev/null +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ArtifactKey.java @@ -0,0 +1,21 @@ +package io.quarkus.maven.dependency; + +public interface ArtifactKey { + + String getGroupId(); + + String getArtifactId(); + + String getClassifier(); + + String getType(); + + default String toGacString() { + final StringBuilder buf = new StringBuilder(); + buf.append(getGroupId()).append(':').append(getArtifactId()); + if (!getClassifier().isEmpty()) { + buf.append(':').append(getClassifier()); + } + return buf.toString(); + } +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/Dependency.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/Dependency.java new file mode 100644 index 0000000000000..9cd0e8cd93f06 --- /dev/null +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/Dependency.java @@ -0,0 +1,40 @@ +package io.quarkus.maven.dependency; + +public interface Dependency extends ArtifactCoords { + + String getScope(); + + int getFlags(); + + default boolean isOptional() { + return isFlagSet(DependencyFlags.OPTIONAL); + } + + default boolean isDirect() { + return isFlagSet(DependencyFlags.DIRECT); + } + + default boolean isRuntimeExtensionArtifact() { + return isFlagSet(DependencyFlags.RUNTIME_EXTENSION_ARTIFACT); + } + + default boolean isRuntimeCp() { + return isFlagSet(DependencyFlags.RUNTIME_CP); + } + + default boolean isDeploymentCp() { + return isFlagSet(DependencyFlags.DEPLOYMENT_CP); + } + + default boolean isWorkspacetModule() { + return isFlagSet(DependencyFlags.WORKSPACE_MODULE); + } + + default boolean isReloadable() { + return isFlagSet(DependencyFlags.RELOADABLE) && isWorkspacetModule(); + } + + default boolean isFlagSet(int flag) { + return (getFlags() & flag) > 0; + } +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/DependencyBuilder.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/DependencyBuilder.java new file mode 100644 index 0000000000000..d9485a32ec750 --- /dev/null +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/DependencyBuilder.java @@ -0,0 +1,13 @@ +package io.quarkus.maven.dependency; + +public class DependencyBuilder extends AbstractDependencyBuilder { + + public static DependencyBuilder newInstance() { + return new DependencyBuilder(); + } + + @Override + public Dependency build() { + return new ArtifactDependency(this); + } +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/DependencyFlags.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/DependencyFlags.java new file mode 100644 index 0000000000000..283945270e452 --- /dev/null +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/DependencyFlags.java @@ -0,0 +1,15 @@ +package io.quarkus.maven.dependency; + +public interface DependencyFlags { + + /* @formatter:off */ + public static final int OPTIONAL = 0b0000001; + public static final int DIRECT = 0b0000010; + public static final int RUNTIME_CP = 0b0000100; + public static final int DEPLOYMENT_CP = 0b0001000; + public static final int RUNTIME_EXTENSION_ARTIFACT = 0b0010000; + public static final int WORKSPACE_MODULE = 0b0100000; + public static final int RELOADABLE = 0b1000000; + /* @formatter:on */ + +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/GACT.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/GACT.java new file mode 100644 index 0000000000000..11c4ff648b4d2 --- /dev/null +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/GACT.java @@ -0,0 +1,160 @@ +package io.quarkus.maven.dependency; + +import java.io.Serializable; +import java.util.Objects; + +public class GACT implements ArtifactKey, Serializable { + + public static GACT fromString(String str) { + return new GACT(split(str, new String[4], str.length())); + } + + protected static String[] split(String str, String[] parts, int fromIndex) { + int i = str.lastIndexOf(':', fromIndex - 1); + if (i <= 0) { + throw new IllegalArgumentException("GroupId and artifactId separating ':' is absent or not in the right place in '" + + str.substring(0, fromIndex) + "'"); + } + parts[3] = str.substring(i + 1, fromIndex); + fromIndex = i; + i = str.lastIndexOf(':', fromIndex - 1); + if (i < 0) { + parts[0] = str.substring(0, fromIndex); + if ((parts[1] = parts[3]).isEmpty()) { + throw new IllegalArgumentException("ArtifactId is empty in `" + str + "`"); + } + parts[2] = ""; + parts[3] = null; + return parts; + } + if (i == 0) { + throw new IllegalArgumentException( + "One of groupId or artifactId is missing from '" + str.substring(0, fromIndex) + "'"); + } + if (i == fromIndex - 1) { + parts[2] = ""; + } else { + parts[2] = str.substring(i + 1, fromIndex); + } + + fromIndex = i; + i = str.lastIndexOf(':', fromIndex - 1); + if (i < 0) { + parts[0] = str.substring(0, fromIndex); + if ((parts[1] = parts[2]).isEmpty()) { + throw new IllegalArgumentException("ArtifactId is empty in `" + str + "`"); + } + parts[2] = parts[3]; + parts[3] = null; + return parts; + } + if (i == 0 || i == fromIndex - 1) { + throw new IllegalArgumentException( + "One of groupId or artifactId is missing from '" + str.substring(0, fromIndex) + "'"); + } + + parts[0] = str.substring(0, i); + parts[1] = str.substring(i + 1, fromIndex); + if (parts[3].isEmpty()) { + parts[3] = null; + } + return parts; + } + + protected final String groupId; + protected final String artifactId; + protected final String classifier; + protected final String type; + + public GACT(String[] parts) { + this.groupId = parts[0]; + this.artifactId = parts[1]; + if (parts.length == 2 || parts[2] == null) { + this.classifier = ""; + } else { + this.classifier = parts[2]; + } + if (parts.length <= 3 || parts[3] == null) { + this.type = "jar"; + } else { + this.type = parts[3]; + } + } + + public GACT(String groupId, String artifactId) { + this(groupId, artifactId, null); + } + + public GACT(String groupId, String artifactId, String classifier) { + this(groupId, artifactId, classifier, null); + } + + public GACT(String groupId, String artifactId, String classifier, String type) { + this.groupId = groupId; + this.artifactId = artifactId; + this.classifier = classifier == null ? "" : classifier; + this.type = type; + } + + @Override + public String getGroupId() { + return groupId; + } + + @Override + public String getArtifactId() { + return artifactId; + } + + @Override + public String getClassifier() { + return classifier; + } + + @Override + public String getType() { + return type; + } + + @Override + public int hashCode() { + return Objects.hash(artifactId, classifier, groupId, type); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + GACT other = (GACT) obj; + return Objects.equals(artifactId, other.artifactId) && Objects.equals(classifier, other.classifier) + && Objects.equals(groupId, other.groupId) && Objects.equals(type, other.type); + } + + @Override + public String toString() { + final StringBuilder buf = new StringBuilder(); + buf.append(groupId).append(':').append(artifactId); + if (!classifier.isEmpty()) { + buf.append(':').append(classifier); + } else if (type != null) { + buf.append(':'); + } + if (type != null) { + buf.append(':').append(type); + } + return buf.toString(); + } + + public String toGacString() { + final StringBuilder buf = new StringBuilder(); + buf.append(groupId).append(':').append(artifactId); + if (!classifier.isEmpty()) { + buf.append(':').append(classifier); + } + return buf.toString(); + } +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/GACTV.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/GACTV.java new file mode 100644 index 0000000000000..38b3afb330349 --- /dev/null +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/GACTV.java @@ -0,0 +1,130 @@ +package io.quarkus.maven.dependency; + +import java.io.Serializable; +import java.util.Objects; + +public class GACTV implements ArtifactCoords, Serializable { + + public static GACTV fromString(String str) { + return new GACTV(split(str, new String[5])); + } + + public static ArtifactCoords pom(String groupId, String artifactId, String version) { + return new GACTV(groupId, artifactId, null, TYPE_POM, version); + } + + protected static String[] split(String str, String[] parts) { + final int versionSep = str.lastIndexOf(':'); + if (versionSep <= 0 || versionSep == str.length() - 1) { + throw new IllegalArgumentException("One of type, version or separating them ':' is missing from '" + str + "'"); + } + parts[4] = str.substring(versionSep + 1); + GACT.split(str, parts, versionSep); + return parts; + } + + private final String groupId; + private final String artifactId; + private final String classifier; + private final String type; + private final String version; + + private transient ArtifactKey key; + + protected GACTV(String[] parts) { + groupId = parts[0]; + artifactId = parts[1]; + classifier = parts[2]; + type = parts[3] == null ? TYPE_JAR : parts[3]; + version = parts[4]; + } + + public GACTV(ArtifactKey key, String version) { + this.key = key; + this.groupId = key.getGroupId(); + this.artifactId = key.getArtifactId(); + this.classifier = key.getClassifier(); + this.type = key.getType(); + this.version = version; + } + + public GACTV(String groupId, String artifactId, String version) { + this(groupId, artifactId, "", TYPE_JAR, version); + } + + public GACTV(String groupId, String artifactId, String type, String version) { + this(groupId, artifactId, "", type, version); + } + + public GACTV(String groupId, String artifactId, String classifier, String type, String version) { + this.groupId = groupId; + this.artifactId = artifactId; + this.classifier = classifier == null ? "" : classifier; + this.type = type == null ? TYPE_JAR : type; + this.version = version; + } + + @Override + public String getGroupId() { + return groupId; + } + + @Override + public String getArtifactId() { + return artifactId; + } + + @Override + public String getClassifier() { + return classifier; + } + + @Override + public String getType() { + return type; + } + + @Override + public String getVersion() { + return version; + } + + @Override + public ArtifactKey getKey() { + return key == null ? key = new GACT(groupId, artifactId, classifier, type) : key; + } + + @Override + public int hashCode() { + return Objects.hash(artifactId, classifier, groupId, type, version); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + GACTV other = (GACTV) obj; + return Objects.equals(artifactId, other.artifactId) && Objects.equals(classifier, other.classifier) + && Objects.equals(groupId, other.groupId) && Objects.equals(type, other.type) + && Objects.equals(version, other.version); + } + + @Override + public String toString() { + final StringBuilder buf = new StringBuilder(); + append(buf); + return buf.toString(); + } + + protected StringBuilder append(final StringBuilder buf) { + buf.append(groupId).append(':').append(artifactId).append(':'); + if (classifier != null && !classifier.isEmpty()) { + buf.append(classifier); + } + return buf.append(':').append(type).append(':').append(version); + } +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/GAV.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/GAV.java new file mode 100644 index 0000000000000..b02672e7f431d --- /dev/null +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/GAV.java @@ -0,0 +1,57 @@ +package io.quarkus.maven.dependency; + +import io.quarkus.bootstrap.workspace.WorkspaceModuleId; +import java.io.Serializable; +import java.util.Objects; + +public class GAV implements WorkspaceModuleId, Serializable { + + private final String groupId; + private final String artifactId; + private final String version; + + public GAV(String groupId, String artifactId, String version) { + super(); + this.groupId = groupId; + this.artifactId = artifactId; + this.version = version; + } + + @Override + public String getGroupId() { + return groupId; + } + + @Override + public String getArtifactId() { + return artifactId; + } + + @Override + public String getVersion() { + return version; + } + + @Override + public int hashCode() { + return Objects.hash(artifactId, groupId, version); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + GAV other = (GAV) obj; + return Objects.equals(artifactId, other.artifactId) && Objects.equals(groupId, other.groupId) + && Objects.equals(version, other.version); + } + + @Override + public String toString() { + return groupId + ":" + artifactId + ":" + version; + } +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ResolvableDependency.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ResolvableDependency.java new file mode 100644 index 0000000000000..8ae99466f559e --- /dev/null +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ResolvableDependency.java @@ -0,0 +1,8 @@ +package io.quarkus.maven.dependency; + +import io.quarkus.paths.PathCollection; + +public interface ResolvableDependency extends ResolvedDependency { + + void setResolvedPaths(PathCollection paths); +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ResolvedArtifactDependency.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ResolvedArtifactDependency.java new file mode 100644 index 0000000000000..aa7274e45168a --- /dev/null +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ResolvedArtifactDependency.java @@ -0,0 +1,88 @@ +package io.quarkus.maven.dependency; + +import io.quarkus.bootstrap.workspace.WorkspaceModule; +import io.quarkus.paths.PathCollection; +import io.quarkus.paths.PathList; +import java.io.Serializable; +import java.nio.file.Path; +import java.util.Objects; + +public class ResolvedArtifactDependency extends ArtifactDependency implements ResolvableDependency, Serializable { + + private PathCollection paths; + private WorkspaceModule module; + + public ResolvedArtifactDependency(ArtifactCoords coords) { + this(coords, (PathCollection) null); + } + + public ResolvedArtifactDependency(ArtifactCoords coords, Path resolvedPath) { + this(coords, PathList.of(resolvedPath)); + } + + public ResolvedArtifactDependency(String groupId, String artifactId, String classifier, String type, String version, + Path resolvedPath) { + this(groupId, artifactId, classifier, type, version, PathList.of(resolvedPath)); + } + + public ResolvedArtifactDependency(String groupId, String artifactId, String classifier, String type, String version, + PathCollection resolvedPath) { + super(groupId, artifactId, classifier, type, version); + this.paths = resolvedPath; + } + + public ResolvedArtifactDependency(ArtifactCoords coords, PathCollection resolvedPaths) { + super(coords); + this.paths = resolvedPaths; + } + + public ResolvedArtifactDependency(ResolvedDependencyBuilder builder) { + super(builder); + this.paths = builder.getResolvedPaths(); + this.module = builder.getWorkspaceModule(); + } + + @Override + public PathCollection getResolvedPaths() { + return paths; + } + + public void setResolvedPaths(PathCollection paths) { + this.paths = paths; + } + + @Override + public WorkspaceModule getWorkspaceModule() { + return module; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + Objects.hash(module, paths); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + ResolvedArtifactDependency other = (ResolvedArtifactDependency) obj; + return Objects.equals(module, other.module) && Objects.equals(paths, other.paths); + } + + @Override + public String toString() { + final StringBuilder buf = new StringBuilder(); + buf.append(toGACTVString()).append(paths); + if (module != null) { + buf.append(" " + module); + } + return buf.toString(); + } +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ResolvedDependency.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ResolvedDependency.java new file mode 100644 index 0000000000000..0c0b3cd118697 --- /dev/null +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ResolvedDependency.java @@ -0,0 +1,18 @@ +package io.quarkus.maven.dependency; + +import io.quarkus.bootstrap.workspace.WorkspaceModule; +import io.quarkus.paths.PathCollection; + +public interface ResolvedDependency extends Dependency { + + PathCollection getResolvedPaths(); + + default boolean isResolved() { + final PathCollection paths = getResolvedPaths(); + return paths != null && !paths.isEmpty(); + } + + default WorkspaceModule getWorkspaceModule() { + return null; + } +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ResolvedDependencyBuilder.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ResolvedDependencyBuilder.java new file mode 100644 index 0000000000000..5ac54ae2f6f4c --- /dev/null +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ResolvedDependencyBuilder.java @@ -0,0 +1,44 @@ +package io.quarkus.maven.dependency; + +import io.quarkus.bootstrap.workspace.WorkspaceModule; +import io.quarkus.paths.PathCollection; +import io.quarkus.paths.PathList; +import java.nio.file.Path; + +public class ResolvedDependencyBuilder extends AbstractDependencyBuilder { + + public static ResolvedDependencyBuilder newInstance() { + return new ResolvedDependencyBuilder(); + } + + PathCollection resolvedPaths; + WorkspaceModule workspaceModule; + + public PathCollection getResolvedPaths() { + return resolvedPaths; + } + + public ResolvedDependencyBuilder setResolvedPath(Path path) { + this.resolvedPaths = path == null ? null : PathList.of(path); + return this; + } + + public ResolvedDependencyBuilder setResolvedPaths(PathCollection resolvedPaths) { + this.resolvedPaths = resolvedPaths; + return this; + } + + public WorkspaceModule getWorkspaceModule() { + return workspaceModule; + } + + public ResolvedDependencyBuilder setWorkspaceModule(WorkspaceModule projectModule) { + this.workspaceModule = projectModule; + return this; + } + + @Override + public ResolvedDependency build() { + return new ResolvedArtifactDependency(this); + } +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathCollection.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathCollection.java new file mode 100644 index 0000000000000..ff5d13b0072b6 --- /dev/null +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathCollection.java @@ -0,0 +1,29 @@ +package io.quarkus.paths; + +import java.nio.file.Path; + +public interface PathCollection extends Iterable { + + boolean isEmpty(); + + int size(); + + boolean isSinglePath(); + + default Path getSinglePath() { + if (size() != 1) { + throw new IllegalStateException("Paths collection expected to contain a single path but contains " + size()); + } + return iterator().next(); + } + + boolean contains(Path path); + + PathCollection add(Path... paths); + + PathCollection addFirst(Path... paths); + + PathCollection addAllFirst(Iterable i); + + Path resolveExistingOrNull(String path); +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathList.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathList.java new file mode 100644 index 0000000000000..84a39c330f744 --- /dev/null +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathList.java @@ -0,0 +1,155 @@ +package io.quarkus.paths; + +import java.io.IOException; +import java.io.Serializable; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +public class PathList implements PathCollection, Serializable { + + public static PathList from(Iterable paths) { + final List list = new ArrayList<>(); + paths.forEach(list::add); + return new PathList(list); + } + + public static PathList of(Path... paths) { + return new PathList(Arrays.asList(paths)); + } + + public static PathList empty() { + return new PathList(Collections.emptyList()); + } + + public static class Builder { + private List paths = new ArrayList<>(); + + private Builder() { + } + + public Builder add(Path path) { + paths.add(path); + return this; + } + + public boolean contains(Path p) { + return paths.contains(p); + } + + public boolean isEmpty() { + return paths.isEmpty(); + } + + public PathList build() { + return new PathList(paths); + } + } + + public static Builder builder() { + return new Builder(); + } + + private List paths; + + private PathList(List paths) { + this.paths = Collections.unmodifiableList(paths); + } + + public boolean isEmpty() { + return paths.isEmpty(); + } + + public int size() { + return paths.size(); + } + + public boolean isSinglePath() { + return paths.size() == 1; + } + + public Path getSinglePath() { + if (paths.size() != 1) { + throw new IllegalStateException("Paths collection expected to contain a single path but contains " + paths.size()); + } + return paths.get(0); + } + + @Override + public Iterator iterator() { + return paths.iterator(); + } + + public boolean contains(Path path) { + return paths.contains(path); + } + + public PathList add(Path... paths) { + final List list = new ArrayList<>(this.paths.size() + paths.length); + list.addAll(this.paths); + for (int i = 0; i < paths.length; ++i) { + list.add(paths[i]); + } + return new PathList(list); + } + + public PathList addFirst(Path... paths) { + final List list = new ArrayList<>(this.paths.size() + paths.length); + for (int i = 0; i < paths.length; ++i) { + list.add(paths[i]); + } + list.addAll(this.paths); + return new PathList(list); + } + + public PathList addAllFirst(Iterable i) { + final List list = new ArrayList<>(); + i.forEach(list::add); + paths.forEach(list::add); + return new PathList(list); + } + + public Path resolveExistingOrNull(String path) { + for (Path p : paths) { + final Path resolved = p.resolve(path); + if (Files.exists(resolved)) { + return resolved; + } + } + return null; + } + + @Override + public String toString() { + final StringBuilder buf = new StringBuilder(); + buf.append("[paths: "); + forEach(p -> buf.append(p).append(';')); + return buf.append(']').toString(); + } + + private void writeObject(java.io.ObjectOutputStream out) throws IOException { + out.writeInt(paths.size()); + for (Path p : paths) { + out.writeUTF(p.toAbsolutePath().toString()); + } + } + + private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { + final int pathsTotal = in.readInt(); + List paths = new ArrayList<>(pathsTotal); + for (int i = 0; i < pathsTotal; ++i) { + paths.add(Paths.get(in.readUTF())); + } + this.paths = Collections.unmodifiableList(paths); + } + + public Collection toList() { + return new ArrayList<>(paths); + } +} \ No newline at end of file diff --git a/independent-projects/bootstrap/app-model/src/test/java/io/quarkus/bootstrap/model/PlatformImportsTest.java b/independent-projects/bootstrap/app-model/src/test/java/io/quarkus/bootstrap/model/PlatformImportsTest.java index b04139d7c05e1..8afa13dc83617 100644 --- a/independent-projects/bootstrap/app-model/src/test/java/io/quarkus/bootstrap/model/PlatformImportsTest.java +++ b/independent-projects/bootstrap/app-model/src/test/java/io/quarkus/bootstrap/model/PlatformImportsTest.java @@ -6,6 +6,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import io.quarkus.bootstrap.util.IoUtils; +import io.quarkus.maven.dependency.ArtifactCoords; +import io.quarkus.maven.dependency.GACTV; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; @@ -50,20 +52,20 @@ public void singlePlatformReleaseInfo() throws Exception { assertEquals("io.playground", release.getPlatformKey()); assertEquals("1.1", release.getStream()); assertEquals("1", release.getVersion()); - final List boms = release.getBoms(); - assertEquals(Arrays.asList(AppArtifactCoords.fromString("io.playground:playground-bom::pom:1.1.1"), - AppArtifactCoords.fromString("io.playground:acme-bom::pom:2.2.2"), - AppArtifactCoords.fromString("io.playground:foo-bom::pom:3.3.3")), boms); + final List boms = release.getBoms(); + assertEquals(Arrays.asList(GACTV.fromString("io.playground:playground-bom::pom:1.1.1"), + GACTV.fromString("io.playground:acme-bom::pom:2.2.2"), + GACTV.fromString("io.playground:foo-bom::pom:3.3.3")), boms); assertEquals(1, stream.getReleases().size()); assertEquals(1, platform.getStreams().size()); assertEquals(1, pi.getPlatforms().size()); assertTrue(pi.isAligned(Collections.singletonMap("io.playground", - Arrays.asList(AppArtifactCoords.fromString("io.playground:playground-bom::pom:1.1.1"), - AppArtifactCoords.fromString("io.playground:acme-bom::pom:2.2.2"))))); + Arrays.asList(GACTV.fromString("io.playground:playground-bom::pom:1.1.1"), + GACTV.fromString("io.playground:acme-bom::pom:2.2.2"))))); assertFalse(pi.isAligned(Collections.singletonMap("io.playground", - Arrays.asList(AppArtifactCoords.fromString("io.playground:playground-bom::pom:1.1.2"), - AppArtifactCoords.fromString("io.playground:acme-bom::pom:2.2.2"))))); + Arrays.asList(GACTV.fromString("io.playground:playground-bom::pom:1.1.2"), + GACTV.fromString("io.playground:acme-bom::pom:2.2.2"))))); } @Test @@ -91,23 +93,23 @@ public void multiplePlatformReleaseInTheSameStream() throws Exception { assertEquals("io.playground", release.getPlatformKey()); assertEquals("1.1", release.getStream()); assertEquals("1", release.getVersion()); - final List boms = release.getBoms(); - assertEquals(Arrays.asList(AppArtifactCoords.fromString("io.playground:playground-bom::pom:1.1.1"), - AppArtifactCoords.fromString("io.playground:acme-bom::pom:2.2.2"), - AppArtifactCoords.fromString("io.playground:foo-bom::pom:3.3.3")), boms); + final List boms = release.getBoms(); + assertEquals(Arrays.asList(GACTV.fromString("io.playground:playground-bom::pom:1.1.1"), + GACTV.fromString("io.playground:acme-bom::pom:2.2.2"), + GACTV.fromString("io.playground:foo-bom::pom:3.3.3")), boms); assertEquals(2, stream.getReleases().size()); assertEquals(1, platform.getStreams().size()); assertEquals(1, pi.getPlatforms().size()); assertTrue(pi.isAligned(Collections.singletonMap("io.playground", - Arrays.asList(AppArtifactCoords.fromString("io.playground:playground-bom::pom:1.1.1"), - AppArtifactCoords.fromString("io.playground:acme-bom::pom:2.2.2"))))); + Arrays.asList(GACTV.fromString("io.playground:playground-bom::pom:1.1.1"), + GACTV.fromString("io.playground:acme-bom::pom:2.2.2"))))); assertTrue(pi.isAligned(Collections.singletonMap("io.playground", - Arrays.asList(AppArtifactCoords.fromString("io.playground:playground-bom::pom:1.1.2"), - AppArtifactCoords.fromString("io.playground:acme-bom::pom:2.2.3"))))); + Arrays.asList(GACTV.fromString("io.playground:playground-bom::pom:1.1.2"), + GACTV.fromString("io.playground:acme-bom::pom:2.2.3"))))); assertFalse(pi.isAligned(Collections.singletonMap("io.playground", - Arrays.asList(AppArtifactCoords.fromString("io.playground:playground-bom::pom:1.1.2"), - AppArtifactCoords.fromString("io.playground:acme-bom::pom:2.2.2"))))); + Arrays.asList(GACTV.fromString("io.playground:playground-bom::pom:1.1.2"), + GACTV.fromString("io.playground:acme-bom::pom:2.2.2"))))); } private PlatformProps newPlatformProps() throws IOException { diff --git a/independent-projects/bootstrap/app-model/src/test/java/io/quarkus/bootstrap/model/PlatformInfoTest.java b/independent-projects/bootstrap/app-model/src/test/java/io/quarkus/bootstrap/model/PlatformInfoTest.java index 8ba4d4eb73af6..1e95064e6f3d9 100644 --- a/independent-projects/bootstrap/app-model/src/test/java/io/quarkus/bootstrap/model/PlatformInfoTest.java +++ b/independent-projects/bootstrap/app-model/src/test/java/io/quarkus/bootstrap/model/PlatformInfoTest.java @@ -3,6 +3,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; +import io.quarkus.maven.dependency.GACTV; import java.util.Arrays; import java.util.Collections; import org.junit.jupiter.api.Test; @@ -12,7 +13,7 @@ public class PlatformInfoTest { @Test public void emptyIsAligned() throws Exception { assertTrue(new PlatformInfo("p") - .isAligned(Collections.singletonList(AppArtifactCoords.fromString("io.playground:playground-bom::pom:1.1.1")))); + .isAligned(Collections.singletonList(GACTV.fromString("io.playground:playground-bom::pom:1.1.1")))); } @Test @@ -24,12 +25,12 @@ public void singleStreamIsAligned() throws Exception { stream.addIfNotPresent("2", () -> new PlatformReleaseInfo("io.playground", "playground-bom", "1.1", "io.playground:playground-bom::pom:1.1.2,org.acme:acme-bom::pom:2.2.3,com.foo:foo-bom::pom:3.3.3")); - assertTrue(platform.isAligned(Arrays.asList(AppArtifactCoords.fromString("io.playground:playground-bom::pom:1.1.1"), - AppArtifactCoords.fromString("org.acme:acme-bom::pom:2.2.2")))); - assertTrue(platform.isAligned(Arrays.asList(AppArtifactCoords.fromString("io.playground:playground-bom::pom:1.1.2"), - AppArtifactCoords.fromString("org.acme:acme-bom::pom:2.2.3")))); - assertFalse(platform.isAligned(Arrays.asList(AppArtifactCoords.fromString("io.playground:playground-bom::pom:1.1.2"), - AppArtifactCoords.fromString("org.acme:acme-bom::pom:2.2.2")))); + assertTrue(platform.isAligned(Arrays.asList(GACTV.fromString("io.playground:playground-bom::pom:1.1.1"), + GACTV.fromString("org.acme:acme-bom::pom:2.2.2")))); + assertTrue(platform.isAligned(Arrays.asList(GACTV.fromString("io.playground:playground-bom::pom:1.1.2"), + GACTV.fromString("org.acme:acme-bom::pom:2.2.3")))); + assertFalse(platform.isAligned(Arrays.asList(GACTV.fromString("io.playground:playground-bom::pom:1.1.2"), + GACTV.fromString("org.acme:acme-bom::pom:2.2.2")))); } @Test @@ -38,6 +39,6 @@ public void multipleStreamsAreNotAligned() throws Exception { platform.getOrCreateStream("1.1"); platform.getOrCreateStream("1.2"); assertFalse(platform - .isAligned(Collections.singletonList(AppArtifactCoords.fromString("io.playground:playground-bom::pom:1.1.1")))); + .isAligned(Collections.singletonList(GACTV.fromString("io.playground:playground-bom::pom:1.1.1")))); } } diff --git a/independent-projects/bootstrap/app-model/src/test/java/io/quarkus/bootstrap/model/PlatformStreamInfoTest.java b/independent-projects/bootstrap/app-model/src/test/java/io/quarkus/bootstrap/model/PlatformStreamInfoTest.java index 75e83c763bd0d..9f41cd6cf5826 100644 --- a/independent-projects/bootstrap/app-model/src/test/java/io/quarkus/bootstrap/model/PlatformStreamInfoTest.java +++ b/independent-projects/bootstrap/app-model/src/test/java/io/quarkus/bootstrap/model/PlatformStreamInfoTest.java @@ -3,6 +3,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; +import io.quarkus.maven.dependency.GACTV; import java.util.Arrays; import java.util.Collections; import org.junit.jupiter.api.Test; @@ -12,7 +13,7 @@ public class PlatformStreamInfoTest { @Test public void emptyIsAligned() throws Exception { assertTrue(new PlatformStreamInfo("1.1") - .isAligned(Collections.singletonList(AppArtifactCoords.fromString("io.playground:playground-bom::pom:1.1.1")))); + .isAligned(Collections.singletonList(GACTV.fromString("io.playground:playground-bom::pom:1.1.1")))); } @Test @@ -22,11 +23,11 @@ public void isAligned() throws Exception { "io.playground:playground-bom::pom:1.1.1,org.acme:acme-bom::pom:2.2.2,com.foo:foo-bom::pom:3.3.3")); stream.addIfNotPresent("2", () -> new PlatformReleaseInfo("io.playground", "playground-bom", "1.1", "io.playground:playground-bom::pom:1.1.2,org.acme:acme-bom::pom:2.2.3,com.foo:foo-bom::pom:3.3.3")); - assertTrue(stream.isAligned(Arrays.asList(AppArtifactCoords.fromString("io.playground:playground-bom::pom:1.1.1"), - AppArtifactCoords.fromString("org.acme:acme-bom::pom:2.2.2")))); - assertTrue(stream.isAligned(Arrays.asList(AppArtifactCoords.fromString("io.playground:playground-bom::pom:1.1.2"), - AppArtifactCoords.fromString("org.acme:acme-bom::pom:2.2.3")))); - assertFalse(stream.isAligned(Arrays.asList(AppArtifactCoords.fromString("io.playground:playground-bom::pom:1.1.2"), - AppArtifactCoords.fromString("org.acme:acme-bom::pom:2.2.2")))); + assertTrue(stream.isAligned(Arrays.asList(GACTV.fromString("io.playground:playground-bom::pom:1.1.1"), + GACTV.fromString("org.acme:acme-bom::pom:2.2.2")))); + assertTrue(stream.isAligned(Arrays.asList(GACTV.fromString("io.playground:playground-bom::pom:1.1.2"), + GACTV.fromString("org.acme:acme-bom::pom:2.2.3")))); + assertFalse(stream.isAligned(Arrays.asList(GACTV.fromString("io.playground:playground-bom::pom:1.1.2"), + GACTV.fromString("org.acme:acme-bom::pom:2.2.2")))); } } diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/BootstrapAppModelFactory.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/BootstrapAppModelFactory.java index b4b0b54047530..9bf94e7afd002 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/BootstrapAppModelFactory.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/BootstrapAppModelFactory.java @@ -1,11 +1,8 @@ package io.quarkus.bootstrap; import io.quarkus.bootstrap.app.CurationResult; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppArtifactCoords; import io.quarkus.bootstrap.model.AppArtifactKey; -import io.quarkus.bootstrap.model.AppDependency; -import io.quarkus.bootstrap.model.AppModel; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.resolver.AppModelResolver; import io.quarkus.bootstrap.resolver.AppModelResolverException; import io.quarkus.bootstrap.resolver.BootstrapAppModelResolver; @@ -22,6 +19,14 @@ import io.quarkus.bootstrap.resolver.update.VersionUpdateNumber; import io.quarkus.bootstrap.util.IoUtils; import io.quarkus.bootstrap.util.ZipUtils; +import io.quarkus.maven.dependency.ArtifactCoords; +import io.quarkus.maven.dependency.ArtifactDependency; +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.DependencyFlags; +import io.quarkus.maven.dependency.GACT; +import io.quarkus.maven.dependency.GACTV; +import io.quarkus.maven.dependency.ResolvedArtifactDependency; +import io.quarkus.maven.dependency.ResolvedDependency; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; @@ -33,10 +38,12 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; import org.apache.maven.model.Dependency; import org.apache.maven.model.Model; import org.jboss.logging.Logger; @@ -66,7 +73,7 @@ public static BootstrapAppModelFactory newInstance() { return new BootstrapAppModelFactory(); } - private AppArtifact managingProject; + private ArtifactCoords managingProject; private Path projectRoot; private List appCp = new ArrayList<>(0); private Boolean localProjectsDiscovery; @@ -79,13 +86,13 @@ public static BootstrapAppModelFactory newInstance() { private VersionUpdateNumber versionUpdateNumber; private VersionUpdate versionUpdate; private DependenciesOrigin dependenciesOrigin; - private AppArtifact appArtifact; + private ResolvedDependency appArtifact; private MavenArtifactResolver mavenArtifactResolver; private BootstrapMavenContext mvnContext; - Set localArtifacts = Collections.emptySet(); + Set reloadableModules = Collections.emptySet(); - private List forcedDependencies = Collections.emptyList(); + private Collection forcedDependencies = Collections.emptyList(); private BootstrapAppModelFactory() { } @@ -100,12 +107,10 @@ public BootstrapAppModelFactory setDevMode(boolean devMode) { return this; } - public Set getLocalArtifacts() { - return localArtifacts; - } - public BootstrapAppModelFactory setLocalArtifacts(Set localArtifacts) { - this.localArtifacts = localArtifacts; + this.reloadableModules = localArtifacts.stream() + .map(k -> new GACT(k.getGroupId(), k.getArtifactId(), k.getClassifier(), k.getType())) + .collect(Collectors.toSet()); return this; } @@ -154,12 +159,13 @@ public BootstrapAppModelFactory setDependenciesOrigin(DependenciesOrigin depende return this; } - public BootstrapAppModelFactory setAppArtifact(AppArtifact appArtifact) { + public BootstrapAppModelFactory setAppArtifact(ResolvedDependency appArtifact) { this.appArtifact = appArtifact; return this; } - public BootstrapAppModelFactory setForcedDependencies(List forcedDependencies) { + public BootstrapAppModelFactory setForcedDependencies( + Collection forcedDependencies) { this.forcedDependencies = forcedDependencies; return this; } @@ -230,11 +236,12 @@ public CurationResult resolveAppModel() throws BootstrapException { } else { serializedModel = System.getProperty(BootstrapConstants.SERIALIZED_APP_MODEL); } + if (serializedModel != null) { final Path p = Paths.get(serializedModel); if (Files.exists(p)) { try (InputStream existing = Files.newInputStream(Paths.get(serializedModel))) { - final AppModel appModel = (AppModel) new ObjectInputStream(existing).readObject(); + final ApplicationModel appModel = (ApplicationModel) new ObjectInputStream(existing).readObject(); return new CurationResult(appModel); } catch (IOException | ClassNotFoundException e) { log.error("Failed to load serialized app mode", e); @@ -251,7 +258,7 @@ public CurationResult resolveAppModel() throws BootstrapException { return createAppModelForJar(projectRoot); } - AppArtifact appArtifact = this.appArtifact; + ResolvedDependency appArtifact = this.appArtifact; try { LocalProject localProject = null; if (appArtifact == null) { @@ -283,11 +290,11 @@ public CurationResult resolveAppModel() throws BootstrapException { if (reader.readInt() == CP_CACHE_FORMAT_ID) { if (reader.readInt() == workspace.getId()) { ObjectInputStream in = new ObjectInputStream(reader); - AppModel appModel = (AppModel) in.readObject(); + ApplicationModel appModel = (ApplicationModel) in.readObject(); log.debugf("Loaded cached AppModel %s from %s", appModel, cachedCpPath); - for (AppDependency i : appModel.getFullDeploymentDeps()) { - for (Path p : i.getArtifact().getPaths()) { + for (ResolvedDependency d : appModel.getDependencies()) { + for (Path p : d.getResolvedPaths()) { if (!Files.exists(p)) { throw new IOException("Cached artifact does not exist: " + p); } @@ -308,14 +315,14 @@ public CurationResult resolveAppModel() throws BootstrapException { } } CurationResult curationResult = new CurationResult(getAppModelResolver() - .resolveManagedModel(appArtifact, forcedDependencies, managingProject, localArtifacts)); + .resolveManagedModel(appArtifact, forcedDependencies, managingProject, reloadableModules)); if (cachedCpPath != null) { Files.createDirectories(cachedCpPath.getParent()); try (DataOutputStream out = new DataOutputStream(Files.newOutputStream(cachedCpPath))) { out.writeInt(CP_CACHE_FORMAT_ID); out.writeInt(workspace.getId()); ObjectOutputStream obj = new ObjectOutputStream(out); - obj.writeObject(curationResult.getAppModel()); + obj.writeObject(curationResult.getApplicationModel()); } catch (Exception e) { log.warn("Failed to write classpath cache", e); } @@ -341,11 +348,11 @@ private CurationResult createAppModelForJar(Path appArtifactPath) { log.debugf("provideOutcome depsOrigin=%s, versionUpdate=%s, versionUpdateNumber=%s", dependenciesOrigin, versionUpdate, versionUpdateNumber); - AppArtifact stateArtifact = null; + ResolvedDependency stateArtifact = null; boolean loadedFromState = false; AppModelResolver modelResolver = getAppModelResolver(); - final AppModel initialDepsList; - AppArtifact appArtifact = this.appArtifact; + final ApplicationModel initialDepsList; + ResolvedDependency appArtifact = this.appArtifact; try { if (appArtifact == null) { appArtifact = ModelUtils.resolveAppArtifact(appArtifactPath); @@ -356,13 +363,15 @@ private CurationResult createAppModelForJar(Path appArtifactPath) { log.info("Looking for the state of the last update"); Path statePath = null; try { - stateArtifact = ModelUtils.getStateArtifact(appArtifact); - final String latest = modelResolver.getLatestVersion(stateArtifact, null, false); - if (!stateArtifact.getVersion().equals(latest)) { - stateArtifact = new AppArtifact(stateArtifact.getGroupId(), stateArtifact.getArtifactId(), - stateArtifact.getClassifier(), stateArtifact.getType(), latest); + ArtifactCoords stateCoords = ModelUtils.getStateArtifact(appArtifact); + final String latest = modelResolver.getLatestVersion(stateCoords, null, false); + if (!stateCoords.getVersion().equals(latest)) { + stateCoords = new GACTV(stateCoords.getGroupId(), + stateCoords.getArtifactId(), + stateCoords.getClassifier(), stateCoords.getType(), latest); } - statePath = modelResolver.resolve(stateArtifact); + stateArtifact = modelResolver.resolve(stateArtifact); + statePath = stateArtifact.getResolvedPaths().getSinglePath(); log.info("- located the state at " + statePath); } catch (AppModelResolverException e) { // for now let's assume this means artifact does not exist @@ -376,15 +385,17 @@ private CurationResult createAppModelForJar(Path appArtifactPath) { throw new RuntimeException("Failed to read application state " + statePath, e); } final List modelStateDeps = model.getDependencies(); - final List updatedDeps = new ArrayList<>(modelStateDeps.size()); + final List updatedDeps = new ArrayList<>(modelStateDeps.size()); final String groupIdProp = "${" + CREATOR_APP_GROUP_ID + "}"; for (Dependency modelDep : modelStateDeps) { if (modelDep.getGroupId().equals(groupIdProp)) { continue; } - updatedDeps.add(new AppDependency(new AppArtifact(modelDep.getGroupId(), modelDep.getArtifactId(), - modelDep.getClassifier(), modelDep.getType(), modelDep.getVersion()), modelDep.getScope(), - modelDep.isOptional())); + updatedDeps.add(new ArtifactDependency( + new ResolvedArtifactDependency(new GACTV(modelDep.getGroupId(), modelDep.getArtifactId(), + modelDep.getClassifier(), modelDep.getType(), modelDep.getVersion())), + modelDep.getScope(), + modelDep.isOptional() ? DependencyFlags.OPTIONAL : 0)); } initialDepsList = modelResolver.resolveModel(appArtifact, updatedDeps); loadedFromState = true; @@ -394,7 +405,7 @@ private CurationResult createAppModelForJar(Path appArtifactPath) { } else { //we need some way to figure out dependencies here initialDepsList = modelResolver.resolveManagedModel(appArtifact, Collections.emptyList(), managingProject, - localArtifacts); + reloadableModules); } } catch (AppModelResolverException | IOException e) { throw new RuntimeException("Failed to resolve initial application dependencies", e); @@ -407,20 +418,21 @@ private CurationResult createAppModelForJar(Path appArtifactPath) { } log.info("Checking for available updates"); - List appDeps; + Collection appDeps; try { - appDeps = modelResolver.resolveUserDependencies(appArtifact, initialDepsList.getUserDependencies()); + appDeps = modelResolver.resolveUserDependencies(appArtifact, + new ArrayList<>(initialDepsList.getRuntimeDependencies())); } catch (AppModelResolverException e) { throw new RuntimeException("Failed to determine the list of dependencies to update", e); } - final Iterator depsI = appDeps.iterator(); + final Iterator depsI = appDeps.iterator(); while (depsI.hasNext()) { - final AppArtifact appDep = depsI.next().getArtifact(); - if (!appDep.getType().equals(AppArtifactCoords.TYPE_JAR)) { + final ResolvedDependency appDep = depsI.next(); + if (!appDep.getType().equals(ArtifactCoords.TYPE_JAR)) { depsI.remove(); continue; } - appDep.getPaths().forEach(path -> { + appDep.getResolvedPaths().forEach(path -> { if (Files.isDirectory(path)) { if (!Files.exists(path.resolve(BootstrapConstants.DESCRIPTOR_PATH))) { depsI.remove(); @@ -438,28 +450,27 @@ private CurationResult createAppModelForJar(Path appArtifactPath) { } final UpdateDiscovery ud = new DefaultUpdateDiscovery(modelResolver, versionUpdateNumber); - List availableUpdates = null; - int i = 0; - while (i < appDeps.size()) { - final AppDependency dep = appDeps.get(i++); - final AppArtifact depArtifact = dep.getArtifact(); + List availableUpdates = null; + for (ResolvedDependency depArtifact : appDeps) { final String updatedVersion = versionUpdate == VersionUpdate.NEXT ? ud.getNextVersion(depArtifact) : ud.getLatestVersion(depArtifact); if (updatedVersion == null || depArtifact.getVersion().equals(updatedVersion)) { continue; } - log.info(dep.getArtifact() + " -> " + updatedVersion); + log.info(depArtifact.toGACTVString() + " -> " + updatedVersion); if (availableUpdates == null) { availableUpdates = new ArrayList<>(); } - availableUpdates.add(new AppDependency(new AppArtifact(depArtifact.getGroupId(), depArtifact.getArtifactId(), - depArtifact.getClassifier(), depArtifact.getType(), updatedVersion), dep.getScope())); + availableUpdates.add(new ArtifactDependency( + new GACTV(depArtifact.getGroupId(), depArtifact.getArtifactId(), depArtifact.getClassifier(), + depArtifact.getType(), updatedVersion), + depArtifact.getScope())); } if (availableUpdates != null) { try { return new CurationResult( - modelResolver.resolveManagedModel(appArtifact, availableUpdates, managingProject, localArtifacts), + modelResolver.resolveManagedModel(appArtifact, availableUpdates, managingProject, reloadableModules), availableUpdates, loadedFromState, appArtifact, stateArtifact); } catch (AppModelResolverException e) { @@ -490,7 +501,7 @@ public BootstrapAppModelFactory setMavenArtifactResolver(MavenArtifactResolver m return this; } - public BootstrapAppModelFactory setManagingProject(AppArtifact managingProject) { + public BootstrapAppModelFactory setManagingProject(ArtifactCoords managingProject) { this.managingProject = managingProject; return this; } diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/IDELauncherImpl.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/IDELauncherImpl.java index cf95c69b7ac22..4368e1f28fb19 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/IDELauncherImpl.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/IDELauncherImpl.java @@ -3,16 +3,12 @@ import io.quarkus.bootstrap.app.AdditionalDependency; import io.quarkus.bootstrap.app.CuratedApplication; import io.quarkus.bootstrap.app.QuarkusBootstrap; -import io.quarkus.bootstrap.devmode.DependenciesFilter; -import io.quarkus.bootstrap.model.AppArtifactKey; -import io.quarkus.bootstrap.model.gradle.QuarkusModel; -import io.quarkus.bootstrap.model.gradle.WorkspaceModule; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.resolver.maven.BootstrapMavenContext; import io.quarkus.bootstrap.resolver.maven.MavenArtifactResolver; -import io.quarkus.bootstrap.resolver.maven.workspace.LocalProject; -import io.quarkus.bootstrap.util.PathsUtils; -import io.quarkus.bootstrap.util.QuarkusModelHelper; +import io.quarkus.bootstrap.util.BootstrapUtils; import io.quarkus.bootstrap.utils.BuildToolHelper; +import io.quarkus.bootstrap.workspace.WorkspaceModule; import java.io.Closeable; import java.io.IOException; import java.nio.file.Path; @@ -43,26 +39,28 @@ public static Closeable launch(Path classesDir, Map context) { .setMode(QuarkusBootstrap.Mode.DEV) .setTargetDirectory(classesDir.getParent()); if (BuildToolHelper.isGradleProject(classesDir)) { - final QuarkusModel quarkusModel = BuildToolHelper.enableGradleAppModelForDevMode(classesDir); - context.put(QuarkusModelHelper.SERIALIZED_QUARKUS_MODEL, - QuarkusModelHelper.serializeQuarkusModel(quarkusModel)); + final ApplicationModel quarkusModel = BuildToolHelper.enableGradleAppModelForDevMode(classesDir); + context.put(BootstrapConstants.SERIALIZED_APP_MODEL, BootstrapUtils.serializeAppModel(quarkusModel, false)); + + final Path launchingModulePath = quarkusModel.getApplicationModule().getMainSources().iterator().next() + .getDestinationDir().toPath(); - final WorkspaceModule launchingModule = quarkusModel.getWorkspace().getMainModule(); - Path launchingModulePath = QuarkusModelHelper.getClassPath(launchingModule); // Gradle uses a different output directory for classes, we override the one used by the IDE builder.setProjectRoot(launchingModulePath) .setApplicationRoot(launchingModulePath) - .setTargetDirectory(launchingModule.getBuildDir().toPath()); + .setTargetDirectory(quarkusModel.getApplicationModule().getBuildDir().toPath()); + + for (WorkspaceModule additionalModule : quarkusModel.getWorkspaceModules()) { + additionalModule.getMainSources().forEach(src -> { + builder.addAdditionalApplicationArchive( + new AdditionalDependency(src.getDestinationDir().toPath(), true, false)); + + }); + additionalModule.getMainResources().forEach(src -> { + builder.addAdditionalApplicationArchive( + new AdditionalDependency(src.getDestinationDir().toPath(), true, false)); - for (WorkspaceModule additionalModule : quarkusModel.getWorkspace().getAllModules()) { - if (!additionalModule.getArtifactCoords().equals(launchingModule.getArtifactCoords())) { - builder.addAdditionalApplicationArchive(new AdditionalDependency( - PathsUtils.toPathsCollection(additionalModule.getSourceSet().getSourceDirectories()), - true, false)); - builder.addAdditionalApplicationArchive(new AdditionalDependency( - PathsUtils.toPathsCollection(additionalModule.getSourceSet().getResourceDirectories()), - true, false)); - } + }); } } else { builder.setApplicationRoot(classesDir) @@ -71,15 +69,8 @@ public static Closeable launch(Path classesDir, Map context) { final BootstrapMavenContext mvnCtx = new BootstrapMavenContext( BootstrapMavenContext.config().setCurrentProject(projectDir.toString())); - final LocalProject currentProject = mvnCtx.getCurrentProject(); - context.put("app-project", currentProject); - final MavenArtifactResolver mvnResolver = new MavenArtifactResolver(mvnCtx); builder.setMavenArtifactResolver(mvnResolver); - - DependenciesFilter.filterNotReloadableDependencies(currentProject, mvnResolver) - .forEach(p -> builder - .addLocalArtifact(new AppArtifactKey(p.getGroupId(), p.getArtifactId(), null, "jar"))); } final CuratedApplication curatedApp = builder.build().bootstrap(); diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/AdditionalDependency.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/AdditionalDependency.java index 0e1e0ee24580e..8c550a165cd68 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/AdditionalDependency.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/AdditionalDependency.java @@ -1,6 +1,8 @@ package io.quarkus.bootstrap.app; import io.quarkus.bootstrap.model.PathsCollection; +import io.quarkus.paths.PathCollection; +import io.quarkus.paths.PathList; import java.io.Serializable; import java.nio.file.Path; @@ -18,7 +20,7 @@ public class AdditionalDependency implements Serializable { /** * The path to the application archive */ - private final PathsCollection archivePath; + private final PathCollection paths; /** * If this archive is hot reloadable, only takes effect in dev mode. @@ -32,17 +34,37 @@ public class AdditionalDependency implements Serializable { private final boolean forceApplicationArchive; public AdditionalDependency(Path archivePath, boolean hotReloadable, boolean forceApplicationArchive) { - this(PathsCollection.of(archivePath), hotReloadable, forceApplicationArchive); + this(PathList.of(archivePath), hotReloadable, forceApplicationArchive); } + /** + * @deprecated in favor of {@link #AdditionalDependency(PathCollection, boolean, boolean)} + * @param archivePath archive paths + * @param hotReloadable whether the dependency is reloadable + * @param forceApplicationArchive whether it should be added as an application archive + */ + @Deprecated public AdditionalDependency(PathsCollection archivePath, boolean hotReloadable, boolean forceApplicationArchive) { - this.archivePath = archivePath; + this(PathList.from(archivePath), hotReloadable, forceApplicationArchive); + } + + public AdditionalDependency(PathCollection paths, boolean hotReloadable, boolean forceApplicationArchive) { + this.paths = paths; this.hotReloadable = hotReloadable; this.forceApplicationArchive = forceApplicationArchive; } + /** + * @deprecated in favor of {@link #getResolvedPaths()} + * @return archive paths + */ + @Deprecated public PathsCollection getArchivePath() { - return archivePath; + return PathsCollection.from(paths); + } + + public PathCollection getResolvedPaths() { + return paths; } public boolean isHotReloadable() { diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/ConfiguredClassLoading.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/ConfiguredClassLoading.java index 58a59d653f128..5ab926fdc76b1 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/ConfiguredClassLoading.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/ConfiguredClassLoading.java @@ -1,6 +1,6 @@ package io.quarkus.bootstrap.app; -import io.quarkus.bootstrap.model.AppArtifactKey; +import io.quarkus.maven.dependency.ArtifactKey; import java.io.Serializable; import java.util.List; import java.util.Map; @@ -8,15 +8,15 @@ public class ConfiguredClassLoading implements Serializable { - public final Set parentFirstArtifacts; - public final Set reloadableArtifacts; - public final Set removedArtifacts; - public final Map> removedResources; + public final Set parentFirstArtifacts; + public final Set reloadableArtifacts; + public final Set removedArtifacts; + public final Map> removedResources; public final boolean flatTestClassPath; - public ConfiguredClassLoading(Set parentFirstArtifacts, Set reloadableArtifacts, - Set removedArtifacts, - Map> removedResources, boolean flatTestClassPath) { + public ConfiguredClassLoading(Set parentFirstArtifacts, Set reloadableArtifacts, + Set removedArtifacts, + Map> removedResources, boolean flatTestClassPath) { this.parentFirstArtifacts = parentFirstArtifacts; this.reloadableArtifacts = reloadableArtifacts; this.removedResources = removedResources; diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/CuratedApplication.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/CuratedApplication.java index 022050b38ec10..b12c6d051bf6c 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/CuratedApplication.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/CuratedApplication.java @@ -1,20 +1,23 @@ package io.quarkus.bootstrap.app; -import io.quarkus.bootstrap.BootstrapConstants; import io.quarkus.bootstrap.classloading.ClassPathElement; import io.quarkus.bootstrap.classloading.ClassPathResource; import io.quarkus.bootstrap.classloading.FilteredClassPathElement; import io.quarkus.bootstrap.classloading.MemoryClassPathElement; import io.quarkus.bootstrap.classloading.QuarkusClassLoader; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppArtifactKey; -import io.quarkus.bootstrap.model.AppDependency; import io.quarkus.bootstrap.model.AppModel; +import io.quarkus.bootstrap.model.ApplicationModel; +import io.quarkus.bootstrap.util.BootstrapUtils; +import io.quarkus.maven.dependency.ArtifactCoords; +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.Dependency; +import io.quarkus.maven.dependency.ResolvedDependency; import java.io.IOException; import java.io.Serializable; import java.nio.file.Path; import java.security.ProtectionDomain; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -45,7 +48,7 @@ public class CuratedApplication implements Serializable, AutoCloseable { * * This should not be used for hot reloadable elements */ - private final Map> augmentationElements = new HashMap<>(); + private final Map> augmentationElements = new HashMap<>(); /** * The augmentation class loader. @@ -61,7 +64,7 @@ public class CuratedApplication implements Serializable, AutoCloseable { private final CurationResult curationResult; private final ConfiguredClassLoading configuredClassLoading; - final AppModel appModel; + final ApplicationModel appModel; final AtomicInteger runtimeClassLoaderCount = new AtomicInteger(); @@ -69,11 +72,20 @@ public class CuratedApplication implements Serializable, AutoCloseable { ConfiguredClassLoading configuredClassLoading) { this.quarkusBootstrap = quarkusBootstrap; this.curationResult = curationResult; - this.appModel = curationResult.getAppModel(); + this.appModel = curationResult.getApplicationModel(); this.configuredClassLoading = configuredClassLoading; } + /** + * @deprecated in favor of {@link #getApplicationModel()} + * @return AppModel + */ + @Deprecated public AppModel getAppModel() { + return BootstrapUtils.convert(appModel); + } + + public ApplicationModel getApplicationModel() { return appModel; } @@ -85,7 +97,7 @@ public boolean hasUpdatedDeps() { return curationResult.hasUpdatedDeps(); } - public List getUpdatedDeps() { + public Collection getUpdatedDeps() { return curationResult.getUpdatedDependencies(); } @@ -143,8 +155,8 @@ private Object runInCl(String consumerName, Map params, QuarkusC } } - private synchronized void processCpElement(AppArtifact artifact, Consumer consumer) { - if (!artifact.getType().equals(BootstrapConstants.JAR)) { + private synchronized void processCpElement(ResolvedDependency artifact, Consumer consumer) { + if (!artifact.getType().equals(ArtifactCoords.TYPE_JAR)) { //avoid the need for this sort of check in multiple places consumer.accept(ClassPathElement.EMPTY); return; @@ -159,7 +171,7 @@ public void accept(ClassPathElement classPathElement) { } }; } - List cpeList = augmentationElements.get(artifact); + List cpeList = augmentationElements.get(artifact.getKey()); if (cpeList != null) { for (ClassPathElement cpe : cpeList) { consumer.accept(cpe); @@ -167,22 +179,22 @@ public void accept(ClassPathElement classPathElement) { return; } cpeList = new ArrayList<>(2); - for (Path path : artifact.getPaths()) { + for (Path path : artifact.getResolvedPaths()) { final ClassPathElement element = ClassPathElement.fromPath(path); consumer.accept(element); cpeList.add(element); } - augmentationElements.put(artifact, cpeList); + augmentationElements.put(artifact.getKey(), cpeList); } - private void addCpElement(QuarkusClassLoader.Builder builder, AppArtifact dep, ClassPathElement element) { - final AppArtifactKey key = dep.getKey(); - if (appModel.getParentFirstArtifacts().contains(key) + private void addCpElement(QuarkusClassLoader.Builder builder, ResolvedDependency dep, ClassPathElement element) { + final ArtifactKey key = dep.getKey(); + if (appModel.getParentFirst().contains(key) || configuredClassLoading.parentFirstArtifacts.contains(dep.getKey())) { //we always load this from the parent if it is available, as this acts as a bridge between the running //app and the dev mode code builder.addParentFirstElement(element); - } else if (appModel.getLesserPriorityArtifacts().contains(key)) { + } else if (appModel.getLowerPriorityArtifacts().contains(key)) { builder.addLesserPriorityElement(element); } builder.addElement(element); @@ -199,14 +211,14 @@ public synchronized QuarkusClassLoader getAugmentClassLoader() { //we want a class loader that can load the deployment artifacts and all their dependencies, but not //any of the runtime artifacts, or user classes //this will load any deployment artifacts from the parent CL if they are present - for (AppDependency i : appModel.getFullDeploymentDeps()) { - if (configuredClassLoading.reloadableArtifacts.contains(i.getArtifact().getKey())) { + for (ResolvedDependency i : appModel.getDependencies()) { + if (configuredClassLoading.reloadableArtifacts.contains(i.getKey())) { continue; } - if (configuredClassLoading.removedArtifacts.contains(i.getArtifact().getKey())) { - processCpElement(i.getArtifact(), builder::addBannedElement); + if (configuredClassLoading.removedArtifacts.contains(i.getKey())) { + processCpElement(i, builder::addBannedElement); } else { - processCpElement(i.getArtifact(), element -> addCpElement(builder, i.getArtifact(), element)); + processCpElement(i, element -> addCpElement(builder, i, element)); } } @@ -259,11 +271,11 @@ public synchronized QuarkusClassLoader getBaseRuntimeClassLoader() { Set hotReloadPaths = new HashSet<>(); for (AdditionalDependency i : quarkusBootstrap.getAdditionalApplicationArchives()) { if (!i.isHotReloadable()) { - for (Path root : i.getArchivePath()) { + for (Path root : i.getResolvedPaths()) { builder.addElement(ClassPathElement.fromPath(root)); } } else { - for (Path root : i.getArchivePath()) { + for (Path root : i.getResolvedPaths()) { hotReloadPaths.add(root); builder.addBannedElement(new ClassFilteredBannedElement(ClassPathElement.fromPath(root))); } @@ -278,18 +290,17 @@ public synchronized QuarkusClassLoader getBaseRuntimeClassLoader() { } builder.addBannedElement(new MemoryClassPathElement(banned)); - for (AppDependency dependency : appModel.getUserDependencies()) { - if (isHotReloadable(dependency.getArtifact(), hotReloadPaths)) { + for (ResolvedDependency dependency : appModel.getRuntimeDependencies()) { + if (isHotReloadable(dependency, hotReloadPaths)) { continue; } - if (configuredClassLoading.reloadableArtifacts.contains(dependency.getArtifact().getKey())) { + if (configuredClassLoading.reloadableArtifacts.contains(dependency.getKey())) { continue; } - if (configuredClassLoading.removedArtifacts.contains(dependency.getArtifact().getKey())) { - processCpElement(dependency.getArtifact(), builder::addBannedElement); + if (configuredClassLoading.removedArtifacts.contains(dependency.getKey())) { + processCpElement(dependency, builder::addBannedElement); } else { - processCpElement(dependency.getArtifact(), - element -> addCpElement(builder, dependency.getArtifact(), element)); + processCpElement(dependency, element -> addCpElement(builder, dependency, element)); } } @@ -298,8 +309,8 @@ public synchronized QuarkusClassLoader getBaseRuntimeClassLoader() { return baseRuntimeClassLoader; } - private static boolean isHotReloadable(AppArtifact a, Set hotReloadPaths) { - for (Path p : a.getPaths()) { + private static boolean isHotReloadable(ResolvedDependency a, Set hotReloadPaths) { + for (Path p : a.getResolvedPaths()) { if (hotReloadPaths.contains(p)) { return true; } @@ -324,13 +335,13 @@ public QuarkusClassLoader createDeploymentClassLoader() { //additional user class path elements first for (AdditionalDependency i : quarkusBootstrap.getAdditionalApplicationArchives()) { - for (Path root : i.getArchivePath()) { + for (Path root : i.getResolvedPaths()) { builder.addElement(ClassPathElement.fromPath(root)); } } - for (AppDependency dependency : appModel.getUserDependencies()) { - if (configuredClassLoading.reloadableArtifacts.contains(dependency.getArtifact().getKey())) { - processCpElement(dependency.getArtifact(), element -> addCpElement(builder, dependency.getArtifact(), element)); + for (ResolvedDependency dependency : appModel.getRuntimeDependencies()) { + if (configuredClassLoading.reloadableArtifacts.contains(dependency.getKey())) { + processCpElement(dependency, element -> addCpElement(builder, dependency, element)); } } return builder.build(); @@ -358,14 +369,14 @@ public QuarkusClassLoader createRuntimeClassLoader(ClassLoader base, Map addCpElement(builder, dependency.getArtifact(), element)); + for (ResolvedDependency dependency : appModel.getRuntimeDependencies()) { + if (configuredClassLoading.reloadableArtifacts.contains(dependency.getKey())) { + processCpElement(dependency, element -> addCpElement(builder, dependency, element)); } } return builder.build(); @@ -383,11 +394,11 @@ public void close() { /** * TODO: Fix everything in the universe to do loading properly - * + * * This class exists because a lot of libraries do getClass().getClassLoader.getResource() * instead of using the context class loader, which breaks tests as these resources are present in the * top CL and not the base CL that is used to load libraries. - * + * * This yucky yucky hack works around this, by allowing non-class files to be loaded parent first, so they * will be loaded from the application ClassLoader. * diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/CurationResult.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/CurationResult.java index 2c99d653e71f9..450eed0c8a75e 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/CurationResult.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/CurationResult.java @@ -1,17 +1,20 @@ package io.quarkus.bootstrap.app; import io.quarkus.bootstrap.BootstrapAppModelFactory; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppDependency; import io.quarkus.bootstrap.model.AppModel; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.resolver.AppModelResolver; import io.quarkus.bootstrap.resolver.BootstrapAppModelResolver; import io.quarkus.bootstrap.resolver.maven.workspace.ModelUtils; +import io.quarkus.bootstrap.util.BootstrapUtils; +import io.quarkus.maven.dependency.ArtifactCoords; +import io.quarkus.maven.dependency.GACTV; +import io.quarkus.maven.dependency.ResolvedDependency; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Collection; import java.util.Collections; -import java.util.List; import org.apache.maven.model.Dependency; import org.apache.maven.model.Exclusion; import org.apache.maven.model.Model; @@ -21,19 +24,20 @@ public class CurationResult { private static final Logger log = Logger.getLogger(CurationResult.class); - private final AppModel appModel; - private final List updatedDependencies; + private final ApplicationModel appModel; + private final Collection updatedDependencies; private final boolean fromState; - private final AppArtifact appArtifact; - private final AppArtifact stateArtifact; + private final ResolvedDependency appArtifact; + private final ResolvedDependency stateArtifact; private boolean persisted; - public CurationResult(AppModel appModel) { + public CurationResult(ApplicationModel appModel) { this(appModel, Collections.emptyList(), false, null, null); } - public CurationResult(AppModel appModel, List updatedDependencies, boolean fromState, - AppArtifact appArtifact, AppArtifact stateArtifact) { + public CurationResult(ApplicationModel appModel, Collection updatedDependencies, + boolean fromState, + ResolvedDependency appArtifact, ResolvedDependency stateArtifact) { this.appModel = appModel; this.updatedDependencies = updatedDependencies; this.fromState = fromState; @@ -41,11 +45,20 @@ public CurationResult(AppModel appModel, List updatedDependencies this.stateArtifact = stateArtifact; } + /** + * @deprecated in favor of {@link #getApplicationModel()} + * @return AppModel + */ + @Deprecated public AppModel getAppModel() { + return BootstrapUtils.convert(appModel); + } + + public ApplicationModel getApplicationModel() { return appModel; } - public List getUpdatedDependencies() { + public Collection getUpdatedDependencies() { return updatedDependencies; } @@ -53,7 +66,7 @@ public boolean isFromState() { return fromState; } - public AppArtifact getStateArtifact() { + public ResolvedDependency getStateArtifact() { return stateArtifact; } @@ -76,15 +89,16 @@ public void persist(AppModelResolver resolver) { } final Path statePom = stateDir.resolve("pom.xml"); - AppArtifact stateArtifact; + ArtifactCoords stateArtifact; if (this.stateArtifact == null) { stateArtifact = ModelUtils.getStateArtifact(appArtifact); } else { - stateArtifact = new AppArtifact(this.stateArtifact.getGroupId(), - this.stateArtifact.getArtifactId(), - this.stateArtifact.getClassifier(), - this.stateArtifact.getType(), - String.valueOf(Long.valueOf(this.stateArtifact.getVersion()) + 1)); + final ArtifactCoords currentCoords = this.stateArtifact; + stateArtifact = new GACTV(currentCoords.getGroupId(), + currentCoords.getArtifactId(), + currentCoords.getClassifier(), + currentCoords.getType(), + String.valueOf(Long.valueOf(currentCoords.getVersion()) + 1)); } final Model model = new Model(); @@ -116,24 +130,23 @@ public void persist(AppModelResolver resolver) { model.addDependency(appDep); if (!updatedDependencies.isEmpty()) { - for (AppDependency dep : updatedDependencies) { - final AppArtifact depArtifact = dep.getArtifact(); - final String groupId = depArtifact.getGroupId(); + for (io.quarkus.maven.dependency.Dependency dep : updatedDependencies) { + final String groupId = dep.getGroupId(); final Exclusion exclusion = new Exclusion(); exclusion.setGroupId(groupId); - exclusion.setArtifactId(depArtifact.getArtifactId()); + exclusion.setArtifactId(dep.getArtifactId()); appDep.addExclusion(exclusion); final Dependency updateDep = new Dependency(); updateDep.setGroupId(groupId); - updateDep.setArtifactId(depArtifact.getArtifactId()); - final String updateClassifier = depArtifact.getClassifier(); + updateDep.setArtifactId(dep.getArtifactId()); + final String updateClassifier = dep.getClassifier(); if (updateClassifier != null && !updateClassifier.isEmpty()) { updateDep.setClassifier(updateClassifier); } - updateDep.setType(depArtifact.getType()); - updateDep.setVersion(depArtifact.getVersion()); + updateDep.setType(dep.getType()); + updateDep.setVersion(dep.getVersion()); updateDep.setScope(dep.getScope()); model.addDependency(updateDep); diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/QuarkusBootstrap.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/QuarkusBootstrap.java index fa5d0eeedc4f0..c3113a8e06e20 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/QuarkusBootstrap.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/QuarkusBootstrap.java @@ -3,16 +3,19 @@ import io.quarkus.bootstrap.BootstrapAppModelFactory; import io.quarkus.bootstrap.BootstrapException; import io.quarkus.bootstrap.classloading.ClassLoaderEventListener; -import io.quarkus.bootstrap.model.AppArtifact; import io.quarkus.bootstrap.model.AppArtifactKey; -import io.quarkus.bootstrap.model.AppDependency; -import io.quarkus.bootstrap.model.AppModel; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.bootstrap.resolver.AppModelResolver; import io.quarkus.bootstrap.resolver.maven.MavenArtifactResolver; import io.quarkus.bootstrap.resolver.update.DependenciesOrigin; import io.quarkus.bootstrap.resolver.update.VersionUpdate; import io.quarkus.bootstrap.resolver.update.VersionUpdateNumber; +import io.quarkus.maven.dependency.ArtifactCoords; +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.Dependency; +import io.quarkus.maven.dependency.GACT; +import io.quarkus.maven.dependency.ResolvedDependency; import java.io.IOException; import java.io.InputStream; import java.io.Serializable; @@ -82,13 +85,13 @@ public class QuarkusBootstrap implements Serializable { private final VersionUpdateNumber versionUpdateNumber; private final VersionUpdate versionUpdate; private final DependenciesOrigin dependenciesOrigin; - private final AppArtifact appArtifact; + private final ResolvedDependency appArtifact; private final boolean isolateDeployment; private final MavenArtifactResolver mavenArtifactResolver; - private final AppArtifact managingProject; - private final List forcedDependencies; + private final ArtifactCoords managingProject; + private final List forcedDependencies; private final boolean disableClasspathCache; - private final AppModel existingModel; + private final ApplicationModel existingModel; private final boolean rebuild; private final Set localArtifacts; private final List classLoadListeners; @@ -184,15 +187,15 @@ private static ConfiguredClassLoading createClassLoadingConfig(PathsCollection a try (InputStream in = Files.newInputStream(props)) { Properties p = new Properties(); p.load(in); - Set parentFirst = toArtifactSet( + Set parentFirst = toArtifactSet( p.getProperty(selectKey("quarkus.class-loading.parent-first-artifacts", p, mode))); - Set liveReloadable = toArtifactSet( + Set liveReloadable = toArtifactSet( p.getProperty(selectKey("quarkus.class-loading.reloadable-artifacts", p, mode))); - Set removedArtifacts = toArtifactSet( + Set removedArtifacts = toArtifactSet( p.getProperty(selectKey("quarkus.class-loading.removed-artifacts", p, mode))); boolean flatClassPath = Boolean.parseBoolean( p.getProperty(selectKey("quarkus.test.flat-class-path", p, mode))); - Map> removedResources = toArtifactMapList( + Map> removedResources = toArtifactMapList( "quarkus.class-loading.removed-resources.", p, mode); return new ConfiguredClassLoading(parentFirst, liveReloadable, removedArtifacts, removedResources, flatClassPath); @@ -205,7 +208,7 @@ private static ConfiguredClassLoading createClassLoadingConfig(PathsCollection a Collections.emptyMap(), false); } - private static Map> toArtifactMapList(String baseConfigKey, Properties properties, Mode mode) { + private static Map> toArtifactMapList(String baseConfigKey, Properties properties, Mode mode) { Properties profileProps = new Properties(); String profile = BootstrapProfile.getActiveProfile(mode); for (Map.Entry i : properties.entrySet()) { @@ -221,7 +224,7 @@ private static Map> toArtifactMapList(String baseCo } } //now we have a 'sanitised' map with the correct props for the profile. - Map> ret = new HashMap<>(); + Map> ret = new HashMap<>(); for (Map.Entry entry : profileProps.entrySet()) { String key = entry.getKey().toString(); String value = entry.getValue().toString(); @@ -229,7 +232,7 @@ private static Map> toArtifactMapList(String baseCo String artifactId = key.substring(baseConfigKey.length()); artifactId = artifactId.replace("\"", ""); List resources = Arrays.asList(value.split(",")); - ret.put(new AppArtifactKey(artifactId.split(":")), resources); + ret.put(new GACT(artifactId.split(":")), resources); } } return ret; @@ -244,13 +247,13 @@ private static String selectKey(String base, Properties p, Mode mode) { return base; } - private static Set toArtifactSet(String config) { + private static Set toArtifactSet(String config) { if (config == null) { return new HashSet<>(); } - Set ret = new HashSet<>(); + Set ret = new HashSet<>(); for (String i : config.split(",")) { - ret.add(new AppArtifactKey(i.split(":"))); + ret.add(new GACT(i.split(":"))); } return ret; } @@ -350,7 +353,7 @@ public Builder clonedBuilder() { .setIsolateDeployment(isolateDeployment) .setMavenArtifactResolver(mavenArtifactResolver) .setManagingProject(managingProject) - .setForcedDependencies(new ArrayList<>(forcedDependencies)) + .setForcedDependencies(forcedDependencies) .setDisableClasspathCache(disableClasspathCache) .addClassLoaderEventListeners(classLoadListeners) .setExistingModel(existingModel); @@ -400,13 +403,13 @@ public static class Builder { VersionUpdateNumber versionUpdateNumber = VersionUpdateNumber.MICRO; VersionUpdate versionUpdate = VersionUpdate.NONE; DependenciesOrigin dependenciesOrigin; - AppArtifact appArtifact; + ResolvedDependency appArtifact; boolean isolateDeployment; MavenArtifactResolver mavenArtifactResolver; - AppArtifact managingProject; - List forcedDependencies = new ArrayList<>(); + ArtifactCoords managingProject; + List forcedDependencies = new ArrayList<>(); boolean disableClasspathCache; - AppModel existingModel; + ApplicationModel existingModel; final Set localArtifacts = new HashSet<>(); boolean auxiliaryApplication; @@ -538,19 +541,19 @@ public Builder setDisableClasspathCache(boolean disableClasspathCache) { * The app artifact. Note that if you want to use this as the basis of the application * you must also explicitly set the application root to this artifacts paths. */ - public Builder setAppArtifact(AppArtifact appArtifact) { + public Builder setAppArtifact(ResolvedDependency appArtifact) { if (applicationRoot != null) { throw new IllegalStateException("Cannot set both application root and app artifact"); } this.appArtifact = appArtifact; - this.applicationRoot = appArtifact.getPaths(); - if (appArtifact.getPaths().isSinglePath()) { - this.projectRoot = appArtifact.getPaths().getSinglePath(); + this.applicationRoot = PathsCollection.from(appArtifact.getResolvedPaths()); + if (appArtifact.getResolvedPaths().isSinglePath()) { + this.projectRoot = appArtifact.getResolvedPaths().getSinglePath(); } return this; } - public Builder setManagingProject(AppArtifact managingProject) { + public Builder setManagingProject(ArtifactCoords managingProject) { this.managingProject = managingProject; return this; } @@ -580,16 +583,16 @@ public Builder setMavenArtifactResolver(MavenArtifactResolver mavenArtifactResol * If set, each of these dependencies will either be added to the application dependencies if the GA doesn't match any * application dependencies, or override the existing version if the GA does match */ - public Builder setForcedDependencies(List forcedDependencies) { + public Builder setForcedDependencies(List forcedDependencies) { this.forcedDependencies = forcedDependencies; return this; } - public AppModel getExistingModel() { + public ApplicationModel getExistingModel() { return existingModel; } - public Builder setExistingModel(AppModel existingModel) { + public Builder setExistingModel(ApplicationModel existingModel) { this.existingModel = existingModel; return this; } @@ -624,7 +627,8 @@ private boolean inheritedAssertionsEnabled() { public QuarkusBootstrap build() { Objects.requireNonNull(applicationRoot, "Application root must not be null"); if (appArtifact != null) { - localArtifacts.add(appArtifact.getKey()); + localArtifacts + .add(new AppArtifactKey(appArtifact.getGroupId(), appArtifact.getArtifactId())); } ConfiguredClassLoading classLoadingConfig = createClassLoadingConfig(applicationRoot, mode); diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/devmode/DependenciesFilter.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/devmode/DependenciesFilter.java index ef000cec22827..c96b13143616a 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/devmode/DependenciesFilter.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/devmode/DependenciesFilter.java @@ -1,153 +1,33 @@ package io.quarkus.bootstrap.devmode; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppArtifactKey; -import io.quarkus.bootstrap.resolver.maven.BootstrapMavenException; -import io.quarkus.bootstrap.resolver.maven.MavenArtifactResolver; -import io.quarkus.bootstrap.resolver.maven.workspace.LocalProject; -import io.quarkus.bootstrap.resolver.maven.workspace.LocalWorkspace; -import java.nio.file.Files; +import io.quarkus.bootstrap.model.ApplicationModel; +import io.quarkus.bootstrap.workspace.WorkspaceModule; import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; import java.util.List; -import java.util.Set; -import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.handler.DefaultArtifactHandler; -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.DependencyCollectionException; -import org.eclipse.aether.graph.Dependency; -import org.eclipse.aether.graph.DependencyNode; -import org.eclipse.aether.graph.DependencyVisitor; -import org.eclipse.aether.repository.RemoteRepository; -import org.eclipse.aether.util.artifact.JavaScopes; -import org.eclipse.aether.util.graph.visitor.TreeDependencyVisitor; import org.jboss.logging.Logger; public class DependenciesFilter { private static final Logger log = Logger.getLogger(DependenciesFilter.class); - public static List filterNotReloadableDependencies(LocalProject localProject, - MavenArtifactResolver mvnResolver) throws BootstrapMavenException { - final AppArtifact appArtifact = localProject.getAppArtifact("jar"); - final List projectDeps = new ArrayList<>(); - mvnResolver - .resolveDependencies( - new DefaultArtifact(appArtifact.getGroupId(), appArtifact.getArtifactId(), - appArtifact.getClassifier(), appArtifact.getType(), appArtifact.getVersion()), - Collections.emptyList()) - .getRoot().accept(new TreeDependencyVisitor(new DependencyVisitor() { - @Override - public boolean visitEnter(DependencyNode node) { - final Dependency dep = node.getDependency(); - if (dep != null && dep.getArtifact().getFile().isDirectory()) { - org.eclipse.aether.artifact.Artifact a = dep.getArtifact(); - final org.apache.maven.artifact.DefaultArtifact mvnArtifact = new org.apache.maven.artifact.DefaultArtifact( - a.getGroupId(), a.getArtifactId(), a.getVersion(), dep.getScope(), a.getExtension(), - a.getClassifier(), new DefaultArtifactHandler("jar")); - mvnArtifact.setFile(a.getFile()); - projectDeps.add(mvnArtifact); - } - return true; - } - - @Override - public boolean visitLeave(DependencyNode node) { - return true; - } - })); - return filterNotReloadableDependencies(localProject, projectDeps, mvnResolver.getSystem(), - mvnResolver.getSession(), mvnResolver.getRepositories()); - } - - public static List filterNotReloadableDependencies(LocalProject localProject, - Iterable projectDeps, - RepositorySystem repoSystem, - RepositorySystemSession repoSession, - List repos) { - final LocalWorkspace workspace = localProject.getWorkspace(); - if (workspace == null) { - return Collections.singletonList(localProject); + public static List getReloadableModules(ApplicationModel appModel) { + final List reloadable = new ArrayList<>(); + if (appModel.getApplicationModule() != null) { + reloadable.add(appModel.getApplicationModule()); } - - List ret = new ArrayList<>(); - Set extensionsAndDeps = new HashSet<>(); - - ret.add(localProject); - for (Artifact a : projectDeps) { - final AppArtifactKey depKey = new AppArtifactKey(a.getGroupId(), a.getArtifactId()); - final LocalProject project = workspace.getProject(depKey); - if (project == null) { - continue; - } - if ("test".equals(a.getScope()) || "pom".equals(a.getType())) { - continue; - } - if (!project.getVersion().equals(a.getVersion())) { - log.warn(depKey + " is excluded from live coding since the application depends on version " - + a.getVersion() + " while the version present in the workspace is " + project.getVersion()); - continue; - } - - if (project.getClassesDir() != null && - //if this project also contains Quarkus extensions we do no want to include these in the discovery - //a bit of an edge case, but if you try and include a sample project with your extension you will - //run into problems without this - (Files.exists(project.getClassesDir().resolve("META-INF/quarkus-extension.properties")) || - Files.exists(project.getClassesDir().resolve("META-INF/quarkus-build-steps.list")))) { - // TODO add the deployment deps - extensionDepWarning(depKey); - try { - final DependencyNode depRoot = repoSystem.collectDependencies(repoSession, new CollectRequest() - .setRoot(new org.eclipse.aether.graph.Dependency( - new DefaultArtifact(a.getGroupId(), a.getArtifactId(), - a.getClassifier(), a.getArtifactHandler().getExtension(), a.getVersion()), - JavaScopes.RUNTIME)) - .setRepositories(repos)).getRoot(); - depRoot.accept(new DependencyVisitor() { - @Override - public boolean visitEnter(DependencyNode node) { - final org.eclipse.aether.artifact.Artifact artifact = node.getArtifact(); - if ("jar".equals(artifact.getExtension())) { - extensionsAndDeps.add(new AppArtifactKey(artifact.getGroupId(), artifact.getArtifactId())); - } - return true; - } - - @Override - public boolean visitLeave(DependencyNode node) { - return true; - } - }); - } catch (DependencyCollectionException e) { - throw new RuntimeException("Failed to collect dependencies for " + a, e); + appModel.getDependencies().forEach(d -> { + final WorkspaceModule module = d.getWorkspaceModule(); + if (module != null) { + if (d.isReloadable()) { + reloadable.add(module); + } else { + //if this project also contains Quarkus extensions we do no want to include these in the discovery + //a bit of an edge case, but if you try and include a sample project with your extension you will + //run into problems without this + log.warn("Local Quarkus extension dependency " + module.getId() + " will not be hot-reloadable"); } - } else { - ret.add(project); } - } - - if (extensionsAndDeps.isEmpty()) { - return ret; - } - - Iterator iterator = ret.iterator(); - while (iterator.hasNext()) { - final LocalProject localDep = iterator.next(); - if (extensionsAndDeps.contains(localDep.getKey())) { - extensionDepWarning(localDep.getKey()); - iterator.remove(); - } - } - return ret; - } - - private static void extensionDepWarning(AppArtifactKey key) { - log.warn("Local Quarkus extension dependency " + key + " will not be hot-reloadable"); + }); + return reloadable; } } diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/jbang/JBangBuilderImpl.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/jbang/JBangBuilderImpl.java index b61633c83073e..29ba65451f225 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/jbang/JBangBuilderImpl.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/jbang/JBangBuilderImpl.java @@ -2,11 +2,14 @@ import io.quarkus.bootstrap.app.CuratedApplication; import io.quarkus.bootstrap.app.QuarkusBootstrap; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppDependency; import io.quarkus.bootstrap.resolver.maven.BootstrapMavenContext; import io.quarkus.bootstrap.resolver.maven.BootstrapMavenException; import io.quarkus.bootstrap.resolver.maven.MavenArtifactResolver; +import io.quarkus.maven.dependency.ArtifactCoords; +import io.quarkus.maven.dependency.ArtifactDependency; +import io.quarkus.maven.dependency.Dependency; +import io.quarkus.maven.dependency.GACTV; +import io.quarkus.maven.dependency.ResolvedArtifactDependency; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; @@ -46,28 +49,28 @@ public static Map postBuild(Path appClasses, Path pomFile, List< try { Path target = Files.createTempDirectory("quarkus-jbang"); - AppArtifact appArtifact = new AppArtifact("dev.jbang.user", "quarkus", null, "jar", "999-SNAPSHOT"); - appArtifact.setPath(appClasses); + final ResolvedArtifactDependency appArtifact = new ResolvedArtifactDependency("dev.jbang.user", "quarkus", null, + "jar", "999-SNAPSHOT", appClasses); final QuarkusBootstrap.Builder builder = QuarkusBootstrap.builder() .setBaseClassLoader(JBangBuilderImpl.class.getClassLoader()) .setMavenArtifactResolver(quarkusResolver) .setProjectRoot(pomFile.getParent()) .setTargetDirectory(target) - .setManagingProject(new AppArtifact("io.quarkus", "quarkus-bom", "", "pom", getQuarkusVersion())) + .setManagingProject(new GACTV("io.quarkus", "quarkus-bom", "", "pom", getQuarkusVersion())) .setForcedDependencies(dependencies.stream().map(s -> { String[] parts = s.getKey().split(":"); - AppArtifact artifact; + Dependency artifact; if (parts.length == 3) { - artifact = new AppArtifact(parts[0], parts[1], parts[2]); + artifact = new ArtifactDependency(parts[0], parts[1], null, ArtifactCoords.TYPE_JAR, parts[2]); } else if (parts.length == 4) { - artifact = new AppArtifact(parts[0], parts[1], null, parts[2], parts[3]); + artifact = new ArtifactDependency(parts[0], parts[1], null, parts[2], parts[3]); } else if (parts.length == 5) { - artifact = new AppArtifact(parts[0], parts[1], parts[3], parts[2], parts[4]); + artifact = new ArtifactDependency(parts[0], parts[1], parts[3], parts[2], parts[4]); } else { throw new RuntimeException("Invalid artifact " + s.getKey()); } - artifact.setPath(s.getValue()); - return new AppDependency(artifact, "compile"); + //artifact.setPath(s.getValue()); + return artifact; }).collect(Collectors.toList())) .setAppArtifact(appArtifact) .setIsolateDeployment(true) diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/jbang/JBangDevModeLauncherImpl.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/jbang/JBangDevModeLauncherImpl.java index 0cec203eb9d4b..4b70ef9b3ebe5 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/jbang/JBangDevModeLauncherImpl.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/jbang/JBangDevModeLauncherImpl.java @@ -2,11 +2,15 @@ import io.quarkus.bootstrap.app.CuratedApplication; import io.quarkus.bootstrap.app.QuarkusBootstrap; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppDependency; import io.quarkus.bootstrap.resolver.maven.BootstrapMavenContext; import io.quarkus.bootstrap.resolver.maven.MavenArtifactResolver; import io.quarkus.bootstrap.resolver.maven.workspace.LocalProject; +import io.quarkus.maven.dependency.ArtifactCoords; +import io.quarkus.maven.dependency.ArtifactDependency; +import io.quarkus.maven.dependency.Dependency; +import io.quarkus.maven.dependency.GACTV; +import io.quarkus.maven.dependency.ResolvedDependency; +import io.quarkus.maven.dependency.ResolvedDependencyBuilder; import java.io.ByteArrayOutputStream; import java.io.Closeable; import java.io.DataInputStream; @@ -81,8 +85,11 @@ public static Closeable main(String... args) { Files.createDirectories(srcDir); Files.createSymbolicLink(srcDir.resolve(sourceFile.getFileName().toString()), sourceFile); final LocalProject currentProject = LocalProject.loadWorkspace(projectRoot); - AppArtifact appArtifact = currentProject.getAppArtifact("jar"); - appArtifact.setPath(targetClasses); + final ResolvedDependency appArtifact = ResolvedDependencyBuilder.newInstance() + .setCoords(currentProject.getAppArtifact(ArtifactCoords.TYPE_JAR)) + .setResolvedPath(targetClasses) + .setWorkspaceModule(currentProject.toWorkspaceModule()) + .build(); //todo : proper support for everything final QuarkusBootstrap.Builder builder = QuarkusBootstrap.builder() @@ -91,21 +98,21 @@ public static Closeable main(String... args) { .setMode(QuarkusBootstrap.Mode.DEV) .setTargetDirectory(targetClasses) .setAppArtifact(appArtifact) - .setManagingProject(new AppArtifact("io.quarkus", "quarkus-bom", "", "pom", getQuarkusVersion())) + .setManagingProject(new GACTV("io.quarkus", "quarkus-bom", "", "pom", getQuarkusVersion())) .setForcedDependencies(deps.entrySet().stream().map(s -> { String[] parts = s.getKey().split(":"); - AppArtifact artifact; + Dependency artifact; if (parts.length == 3) { - artifact = new AppArtifact(parts[0], parts[1], parts[2]); + artifact = new ArtifactDependency(parts[0], parts[1], null, ArtifactCoords.TYPE_JAR, parts[2]); } else if (parts.length == 4) { - artifact = new AppArtifact(parts[0], parts[1], null, parts[2], parts[3]); + artifact = new ArtifactDependency(parts[0], parts[1], null, parts[2], parts[3]); } else if (parts.length == 5) { - artifact = new AppArtifact(parts[0], parts[1], parts[3], parts[2], parts[4]); + artifact = new ArtifactDependency(parts[0], parts[1], parts[3], parts[2], parts[4]); } else { throw new RuntimeException("Invalid artifact " + s); } - artifact.setPath(s.getValue()); - return new AppDependency(artifact, "compile"); + //artifact.setPath(s.getValue()); + return artifact; }).collect(Collectors.toList())) .setApplicationRoot(targetClasses) .setProjectRoot(projectRoot); diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/resolver/update/DefaultUpdateDiscovery.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/resolver/update/DefaultUpdateDiscovery.java index 7f4b6f34a6558..596c3900b8392 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/resolver/update/DefaultUpdateDiscovery.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/resolver/update/DefaultUpdateDiscovery.java @@ -1,8 +1,8 @@ package io.quarkus.bootstrap.resolver.update; -import io.quarkus.bootstrap.model.AppArtifact; import io.quarkus.bootstrap.resolver.AppModelResolver; import io.quarkus.bootstrap.resolver.AppModelResolverException; +import io.quarkus.maven.dependency.ResolvedDependency; import java.util.List; /** @@ -20,7 +20,7 @@ public DefaultUpdateDiscovery(AppModelResolver resolver, VersionUpdateNumber upd } @Override - public List listUpdates(AppArtifact artifact) { + public List listUpdates(ResolvedDependency artifact) { try { return resolver.listLaterVersions(artifact, resolveUpToVersion(artifact), false); } catch (AppModelResolverException e) { @@ -29,7 +29,7 @@ public List listUpdates(AppArtifact artifact) { } @Override - public String getNextVersion(AppArtifact artifact) { + public String getNextVersion(ResolvedDependency artifact) { try { return resolver.getNextVersion(artifact, getFromVersion(artifact), true, resolveUpToVersion(artifact), false); } catch (AppModelResolverException e) { @@ -38,7 +38,7 @@ public String getNextVersion(AppArtifact artifact) { } @Override - public String getLatestVersion(AppArtifact artifact) { + public String getLatestVersion(ResolvedDependency artifact) { /* * to control how the versions are compared * DefaultArtifactVersion latest = null; @@ -59,7 +59,7 @@ public String getLatestVersion(AppArtifact artifact) { } } - private String resolveUpToVersion(AppArtifact artifact) { + private String resolveUpToVersion(ResolvedDependency artifact) { if (updateNumber == VersionUpdateNumber.MAJOR) { return null; } @@ -98,7 +98,7 @@ private String resolveUpToVersion(AppArtifact artifact) { return majorStr + "." + String.valueOf(minor + 1) + ".alpha"; } - private String getFromVersion(AppArtifact artifact) { + private String getFromVersion(ResolvedDependency artifact) { // here we are looking for the major version which is going to be used // as the base for the version range to look for the updates final String version = artifact.getVersion(); diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/resolver/update/UpdateDiscovery.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/resolver/update/UpdateDiscovery.java index 893cbedf14e9f..bf2cd64a00756 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/resolver/update/UpdateDiscovery.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/resolver/update/UpdateDiscovery.java @@ -1,6 +1,6 @@ package io.quarkus.bootstrap.resolver.update; -import io.quarkus.bootstrap.model.AppArtifact; +import io.quarkus.maven.dependency.ResolvedDependency; import java.util.List; /** @@ -9,9 +9,9 @@ */ public interface UpdateDiscovery { - List listUpdates(AppArtifact artifact); + List listUpdates(ResolvedDependency artifact); - String getNextVersion(AppArtifact artifact); + String getNextVersion(ResolvedDependency artifact); - String getLatestVersion(AppArtifact artifact); + String getLatestVersion(ResolvedDependency artifact); } diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/utils/BuildToolHelper.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/utils/BuildToolHelper.java index 34d44ef2d66ba..b80ad18fa9bb5 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/utils/BuildToolHelper.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/utils/BuildToolHelper.java @@ -1,16 +1,13 @@ package io.quarkus.bootstrap.utils; -import static io.quarkus.bootstrap.util.QuarkusModelHelper.DEVMODE_REQUIRED_TASKS; -import static io.quarkus.bootstrap.util.QuarkusModelHelper.ENABLE_JAR_PACKAGING; -import static io.quarkus.bootstrap.util.QuarkusModelHelper.TEST_REQUIRED_TASKS; - -import io.quarkus.bootstrap.model.gradle.QuarkusModel; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.resolver.AppModelResolverException; import io.quarkus.bootstrap.resolver.QuarkusGradleModelFactory; -import io.quarkus.bootstrap.util.QuarkusModelHelper; +import io.quarkus.bootstrap.util.BootstrapUtils; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Collections; import java.util.List; import org.jboss.logging.Logger; @@ -21,6 +18,11 @@ public class BuildToolHelper { private static final Logger log = Logger.getLogger(BuildToolHelper.class); + private final static String[] DEVMODE_REQUIRED_TASKS = new String[] { "classes" }; + private final static String[] TEST_REQUIRED_TASKS = new String[] { "classes", "testClasses" }; + private final static List ENABLE_JAR_PACKAGING = Collections + .singletonList("-Dorg.gradle.java.compile-classpath-packaging=true"); + public enum BuildTool { MAVEN("pom.xml"), GRADLE("build.gradle", "build.gradle.kts"); @@ -95,29 +97,30 @@ public static Path getBuildFile(Path project, BuildTool tool) { return null; } - public static QuarkusModel enableGradleAppModelForTest(Path projectRoot) + public static ApplicationModel enableGradleAppModelForTest(Path projectRoot) throws IOException, AppModelResolverException { // We enable jar packaging since we want test-fixtures as jars return enableGradleAppModel(projectRoot, "TEST", ENABLE_JAR_PACKAGING, TEST_REQUIRED_TASKS); } - public static QuarkusModel enableGradleAppModel(Path projectRoot, String mode, List jvmArgs, String... tasks) + public static ApplicationModel enableGradleAppModel(Path projectRoot, String mode, List jvmArgs, String... tasks) throws IOException, AppModelResolverException { if (isGradleProject(projectRoot)) { - final QuarkusModel model = QuarkusGradleModelFactory.create(getBuildFile(projectRoot, BuildTool.GRADLE).toFile(), + final ApplicationModel model = QuarkusGradleModelFactory.create( + getBuildFile(projectRoot, BuildTool.GRADLE).toFile(), mode, jvmArgs, tasks); - QuarkusModelHelper.exportModel(model, "TEST".equalsIgnoreCase(mode)); + BootstrapUtils.exportModel(model, "TEST".equalsIgnoreCase(mode)); return model; } return null; } - public static QuarkusModel enableGradleAppModelForDevMode(Path projectRoot) + public static ApplicationModel enableGradleAppModelForDevMode(Path projectRoot) throws IOException, AppModelResolverException { if (isGradleProject(projectRoot)) { - final QuarkusModel model = QuarkusGradleModelFactory + final ApplicationModel model = QuarkusGradleModelFactory .createForTasks(getBuildFile(projectRoot, BuildTool.GRADLE).toFile(), DEVMODE_REQUIRED_TASKS); - QuarkusModelHelper.exportModel(model, false); + BootstrapUtils.exportModel(model, false); return model; } return null; diff --git a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/CollectDependenciesBase.java b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/CollectDependenciesBase.java index 40606c0eb741a..4ca3e87858bf0 100644 --- a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/CollectDependenciesBase.java +++ b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/CollectDependenciesBase.java @@ -2,12 +2,16 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -import io.quarkus.bootstrap.model.AppDependency; +import io.quarkus.maven.dependency.ArtifactDependency; +import io.quarkus.maven.dependency.Dependency; +import io.quarkus.maven.dependency.DependencyFlags; +import io.quarkus.maven.dependency.ResolvedArtifactDependency; import java.nio.file.Path; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.stream.Collectors; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -18,8 +22,8 @@ public abstract class CollectDependenciesBase extends ResolverSetupCleanup { protected TsArtifact root; - protected List expectedResult = Collections.emptyList(); - protected List deploymentDeps = Collections.emptyList(); + protected List expectedResult = Collections.emptyList(); + protected List deploymentDeps = Collections.emptyList(); @Override @BeforeEach @@ -34,7 +38,7 @@ public void setup() throws Exception { @Test public void testCollectedDependencies() throws Exception { install(root); - List expected; + List expected; if (deploymentDeps.isEmpty()) { expected = expectedResult; } else { @@ -42,7 +46,10 @@ public void testCollectedDependencies() throws Exception { expected.addAll(expectedResult); expected.addAll(deploymentDeps); } - final List resolvedDeps = getTestResolver().resolveModel(root.toAppArtifact()).getFullDeploymentDeps(); + // stripping the resolved paths + final List resolvedDeps = getTestResolver().resolveModel(root.toArtifact()).getDependencies() + .stream() + .map(d -> new ArtifactDependency(d)).collect(Collectors.toList()); assertEquals(new HashSet<>(expected), new HashSet<>(resolvedDeps)); } @@ -87,7 +94,7 @@ protected TsQuarkusExt install(TsQuarkusExt ext) { protected void install(TsQuarkusExt ext, boolean collected) { ext.install(repo); if (collected) { - addCollectedDep(ext.getRuntime(), "compile", false, AppDependency.RUNTIME_EXTENSION_ARTIFACT_FLAG); + addCollectedDep(ext.getRuntime(), "compile", false, DependencyFlags.RUNTIME_EXTENSION_ARTIFACT); addCollectedDeploymentDep(ext.getDeployment()); } } @@ -95,8 +102,8 @@ protected void install(TsQuarkusExt ext, boolean collected) { protected void installAsDep(TsQuarkusExt ext) { ext.install(repo); root.addDependency(ext); - addCollectedDep(ext.getRuntime(), "compile", false, AppDependency.DIRECT_FLAG, - AppDependency.RUNTIME_EXTENSION_ARTIFACT_FLAG); + addCollectedDep(ext.getRuntime(), "compile", false, + DependencyFlags.DIRECT | DependencyFlags.RUNTIME_EXTENSION_ARTIFACT); addCollectedDeploymentDep(ext.getDeployment()); } @@ -131,7 +138,7 @@ protected void installAsDep(TsDependency dep, Path p, boolean collected, int... if (!collected) { return; } - int allFlags = AppDependency.DIRECT_FLAG; + int allFlags = DependencyFlags.DIRECT; for (int f : flags) { allFlags |= f; } @@ -143,21 +150,26 @@ protected void addCollectedDep(final TsArtifact artifact, int... flags) { } protected void addCollectedDep(final TsArtifact artifact, final String scope, boolean optional, int... flags) { - int allFlags = AppDependency.RUNTIME_CP_FLAG | AppDependency.DEPLOYMENT_CP_FLAG; + int allFlags = DependencyFlags.RUNTIME_CP | DependencyFlags.DEPLOYMENT_CP; + if (optional) { + allFlags |= DependencyFlags.OPTIONAL; + } for (int f : flags) { allFlags |= f; } if (expectedResult.isEmpty()) { expectedResult = new ArrayList<>(); } - expectedResult.add(new AppDependency(artifact.toAppArtifact(), scope, optional, allFlags)); + expectedResult.add(new ArtifactDependency(new ResolvedArtifactDependency(artifact.toArtifact()), scope, allFlags)); } protected void addCollectedDeploymentDep(TsArtifact ext) { if (deploymentDeps.isEmpty()) { deploymentDeps = new ArrayList<>(); } - deploymentDeps.add(new AppDependency(ext.toAppArtifact(), "compile", false, AppDependency.DEPLOYMENT_CP_FLAG)); + deploymentDeps + .add(new ArtifactDependency(new ResolvedArtifactDependency(ext.toArtifact()), "compile", + DependencyFlags.DEPLOYMENT_CP)); } protected void addManagedDep(TsQuarkusExt ext) { diff --git a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/TsArtifact.java b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/TsArtifact.java index 041d37ea024cb..e55bdc1ad31ef 100644 --- a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/TsArtifact.java +++ b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/TsArtifact.java @@ -1,7 +1,9 @@ package io.quarkus.bootstrap.resolver; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppArtifactKey; +import io.quarkus.maven.dependency.ArtifactCoords; +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.GACT; +import io.quarkus.maven.dependency.GACTV; import java.io.IOException; import java.nio.file.Path; import java.util.ArrayList; @@ -87,8 +89,8 @@ public TsArtifact(String groupId, String artifactId, String classifier, String t this.version = version; } - public AppArtifactKey getKey() { - return new AppArtifactKey(groupId, artifactId); + public ArtifactKey getKey() { + return new GACT(groupId, artifactId); } public String getGroupId() { @@ -223,8 +225,8 @@ public Model getPomModel() { return model; } - public AppArtifact toAppArtifact() { - return new AppArtifact(groupId, artifactId, classifier, type, version); + public ArtifactCoords toArtifact() { + return new GACTV(groupId, artifactId, classifier, type, version); } /** diff --git a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/TsRepoBuilder.java b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/TsRepoBuilder.java index 0bf68c7373829..43b240a2c4c08 100644 --- a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/TsRepoBuilder.java +++ b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/TsRepoBuilder.java @@ -1,7 +1,7 @@ package io.quarkus.bootstrap.resolver; -import io.quarkus.bootstrap.model.AppArtifact; import io.quarkus.bootstrap.resolver.maven.workspace.ModelUtils; +import io.quarkus.maven.dependency.ArtifactCoords; import java.io.BufferedWriter; import java.io.IOException; import java.nio.file.Files; @@ -49,7 +49,7 @@ public void install(TsArtifact artifact, Path p) { } catch (Exception e) { error("Failed to persist pom.xml for " + artifact, e); } - install(artifact.toPomArtifact().toAppArtifact(), pomXml); + install(artifact.toPomArtifact().toArtifact(), pomXml); if (p == null) { switch (artifact.type) { case TsArtifact.TYPE_JAR: @@ -71,11 +71,11 @@ public void install(TsArtifact artifact, Path p) { } } if (p != null) { - install(artifact.toAppArtifact(), p); + install(artifact.toArtifact(), p); } } - protected void install(AppArtifact artifact, Path file) { + protected void install(ArtifactCoords artifact, Path file) { try { resolver.install(artifact, file); } catch (AppModelResolverException e) { diff --git a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/replace/test/ManagedReplacedDependencyTestCase.java b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/replace/test/ManagedReplacedDependencyTestCase.java index 72511dd27df07..6bf2876153dec 100644 --- a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/replace/test/ManagedReplacedDependencyTestCase.java +++ b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/replace/test/ManagedReplacedDependencyTestCase.java @@ -1,9 +1,9 @@ package io.quarkus.bootstrap.resolver.replace.test; -import io.quarkus.bootstrap.model.AppDependency; import io.quarkus.bootstrap.resolver.CollectDependenciesBase; import io.quarkus.bootstrap.resolver.TsArtifact; import io.quarkus.bootstrap.resolver.TsQuarkusExt; +import io.quarkus.maven.dependency.DependencyFlags; /** * @@ -52,7 +52,7 @@ protected void setupDependencies() throws Exception { addManagedDep(ext201); addManagedDep(ext301); - addCollectedDep(ext301.getRuntime(), AppDependency.DIRECT_FLAG, AppDependency.RUNTIME_EXTENSION_ARTIFACT_FLAG); + addCollectedDep(ext301.getRuntime(), DependencyFlags.DIRECT | DependencyFlags.RUNTIME_EXTENSION_ARTIFACT); addCollectedDeploymentDep(ext301.getDeployment()); } } diff --git a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/test/SystemPropertyOverridesPomPropertyDependencyTestCase.java b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/test/SystemPropertyOverridesPomPropertyDependencyTestCase.java index e9f424e1af6bb..66319a02146fb 100644 --- a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/test/SystemPropertyOverridesPomPropertyDependencyTestCase.java +++ b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/test/SystemPropertyOverridesPomPropertyDependencyTestCase.java @@ -1,11 +1,11 @@ package io.quarkus.bootstrap.resolver.test; -import io.quarkus.bootstrap.model.AppDependency; import io.quarkus.bootstrap.resolver.BootstrapAppModelResolver; import io.quarkus.bootstrap.resolver.CollectDependenciesBase; import io.quarkus.bootstrap.resolver.TsArtifact; import io.quarkus.bootstrap.resolver.maven.workspace.LocalProject; import io.quarkus.bootstrap.util.IoUtils; +import io.quarkus.maven.dependency.DependencyFlags; import java.nio.file.Files; import java.nio.file.Path; @@ -31,7 +31,7 @@ protected void setupDependencies() { setSystemProperty("x.version", "3"); // it is expected that the system property will dominate - addCollectedDep(x13, AppDependency.DIRECT_FLAG); + addCollectedDep(x13, DependencyFlags.DIRECT); } @Override diff --git a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/test/VersionPropertyDependencyTestCase.java b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/test/VersionPropertyDependencyTestCase.java index 7ea2f804a9e76..7f18886a0e230 100644 --- a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/test/VersionPropertyDependencyTestCase.java +++ b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/test/VersionPropertyDependencyTestCase.java @@ -1,8 +1,8 @@ package io.quarkus.bootstrap.resolver.test; -import io.quarkus.bootstrap.model.AppDependency; import io.quarkus.bootstrap.resolver.CollectDependenciesBase; import io.quarkus.bootstrap.resolver.TsArtifact; +import io.quarkus.maven.dependency.DependencyFlags; /** * @@ -21,6 +21,6 @@ protected void setupDependencies() { setPomProperty("x.version", "2"); addDep(new TsArtifact("x", "${x.version}")); - addCollectedDep(x12, AppDependency.DIRECT_FLAG); + addCollectedDep(x12, DependencyFlags.DIRECT); } -} \ No newline at end of file +} diff --git a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/update/CheckForLatestMajorUpdatesTest.java b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/update/CheckForLatestMajorUpdatesTest.java deleted file mode 100644 index 0ebe54ab1bd49..0000000000000 --- a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/update/CheckForLatestMajorUpdatesTest.java +++ /dev/null @@ -1,68 +0,0 @@ -package io.quarkus.bootstrap.resolver.update; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import io.quarkus.bootstrap.app.CuratedApplication; -import io.quarkus.bootstrap.app.QuarkusBootstrap; -import io.quarkus.bootstrap.model.AppDependency; -import io.quarkus.bootstrap.model.AppModel; -import io.quarkus.bootstrap.resolver.TsArtifact; -import io.quarkus.bootstrap.resolver.TsQuarkusExt; -import java.util.Arrays; - -public class CheckForLatestMajorUpdatesTest extends CreatorOutcomeTestBase { - - @Override - protected void initProps(QuarkusBootstrap.Builder builder) { - builder.setVersionUpdateNumber(VersionUpdateNumber.MAJOR); - builder.setVersionUpdate(VersionUpdate.LATEST); - } - - @Override - protected TsArtifact modelApp() throws Exception { - new TsQuarkusExt("ext1", "1.0.1").install(repo); - new TsQuarkusExt("ext1", "1.1.0").install(repo); - new TsQuarkusExt("ext1", "2.0.0").install(repo); - new TsQuarkusExt("ext1", "3.0.0").install(repo); - new TsQuarkusExt("ext1", "3.0.1").install(repo); - new TsQuarkusExt("ext1", "3.1.0").install(repo); - new TsQuarkusExt("ext1", "3.1.1").install(repo); - - return TsArtifact.jar("app") - .addDependency(new TsQuarkusExt("ext1", "1.0.0")) - .addDependency(TsArtifact.jar("random")) - .addDependency(new TsQuarkusExt("ext2", "1.0.0")); - } - - @Override - protected void testCreator(QuarkusBootstrap creator) throws Exception { - final CuratedApplication outcome = creator.bootstrap(); - - assertTrue(outcome.hasUpdatedDeps()); - - assertEquals(Arrays.asList(new AppDependency[] { - new AppDependency(TsArtifact.jar("ext1", "3.1.1").toAppArtifact(), "compile") - }), outcome.getUpdatedDeps()); - - final AppModel effectiveModel = outcome.getAppModel(); - assertEquals(Arrays.asList(new AppDependency[] { - new AppDependency(TsArtifact.jar("ext1", "3.1.1").toAppArtifact(), "compile", AppDependency.DIRECT_FLAG, - AppDependency.RUNTIME_EXTENSION_ARTIFACT_FLAG, AppDependency.RUNTIME_CP_FLAG, - AppDependency.DEPLOYMENT_CP_FLAG), - new AppDependency(TsArtifact.jar("random").toAppArtifact(), "compile", AppDependency.DIRECT_FLAG, - AppDependency.RUNTIME_CP_FLAG, AppDependency.DEPLOYMENT_CP_FLAG), - new AppDependency(TsArtifact.jar("ext2", "1.0.0").toAppArtifact(), "compile", AppDependency.DIRECT_FLAG, - AppDependency.RUNTIME_EXTENSION_ARTIFACT_FLAG, AppDependency.RUNTIME_CP_FLAG, - AppDependency.DEPLOYMENT_CP_FLAG) - }), effectiveModel.getUserDependencies()); - - assertEquals(Arrays.asList(new AppDependency[] { - new AppDependency(TsArtifact.jar("ext1-deployment", "3.1.1").toAppArtifact(), "compile", - AppDependency.DEPLOYMENT_CP_FLAG), - new AppDependency(TsArtifact.jar("ext2-deployment", "1.0.0").toAppArtifact(), "compile", - AppDependency.DEPLOYMENT_CP_FLAG) - }), effectiveModel.getDeploymentDependencies()); - - } -} diff --git a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/update/CheckForLatestMicroUpdatesTest.java b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/update/CheckForLatestMicroUpdatesTest.java deleted file mode 100644 index 7efdcf844d6c1..0000000000000 --- a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/update/CheckForLatestMicroUpdatesTest.java +++ /dev/null @@ -1,65 +0,0 @@ -package io.quarkus.bootstrap.resolver.update; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import io.quarkus.bootstrap.app.CuratedApplication; -import io.quarkus.bootstrap.app.QuarkusBootstrap; -import io.quarkus.bootstrap.model.AppDependency; -import io.quarkus.bootstrap.model.AppModel; -import io.quarkus.bootstrap.resolver.TsArtifact; -import io.quarkus.bootstrap.resolver.TsQuarkusExt; -import java.util.Arrays; - -public class CheckForLatestMicroUpdatesTest extends CreatorOutcomeTestBase { - - @Override - protected void initProps(QuarkusBootstrap.Builder builder) { - builder.setVersionUpdate(VersionUpdate.LATEST) - .setVersionUpdateNumber(VersionUpdateNumber.MICRO); - } - - @Override - protected TsArtifact modelApp() throws Exception { - new TsQuarkusExt("ext1", "1.0.1").install(repo); - new TsQuarkusExt("ext1", "1.0.2").install(repo); - new TsQuarkusExt("ext1", "1.1.0").install(repo); - new TsQuarkusExt("ext1", "2.0.0").install(repo); - - return TsArtifact.jar("app") - .addDependency(new TsQuarkusExt("ext1", "1.0.0")) - .addDependency(TsArtifact.jar("random")) - .addDependency(new TsQuarkusExt("ext2", "1.0.0")); - } - - @Override - protected void testCreator(QuarkusBootstrap creator) throws Exception { - final CuratedApplication outcome = creator.bootstrap(); - - assertTrue(outcome.hasUpdatedDeps()); - - assertEquals(Arrays.asList(new AppDependency[] { - new AppDependency(TsArtifact.jar("ext1", "1.0.2").toAppArtifact(), "compile") - }), outcome.getUpdatedDeps()); - - final AppModel effectiveModel = outcome.getAppModel(); - assertEquals(Arrays.asList(new AppDependency[] { - new AppDependency(TsArtifact.jar("ext1", "1.0.2").toAppArtifact(), "compile", AppDependency.DIRECT_FLAG, - AppDependency.RUNTIME_EXTENSION_ARTIFACT_FLAG, AppDependency.RUNTIME_CP_FLAG, - AppDependency.DEPLOYMENT_CP_FLAG), - new AppDependency(TsArtifact.jar("random").toAppArtifact(), "compile", AppDependency.DIRECT_FLAG, - AppDependency.RUNTIME_CP_FLAG, AppDependency.DEPLOYMENT_CP_FLAG), - new AppDependency(TsArtifact.jar("ext2", "1.0.0").toAppArtifact(), "compile", AppDependency.DIRECT_FLAG, - AppDependency.RUNTIME_EXTENSION_ARTIFACT_FLAG, AppDependency.RUNTIME_CP_FLAG, - AppDependency.DEPLOYMENT_CP_FLAG) - }), effectiveModel.getUserDependencies()); - - assertEquals(Arrays.asList(new AppDependency[] { - new AppDependency(TsArtifact.jar("ext1-deployment", "1.0.2").toAppArtifact(), "compile", - AppDependency.DEPLOYMENT_CP_FLAG), - new AppDependency(TsArtifact.jar("ext2-deployment", "1.0.0").toAppArtifact(), "compile", - AppDependency.DEPLOYMENT_CP_FLAG) - }), effectiveModel.getDeploymentDependencies()); - - } -} diff --git a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/update/CheckForLatestMinorUpdatesTest.java b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/update/CheckForLatestMinorUpdatesTest.java deleted file mode 100644 index 361ce19f3d0fd..0000000000000 --- a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/update/CheckForLatestMinorUpdatesTest.java +++ /dev/null @@ -1,65 +0,0 @@ -package io.quarkus.bootstrap.resolver.update; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import io.quarkus.bootstrap.app.CuratedApplication; -import io.quarkus.bootstrap.app.QuarkusBootstrap; -import io.quarkus.bootstrap.model.AppDependency; -import io.quarkus.bootstrap.model.AppModel; -import io.quarkus.bootstrap.resolver.TsArtifact; -import io.quarkus.bootstrap.resolver.TsQuarkusExt; -import java.util.Arrays; - -public class CheckForLatestMinorUpdatesTest extends CreatorOutcomeTestBase { - - @Override - protected void initProps(QuarkusBootstrap.Builder builder) { - builder.setVersionUpdateNumber(VersionUpdateNumber.MINOR).setVersionUpdate(VersionUpdate.LATEST); - } - - @Override - protected TsArtifact modelApp() throws Exception { - new TsQuarkusExt("ext1", "1.0.1").install(repo); - new TsQuarkusExt("ext1", "1.1.0").install(repo); - new TsQuarkusExt("ext1", "1.2.0").install(repo); - new TsQuarkusExt("ext1", "1.2.1").install(repo); - new TsQuarkusExt("ext1", "2.0.0").install(repo); - - return TsArtifact.jar("app") - .addDependency(new TsQuarkusExt("ext1", "1.0.0")) - .addDependency(TsArtifact.jar("random")) - .addDependency(new TsQuarkusExt("ext2", "1.0.0")); - } - - @Override - protected void testCreator(QuarkusBootstrap creator) throws Exception { - final CuratedApplication outcome = creator.bootstrap(); - - assertTrue(outcome.hasUpdatedDeps()); - - assertEquals(Arrays.asList(new AppDependency[] { - new AppDependency(TsArtifact.jar("ext1", "1.2.1").toAppArtifact(), "compile") - }), outcome.getUpdatedDeps()); - - final AppModel effectiveModel = outcome.getAppModel(); - assertEquals(Arrays.asList(new AppDependency[] { - new AppDependency(TsArtifact.jar("ext1", "1.2.1").toAppArtifact(), "compile", AppDependency.DIRECT_FLAG, - AppDependency.RUNTIME_EXTENSION_ARTIFACT_FLAG, AppDependency.RUNTIME_CP_FLAG, - AppDependency.DEPLOYMENT_CP_FLAG), - new AppDependency(TsArtifact.jar("random").toAppArtifact(), "compile", AppDependency.DIRECT_FLAG, - AppDependency.RUNTIME_CP_FLAG, AppDependency.DEPLOYMENT_CP_FLAG), - new AppDependency(TsArtifact.jar("ext2", "1.0.0").toAppArtifact(), "compile", AppDependency.DIRECT_FLAG, - AppDependency.RUNTIME_EXTENSION_ARTIFACT_FLAG, AppDependency.RUNTIME_CP_FLAG, - AppDependency.DEPLOYMENT_CP_FLAG) - }), effectiveModel.getUserDependencies()); - - assertEquals(Arrays.asList(new AppDependency[] { - new AppDependency(TsArtifact.jar("ext1-deployment", "1.2.1").toAppArtifact(), "compile", - AppDependency.DEPLOYMENT_CP_FLAG), - new AppDependency(TsArtifact.jar("ext2-deployment", "1.0.0").toAppArtifact(), "compile", - AppDependency.DEPLOYMENT_CP_FLAG) - }), effectiveModel.getDeploymentDependencies()); - - } -} diff --git a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/update/CheckForNextMajorUpdatesTest.java b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/update/CheckForNextMajorUpdatesTest.java deleted file mode 100644 index 5e1a0e87d9ac8..0000000000000 --- a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/update/CheckForNextMajorUpdatesTest.java +++ /dev/null @@ -1,67 +0,0 @@ -package io.quarkus.bootstrap.resolver.update; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import io.quarkus.bootstrap.app.CuratedApplication; -import io.quarkus.bootstrap.app.QuarkusBootstrap; -import io.quarkus.bootstrap.model.AppDependency; -import io.quarkus.bootstrap.model.AppModel; -import io.quarkus.bootstrap.resolver.TsArtifact; -import io.quarkus.bootstrap.resolver.TsQuarkusExt; -import java.util.Arrays; - -public class CheckForNextMajorUpdatesTest extends CreatorOutcomeTestBase { - - @Override - protected void initProps(QuarkusBootstrap.Builder builder) { - builder.setVersionUpdateNumber(VersionUpdateNumber.MAJOR) - .setVersionUpdate(VersionUpdate.NEXT); - } - - @Override - protected TsArtifact modelApp() throws Exception { - new TsQuarkusExt("ext1", "1.0.1").install(repo); - new TsQuarkusExt("ext1", "1.1.0").install(repo); - new TsQuarkusExt("ext1", "2.0.0").install(repo); - new TsQuarkusExt("ext1", "2.0.1").install(repo); - new TsQuarkusExt("ext1", "2.1.0").install(repo); - new TsQuarkusExt("ext1", "3.0.0").install(repo); - - return TsArtifact.jar("app") - .addDependency(new TsQuarkusExt("ext1", "1.0.0")) - .addDependency(TsArtifact.jar("random")) - .addDependency(new TsQuarkusExt("ext2", "1.0.0")); - } - - @Override - protected void testCreator(QuarkusBootstrap creator) throws Exception { - final CuratedApplication outcome = creator.bootstrap(); - - assertTrue(outcome.hasUpdatedDeps()); - - assertEquals(Arrays.asList(new AppDependency[] { - new AppDependency(TsArtifact.jar("ext1", "2.0.0").toAppArtifact(), "compile") - }), outcome.getUpdatedDeps()); - - final AppModel effectiveModel = outcome.getAppModel(); - assertEquals(Arrays.asList(new AppDependency[] { - new AppDependency(TsArtifact.jar("ext1", "2.0.0").toAppArtifact(), "compile", AppDependency.DIRECT_FLAG, - AppDependency.RUNTIME_EXTENSION_ARTIFACT_FLAG, AppDependency.RUNTIME_CP_FLAG, - AppDependency.DEPLOYMENT_CP_FLAG), - new AppDependency(TsArtifact.jar("random").toAppArtifact(), "compile", AppDependency.DIRECT_FLAG, - AppDependency.RUNTIME_CP_FLAG, AppDependency.DEPLOYMENT_CP_FLAG), - new AppDependency(TsArtifact.jar("ext2", "1.0.0").toAppArtifact(), "compile", AppDependency.DIRECT_FLAG, - AppDependency.RUNTIME_EXTENSION_ARTIFACT_FLAG, AppDependency.RUNTIME_CP_FLAG, - AppDependency.DEPLOYMENT_CP_FLAG) - }), effectiveModel.getUserDependencies()); - - assertEquals(Arrays.asList(new AppDependency[] { - new AppDependency(TsArtifact.jar("ext1-deployment", "2.0.0").toAppArtifact(), "compile", - AppDependency.DEPLOYMENT_CP_FLAG), - new AppDependency(TsArtifact.jar("ext2-deployment", "1.0.0").toAppArtifact(), "compile", - AppDependency.DEPLOYMENT_CP_FLAG) - }), effectiveModel.getDeploymentDependencies()); - - } -} diff --git a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/update/CheckForNextMicroUpdatesTest.java b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/update/CheckForNextMicroUpdatesTest.java deleted file mode 100644 index 6cdf62dc0c304..0000000000000 --- a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/update/CheckForNextMicroUpdatesTest.java +++ /dev/null @@ -1,66 +0,0 @@ -package io.quarkus.bootstrap.resolver.update; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import io.quarkus.bootstrap.app.CuratedApplication; -import io.quarkus.bootstrap.app.QuarkusBootstrap; -import io.quarkus.bootstrap.model.AppDependency; -import io.quarkus.bootstrap.model.AppModel; -import io.quarkus.bootstrap.resolver.TsArtifact; -import io.quarkus.bootstrap.resolver.TsQuarkusExt; -import java.util.Arrays; - -public class CheckForNextMicroUpdatesTest extends CreatorOutcomeTestBase { - - @Override - protected void initProps(QuarkusBootstrap.Builder builder) { - builder.setVersionUpdate(VersionUpdate.NEXT); - builder.setVersionUpdateNumber(VersionUpdateNumber.MICRO); - } - - @Override - protected TsArtifact modelApp() throws Exception { - new TsQuarkusExt("ext1", "1.0.1").install(repo); - new TsQuarkusExt("ext1", "1.0.2").install(repo); - new TsQuarkusExt("ext1", "1.1.0").install(repo); - new TsQuarkusExt("ext1", "2.0.0").install(repo); - - return TsArtifact.jar("app") - .addDependency(new TsQuarkusExt("ext1", "1.0.0")) - .addDependency(TsArtifact.jar("random")) - .addDependency(new TsQuarkusExt("ext2", "1.0.0")); - } - - @Override - protected void testCreator(QuarkusBootstrap creator) throws Exception { - final CuratedApplication outcome = creator.bootstrap(); - - assertTrue(outcome.hasUpdatedDeps()); - - assertEquals(Arrays.asList(new AppDependency[] { - new AppDependency(TsArtifact.jar("ext1", "1.0.1").toAppArtifact(), "compile") - }), outcome.getUpdatedDeps()); - - final AppModel effectiveModel = outcome.getAppModel(); - assertEquals(Arrays.asList(new AppDependency[] { - new AppDependency(TsArtifact.jar("ext1", "1.0.1").toAppArtifact(), "compile", AppDependency.DIRECT_FLAG, - AppDependency.RUNTIME_EXTENSION_ARTIFACT_FLAG, AppDependency.RUNTIME_CP_FLAG, - AppDependency.DEPLOYMENT_CP_FLAG), - new AppDependency(TsArtifact.jar("random").toAppArtifact(), "compile", AppDependency.DIRECT_FLAG, - AppDependency.RUNTIME_CP_FLAG, AppDependency.DEPLOYMENT_CP_FLAG), - new AppDependency(TsArtifact.jar("ext2", "1.0.0").toAppArtifact(), "compile", AppDependency.DIRECT_FLAG, - AppDependency.RUNTIME_EXTENSION_ARTIFACT_FLAG, AppDependency.RUNTIME_CP_FLAG, - AppDependency.DEPLOYMENT_CP_FLAG) - }), effectiveModel.getUserDependencies()); - - assertEquals(Arrays.asList(new AppDependency[] { - new AppDependency(TsArtifact.jar("ext1-deployment", "1.0.1").toAppArtifact(), "compile", - AppDependency.DEPLOYMENT_CP_FLAG), - new AppDependency(TsArtifact.jar("ext2-deployment", "1.0.0").toAppArtifact(), "compile", - AppDependency.DEPLOYMENT_CP_FLAG) - }), effectiveModel.getDeploymentDependencies()); - - } - -} diff --git a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/update/CheckForNextMinorUpdatesTest.java b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/update/CheckForNextMinorUpdatesTest.java deleted file mode 100644 index a0699c63f8883..0000000000000 --- a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/update/CheckForNextMinorUpdatesTest.java +++ /dev/null @@ -1,65 +0,0 @@ -package io.quarkus.bootstrap.resolver.update; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import io.quarkus.bootstrap.app.CuratedApplication; -import io.quarkus.bootstrap.app.QuarkusBootstrap; -import io.quarkus.bootstrap.model.AppDependency; -import io.quarkus.bootstrap.model.AppModel; -import io.quarkus.bootstrap.resolver.TsArtifact; -import io.quarkus.bootstrap.resolver.TsQuarkusExt; -import java.util.Arrays; - -public class CheckForNextMinorUpdatesTest extends CreatorOutcomeTestBase { - - @Override - protected void initProps(QuarkusBootstrap.Builder builder) { - builder.setVersionUpdate(VersionUpdate.NEXT).setVersionUpdateNumber(VersionUpdateNumber.MINOR); - } - - @Override - protected TsArtifact modelApp() throws Exception { - new TsQuarkusExt("ext1", "1.0.1").install(repo); - new TsQuarkusExt("ext1", "1.1.0").install(repo); - new TsQuarkusExt("ext1", "1.1.1").install(repo); - new TsQuarkusExt("ext1", "1.2.0").install(repo); - new TsQuarkusExt("ext1", "2.0.0").install(repo); - - return TsArtifact.jar("app") - .addDependency(new TsQuarkusExt("ext1", "1.0.0")) - .addDependency(TsArtifact.jar("random")) - .addDependency(new TsQuarkusExt("ext2", "1.0.0")); - } - - @Override - protected void testCreator(QuarkusBootstrap creator) throws Exception { - final CuratedApplication outcome = creator.bootstrap(); - - assertTrue(outcome.hasUpdatedDeps()); - - assertEquals(Arrays.asList(new AppDependency[] { - new AppDependency(TsArtifact.jar("ext1", "1.1.0").toAppArtifact(), "compile") - }), outcome.getUpdatedDeps()); - - final AppModel effectiveModel = outcome.getAppModel(); - assertEquals(Arrays.asList(new AppDependency[] { - new AppDependency(TsArtifact.jar("ext1", "1.1.0").toAppArtifact(), "compile", AppDependency.DIRECT_FLAG, - AppDependency.RUNTIME_EXTENSION_ARTIFACT_FLAG, AppDependency.RUNTIME_CP_FLAG, - AppDependency.DEPLOYMENT_CP_FLAG), - new AppDependency(TsArtifact.jar("random").toAppArtifact(), "compile", AppDependency.DIRECT_FLAG, - AppDependency.RUNTIME_CP_FLAG, AppDependency.DEPLOYMENT_CP_FLAG), - new AppDependency(TsArtifact.jar("ext2", "1.0.0").toAppArtifact(), "compile", AppDependency.DIRECT_FLAG, - AppDependency.RUNTIME_EXTENSION_ARTIFACT_FLAG, AppDependency.RUNTIME_CP_FLAG, - AppDependency.DEPLOYMENT_CP_FLAG) - }), effectiveModel.getUserDependencies()); - - assertEquals(Arrays.asList(new AppDependency[] { - new AppDependency(TsArtifact.jar("ext1-deployment", "1.1.0").toAppArtifact(), "compile", - AppDependency.DEPLOYMENT_CP_FLAG), - new AppDependency(TsArtifact.jar("ext2-deployment", "1.0.0").toAppArtifact(), "compile", - AppDependency.DEPLOYMENT_CP_FLAG) - }), effectiveModel.getDeploymentDependencies()); - - } -} diff --git a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/update/CheckUpdatesDisableTest.java b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/update/CheckUpdatesDisableTest.java deleted file mode 100644 index da4e766b8dccb..0000000000000 --- a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/update/CheckUpdatesDisableTest.java +++ /dev/null @@ -1,68 +0,0 @@ -package io.quarkus.bootstrap.resolver.update; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; - -import io.quarkus.bootstrap.app.CuratedApplication; -import io.quarkus.bootstrap.app.QuarkusBootstrap; -import io.quarkus.bootstrap.model.AppDependency; -import io.quarkus.bootstrap.model.AppModel; -import io.quarkus.bootstrap.resolver.TsArtifact; -import io.quarkus.bootstrap.resolver.TsQuarkusExt; -import java.util.Arrays; -import java.util.Collections; - -public class CheckUpdatesDisableTest extends CreatorOutcomeTestBase { - - @Override - protected void initProps(QuarkusBootstrap.Builder builder) { - builder.setVersionUpdate(VersionUpdate.NONE).setVersionUpdateNumber(VersionUpdateNumber.MAJOR); - } - - @Override - protected TsArtifact modelApp() throws Exception { - new TsQuarkusExt("ext1", "1.0.1").install(repo); - new TsQuarkusExt("ext1", "1.0.2").install(repo); - new TsQuarkusExt("ext1", "1.1.0").install(repo); - new TsQuarkusExt("ext1", "1.2.0").install(repo); - new TsQuarkusExt("ext1", "2.0.0").install(repo); - new TsQuarkusExt("ext1", "3.0.0").install(repo); - new TsQuarkusExt("ext1", "3.0.1").install(repo); - new TsQuarkusExt("ext1", "3.1.0").install(repo); - new TsQuarkusExt("ext1", "3.1.1").install(repo); - - return TsArtifact.jar("app") - .addDependency(new TsQuarkusExt("ext1", "1.0.0")) - .addDependency(TsArtifact.jar("random")) - .addDependency(new TsQuarkusExt("ext2", "1.0.0")); - } - - @Override - protected void testCreator(QuarkusBootstrap creator) throws Exception { - final CuratedApplication outcome = creator.bootstrap(); - - assertFalse(outcome.hasUpdatedDeps()); - - assertEquals(Collections.emptyList(), outcome.getUpdatedDeps()); - - final AppModel effectiveModel = outcome.getAppModel(); - assertEquals(Arrays.asList(new AppDependency[] { - new AppDependency(TsArtifact.jar("ext1", "1.0.0").toAppArtifact(), "compile", AppDependency.DIRECT_FLAG, - AppDependency.RUNTIME_EXTENSION_ARTIFACT_FLAG, AppDependency.RUNTIME_CP_FLAG, - AppDependency.DEPLOYMENT_CP_FLAG), - new AppDependency(TsArtifact.jar("random").toAppArtifact(), "compile", AppDependency.DIRECT_FLAG, - AppDependency.RUNTIME_CP_FLAG, AppDependency.DEPLOYMENT_CP_FLAG), - new AppDependency(TsArtifact.jar("ext2", "1.0.0").toAppArtifact(), "compile", AppDependency.DIRECT_FLAG, - AppDependency.RUNTIME_EXTENSION_ARTIFACT_FLAG, AppDependency.RUNTIME_CP_FLAG, - AppDependency.DEPLOYMENT_CP_FLAG) - }), effectiveModel.getUserDependencies()); - - assertEquals(Arrays.asList(new AppDependency[] { - new AppDependency(TsArtifact.jar("ext1-deployment", "1.0.0").toAppArtifact(), "compile", - AppDependency.DEPLOYMENT_CP_FLAG), - new AppDependency(TsArtifact.jar("ext2-deployment", "1.0.0").toAppArtifact(), "compile", - AppDependency.DEPLOYMENT_CP_FLAG) - }), effectiveModel.getDeploymentDependencies()); - - } -} diff --git a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/update/CreatorOutcomeTestBase.java b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/update/CreatorOutcomeTestBase.java index 309248fe45c93..8848530373fbb 100644 --- a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/update/CreatorOutcomeTestBase.java +++ b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/update/CreatorOutcomeTestBase.java @@ -37,7 +37,7 @@ protected void rebuild() throws Exception { IoUtils.recursiveDelete(ws); final Path outputDir = IoUtils.mkdirs(ws.resolve("target")); - Path applicationRoot = resolver.resolve(appJar.toAppArtifact()); + Path applicationRoot = resolver.resolve(appJar.toArtifact()).getResolvedPaths().getSinglePath(); final QuarkusBootstrap.Builder bootstrap = QuarkusBootstrap.builder() .setApplicationRoot(applicationRoot) .setProjectRoot(applicationRoot) diff --git a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/update/UpdateToNextMicroAndPersistStateTest.java b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/update/UpdateToNextMicroAndPersistStateTest.java deleted file mode 100644 index 4100bc7c998d7..0000000000000 --- a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/resolver/update/UpdateToNextMicroAndPersistStateTest.java +++ /dev/null @@ -1,86 +0,0 @@ -package io.quarkus.bootstrap.resolver.update; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import io.quarkus.bootstrap.app.CuratedApplication; -import io.quarkus.bootstrap.app.QuarkusBootstrap; -import io.quarkus.bootstrap.model.AppDependency; -import io.quarkus.bootstrap.model.AppModel; -import io.quarkus.bootstrap.resolver.TsArtifact; -import io.quarkus.bootstrap.resolver.TsQuarkusExt; -import java.util.Arrays; -import java.util.Collections; - -public class UpdateToNextMicroAndPersistStateTest extends CreatorOutcomeTestBase { - - private static final String[] EXPECTED_UPDATES = new String[] { "1.0.1", "1.0.2" }; - - private int buildNo; - - @Override - protected void initProps(QuarkusBootstrap.Builder builder) { - builder.setVersionUpdateNumber(VersionUpdateNumber.MICRO) - .setVersionUpdate(VersionUpdate.NEXT) - .setDependenciesOrigin(DependenciesOrigin.LAST_UPDATE); - } - - @Override - protected TsArtifact modelApp() throws Exception { - new TsQuarkusExt("ext1", "1.0.1").install(repo); - new TsQuarkusExt("ext1", "1.0.2").install(repo); - new TsQuarkusExt("ext1", "1.1.0").install(repo); - new TsQuarkusExt("ext1", "2.0.0").install(repo); - - return TsArtifact.jar("app") - .addDependency(new TsQuarkusExt("ext1", "1.0.0")) - .addDependency(TsArtifact.jar("random")) - .addDependency(new TsQuarkusExt("ext2", "1.0.0")); - } - - @Override - protected void testCreator(QuarkusBootstrap creator) throws Exception { - - final CuratedApplication outcome = creator.bootstrap(); - - final String expectedVersion; - - if (buildNo < EXPECTED_UPDATES.length) { - expectedVersion = EXPECTED_UPDATES[buildNo]; - assertTrue(outcome.hasUpdatedDeps()); - assertEquals(Arrays.asList(new AppDependency[] { - new AppDependency(TsArtifact.jar("ext1", expectedVersion).toAppArtifact(), "compile") - }), outcome.getUpdatedDeps()); - } else { - expectedVersion = EXPECTED_UPDATES[buildNo - 1]; - assertFalse(outcome.hasUpdatedDeps()); - assertEquals(Collections.emptyList(), outcome.getUpdatedDeps()); - } - - final AppModel effectiveModel = outcome.getAppModel(); - assertEquals(Arrays.asList(new AppDependency[] { - new AppDependency(TsArtifact.jar("ext1", expectedVersion).toAppArtifact(), "compile", AppDependency.DIRECT_FLAG, - AppDependency.RUNTIME_EXTENSION_ARTIFACT_FLAG, AppDependency.RUNTIME_CP_FLAG, - AppDependency.DEPLOYMENT_CP_FLAG), - new AppDependency(TsArtifact.jar("random").toAppArtifact(), "compile", AppDependency.DIRECT_FLAG, - AppDependency.RUNTIME_CP_FLAG, AppDependency.DEPLOYMENT_CP_FLAG), - new AppDependency(TsArtifact.jar("ext2", "1.0.0").toAppArtifact(), "compile", AppDependency.DIRECT_FLAG, - AppDependency.RUNTIME_EXTENSION_ARTIFACT_FLAG, AppDependency.RUNTIME_CP_FLAG, - AppDependency.DEPLOYMENT_CP_FLAG) - }), effectiveModel.getUserDependencies()); - - assertEquals(Arrays.asList(new AppDependency[] { - new AppDependency(TsArtifact.jar("ext1-deployment", expectedVersion).toAppArtifact(), "compile", - AppDependency.DEPLOYMENT_CP_FLAG), - new AppDependency(TsArtifact.jar("ext2-deployment", "1.0.0").toAppArtifact(), "compile", - AppDependency.DEPLOYMENT_CP_FLAG) - }), effectiveModel.getDeploymentDependencies()); - - outcome.getCurationResult().persist(outcome.getQuarkusBootstrap().getAppModelResolver()); - - if (++buildNo <= EXPECTED_UPDATES.length) { - rebuild(); - } - } -} diff --git a/independent-projects/bootstrap/gradle-resolver/src/main/java/io/quarkus/bootstrap/resolver/QuarkusGradleModelFactory.java b/independent-projects/bootstrap/gradle-resolver/src/main/java/io/quarkus/bootstrap/resolver/QuarkusGradleModelFactory.java index a760ed68b9277..fbc32145a0cd1 100644 --- a/independent-projects/bootstrap/gradle-resolver/src/main/java/io/quarkus/bootstrap/resolver/QuarkusGradleModelFactory.java +++ b/independent-projects/bootstrap/gradle-resolver/src/main/java/io/quarkus/bootstrap/resolver/QuarkusGradleModelFactory.java @@ -1,6 +1,6 @@ package io.quarkus.bootstrap.resolver; -import io.quarkus.bootstrap.model.gradle.QuarkusModel; +import io.quarkus.bootstrap.model.ApplicationModel; import java.io.File; import java.util.Collections; import java.util.List; @@ -10,11 +10,11 @@ public class QuarkusGradleModelFactory { - public static QuarkusModel create(File projectDir, String mode, String... tasks) { + public static ApplicationModel create(File projectDir, String mode, String... tasks) { return create(projectDir, mode, Collections.emptyList(), tasks); } - public static QuarkusModel create(File projectDir, String mode, List jvmArgs, String... tasks) { + public static ApplicationModel create(File projectDir, String mode, List jvmArgs, String... tasks) { try (ProjectConnection connection = GradleConnector.newConnector() .forProjectDirectory(projectDir) .connect()) { @@ -22,11 +22,11 @@ public static QuarkusModel create(File projectDir, String mode, List jvm } } - public static QuarkusModel createForTasks(File projectDir, String... tasks) { + public static ApplicationModel createForTasks(File projectDir, String... tasks) { try (ProjectConnection connection = GradleConnector.newConnector() .forProjectDirectory(projectDir) .connect()) { - final ModelBuilder modelBuilder = connection.model(QuarkusModel.class); + final ModelBuilder modelBuilder = connection.model(ApplicationModel.class); if (tasks.length != 0) { modelBuilder.forTasks(tasks); } diff --git a/independent-projects/bootstrap/gradle-resolver/src/main/java/io/quarkus/bootstrap/resolver/QuarkusModelBuildAction.java b/independent-projects/bootstrap/gradle-resolver/src/main/java/io/quarkus/bootstrap/resolver/QuarkusModelBuildAction.java index 94d5f6099482c..d336faa89eaac 100644 --- a/independent-projects/bootstrap/gradle-resolver/src/main/java/io/quarkus/bootstrap/resolver/QuarkusModelBuildAction.java +++ b/independent-projects/bootstrap/gradle-resolver/src/main/java/io/quarkus/bootstrap/resolver/QuarkusModelBuildAction.java @@ -1,12 +1,12 @@ package io.quarkus.bootstrap.resolver; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.model.gradle.ModelParameter; -import io.quarkus.bootstrap.model.gradle.QuarkusModel; import java.io.Serializable; import org.gradle.tooling.BuildAction; import org.gradle.tooling.BuildController; -public class QuarkusModelBuildAction implements BuildAction, Serializable { +public class QuarkusModelBuildAction implements BuildAction, Serializable { private final String mode; public QuarkusModelBuildAction(String mode) { @@ -14,7 +14,7 @@ public QuarkusModelBuildAction(String mode) { } @Override - public QuarkusModel execute(BuildController controller) { - return controller.getModel(QuarkusModel.class, ModelParameter.class, p -> p.setMode(mode)); + public ApplicationModel execute(BuildController controller) { + return controller.getModel(ApplicationModel.class, ModelParameter.class, p -> p.setMode(mode)); } } diff --git a/independent-projects/bootstrap/gradle-resolver/src/main/java/io/quarkus/bootstrap/util/QuarkusModelHelper.java b/independent-projects/bootstrap/gradle-resolver/src/main/java/io/quarkus/bootstrap/util/QuarkusModelHelper.java deleted file mode 100644 index f9d5d88adf536..0000000000000 --- a/independent-projects/bootstrap/gradle-resolver/src/main/java/io/quarkus/bootstrap/util/QuarkusModelHelper.java +++ /dev/null @@ -1,230 +0,0 @@ -package io.quarkus.bootstrap.util; - -import io.quarkus.bootstrap.BootstrapConstants; -import io.quarkus.bootstrap.BootstrapGradleException; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppArtifactKey; -import io.quarkus.bootstrap.model.AppDependency; -import io.quarkus.bootstrap.model.AppModel; -import io.quarkus.bootstrap.model.CapabilityContract; -import io.quarkus.bootstrap.model.PathsCollection; -import io.quarkus.bootstrap.model.gradle.ArtifactCoords; -import io.quarkus.bootstrap.model.gradle.Dependency; -import io.quarkus.bootstrap.model.gradle.QuarkusModel; -import io.quarkus.bootstrap.model.gradle.WorkspaceModule; -import io.quarkus.bootstrap.resolver.AppModelResolverException; -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.UncheckedIOException; -import java.nio.file.FileSystem; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Properties; - -public class QuarkusModelHelper { - - private QuarkusModelHelper() { - - } - - public final static String SERIALIZED_QUARKUS_MODEL = "quarkus-internal.serialized-quarkus-model.path"; - public final static String[] DEVMODE_REQUIRED_TASKS = new String[] { "classes" }; - public final static String[] TEST_REQUIRED_TASKS = new String[] { "classes", "testClasses" }; - public final static List ENABLE_JAR_PACKAGING = Collections - .singletonList("-Dorg.gradle.java.compile-classpath-packaging=true"); - - public static void exportModel(QuarkusModel model, boolean test) throws AppModelResolverException, IOException { - Path serializedModel = QuarkusModelHelper - .serializeAppModel(model, test); - System.setProperty(test ? BootstrapConstants.SERIALIZED_TEST_APP_MODEL : BootstrapConstants.SERIALIZED_APP_MODEL, - serializedModel.toString()); - } - - public static Path serializeAppModel(QuarkusModel model, boolean test) throws AppModelResolverException, IOException { - final Path serializedModel = File.createTempFile("quarkus-" + (test ? "test-" : "") + "app-model", ".dat").toPath(); - final ArtifactCoords artifactCoords = model.getWorkspace().getMainModule().getArtifactCoords(); - AppArtifact appArtifact = new AppArtifact(artifactCoords.getGroupId(), - artifactCoords.getArtifactId(), - artifactCoords.getVersion()); - try (ObjectOutputStream out = new ObjectOutputStream(Files.newOutputStream(serializedModel))) { - out.writeObject(QuarkusModelHelper.convert(model, appArtifact)); - } - return serializedModel; - } - - public static Path serializeQuarkusModel(QuarkusModel model) throws IOException { - final Path serializedModel = File.createTempFile("quarkus-model", ".dat").toPath(); - try (ObjectOutputStream out = new ObjectOutputStream(Files.newOutputStream(serializedModel))) { - out.writeObject(model); - } - return serializedModel; - } - - public static QuarkusModel deserializeQuarkusModel(Path modelPath) throws BootstrapGradleException { - if (Files.exists(modelPath)) { - try (InputStream existing = Files.newInputStream(modelPath); - ObjectInputStream object = new ObjectInputStream(existing)) { - QuarkusModel model = (QuarkusModel) object.readObject(); - IoUtils.recursiveDelete(modelPath); - return model; - } catch (IOException | ClassNotFoundException e) { - throw new BootstrapGradleException("Failed to deserialize quarkus model", e); - } - } - throw new BootstrapGradleException("Unable to locate quarkus model"); - } - - public static Path getClassPath(WorkspaceModule model) throws BootstrapGradleException { - // TODO handle multiple class directory - final Optional classDir = model.getSourceSet().getSourceDirectories().stream() - .filter(File::exists) - .map(File::toPath) - .findFirst(); - if (!classDir.isPresent()) { - throw new BootstrapGradleException("Failed to locate class directory"); - } - return classDir.get(); - } - - public static AppModel convert(QuarkusModel model, AppArtifact appArtifact) throws AppModelResolverException { - AppModel.Builder appBuilder = new AppModel.Builder(); - - final Map capabilities = new HashMap<>(); - final Map capabilitiesContracts = new HashMap<>(); - for (Dependency extensionDependency : model.getDependencies()) { - boolean extension = false; - for (File f : extensionDependency.getPaths()) { - final Path artifactPath = f.toPath(); - if (!Files.exists(artifactPath) || !extensionDependency.getType().equals("jar")) { - continue; - } - if (Files.isDirectory(artifactPath)) { - extension |= processQuarkusDir(extensionDependency, - artifactPath.resolve(BootstrapConstants.META_INF), - appBuilder, capabilities, capabilitiesContracts); - } else { - try (FileSystem artifactFs = FileSystems.newFileSystem(artifactPath, - QuarkusModelHelper.class.getClassLoader())) { - extension |= processQuarkusDir(extensionDependency, - artifactFs.getPath(BootstrapConstants.META_INF), - appBuilder, capabilities, capabilitiesContracts); - } catch (IOException e) { - throw new AppModelResolverException("Failed to process " + artifactPath, e); - } - } - } - appBuilder.addDependency(toAppDependency(extensionDependency, extensionDependency.getFlags(), - extension ? AppDependency.RUNTIME_EXTENSION_ARTIFACT_FLAG : 0)); - } - appBuilder.setCapabilitiesContracts(capabilitiesContracts); - - if (!appArtifact.isResolved()) { - PathsCollection.Builder paths = PathsCollection.builder(); - WorkspaceModule module = model.getWorkspace().getMainModule(); - module.getSourceSet().getSourceDirectories().stream() - .filter(File::exists) - .map(File::toPath) - .forEach(paths::add); - module.getSourceSet().getResourceDirectories().stream() - .filter(File::exists) - .map(File::toPath) - .forEach(paths::add); - appArtifact.setPaths(paths.build()); - } - - for (WorkspaceModule module : model.getWorkspace().getAllModules()) { - final ArtifactCoords coords = module.getArtifactCoords(); - appBuilder.addLocalProjectArtifact( - new AppArtifactKey(coords.getGroupId(), coords.getArtifactId(), null, coords.getType())); - } - - appBuilder.setAppArtifact(appArtifact) - .setPlatformImports(model.getPlatformImports()); - return appBuilder.build(); - } - - public static AppDependency toAppDependency(Dependency dependency, int... flags) { - int allFlags = dependency.getFlags(); - for (int f : flags) { - allFlags |= f; - } - return new AppDependency(toAppArtifact(dependency), "runtime", allFlags); - } - - private static AppArtifact toAppArtifact(Dependency dependency) { - AppArtifact artifact = new AppArtifact(dependency.getGroupId(), dependency.getName(), dependency.getClassifier(), - dependency.getType(), dependency.getVersion()); - artifact.setPaths(QuarkusModelHelper.toPathsCollection(dependency.getPaths())); - return artifact; - } - - public static PathsCollection toPathsCollection(Collection files) { - PathsCollection.Builder paths = PathsCollection.builder(); - for (File f : files) { - paths.add(f.toPath()); - } - return paths.build(); - } - - public static Properties resolveDescriptor(final Path path) { - final Properties rtProps; - if (!Files.exists(path)) { - // not a platform artifact - return null; - } - rtProps = new Properties(); - try (BufferedReader reader = Files.newBufferedReader(path)) { - rtProps.load(reader); - } catch (IOException e) { - throw new UncheckedIOException("Failed to load extension description " + path, e); - } - return rtProps; - } - - private static boolean processQuarkusDir(Dependency d, Path quarkusDir, AppModel.Builder appBuilder, - Map capabilities, Map capabilitiesContracts) { - if (!Files.exists(quarkusDir)) { - return false; - } - final Path quarkusDescr = quarkusDir.resolve(BootstrapConstants.DESCRIPTOR_FILE_NAME); - if (!Files.exists(quarkusDescr)) { - return false; - } - final Properties extProps = QuarkusModelHelper.resolveDescriptor(quarkusDescr); - if (extProps == null) { - return false; - } - final String extensionCoords = d.getGroupId() + ":" + d.getName() + ":" - + (d.getClassifier() == null ? "" : d.getClassifier()) + ":" - + (d.getType() == null || d.getType().isEmpty() ? "jar" : d.getType()) + ":" + d.getVersion(); - appBuilder.handleExtensionProperties(extProps, extensionCoords); - - final String providesCapabilities = extProps.getProperty(BootstrapConstants.PROP_PROVIDES_CAPABILITIES); - if (providesCapabilities != null) { - capabilitiesContracts.put(extensionCoords, - CapabilityContract.providesCapabilities(extensionCoords, providesCapabilities)); - } - return true; - } - - static AppDependency alignVersion(AppDependency dependency, Map versionMap) { - AppArtifactKey appKey = new AppArtifactKey(dependency.getArtifact().getGroupId(), - dependency.getArtifact().getArtifactId()); - if (versionMap.containsKey(appKey)) { - return versionMap.get(appKey); - } - return dependency; - } - -} diff --git a/independent-projects/bootstrap/gradle-resolver/src/test/java/io/quarkus/bootstrap/util/QuarkusModelHelperTest.java b/independent-projects/bootstrap/gradle-resolver/src/test/java/io/quarkus/bootstrap/util/QuarkusModelHelperTest.java deleted file mode 100644 index 7626776874559..0000000000000 --- a/independent-projects/bootstrap/gradle-resolver/src/test/java/io/quarkus/bootstrap/util/QuarkusModelHelperTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package io.quarkus.bootstrap.util; - -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppArtifactKey; -import io.quarkus.bootstrap.model.AppDependency; -import java.util.HashMap; -import java.util.Map; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -public class QuarkusModelHelperTest { - - @Test - public void shouldKeepExtensionDependencyVersion() { - Map userDependencies = new HashMap<>(); - - final AppArtifact appArtifact = new AppArtifact("org.acme", "common", "0.0.1-SNAPSHOT"); - AppDependency extensionDependency = new AppDependency(appArtifact, "runtime", false); - - final AppDependency dependency = QuarkusModelHelper.alignVersion(extensionDependency, userDependencies); - - Assertions.assertEquals(extensionDependency, dependency); - } - - @Test - public void shouldUseUserDependencyVersion() { - Map userDependencies = new HashMap<>(); - final AppArtifact userAppArtifact = new AppArtifact("org.acme", "common", "1.0.0-SNAPSHOT"); - final AppDependency userDependency = new AppDependency(userAppArtifact, "runtime", false); - userDependencies.put(new AppArtifactKey("org.acme", "common"), userDependency); - - final AppArtifact appArtifact = new AppArtifact("org.acme", "common", "0.0.1-SNAPSHOT"); - AppDependency extensionDependency = new AppDependency(appArtifact, "runtime", false); - - final AppDependency dependency = QuarkusModelHelper.alignVersion(extensionDependency, userDependencies); - - Assertions.assertEquals(userDependency, dependency); - } -} diff --git a/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/BootstrapAppModelResolver.java b/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/BootstrapAppModelResolver.java index cbddded5c0c4f..4f7d8ff9b9dfc 100644 --- a/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/BootstrapAppModelResolver.java +++ b/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/BootstrapAppModelResolver.java @@ -2,19 +2,28 @@ import io.quarkus.bootstrap.BootstrapConstants; import io.quarkus.bootstrap.BootstrapDependencyProcessingException; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppArtifactKey; -import io.quarkus.bootstrap.model.AppDependency; -import io.quarkus.bootstrap.model.AppModel; -import io.quarkus.bootstrap.model.PathsCollection; +import io.quarkus.bootstrap.model.ApplicationModel; +import io.quarkus.bootstrap.model.ApplicationModelBuilder; import io.quarkus.bootstrap.model.PlatformImportsImpl; +import io.quarkus.bootstrap.resolver.maven.BootstrapMavenException; import io.quarkus.bootstrap.resolver.maven.BuildDependencyGraphVisitor; import io.quarkus.bootstrap.resolver.maven.DeploymentInjectingDependencyVisitor; import io.quarkus.bootstrap.resolver.maven.MavenArtifactResolver; import io.quarkus.bootstrap.resolver.maven.SimpleDependencyGraphTransformationContext; -import java.io.File; +import io.quarkus.bootstrap.workspace.ProcessedSources; +import io.quarkus.bootstrap.workspace.WorkspaceModule; +import io.quarkus.maven.dependency.ArtifactCoords; +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.DependencyFlags; +import io.quarkus.maven.dependency.GACT; +import io.quarkus.maven.dependency.ResolvableDependency; +import io.quarkus.maven.dependency.ResolvedDependency; +import io.quarkus.maven.dependency.ResolvedDependencyBuilder; +import io.quarkus.paths.PathCollection; +import io.quarkus.paths.PathList; import java.nio.file.Path; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -46,6 +55,7 @@ public class BootstrapAppModelResolver implements AppModelResolver { protected Consumer buildTreeConsumer; protected boolean devmode; protected boolean test; + private boolean collectReloadableDeps = true; public BootstrapAppModelResolver(MavenArtifactResolver mvn) { this.mvn = mvn; @@ -73,43 +83,46 @@ public BootstrapAppModelResolver setTest(boolean test) { return this; } + public BootstrapAppModelResolver setCollectReloadableDependencies(boolean collectReloadableDeps) { + this.collectReloadableDeps = collectReloadableDeps; + return this; + } + public void addRemoteRepositories(List repos) { mvn.addRemoteRepositories(repos); } @Override - public void relink(AppArtifact artifact, Path path) throws AppModelResolverException { + public void relink(ArtifactCoords artifact, Path path) throws AppModelResolverException { if (mvn.getLocalRepositoryManager() == null) { return; } mvn.getLocalRepositoryManager().relink(artifact.getGroupId(), artifact.getArtifactId(), artifact.getClassifier(), artifact.getType(), artifact.getVersion(), path); - artifact.setPaths(PathsCollection.of(path)); + if (artifact instanceof ResolvableDependency) { + ((ResolvableDependency) artifact).setResolvedPaths(PathList.of(path)); + } } @Override - public Path resolve(AppArtifact artifact) throws AppModelResolverException { - if (artifact.isResolved()) { - return artifact.getPaths().iterator().next(); - } - final Path path = mvn.resolve(toAetherArtifact(artifact)).getArtifact().getFile().toPath(); - artifact.setPaths(PathsCollection.of(path)); - return path; + public ResolvedDependency resolve(ArtifactCoords artifact) throws AppModelResolverException { + return resolve(artifact, toAetherArtifact(artifact), Collections.emptyList()); } @Override - public List resolveUserDependencies(AppArtifact appArtifact, List deps) + public Collection resolveUserDependencies(ArtifactCoords appArtifact, + Collection deps) throws AppModelResolverException { final List mvnDeps; if (deps.isEmpty()) { mvnDeps = Collections.emptyList(); } else { mvnDeps = new ArrayList<>(deps.size()); - for (AppDependency dep : deps) { - mvnDeps.add(new Dependency(toAetherArtifact(dep.getArtifact()), dep.getScope())); + for (io.quarkus.maven.dependency.Dependency dep : deps) { + mvnDeps.add(new Dependency(toAetherArtifact(dep), dep.getScope())); } } - final List result = new ArrayList<>(); + final List result = new ArrayList<>(); final TreeDependencyVisitor visitor = new TreeDependencyVisitor(new DependencyVisitor() { @Override public boolean visitEnter(DependencyNode node) { @@ -120,7 +133,7 @@ public boolean visitEnter(DependencyNode node) { public boolean visitLeave(DependencyNode node) { final Dependency dep = node.getDependency(); if (dep != null) { - result.add(new AppDependency(toAppArtifact(dep.getArtifact()), dep.getScope(), dep.isOptional())); + result.add(toAppArtifact(dep.getArtifact()).setScope(dep.getScope()).setOptional(dep.isOptional()).build()); } return true; } @@ -130,32 +143,38 @@ public boolean visitLeave(DependencyNode node) { } @Override - public AppModel resolveModel(AppArtifact appArtifact) throws AppModelResolverException { + public ApplicationModel resolveModel(ArtifactCoords appArtifact) + throws AppModelResolverException { return resolveManagedModel(appArtifact, Collections.emptyList(), null, Collections.emptySet()); } @Override - public AppModel resolveModel(AppArtifact appArtifact, List directDeps) throws AppModelResolverException { + public ApplicationModel resolveModel(ArtifactCoords appArtifact, + Collection directDeps) + throws AppModelResolverException { return resolveManagedModel(appArtifact, directDeps, null, Collections.emptySet()); } @Override - public AppModel resolveManagedModel(AppArtifact appArtifact, List directDeps, AppArtifact managingProject, - Set localProjects) + public ApplicationModel resolveManagedModel(ArtifactCoords appArtifact, + Collection directDeps, + ArtifactCoords managingProject, + Set reloadableModules) throws AppModelResolverException { - return doResolveModel(appArtifact, toAetherDeps(directDeps), managingProject, localProjects); + return doResolveModel(appArtifact, toAetherDeps(directDeps), managingProject, reloadableModules); } - private AppModel doResolveModel(AppArtifact appArtifact, List directMvnDeps, AppArtifact managingProject, - Set localProjects) + private ApplicationModel doResolveModel(ArtifactCoords coords, + List directMvnDeps, + ArtifactCoords managingProject, + Set reloadableModules) throws AppModelResolverException { - if (appArtifact == null) { + if (coords == null) { throw new IllegalArgumentException("Application artifact is null"); } - final Artifact mvnArtifact = toAetherArtifact(appArtifact); + final Artifact mvnArtifact = toAetherArtifact(coords); - AppModel.Builder appBuilder = new AppModel.Builder().setAppArtifact(appArtifact); List managedDeps = Collections.emptyList(); List managedRepos = Collections.emptyList(); if (managingProject != null) { @@ -171,9 +190,14 @@ private AppModel doResolveModel(AppArtifact appArtifact, List direct excludedScopes.add("provided"); } - if (!appArtifact.isResolved()) { - final ArtifactResult resolveResult = mvn.resolve(mvnArtifact, managedRepos); - appArtifact.setPaths(PathsCollection.of(resolveResult.getArtifact().getFile().toPath())); + final ResolvedDependency appArtifact = resolve(coords, mvnArtifact, managedRepos); + + final ApplicationModelBuilder appBuilder = new ApplicationModelBuilder().setAppArtifact(appArtifact); + if (appArtifact.getWorkspaceModule() != null) { + appBuilder.addReloadableWorkspaceModule(new GACT(appArtifact.getGroupId(), appArtifact.getArtifactId())); + } + if (!reloadableModules.isEmpty()) { + appBuilder.addReloadableWorkspaceModules(reloadableModules); } DependencyNode resolvedDeps = mvn.resolveManagedDependencies(mvnArtifact, @@ -184,7 +208,7 @@ private AppModel doResolveModel(AppArtifact appArtifact, List direct managedDeps = appArtifactDescr.getManagedDependencies(); } else { final List mergedManagedDeps = new ArrayList<>(managedDeps.size()); - final Set mergedKeys = new HashSet<>(managedDeps.size()); + final Set mergedKeys = new HashSet<>(managedDeps.size()); for (Dependency dep : managedDeps) { mergedKeys.add(getKey(dep.getArtifact())); mergedManagedDeps.add(dep); @@ -203,7 +227,8 @@ private AppModel doResolveModel(AppArtifact appArtifact, List direct final DeploymentInjectingDependencyVisitor deploymentInjector; try { - deploymentInjector = new DeploymentInjectingDependencyVisitor(mvn, managedDeps, repos, appBuilder); + deploymentInjector = new DeploymentInjectingDependencyVisitor(mvn, managedDeps, repos, appBuilder, devmode || test, + collectReloadableDeps && reloadableModules.isEmpty()); deploymentInjector.injectDeploymentDependencies(resolvedDeps); } catch (BootstrapDependencyProcessingException e) { throw new AppModelResolverException( @@ -238,24 +263,83 @@ private AppModel doResolveModel(AppArtifact appArtifact, List direct } final List deploymentDepNodes = buildDepsVisitor.getDeploymentNodes(); for (DependencyNode dep : deploymentDepNodes) { - appBuilder.addDependency(new AppDependency(BootstrapAppModelResolver.toAppArtifact(dep.getArtifact()), - dep.getDependency().getScope(), dep.getDependency().isOptional(), - AppDependency.DEPLOYMENT_CP_FLAG)); + int flags = DependencyFlags.DEPLOYMENT_CP; + if (dep.getDependency().isOptional()) { + flags |= DependencyFlags.OPTIONAL; + } + WorkspaceModule module = null; + if (mvn.getProjectModuleResolver() != null) { + module = mvn.getProjectModuleResolver().getProjectModule(dep.getArtifact().getGroupId(), + dep.getArtifact().getArtifactId()); + if (module != null) { + flags |= DependencyFlags.WORKSPACE_MODULE; + } + } + appBuilder.addDependency( + toAppArtifact(dep.getArtifact(), module, devmode || test) + .setScope(dep.getDependency().getScope()) + .setFlags(flags).build()); } } } collectPlatformProperties(appBuilder, managedDeps); - //we need these to have a type of 'jar' - //type is blank when loaded - for (AppArtifactKey i : localProjects) { - appBuilder.addLocalProjectArtifact(new AppArtifactKey(i.getGroupId(), i.getArtifactId(), null, "jar")); - } return appBuilder.build(); } - private void collectPlatformProperties(AppModel.Builder appBuilder, List managedDeps) + private io.quarkus.maven.dependency.ResolvedDependency resolve(ArtifactCoords appArtifact, Artifact mvnArtifact, + List managedRepos) throws BootstrapMavenException { + + final ResolvedDependency resolvedArtifact = ResolvedDependency.class.isAssignableFrom(appArtifact.getClass()) + ? (ResolvedDependency) appArtifact + : null; + if (resolvedArtifact != null + && (resolvedArtifact.getWorkspaceModule() != null || mvn.getProjectModuleResolver() == null)) { + return resolvedArtifact; + } + + final WorkspaceModule resolvedModule = mvn.getProjectModuleResolver() == null ? null + : mvn.getProjectModuleResolver().getProjectModule(appArtifact.getGroupId(), appArtifact.getArtifactId()); + if (resolvedArtifact != null && resolvedModule == null) { + return resolvedArtifact; + } + + PathCollection resolvedPaths = null; + if ((devmode || test) && resolvedModule != null) { + final PathList.Builder pathBuilder = PathList.builder(); + for (ProcessedSources src : resolvedModule.getMainSources()) { + if (src.getDestinationDir().exists()) { + final Path p = src.getDestinationDir().toPath(); + if (!pathBuilder.contains(p)) { + pathBuilder.add(p); + } + } + } + for (ProcessedSources src : resolvedModule.getMainResources()) { + if (src.getDestinationDir().exists()) { + final Path p = src.getDestinationDir().toPath(); + if (!pathBuilder.contains(p)) { + pathBuilder.add(p); + } + } + } + if (!pathBuilder.isEmpty()) { + resolvedPaths = pathBuilder.build(); + } + } + if (resolvedPaths == null) { + if (resolvedArtifact == null || resolvedArtifact.getResolvedPaths() == null) { + resolvedPaths = PathList.of(mvn.resolve(mvnArtifact, managedRepos).getArtifact().getFile().toPath()); + } else { + resolvedPaths = resolvedArtifact.getResolvedPaths(); + } + } + return ResolvedDependencyBuilder.newInstance().setCoords(appArtifact).setWorkspaceModule(resolvedModule) + .setResolvedPaths(resolvedPaths).build(); + } + + private void collectPlatformProperties(ApplicationModelBuilder appBuilder, List managedDeps) throws AppModelResolverException { final PlatformImportsImpl platformReleases = new PlatformImportsImpl(); for (Dependency d : managedDeps) { @@ -276,9 +360,10 @@ private void collectPlatformProperties(AppModel.Builder appBuilder, List listLaterVersions(AppArtifact appArtifact, String upToVersion, boolean inclusive) + public List listLaterVersions(ArtifactCoords appArtifact, String upToVersion, boolean inclusive) throws AppModelResolverException { - final VersionRangeResult rangeResult = resolveVersionRangeResult(appArtifact, appArtifact.getVersion(), false, + final VersionRangeResult rangeResult = resolveVersionRangeResult(appArtifact, appArtifact.getVersion(), + false, upToVersion, inclusive); final List resolvedVersions = rangeResult.getVersions(); final List versions = new ArrayList<>(resolvedVersions.size()); @@ -289,7 +374,8 @@ public List listLaterVersions(AppArtifact appArtifact, String upToVersio } @Override - public String getNextVersion(AppArtifact appArtifact, String fromVersion, boolean fromVersionIncluded, String upToVersion, + public String getNextVersion(ArtifactCoords appArtifact, String fromVersion, + boolean fromVersionIncluded, String upToVersion, boolean upToVersionInclusive) throws AppModelResolverException { final VersionRangeResult rangeResult = resolveVersionRangeResult(appArtifact, fromVersion, fromVersionIncluded, upToVersion, upToVersionInclusive); @@ -297,32 +383,36 @@ public String getNextVersion(AppArtifact appArtifact, String fromVersion, boolea } @Override - public String getLatestVersion(AppArtifact appArtifact, String upToVersion, boolean inclusive) + public String getLatestVersion(ArtifactCoords appArtifact, String upToVersion, + boolean inclusive) throws AppModelResolverException { - final VersionRangeResult rangeResult = resolveVersionRangeResult(appArtifact, appArtifact.getVersion(), false, + final VersionRangeResult rangeResult = resolveVersionRangeResult(appArtifact, appArtifact.getVersion(), + false, upToVersion, inclusive); final String latest = getLatest(rangeResult); return latest == null ? appArtifact.getVersion() : latest; } @Override - public String getLatestVersionFromRange(AppArtifact appArtifact, String range) throws AppModelResolverException { + public String getLatestVersionFromRange(ArtifactCoords appArtifact, String range) + throws AppModelResolverException { final VersionRangeResult rangeResult = resolveVersionRangeResult(appArtifact, range); return getLatest(rangeResult); } - public List resolveArtifactRepos(AppArtifact appArtifact) throws AppModelResolverException { + public List resolveArtifactRepos(ArtifactCoords appArtifact) throws AppModelResolverException { return mvn.resolveDescriptor(toAetherArtifact(appArtifact)).getRepositories(); } - public void install(AppArtifact appArtifact, Path localPath) throws AppModelResolverException { - mvn.install(new DefaultArtifact(appArtifact.getGroupId(), appArtifact.getArtifactId(), appArtifact.getClassifier(), - appArtifact.getType(), appArtifact.getVersion(), Collections.emptyMap(), localPath.toFile())); + public void install(ArtifactCoords artifact, Path localPath) + throws AppModelResolverException { + mvn.install(new DefaultArtifact(artifact.getGroupId(), artifact.getArtifactId(), artifact.getClassifier(), + artifact.getType(), + artifact.getVersion(), Collections.emptyMap(), localPath.toFile())); } - private AppArtifactKey getKey(final Artifact artifact) { - return new AppArtifactKey(artifact.getGroupId(), artifact.getArtifactId(), - artifact.getClassifier(), artifact.getExtension()); + private static ArtifactKey getKey(Artifact artifact) { + return DeploymentInjectingDependencyVisitor.getKey(artifact); } private String getEarliest(final VersionRangeResult rangeResult) { @@ -355,7 +445,8 @@ private String getLatest(final VersionRangeResult rangeResult) { return next.toString(); } - private VersionRangeResult resolveVersionRangeResult(AppArtifact appArtifact, String fromVersion, + private VersionRangeResult resolveVersionRangeResult(ArtifactCoords appArtifact, + String fromVersion, boolean fromVersionIncluded, String upToVersion, boolean upToVersionIncluded) throws AppModelResolverException { return resolveVersionRangeResult(appArtifact, @@ -364,53 +455,32 @@ private VersionRangeResult resolveVersionRangeResult(AppArtifact appArtifact, St + (upToVersion == null ? ')' : upToVersion + (upToVersionIncluded ? ']' : ')'))); } - private VersionRangeResult resolveVersionRangeResult(AppArtifact appArtifact, String range) + private VersionRangeResult resolveVersionRangeResult(ArtifactCoords appArtifact, String range) throws AppModelResolverException { return mvn.resolveVersionRange(new DefaultArtifact(appArtifact.getGroupId(), appArtifact.getArtifactId(), appArtifact.getType(), range)); } - static List toAppDepList(DependencyNode rootNode) { - final List depNodes = rootNode.getChildren(); - if (depNodes.isEmpty()) { - return Collections.emptyList(); - } - final List appDeps = new ArrayList<>(); - collect(depNodes, appDeps); - return appDeps; - } - - private static void collect(List nodes, List appDeps) { - for (DependencyNode node : nodes) { - collect(node.getChildren(), appDeps); - final Dependency dep = node.getDependency(); - appDeps.add(new AppDependency(toAppArtifact(node.getArtifact()), dep.getScope(), dep.isOptional())); - } + private static Artifact toAetherArtifact(ArtifactCoords artifact) { + return new DefaultArtifact(artifact.getGroupId(), artifact.getArtifactId(), + artifact.getClassifier(), artifact.getType(), artifact.getVersion()); } - private static Artifact toAetherArtifact(AppArtifact artifact) { - return new DefaultArtifact(artifact.getGroupId(), artifact.getArtifactId(), - artifact.getClassifier(), - artifact.getType(), artifact.getVersion()); + private ResolvedDependencyBuilder toAppArtifact(Artifact artifact) { + return toAppArtifact(artifact, null, false); } - private static AppArtifact toAppArtifact(Artifact artifact) { - final AppArtifact appArtifact = new AppArtifact(artifact.getGroupId(), artifact.getArtifactId(), - artifact.getClassifier(), artifact.getExtension(), artifact.getVersion()); - final File file = artifact.getFile(); - if (file != null) { - appArtifact.setPaths(PathsCollection.of(file.toPath())); - } - return appArtifact; + private ResolvedDependencyBuilder toAppArtifact(Artifact artifact, WorkspaceModule module, boolean preferWorkspacePaths) { + return DeploymentInjectingDependencyVisitor.toAppArtifact(artifact, module, preferWorkspacePaths); } - private static List toAetherDeps(List directDeps) { + private static List toAetherDeps(Collection directDeps) { if (directDeps.isEmpty()) { return Collections.emptyList(); } final List directMvnDeps = new ArrayList<>(directDeps.size()); - for (AppDependency dep : directDeps) { - directMvnDeps.add(new Dependency(toAetherArtifact(dep.getArtifact()), dep.getScope())); + for (io.quarkus.maven.dependency.Dependency dep : directDeps) { + directMvnDeps.add(new Dependency(toAetherArtifact(dep), dep.getScope())); } return directMvnDeps; } diff --git a/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/BuildDependencyGraphVisitor.java b/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/BuildDependencyGraphVisitor.java index 247fe294b813c..c3bfea2fd193f 100644 --- a/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/BuildDependencyGraphVisitor.java +++ b/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/BuildDependencyGraphVisitor.java @@ -3,8 +3,8 @@ */ package io.quarkus.bootstrap.resolver.maven; -import io.quarkus.bootstrap.model.AppArtifactKey; -import io.quarkus.bootstrap.util.DependencyNodeUtils; +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.GACT; import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -16,7 +16,7 @@ public class BuildDependencyGraphVisitor { - private final Set allRuntimeDeps; + private final Set allRuntimeDeps; private final StringBuilder buf; private final Consumer buildTreeConsumer; private final List depth; @@ -31,7 +31,7 @@ public class BuildDependencyGraphVisitor { private final List deploymentDepNodes = new ArrayList<>(); private final List requests = new ArrayList<>(); - public BuildDependencyGraphVisitor(Set allRuntimeDeps, Consumer buildTreeConsumer) { + public BuildDependencyGraphVisitor(Set allRuntimeDeps, Consumer buildTreeConsumer) { this.allRuntimeDeps = allRuntimeDeps; this.buildTreeConsumer = buildTreeConsumer; if (buildTreeConsumer == null) { @@ -143,7 +143,8 @@ private void visitLeave(DependencyNode node) { requests.add(new ArtifactRequest(node)); } if (currentDeployment != null) { - if (currentRuntime == null && !allRuntimeDeps.contains(DependencyNodeUtils.toKey(artifact))) { + if (currentRuntime == null && !allRuntimeDeps.contains(new GACT(artifact.getGroupId(), artifact.getArtifactId(), + artifact.getClassifier(), artifact.getExtension()))) { deploymentDepNodes.add(node); } else if (currentRuntime == node) { currentRuntime = null; diff --git a/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/DeploymentInjectingDependencyVisitor.java b/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/DeploymentInjectingDependencyVisitor.java index 1843d6bc2d016..037684a8b9207 100644 --- a/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/DeploymentInjectingDependencyVisitor.java +++ b/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/DeploymentInjectingDependencyVisitor.java @@ -2,18 +2,22 @@ import io.quarkus.bootstrap.BootstrapConstants; import io.quarkus.bootstrap.BootstrapDependencyProcessingException; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppArtifactKey; -import io.quarkus.bootstrap.model.AppDependency; -import io.quarkus.bootstrap.model.AppModel; +import io.quarkus.bootstrap.model.ApplicationModelBuilder; import io.quarkus.bootstrap.model.CapabilityContract; -import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.bootstrap.resolver.AppModelResolverException; import io.quarkus.bootstrap.util.BootstrapUtils; import io.quarkus.bootstrap.util.DependencyNodeUtils; import io.quarkus.bootstrap.util.ZipUtils; +import io.quarkus.bootstrap.workspace.ProcessedSources; +import io.quarkus.bootstrap.workspace.WorkspaceModule; +import io.quarkus.maven.dependency.ArtifactDependency; +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.DependencyFlags; +import io.quarkus.maven.dependency.GACT; +import io.quarkus.maven.dependency.ResolvedDependencyBuilder; +import io.quarkus.paths.PathCollection; +import io.quarkus.paths.PathList; import java.io.BufferedReader; -import java.io.File; import java.io.IOException; import java.nio.file.FileSystem; import java.nio.file.Files; @@ -63,22 +67,26 @@ public static Artifact getRuntimeArtifact(DependencyNode dep) { private final MavenArtifactResolver resolver; private final List managedDeps; private final List mainRepos; - private final AppModel.Builder appBuilder; + private final ApplicationModelBuilder appBuilder; + private final boolean preferWorkspacePaths; + private final boolean collectReloadableModules; - private boolean collectingTopRuntimeNodes = true; - private boolean collectingDirectExtensionDeps = true; + private boolean collectingTopExtensionRuntimeNodes = true; + private boolean collectingDirectDeps = true; private final List topExtensionDeps = new ArrayList<>(); private ExtensionDependency lastVisitedRuntimeExtNode; - private final Map allExtensions = new HashMap<>(); + private final Map allExtensions = new HashMap<>(); private List conditionalDepsToProcess = new ArrayList<>(); private final Deque> exclusionStack = new ArrayDeque<>(); - public final Set allRuntimeDeps = new HashSet<>(); - - private final Map capabilitiesContracts = new HashMap<>(); + public final Set allRuntimeDeps = new HashSet<>(); public DeploymentInjectingDependencyVisitor(MavenArtifactResolver resolver, List managedDeps, - List mainRepos, AppModel.Builder appBuilder) throws BootstrapDependencyProcessingException { + List mainRepos, ApplicationModelBuilder appBuilder, boolean preferWorkspacePaths, + boolean collectReloadableModules) + throws BootstrapDependencyProcessingException { + this.preferWorkspacePaths = preferWorkspacePaths; + this.collectReloadableModules = collectReloadableModules; // we need to be able to take into account whether the deployment dependencies are on an optional dependency branch // for that we are going to use a custom dependency selector and re-initialize the resolver to use it final DefaultRepositorySystemSession session = new DefaultRepositorySystemSession(resolver.getSession()); @@ -90,6 +98,7 @@ public DeploymentInjectingDependencyVisitor(MavenArtifactResolver resolver, List .setRepositorySystemSession(session) .setRemoteRepositories(resolver.getRepositories()) .setRemoteRepositoryManager(resolver.getRemoteRepositoryManager()) + .setCurrentProject(resolver.getMavenContext().getCurrentProject()) .setWorkspaceDiscovery(false))); } catch (BootstrapMavenException e) { throw new BootstrapDependencyProcessingException("Failed to initialize deployment dependencies resolver", @@ -149,11 +158,9 @@ public void injectDeploymentDependencies(DependencyNode root) throws BootstrapDe injectDeploymentDependencies(cd.getExtensionDependency()); } } - - appBuilder.setCapabilitiesContracts(capabilitiesContracts); } - private boolean isRuntimeArtifact(AppArtifactKey key) { + private boolean isRuntimeArtifact(ArtifactKey key) { return allRuntimeDeps.contains(key); } @@ -166,8 +173,8 @@ private void visitRuntimeDependencies(List list) { private void visitRuntimeDependency(DependencyNode node) { - final boolean prevCollectingDirectExtensionDeps = collectingDirectExtensionDeps; - final boolean prevCollectingTopRtNodes = collectingTopRuntimeNodes; + final boolean prevCollectingDirectDeps = collectingDirectDeps; + final boolean prevCollectingTopExtRtNodes = collectingTopExtensionRuntimeNodes; final ExtensionDependency prevLastVisitedRtExtNode = lastVisitedRuntimeExtNode; final boolean popExclusions; @@ -176,25 +183,38 @@ private void visitRuntimeDependency(DependencyNode node) { } Artifact artifact = node.getArtifact(); - AppArtifact newRtArtifactDep = null; - if (allRuntimeDeps.add(DependencyNodeUtils.toKey(artifact))) { + ResolvedDependencyBuilder newRtDep = null; + if (allRuntimeDeps.add(getKey(artifact))) { artifact = resolve(artifact); - newRtArtifactDep = toAppArtifact(artifact); + WorkspaceModule module = null; + if (resolver.getProjectModuleResolver() != null) { + module = resolver.getProjectModuleResolver().getProjectModule(artifact.getGroupId(), artifact.getArtifactId()); + } + newRtDep = toAppArtifact(artifact, module, preferWorkspacePaths) + .setRuntimeCp() + .setDeploymentCp() + .setOptional(node.getDependency().isOptional()) + .setScope(node.getDependency().getScope()) + .setDirect(collectingDirectDeps); + if (module != null) { + newRtDep.setWorkspaceModule().setReloadable(); + if (collectReloadableModules) { + appBuilder.addReloadableWorkspaceModule(new GACT(artifact.getGroupId(), artifact.getArtifactId())); + } + } } try { final ExtensionDependency extDep = getExtensionDependencyOrNull(node, artifact); - if (newRtArtifactDep != null) { - final AppDependency appDep = new AppDependency(newRtArtifactDep, node.getDependency().getScope(), - node.getDependency().isOptional(), - collectingDirectExtensionDeps ? AppDependency.DIRECT_FLAG : 0, - extDep == null ? 0 : AppDependency.RUNTIME_EXTENSION_ARTIFACT_FLAG, - AppDependency.RUNTIME_CP_FLAG, AppDependency.DEPLOYMENT_CP_FLAG); - appBuilder.addDependency(appDep); + if (newRtDep != null) { + if (extDep != null) { + newRtDep.setRuntimeExtensionArtifact(); + } + appBuilder.addDependency(newRtDep.build()); } - collectingDirectExtensionDeps = false; + collectingDirectDeps = false; if (extDep != null) { extDep.info.ensureActivated(); @@ -210,8 +230,8 @@ private void visitRuntimeDependency(DependencyNode node) { if (popExclusions) { exclusionStack.pollLast(); } - collectingDirectExtensionDeps = prevCollectingDirectExtensionDeps; - collectingTopRuntimeNodes = prevCollectingTopRtNodes; + collectingDirectDeps = prevCollectingDirectDeps; + collectingTopExtensionRuntimeNodes = prevCollectingTopExtRtNodes; lastVisitedRuntimeExtNode = prevLastVisitedRtExtNode; } @@ -248,8 +268,8 @@ private void visitExtensionDependency(ExtensionDependency extDep) collectConditionalDependencies(extDep); - if (collectingTopRuntimeNodes) { - collectingTopRuntimeNodes = false; + if (collectingTopExtensionRuntimeNodes) { + collectingTopExtensionRuntimeNodes = false; topExtensionDeps.add(extDep); } if (lastVisitedRuntimeExtNode != null) { @@ -282,7 +302,7 @@ private ExtensionInfo getExtensionInfoOrNull(Artifact artifact) throws Bootstrap if (!artifact.getExtension().equals("jar")) { return null; } - final AppArtifactKey extKey = DependencyNodeUtils.toKey(artifact); + final ArtifactKey extKey = getKey(artifact); ExtensionInfo ext = allExtensions.get(extKey); if (ext != null) { return ext; @@ -316,6 +336,11 @@ private void injectDeploymentDependencies(ExtensionDependency extDep) throws BootstrapDependencyProcessingException { log.debugf("Injecting deployment dependency %s", extDep.info.deploymentArtifact); final DependencyNode deploymentNode = collectDependencies(extDep.info.deploymentArtifact, extDep.exclusions); + + if (resolver.getProjectModuleResolver() != null) { + clearReloadable(deploymentNode); + } + final List deploymentDeps = deploymentNode.getChildren(); if (!replaceDirectDepBranch(extDep, deploymentDeps)) { throw new BootstrapDependencyProcessingException( @@ -331,6 +356,16 @@ private void injectDeploymentDependencies(ExtensionDependency extDep) runtimeNode.setChildren(deploymentDeps); } + private void clearReloadable(DependencyNode node) { + for (DependencyNode child : node.getChildren()) { + clearReloadable(child); + } + final io.quarkus.maven.dependency.Dependency dep = appBuilder.getDependency(getKey(node.getArtifact())); + if (dep != null && dep.isWorkspacetModule()) { + ((ArtifactDependency) dep).clearFlag(DependencyFlags.RELOADABLE); + } + } + private boolean replaceDirectDepBranch(ExtensionDependency extDep, List deploymentDeps) throws BootstrapDependencyProcessingException { int i = 0; @@ -431,7 +466,7 @@ private class ExtensionInfo { final Properties props; final Artifact deploymentArtifact; final Artifact[] conditionalDeps; - final AppArtifactKey[] dependencyCondition; + final ArtifactKey[] dependencyCondition; boolean activated; ExtensionInfo(Artifact runtimeArtifact, Properties props) throws BootstrapDependencyProcessingException { @@ -478,7 +513,7 @@ void ensureActivated() { final String providesCapabilities = props.getProperty(BootstrapConstants.PROP_PROVIDES_CAPABILITIES); if (providesCapabilities != null) { - capabilitiesContracts.put(toGactv(runtimeArtifact), + appBuilder.addExtensionCapabilities( CapabilityContract.providesCapabilities(toGactv(runtimeArtifact), providesCapabilities)); } } @@ -547,7 +582,7 @@ void activate() throws BootstrapDependencyProcessingException { return; } activated = true; - collectingTopRuntimeNodes = false; + collectingTopExtensionRuntimeNodes = false; final ExtensionDependency extDep = getExtensionDependency(); final DependencyNode originalNode = collectDependencies(info.runtimeArtifact, extDep.exclusions); final DefaultDependencyNode rtNode = (DefaultDependencyNode) extDep.runtimeNode; @@ -568,7 +603,7 @@ boolean isSatisfied() throws BootstrapDependencyProcessingException { if (info.dependencyCondition == null) { return true; } - for (AppArtifactKey key : info.dependencyCondition) { + for (ArtifactKey key : info.dependencyCondition) { if (!isRuntimeArtifact(key)) { return false; } @@ -584,14 +619,46 @@ private static boolean isSameKey(Artifact a1, Artifact a2) { && a2.getExtension().equals(a1.getExtension()); } - private static AppArtifact toAppArtifact(Artifact artifact) { - final AppArtifact appArtifact = new AppArtifact(artifact.getGroupId(), artifact.getArtifactId(), - artifact.getClassifier(), artifact.getExtension(), artifact.getVersion()); - final File file = artifact.getFile(); - if (file != null) { - appArtifact.setPaths(PathsCollection.of(file.toPath())); + public static GACT getKey(Artifact a) { + return new GACT(a.getGroupId(), a.getArtifactId(), a.getClassifier(), a.getExtension()); + } + + public static ResolvedDependencyBuilder toAppArtifact(Artifact artifact, WorkspaceModule module, + boolean preferWorkspacePaths) { + return ResolvedDependencyBuilder.newInstance() + .setWorkspaceModule(module) + .setGroupId(artifact.getGroupId()) + .setArtifactId(artifact.getArtifactId()) + .setClassifier(artifact.getClassifier()) + .setType(artifact.getExtension()) + .setVersion(artifact.getVersion()) + .setResolvedPaths(getResolvedPaths(artifact, module, preferWorkspacePaths)); + } + + public static PathCollection getResolvedPaths(Artifact artifact, WorkspaceModule module, boolean preferWorkspacePaths) { + if (preferWorkspacePaths && module != null) { + final PathList.Builder pathBuilder = PathList.builder(); + for (ProcessedSources src : module.getMainSources()) { + if (src.getDestinationDir().exists()) { + final Path p = src.getDestinationDir().toPath(); + if (!pathBuilder.contains(p)) { + pathBuilder.add(p); + } + } + } + for (ProcessedSources src : module.getMainResources()) { + if (src.getDestinationDir().exists()) { + final Path p = src.getDestinationDir().toPath(); + if (!pathBuilder.contains(p)) { + pathBuilder.add(p); + } + } + } + if (!pathBuilder.isEmpty()) { + return pathBuilder.build(); + } } - return appArtifact; + return artifact.getFile() == null ? PathList.empty() : PathList.of(artifact.getFile().toPath()); } private static String toGactv(Artifact a) { diff --git a/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/MavenArtifactResolver.java b/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/MavenArtifactResolver.java index 1837cfae184b8..19739c4be07d0 100644 --- a/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/MavenArtifactResolver.java +++ b/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/MavenArtifactResolver.java @@ -4,6 +4,7 @@ package io.quarkus.bootstrap.resolver.maven; import io.quarkus.bootstrap.model.AppArtifactKey; +import io.quarkus.bootstrap.resolver.maven.workspace.ProjectModuleResolver; import io.quarkus.bootstrap.util.PropertyUtils; import java.nio.file.Path; import java.nio.file.Paths; @@ -117,6 +118,10 @@ public MavenArtifactResolver(BootstrapMavenContext mvnSettings) throws Bootstrap this.remoteRepoManager = mvnSettings.getRemoteRepositoryManager(); } + public ProjectModuleResolver getProjectModuleResolver() { + return context.getWorkspace() == null ? null : context.getWorkspace(); + } + public BootstrapMavenContext getMavenContext() { return context; } diff --git a/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/workspace/LocalProject.java b/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/workspace/LocalProject.java index 15c1557db6863..0c3437ca8fbe7 100644 --- a/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/workspace/LocalProject.java +++ b/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/workspace/LocalProject.java @@ -5,6 +5,11 @@ import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.bootstrap.resolver.maven.BootstrapMavenContext; import io.quarkus.bootstrap.resolver.maven.BootstrapMavenException; +import io.quarkus.bootstrap.workspace.DefaultProcessedSources; +import io.quarkus.bootstrap.workspace.DefaultWorkspaceModule; +import io.quarkus.bootstrap.workspace.WorkspaceModule; +import io.quarkus.maven.dependency.GAV; +import io.quarkus.paths.PathList; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -309,4 +314,45 @@ private static String configuredBuildDir(LocalProject project, Function resources = rawModel.getBuild() == null ? Collections.emptyList() + : rawModel.getBuild().getResources(); + if (resources.isEmpty()) { + module.addMainResources(new DefaultProcessedSources( + resolveRelativeToBaseDir(null, "src/main/resources").toFile(), getClassesDir().toFile())); + } else { + for (Resource r : resources) { + module.addMainResources( + new DefaultProcessedSources(resolveRelativeToBaseDir(r.getDirectory(), "src/main/resources").toFile(), + resolveRelativeToBuildDir(r.getTargetPath(), "classes").toFile())); + } + } + } + + private void addTestResources(DefaultWorkspaceModule module) { + final List resources = rawModel.getBuild() == null ? Collections.emptyList() + : rawModel.getBuild().getTestResources(); + if (resources.isEmpty()) { + module.addTestResources(new DefaultProcessedSources( + resolveRelativeToBaseDir(null, "src/test/resources").toFile(), getTestClassesDir().toFile())); + } else { + for (Resource r : resources) { + module.addTestResources( + new DefaultProcessedSources(resolveRelativeToBaseDir(r.getDirectory(), "src/test/resources").toFile(), + resolveRelativeToBuildDir(r.getTargetPath(), "test-classes").toFile())); + } + } + } } diff --git a/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/workspace/LocalWorkspace.java b/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/workspace/LocalWorkspace.java index 34b1e417b1904..0e23ded7abfc1 100644 --- a/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/workspace/LocalWorkspace.java +++ b/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/workspace/LocalWorkspace.java @@ -4,6 +4,7 @@ import io.quarkus.bootstrap.model.AppArtifactKey; import io.quarkus.bootstrap.resolver.maven.BootstrapMavenContext; import io.quarkus.bootstrap.resolver.maven.BootstrapMavenException; +import io.quarkus.bootstrap.workspace.WorkspaceModule; import java.io.File; import java.io.IOException; import java.nio.file.Files; @@ -26,7 +27,7 @@ * * @author Alexey Loubyansky */ -public class LocalWorkspace implements WorkspaceModelResolver, WorkspaceReader { +public class LocalWorkspace implements WorkspaceModelResolver, WorkspaceReader, ProjectModuleResolver { private final Map projects = new HashMap<>(); @@ -242,4 +243,10 @@ void setCurrentProject(LocalProject currentProject) { void setBootstrapMavenContext(BootstrapMavenContext mvnCtx) { this.mvnCtx = mvnCtx; } + + @Override + public WorkspaceModule getProjectModule(String groupId, String artifactId) { + final LocalProject project = getProject(groupId, artifactId); + return project == null ? null : project.toWorkspaceModule(); + } } diff --git a/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/workspace/ModelUtils.java b/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/workspace/ModelUtils.java index 5a478fb72ffd1..14b8969a6c8fe 100644 --- a/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/workspace/ModelUtils.java +++ b/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/workspace/ModelUtils.java @@ -4,6 +4,8 @@ import io.quarkus.bootstrap.model.AppArtifactKey; import io.quarkus.bootstrap.model.AppDependency; import io.quarkus.bootstrap.util.PropertyUtils; +import io.quarkus.maven.dependency.ArtifactCoords; +import io.quarkus.maven.dependency.GACTV; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; @@ -57,8 +59,8 @@ private static Pattern getUnresolvedVersionPattern() { * @param appArtifact application artifact * @return provisioning state artifact */ - public static AppArtifact getStateArtifact(AppArtifact appArtifact) { - return new AppArtifact(appArtifact.getGroupId() + ".quarkus.curate", + public static ArtifactCoords getStateArtifact(ArtifactCoords appArtifact) { + return new GACTV(appArtifact.getGroupId() + ".quarkus.curate", appArtifact.getArtifactId(), "", "pom", diff --git a/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/workspace/ProjectModuleResolver.java b/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/workspace/ProjectModuleResolver.java new file mode 100644 index 0000000000000..14f40bda8efa7 --- /dev/null +++ b/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/workspace/ProjectModuleResolver.java @@ -0,0 +1,13 @@ +package io.quarkus.bootstrap.resolver.maven.workspace; + +import io.quarkus.bootstrap.workspace.WorkspaceModule; +import io.quarkus.maven.dependency.ArtifactKey; + +public interface ProjectModuleResolver { + + WorkspaceModule getProjectModule(String groupId, String artifactId); + + default WorkspaceModule getProjectModule(ArtifactKey key) { + return getProjectModule(key.getGroupId(), key.getArtifactId()); + } +} diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/platform/descriptor/ProjectPlatformDescriptorJsonUtil.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/platform/descriptor/ProjectPlatformDescriptorJsonUtil.java deleted file mode 100644 index d6a2801ed0c62..0000000000000 --- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/platform/descriptor/ProjectPlatformDescriptorJsonUtil.java +++ /dev/null @@ -1,103 +0,0 @@ -package io.quarkus.platform.descriptor; - -import io.quarkus.bootstrap.BootstrapConstants; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.resolver.AppModelResolver; -import io.quarkus.bootstrap.resolver.AppModelResolverException; -import io.quarkus.maven.ArtifactCoords; -import io.quarkus.maven.ArtifactKey; -import io.quarkus.registry.catalog.Category; -import io.quarkus.registry.catalog.Extension; -import io.quarkus.registry.catalog.ExtensionOrigin; -import io.quarkus.registry.catalog.json.JsonCatalogMapperHelper; -import io.quarkus.registry.catalog.json.JsonExtensionCatalog; -import io.quarkus.registry.catalog.json.JsonExtensionOrigin; -import java.io.IOException; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -public class ProjectPlatformDescriptorJsonUtil { - - public static JsonExtensionCatalog resolveCatalog(AppModelResolver resolver, List depConstraints) - throws AppModelResolverException { - final List platforms = new ArrayList<>(2); - final Set processedPlatforms = new HashSet<>(); - for (int i = 0; i < depConstraints.size(); ++i) { - final AppArtifact artifact = depConstraints.get(i); - if (!artifact.getArtifactId().endsWith(BootstrapConstants.PLATFORM_DESCRIPTOR_ARTIFACT_ID_SUFFIX) - && !artifact.getType().equals("json")) { - continue; - } - if (!processedPlatforms.add(new ArtifactKey(artifact.getGroupId(), artifact.getArtifactId(), - artifact.getClassifier(), artifact.getType()))) { - continue; - } - final Path json = resolver.resolve(artifact); - final JsonExtensionCatalog platform; - try { - platform = JsonCatalogMapperHelper.deserialize(json, JsonExtensionCatalog.class); - } catch (IOException e) { - throw new AppModelResolverException("Failed to deserialize a platform descriptor from " + json, e); - } - platform.getDerivedFrom().forEach(o -> processedPlatforms.add(ArtifactCoords.fromString(o.getId()).getKey())); - platforms.add(platform); - } - if (platforms.isEmpty()) { - return null; - } - - final List derivedFrom = new ArrayList<>(); - final List extensions = new ArrayList<>(); - final Set extensionKeys = new HashSet<>(); - final List categories = new ArrayList<>(); - final Set categoryIds = new HashSet<>(); - final Map metadata = new HashMap<>(); - - final JsonExtensionCatalog catalog = new JsonExtensionCatalog(); - catalog.setPlatform(false); - catalog.setDerivedFrom(derivedFrom); - catalog.setExtensions(extensions); - catalog.setCategories(categories); - catalog.setMetadata(metadata); - - final JsonExtensionCatalog dominatingPlatform = platforms.get(0); - catalog.setQuarkusCoreVersion(dominatingPlatform.getQuarkusCoreVersion()); - catalog.setUpstreamQuarkusCoreVersion(dominatingPlatform.getUpstreamQuarkusCoreVersion()); - - for (int i = 0; i < platforms.size(); ++i) { - final JsonExtensionCatalog platform = platforms.get(i); - if (platform.getBom() != null) { - catalog.setBom(platform.getBom()); - } - final JsonExtensionOrigin origin = new JsonExtensionOrigin(); - origin.setId(platform.getId()); - origin.setPlatform(platform.isPlatform()); - origin.setBom(platform.getBom()); - derivedFrom.add(origin); - - for (Extension e : platform.getExtensions()) { - if (extensionKeys.add(e.getArtifact().getKey())) { - extensions.add(e); - } - } - - for (Category c : platform.getCategories()) { - if (categoryIds.add(c.getId())) { - categories.add(c); - } - } - - for (Map.Entry entry : platform.getMetadata().entrySet()) { - if (!metadata.containsKey(entry.getKey())) { - metadata.put(entry.getKey(), entry.getValue()); - } - } - } - return catalog; - } -} diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/platform/tools/ToolsUtils.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/platform/tools/ToolsUtils.java index 4445cabb872c0..1c4ef029d776e 100644 --- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/platform/tools/ToolsUtils.java +++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/platform/tools/ToolsUtils.java @@ -1,12 +1,12 @@ package io.quarkus.platform.tools; import io.quarkus.bootstrap.BootstrapConstants; -import io.quarkus.bootstrap.model.AppArtifact; import io.quarkus.bootstrap.resolver.AppModelResolver; import io.quarkus.bootstrap.resolver.BootstrapAppModelResolver; import io.quarkus.bootstrap.resolver.maven.MavenArtifactResolver; import io.quarkus.devtools.messagewriter.MessageWriter; import io.quarkus.maven.ArtifactCoords; +import io.quarkus.maven.dependency.GACTV; import io.quarkus.registry.catalog.ExtensionCatalog; import io.quarkus.registry.catalog.json.JsonCatalogMapperHelper; import io.quarkus.registry.catalog.json.JsonCatalogMerger; @@ -179,8 +179,9 @@ public static ExtensionCatalog mergePlatforms(List platforms, Ap for (ArtifactCoords platform : platforms) { final Path json; try { - json = artifactResolver.resolve(new AppArtifact(platform.getGroupId(), platform.getArtifactId(), - platform.getClassifier(), platform.getType(), platform.getVersion())); + json = artifactResolver.resolve(new GACTV(platform.getGroupId(), platform.getArtifactId(), + platform.getClassifier(), platform.getType(), platform.getVersion())).getResolvedPaths() + .getSinglePath(); } catch (Exception e) { throw new RuntimeException("Failed to resolve platform descriptor " + platform, e); } diff --git a/integration-tests/gradle/src/main/resources/builder/multi-module-project/application/src/main/java/App.java b/integration-tests/gradle/src/main/resources/builder/multi-module-project/application/src/main/java/App.java new file mode 100644 index 0000000000000..e9548912c5bea --- /dev/null +++ b/integration-tests/gradle/src/main/resources/builder/multi-module-project/application/src/main/java/App.java @@ -0,0 +1,2 @@ +class App { +} \ No newline at end of file diff --git a/integration-tests/gradle/src/main/resources/builder/multi-module-project/application/src/main/resources/application.properties b/integration-tests/gradle/src/main/resources/builder/multi-module-project/application/src/main/resources/application.properties new file mode 100644 index 0000000000000..4287ca8617970 --- /dev/null +++ b/integration-tests/gradle/src/main/resources/builder/multi-module-project/application/src/main/resources/application.properties @@ -0,0 +1 @@ +# \ No newline at end of file diff --git a/integration-tests/gradle/src/main/resources/builder/multi-module-project/application/src/test/java/Test.java b/integration-tests/gradle/src/main/resources/builder/multi-module-project/application/src/test/java/Test.java new file mode 100644 index 0000000000000..96d83e0c5031a --- /dev/null +++ b/integration-tests/gradle/src/main/resources/builder/multi-module-project/application/src/test/java/Test.java @@ -0,0 +1,2 @@ +class Test { +} \ No newline at end of file diff --git a/integration-tests/gradle/src/main/resources/builder/multi-module-project/application/src/test/resources/test-resources.txt b/integration-tests/gradle/src/main/resources/builder/multi-module-project/application/src/test/resources/test-resources.txt new file mode 100644 index 0000000000000..4287ca8617970 --- /dev/null +++ b/integration-tests/gradle/src/main/resources/builder/multi-module-project/application/src/test/resources/test-resources.txt @@ -0,0 +1 @@ +# \ No newline at end of file diff --git a/integration-tests/gradle/src/main/resources/builder/multi-module-project/common/src/main/java/Common.java b/integration-tests/gradle/src/main/resources/builder/multi-module-project/common/src/main/java/Common.java new file mode 100644 index 0000000000000..c86db65d5db8f --- /dev/null +++ b/integration-tests/gradle/src/main/resources/builder/multi-module-project/common/src/main/java/Common.java @@ -0,0 +1,2 @@ +class Common { +} \ No newline at end of file diff --git a/integration-tests/gradle/src/main/resources/builder/multi-module-project/common/src/main/resources/test-resources.txt b/integration-tests/gradle/src/main/resources/builder/multi-module-project/common/src/main/resources/test-resources.txt new file mode 100644 index 0000000000000..4287ca8617970 --- /dev/null +++ b/integration-tests/gradle/src/main/resources/builder/multi-module-project/common/src/main/resources/test-resources.txt @@ -0,0 +1 @@ +# \ No newline at end of file diff --git a/integration-tests/gradle/src/main/resources/builder/multi-module-project/common/src/test/Test.java b/integration-tests/gradle/src/main/resources/builder/multi-module-project/common/src/test/Test.java new file mode 100644 index 0000000000000..96d83e0c5031a --- /dev/null +++ b/integration-tests/gradle/src/main/resources/builder/multi-module-project/common/src/test/Test.java @@ -0,0 +1,2 @@ +class Test { +} \ No newline at end of file diff --git a/integration-tests/gradle/src/test/java/io/quarkus/gradle/CustomFileSystemProviderTest.java b/integration-tests/gradle/src/test/java/io/quarkus/gradle/CustomFileSystemProviderTest.java index bca7be35082de..983a91b3d7ca0 100644 --- a/integration-tests/gradle/src/test/java/io/quarkus/gradle/CustomFileSystemProviderTest.java +++ b/integration-tests/gradle/src/test/java/io/quarkus/gradle/CustomFileSystemProviderTest.java @@ -1,5 +1,7 @@ package io.quarkus.gradle; +import static org.assertj.core.api.Assertions.assertThat; + import java.io.File; import org.junit.jupiter.api.Test; @@ -11,6 +13,7 @@ public void test() throws Exception { final File projectDir = getProjectDir("custom-filesystem-provider"); - runGradleWrapper(projectDir, "clean", ":application:test"); + BuildResult build = runGradleWrapper(projectDir, "clean", ":application:test"); + assertThat(build.getTasks().get(":application:test")).isEqualTo(BuildResult.SUCCESS_OUTCOME); } } diff --git a/integration-tests/gradle/src/test/java/io/quarkus/gradle/builder/QuarkusModelBuilderTest.java b/integration-tests/gradle/src/test/java/io/quarkus/gradle/builder/QuarkusModelBuilderTest.java index 315fa97abfb13..aa30735417aa6 100644 --- a/integration-tests/gradle/src/test/java/io/quarkus/gradle/builder/QuarkusModelBuilderTest.java +++ b/integration-tests/gradle/src/test/java/io/quarkus/gradle/builder/QuarkusModelBuilderTest.java @@ -12,59 +12,75 @@ import java.net.URL; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Collection; import java.util.Properties; import org.junit.jupiter.api.Test; -import io.quarkus.bootstrap.model.gradle.QuarkusModel; -import io.quarkus.bootstrap.model.gradle.SourceSet; -import io.quarkus.bootstrap.model.gradle.Workspace; -import io.quarkus.bootstrap.model.gradle.WorkspaceModule; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.resolver.QuarkusGradleModelFactory; +import io.quarkus.bootstrap.workspace.ProcessedSources; +import io.quarkus.bootstrap.workspace.WorkspaceModule; class QuarkusModelBuilderTest { @Test public void shouldLoadSimpleModuleModel() throws URISyntaxException, IOException { File projectDir = getResourcesProject("builder/simple-module-project"); - final QuarkusModel quarkusModel = QuarkusGradleModelFactory.create(projectDir, "TEST"); + final ApplicationModel quarkusModel = QuarkusGradleModelFactory.create(projectDir, "TEST"); assertNotNull(quarkusModel); - Workspace workspace = quarkusModel.getWorkspace(); - assertWorkspace(workspace.getMainModule(), projectDir); - assertEquals(1, quarkusModel.getWorkspace().getAllModules().size()); + assertNotNull(quarkusModel.getApplicationModule()); + assertThat(quarkusModel.getWorkspaceModules()).isEmpty(); } @Test public void shouldLoadMultiModuleModel() throws URISyntaxException, IOException { File projectDir = getResourcesProject("builder/multi-module-project"); - createFakeBuildOutput(projectDir); - final QuarkusModel quarkusModel = QuarkusGradleModelFactory.create(new File(projectDir, "application"), "TEST"); + final ApplicationModel quarkusModel = QuarkusGradleModelFactory.create(new File(projectDir, "application"), "TEST"); assertNotNull(quarkusModel); - assertEquals(2, quarkusModel.getWorkspace().getAllModules().size()); - for (WorkspaceModule module : quarkusModel.getWorkspace().getAllModules()) { - assertWorkspace(module, new File(projectDir, module.getArtifactCoords().getArtifactId())); + assertProjectModule(quarkusModel.getApplicationModule(), + new File(projectDir, quarkusModel.getApplicationModule().getId().getArtifactId()), true); + + final Collection projectModules = quarkusModel.getWorkspaceModules(); + assertEquals(projectModules.size(), 1); + for (WorkspaceModule p : projectModules) { + assertProjectModule(p, new File(projectDir, p.getId().getArtifactId()), false); } } - private void assertWorkspace(WorkspaceModule workspaceModule, File projectDir) { - assertNotNull(workspaceModule); - assertEquals(projectDir, workspaceModule.getProjectRoot()); - assertEquals(new File(projectDir, "build"), workspaceModule.getBuildDir()); - final SourceSet sourceSet = workspaceModule.getSourceSet(); - assertNotNull(sourceSet); - assertTrue(sourceSet.getResourceDirectories().isEmpty()); - assertThat(sourceSet.getSourceDirectories()).containsAnyOf( - new File(projectDir, "build/classes/java/main"), - new File(projectDir, "build/classes/java/test")); - final SourceSet sourceSourceSet = workspaceModule.getSourceSourceSet(); - assertThat(sourceSourceSet.getResourceDirectories()) - .containsAnyOf(new File(projectDir, "src/main/resources")); - assertEquals(5, sourceSourceSet.getSourceDirectories().size()); - assertThat(sourceSourceSet.getSourceDirectories()).contains(new File(projectDir, "src/main/java")); + private void assertProjectModule(WorkspaceModule projectModule, File projectDir, boolean withTests) { + assertNotNull(projectModule); + assertEquals(projectDir, projectModule.getModuleDir()); + assertEquals(new File(projectDir, "build"), projectModule.getBuildDir()); + + ProcessedSources src = projectModule.getMainSources().iterator().next(); + assertNotNull(src); + assertThat(src.getDestinationDir()).isEqualTo(new File(projectDir, "build/classes/java/main")); + assertThat(src.getSourceDir()).isEqualTo(new File(projectDir, "src/main/java")); + + src = projectModule.getMainResources().iterator().next(); + assertNotNull(src); + assertThat(src.getDestinationDir()).isEqualTo(new File(projectDir, "build/resources/main")); + assertThat(src.getSourceDir()).isEqualTo(new File(projectDir, "src/main/resources")); + + if (withTests) { + src = projectModule.getTestSources().iterator().next(); + assertNotNull(src); + assertThat(src.getDestinationDir()).isEqualTo(new File(projectDir, "build/classes/java/test")); + assertThat(src.getSourceDir()).isEqualTo(new File(projectDir, "src/test/java")); + + src = projectModule.getTestResources().iterator().next(); + assertNotNull(src); + assertThat(src.getDestinationDir()).isEqualTo(new File(projectDir, "build/resources/test")); + assertThat(src.getSourceDir()).isEqualTo(new File(projectDir, "src/test/resources")); + } else { + assertThat(projectModule.getTestSources()).isEmpty(); + assertThat(projectModule.getTestResources()).isEmpty(); + } } private File getResourcesProject(String projectName) throws URISyntaxException, IOException { @@ -84,14 +100,6 @@ private File getResourcesProject(String projectName) throws URISyntaxException, return projectDir; } - private void createFakeBuildOutput(File projectDir) { - String[] modules = new String[] { "application", "common" }; - for (String module : modules) { - new File(projectDir, module + "/build/classes/java/main").mkdirs(); - new File(projectDir, module + "/build/classes/java/main").mkdirs(); - } - } - protected String getQuarkusVersion() throws IOException { final Path curDir = Paths.get("").toAbsolutePath().normalize(); final Path gradlePropsFile = curDir.resolve("gradle.properties"); diff --git a/integration-tests/maven/src/test/java/io/quarkus/maven/it/DevMojoIT.java b/integration-tests/maven/src/test/java/io/quarkus/maven/it/DevMojoIT.java index 4305ce915e4cd..77aa35d37bbb4 100644 --- a/integration-tests/maven/src/test/java/io/quarkus/maven/it/DevMojoIT.java +++ b/integration-tests/maven/src/test/java/io/quarkus/maven/it/DevMojoIT.java @@ -488,13 +488,16 @@ public void testProjectWithExtension() throws MavenInvocationException, IOExcept .collect(Collectors.toList()); assertTrue(extDepWarnings .contains( - "[WARNING] [io.quarkus.bootstrap.devmode.DependenciesFilter] Local Quarkus extension dependency org.acme:acme-quarkus-ext will not be hot-reloadable")); + "[WARNING] [io.quarkus.bootstrap.devmode.DependenciesFilter] Local Quarkus extension dependency org.acme:acme-quarkus-ext:1.0-SNAPSHOT will not be hot-reloadable")); assertTrue(extDepWarnings .contains( - "[WARNING] [io.quarkus.bootstrap.devmode.DependenciesFilter] Local Quarkus extension dependency org.acme:acme-common will not be hot-reloadable")); + "[WARNING] [io.quarkus.bootstrap.devmode.DependenciesFilter] Local Quarkus extension dependency org.acme:acme-quarkus-ext-deployment:1.0-SNAPSHOT will not be hot-reloadable")); + assertTrue(extDepWarnings + .contains( + "[WARNING] [io.quarkus.bootstrap.devmode.DependenciesFilter] Local Quarkus extension dependency org.acme:acme-common:1.0-SNAPSHOT will not be hot-reloadable")); assertTrue(extDepWarnings.contains( - "[WARNING] [io.quarkus.bootstrap.devmode.DependenciesFilter] Local Quarkus extension dependency org.acme:acme-common-transitive will not be hot-reloadable")); - assertEquals(3, extDepWarnings.size()); + "[WARNING] [io.quarkus.bootstrap.devmode.DependenciesFilter] Local Quarkus extension dependency org.acme:acme-common-transitive:1.0-SNAPSHOT will not be hot-reloadable")); + assertEquals(4, extDepWarnings.size()); } @Test @@ -510,7 +513,7 @@ public void testRestClientCustomHeadersExtension() throws MavenInvocationExcepti .collect(Collectors.toList()); assertTrue(extDepWarnings .contains( - "[WARNING] [io.quarkus.bootstrap.devmode.DependenciesFilter] Local Quarkus extension dependency org.acme:rest-client-custom-headers will not be hot-reloadable")); + "[WARNING] [io.quarkus.bootstrap.devmode.DependenciesFilter] Local Quarkus extension dependency org.acme:rest-client-custom-headers:1.0-SNAPSHOT will not be hot-reloadable")); assertThat(DevModeTestUtils.getHttpResponse("/app/frontend")).isEqualTo("CustomValue1 CustomValue2"); } diff --git a/test-framework/jacoco/deployment/src/main/java/io/quarkus/jacoco/deployment/JacocoProcessor.java b/test-framework/jacoco/deployment/src/main/java/io/quarkus/jacoco/deployment/JacocoProcessor.java index 2f825a126f179..6bdd6abf9b20b 100644 --- a/test-framework/jacoco/deployment/src/main/java/io/quarkus/jacoco/deployment/JacocoProcessor.java +++ b/test-framework/jacoco/deployment/src/main/java/io/quarkus/jacoco/deployment/JacocoProcessor.java @@ -6,7 +6,6 @@ import java.nio.file.Paths; import java.util.Collections; import java.util.HashSet; -import java.util.Map; import java.util.Set; import java.util.function.BiFunction; @@ -16,12 +15,10 @@ import org.jacoco.core.runtime.OfflineInstrumentationAccessGenerator; import org.jboss.jandex.ClassInfo; -import io.quarkus.bootstrap.model.AppArtifactKey; -import io.quarkus.bootstrap.model.AppDependency; -import io.quarkus.bootstrap.model.gradle.QuarkusModel; -import io.quarkus.bootstrap.model.gradle.WorkspaceModule; -import io.quarkus.bootstrap.resolver.maven.workspace.LocalProject; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.utils.BuildToolHelper; +import io.quarkus.bootstrap.workspace.ProcessedSources; +import io.quarkus.bootstrap.workspace.WorkspaceModule; import io.quarkus.deployment.ApplicationArchive; import io.quarkus.deployment.IsTest; import io.quarkus.deployment.annotations.BuildProducer; @@ -36,6 +33,7 @@ import io.quarkus.jacoco.runtime.JacocoConfig; import io.quarkus.jacoco.runtime.ReportCreator; import io.quarkus.jacoco.runtime.ReportInfo; +import io.quarkus.maven.dependency.ResolvedDependency; public class JacocoProcessor { @@ -108,55 +106,45 @@ public byte[] apply(String className, byte[] bytes) { info.classFiles = classes; Set sources = new HashSet<>(); + ApplicationModel model; if (BuildToolHelper.isMavenProject(targetdir.toPath())) { - Set runtimeDeps = new HashSet<>(); - for (AppDependency i : curateOutcomeBuildItem.getEffectiveModel().getUserDependencies()) { - runtimeDeps.add(new AppArtifactKey(i.getArtifact().getGroupId(), i.getArtifact().getArtifactId())); - } - LocalProject project = LocalProject.loadWorkspace(targetdir.toPath()); - runtimeDeps.add(project.getKey()); - for (Map.Entry i : project.getWorkspace().getProjects().entrySet()) { - if (runtimeDeps.contains(i.getKey())) { - info.savedData.add(i.getValue().getOutputDir().resolve(config.dataFile).toAbsolutePath().toString()); - sources.add(i.getValue().getSourcesSourcesDir().toFile().getAbsolutePath()); - File classesDir = i.getValue().getClassesDir().toFile(); - if (classesDir.isDirectory()) { - for (final File file : FileUtils.getFiles(classesDir, includes, excludes, - true)) { - if (file.getName().endsWith(".class")) { - classes.add(file.getAbsolutePath()); - } - } - } - } - } + model = curateOutcomeBuildItem.getApplicationModel(); } else if (BuildToolHelper.isGradleProject(targetdir.toPath())) { //this seems counter productive, but we want the dev mode model and not the test model //as the test model will include the test classes that we don't want in the report - QuarkusModel model = BuildToolHelper.enableGradleAppModelForDevMode(targetdir.toPath()); - for (WorkspaceModule i : model.getWorkspace().getAllModules()) { - info.savedData.add(new File(i.getBuildDir(), config.dataFile).getAbsolutePath()); - for (File src : i.getSourceSourceSet().getSourceDirectories()) { - sources.add(src.getAbsolutePath()); - } - for (File classesDir : i.getSourceSet().getSourceDirectories()) { - if (classesDir.isDirectory()) { - for (final File file : FileUtils.getFiles(classesDir, includes, excludes, - true)) { - if (file.getName().endsWith(".class")) { - classes.add(file.getAbsolutePath()); - } - } - } - } - } + model = BuildToolHelper.enableGradleAppModelForDevMode(targetdir.toPath()); } else { throw new RuntimeException("Cannot determine project type generating Jacoco report"); } + + if (model.getApplicationModule() != null) { + addProjectModule(model.getApplicationModule(), config, info, includes, excludes, classes, sources); + } + for (ResolvedDependency d : model.getDependencies()) { + if (d.isRuntimeCp() && d.isWorkspacetModule()) { + addProjectModule(d.getWorkspaceModule(), config, info, includes, excludes, classes, sources); + } + } + info.sourceDirectories = sources; info.artifactId = buildSystemTargetBuildItem.getBaseName(); Runtime.getRuntime().addShutdownHook(new Thread(new ReportCreator(info, config))); } } + private void addProjectModule(WorkspaceModule module, JacocoConfig config, ReportInfo info, String includes, + String excludes, Set classes, Set sources) throws Exception { + info.savedData.add(new File(module.getBuildDir(), config.dataFile).getAbsolutePath()); + for (ProcessedSources src : module.getMainSources()) { + sources.add(src.getSourceDir().getAbsolutePath()); + if (src.getDestinationDir().isDirectory()) { + for (final File file : FileUtils.getFiles(src.getDestinationDir(), includes, excludes, + true)) { + if (file.getName().endsWith(".class")) { + classes.add(file.getAbsolutePath()); + } + } + } + } + } } diff --git a/test-framework/junit5-internal/src/main/java/io/quarkus/test/QuarkusDevModeTest.java b/test-framework/junit5-internal/src/main/java/io/quarkus/test/QuarkusDevModeTest.java index b038d6f9b9c1c..19a8590b5aec6 100644 --- a/test-framework/junit5-internal/src/main/java/io/quarkus/test/QuarkusDevModeTest.java +++ b/test-framework/junit5-internal/src/main/java/io/quarkus/test/QuarkusDevModeTest.java @@ -45,7 +45,6 @@ import org.junit.jupiter.api.extension.TestInstanceFactoryContext; import org.junit.jupiter.api.extension.TestInstantiationException; -import io.quarkus.bootstrap.model.AppArtifactKey; import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.bootstrap.util.ZipUtils; import io.quarkus.deployment.dev.CompilationProvider; @@ -54,6 +53,7 @@ import io.quarkus.deployment.util.FileUtil; import io.quarkus.dev.appstate.ApplicationStateNotification; import io.quarkus.dev.testing.TestScanningLock; +import io.quarkus.maven.dependency.GACT; import io.quarkus.runtime.LaunchMode; import io.quarkus.runtime.configuration.ProfileManager; import io.quarkus.runtime.util.ClassPathUtils; @@ -344,7 +344,7 @@ private DevModeContext exportArchive(Path deploymentDir, Path testSourceDir, Pat context.setCacheDir(cache.toFile()); DevModeContext.ModuleInfo.Builder moduleBuilder = new DevModeContext.ModuleInfo.Builder() - .setAppArtifactKey(AppArtifactKey.fromString("io.quarkus.test:app-under-test")) + .setArtifactKey(GACT.fromString("io.quarkus.test:app-under-test")) .setName("default") .setProjectDirectory(deploymentDir.toAbsolutePath().toString()) .setSourcePaths(PathsCollection.of(deploymentSourcePath.toAbsolutePath())) diff --git a/test-framework/junit5-internal/src/main/java/io/quarkus/test/QuarkusProdModeTest.java b/test-framework/junit5-internal/src/main/java/io/quarkus/test/QuarkusProdModeTest.java index 9b9ae5104f419..70db8686ab390 100644 --- a/test-framework/junit5-internal/src/main/java/io/quarkus/test/QuarkusProdModeTest.java +++ b/test-framework/junit5-internal/src/main/java/io/quarkus/test/QuarkusProdModeTest.java @@ -55,11 +55,10 @@ import io.quarkus.bootstrap.app.AugmentResult; import io.quarkus.bootstrap.app.CuratedApplication; import io.quarkus.bootstrap.app.QuarkusBootstrap; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppDependency; import io.quarkus.builder.BuildStep; import io.quarkus.builder.item.BuildItem; import io.quarkus.deployment.util.FileUtil; +import io.quarkus.maven.dependency.Dependency; import io.quarkus.test.common.PathTestHelper; import io.quarkus.test.common.RestAssuredURLManager; import io.quarkus.test.common.TestResourceManager; @@ -124,7 +123,7 @@ public class QuarkusProdModeTest private Optional prodModeTestResultsField = Optional.empty(); private Path logfilePath; private Optional logfileField = Optional.empty(); - private List forcedDependencies = Collections.emptyList(); + private List forcedDependencies = Collections.emptyList(); private InMemoryLogHandler inMemoryLogHandler = new InMemoryLogHandler((r) -> false); private boolean expectExit; private String startupConsoleOutput; @@ -238,7 +237,7 @@ public QuarkusProdModeTest setLogRecordPredicate(Predicate predicate) * Provides a convenient way to either add additional dependencies to the application (if it doesn't already contain a * dependency), or override a version (if the dependency already exists) */ - public QuarkusProdModeTest setForcedDependencies(List forcedDependencies) { + public QuarkusProdModeTest setForcedDependencies(List forcedDependencies) { this.forcedDependencies = forcedDependencies; return this; @@ -396,8 +395,7 @@ public void close() throws Throwable { .addExcludedPath(testLocation) .setProjectRoot(testLocation) .setTargetDirectory(buildDir) - .setForcedDependencies(forcedDependencies.stream().map(d -> new AppDependency(d, "compile")) - .collect(Collectors.toList())); + .setForcedDependencies(forcedDependencies); if (applicationName != null) { builder.setBaseName(applicationName); } diff --git a/test-framework/junit5-internal/src/main/java/io/quarkus/test/QuarkusUnitTest.java b/test-framework/junit5-internal/src/main/java/io/quarkus/test/QuarkusUnitTest.java index 463cc04bb00c6..7e387d657b0e6 100644 --- a/test-framework/junit5-internal/src/main/java/io/quarkus/test/QuarkusUnitTest.java +++ b/test-framework/junit5-internal/src/main/java/io/quarkus/test/QuarkusUnitTest.java @@ -28,7 +28,6 @@ import java.util.logging.Handler; import java.util.logging.LogManager; import java.util.logging.LogRecord; -import java.util.stream.Collectors; import org.jboss.logmanager.Logger; import org.jboss.shrinkwrap.api.ShrinkWrap; @@ -50,8 +49,6 @@ import io.quarkus.bootstrap.classloading.ClassLoaderEventListener; import io.quarkus.bootstrap.classloading.ClassPathElement; import io.quarkus.bootstrap.classloading.QuarkusClassLoader; -import io.quarkus.bootstrap.model.AppArtifact; -import io.quarkus.bootstrap.model.AppDependency; import io.quarkus.builder.BuildChainBuilder; import io.quarkus.builder.BuildContext; import io.quarkus.builder.BuildException; @@ -59,6 +56,7 @@ import io.quarkus.builder.item.BuildItem; import io.quarkus.deployment.builditem.ApplicationClassPredicateBuildItem; import io.quarkus.deployment.util.FileUtil; +import io.quarkus.maven.dependency.Dependency; import io.quarkus.runner.bootstrap.AugmentActionImpl; import io.quarkus.runner.bootstrap.StartupActionImpl; import io.quarkus.runtime.LaunchMode; @@ -107,7 +105,7 @@ public class QuarkusUnitTest private CuratedApplication curatedApplication; private RunningQuarkusApplication runningQuarkusApplication; private ClassLoader originalClassLoader; - private List forcedDependencies = Collections.emptyList(); + private List forcedDependencies = Collections.emptyList(); private boolean useSecureConnection; @@ -237,7 +235,7 @@ public QuarkusUnitTest setAfterAllCustomizer(Runnable afterAllCustomizer) { * Provides a convenient way to either add additional dependencies to the application (if it doesn't already contain a * dependency), or override a version (if the dependency already exists) */ - public QuarkusUnitTest setForcedDependencies(List forcedDependencies) { + public QuarkusUnitTest setForcedDependencies(List forcedDependencies) { this.forcedDependencies = forcedDependencies; return this; } @@ -484,8 +482,7 @@ public boolean test(String s) { .addExcludedPath(testLocation) .setProjectRoot(testLocation) .setFlatClassPath(flatClassPath) - .setForcedDependencies(forcedDependencies.stream().map(d -> new AppDependency(d, "compile")) - .collect(Collectors.toList())); + .setForcedDependencies(forcedDependencies); if (!forcedDependencies.isEmpty()) { //if we have forced dependencies we can't use the cache //as it can screw everything up diff --git a/test-framework/junit5/src/main/java/io/quarkus/test/junit/AbstractJvmQuarkusTestExtension.java b/test-framework/junit5/src/main/java/io/quarkus/test/junit/AbstractJvmQuarkusTestExtension.java index 20d39eaa8f52e..e0572ed559337 100644 --- a/test-framework/junit5/src/main/java/io/quarkus/test/junit/AbstractJvmQuarkusTestExtension.java +++ b/test-framework/junit5/src/main/java/io/quarkus/test/junit/AbstractJvmQuarkusTestExtension.java @@ -22,10 +22,9 @@ import io.quarkus.bootstrap.app.AugmentAction; import io.quarkus.bootstrap.app.CuratedApplication; import io.quarkus.bootstrap.app.QuarkusBootstrap; +import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.model.PathsCollection; -import io.quarkus.bootstrap.model.gradle.QuarkusModel; import io.quarkus.bootstrap.runner.Timing; -import io.quarkus.bootstrap.util.PathsUtils; import io.quarkus.bootstrap.utils.BuildToolHelper; import io.quarkus.deployment.dev.testing.CurrentTestApplication; import io.quarkus.runtime.configuration.ProfileManager; @@ -116,16 +115,24 @@ protected PrepareResult createAugmentor(ExtensionContext context, Class { + if (src.getDestinationDir().exists()) { + final Path classesDir = src.getDestinationDir().toPath(); + if (!rootBuilder.contains(classesDir)) { + rootBuilder.add(classesDir); + } } - } + }); + model.getApplicationModule().getMainSources().forEach(src -> { + if (src.getDestinationDir().exists()) { + final Path classesDir = src.getDestinationDir().toPath(); + if (!rootBuilder.contains(classesDir)) { + rootBuilder.add(classesDir); + } + } + }); } } else if (System.getProperty(BootstrapConstants.OUTPUT_SOURCES_DIR) != null) { final String[] sourceDirectories = System.getProperty(BootstrapConstants.OUTPUT_SOURCES_DIR).split(","); @@ -154,7 +161,7 @@ protected PrepareResult createAugmentor(ExtensionContext context, Class { + if (!src.getDestinationDir().exists()) { + final Path classes = src.getDestinationDir().toPath(); + if (!rootBuilder.contains(classes)) { + rootBuilder.add(classes); + } } - } + }); + model.getApplicationModule().getMainSources().forEach(src -> { + if (!src.getDestinationDir().exists()) { + final Path classes = src.getDestinationDir().toPath(); + if (!rootBuilder.contains(classes)) { + rootBuilder.add(classes); + } + } + }); } } else if (System.getProperty(BootstrapConstants.OUTPUT_SOURCES_DIR) != null) { final String[] sourceDirectories = System.getProperty(BootstrapConstants.OUTPUT_SOURCES_DIR).split(",");