-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
init custom gradle tooling model #10459
Conversation
&& appArtifact.getGroupId().equals(a.getModuleVersion().getId().getGroup())) { | ||
appArtifact.setPath(a.getFile().toPath()); | ||
for (io.quarkus.gradle.workspace.model.Dependency dependency : model.getAppDependencies()) { | ||
// TODO there used to be a check on appArtifact.getType() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it not available in the model?
&& appArtifact.getType().equals(a.getType()) | ||
&& appArtifact.getGroupId().equals(a.getModuleVersion().getId().getGroup())) { | ||
appArtifact.setPath(a.getFile().toPath()); | ||
for (io.quarkus.gradle.workspace.model.Dependency dependency : model.getAppDependencies()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is actually very limiting, since the scope is limited to the app model only. I'll need to check whether the devtools could be affected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you tried running the full testsuite with these changes? Or more specifically all the gradle tests including the tooling ones, such add/list extensions, create project? I'm wondering whether we should be changing this method at all. What we need to providing at the end is the AppModel and the workspace structure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I run some tests on my machine on a sample project and everything was ok. Regarding the testsuite, I still have some failures. I will revert that change as you suggest.
if (!appArtifact.isResolved()) { | ||
PathsCollection.Builder paths = PathsCollection.builder(); | ||
for (SourceSet sourceSet : model.getSourceSets()) { | ||
sourceSet.getSourceDirectories().stream().filter(File::exists).map(File::toPath).forEach(paths::add); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these java sources?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these are more BuildOutput
such as build/classes/java/main
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well actually it's not, but I will update so it points to classes and not java files
@@ -284,7 +284,8 @@ public void startDev() { | |||
StringBuilder classPathManifest = new StringBuilder(); | |||
|
|||
final AppModel appModel; | |||
final AppModelResolver modelResolver = extension().getAppModelResolver(LaunchMode.DEVELOPMENT); | |||
final QuarkusModel quarkusModel = extension().getQuarkusModel(LaunchMode.DEVELOPMENT); | |||
final AppModelResolver modelResolver = new AppModelGradleResolver(quarkusModel); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this could stay the way it was?
} | ||
|
||
final SourceSet mainSourceSet = QuarkusGradleUtils.getSourceSet(project, SourceSet.MAIN_SOURCE_SET_NAME); | ||
final SourceSet testSourceSet = QuarkusGradleUtils.getSourceSet(project, SourceSet.TEST_SOURCE_SET_NAME); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this could depend on the launch mode.
@@ -0,0 +1,13 @@ | |||
package io.quarkus.bootstrap.model; | |||
|
|||
public interface ArtifactKey { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this used anywhere else then in AppArtifactKey?
|
||
Collection<Dependency> getAppDependencies(); | ||
|
||
Collection<String> getExtensions(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this for? It looks like it also includes all the enforced platforms.
final SourceSet mainSourceSet = QuarkusGradleUtils.getSourceSet(project, SourceSet.MAIN_SOURCE_SET_NAME); | ||
final SourceSet testSourceSet = QuarkusGradleUtils.getSourceSet(project, SourceSet.TEST_SOURCE_SET_NAME); | ||
|
||
final Collection<org.gradle.api.artifacts.Dependency> platformExtension = getPlatformExtension(project); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure what platformExtension signifies here. These are application direct extension dependencies, maybe let's call it that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I agree with you
platformExtension.addAll(getExtensions(configuration.getFirstLevelModuleDependencies(), appDependencies)); | ||
} | ||
|
||
final Collection<Dependency> platformDependencies = collectExtensionDependencies(project, platformExtension); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's call them either extension dependencies or deployment dependencies.
@aloubyansky thanks for the review, I will update my branch :) |
96dc2f2
to
b4139b6
Compare
<dependency> | ||
<groupId>org.gradle</groupId> | ||
<artifactId>gradle-core-api</artifactId> | ||
<version>6.1.1</version> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't realize we'd introduce Gradle deps in the app-model. This is not a good thing. For Maven we have quarkus-bootstrap-maven-resolver
that depends on app-model and adds the Maven deps. I think we should do the same for Gradle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be getting now into the launcher JAR. Have you noticed how much bigger it becomes with the Gradle part?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, we don't need this dependency anymore, we only need the gradle-tooling-api
. But, yes I think externalizing it to a module could be a good idea.
6048110
to
8258472
Compare
4503657
to
16632d2
Compare
project.getBuildDir().getAbsoluteFile(), getSourceSourceSet(mainSourceSet), convert(mainSourceSet)); | ||
} | ||
|
||
private Set<Workspace> getAdditionalWorkspaces(Project project, String mainProjectName) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is only one workspace that may include multiple projects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I will introduce a project
or module
type to only keep one worksapce
return workspaces; | ||
} | ||
|
||
private Set<org.gradle.api.artifacts.Dependency> getDirectExtension(Project project) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method should be renamed. It's not about extensions here. All it does it collects the enforced platforms. It should reflect that in the name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 , I will rename it
Optional<Method> initAndRun = Arrays.stream(codeGenerator.getMethods()) | ||
.filter(m -> m.getName().equals(INIT_AND_RUN)) | ||
.findAny(); | ||
if (!initAndRun.isPresent()) { | ||
throw new GradleException("Failed to find " + INIT_AND_RUN + " method in " + CodeGenerator.class.getName()); | ||
} | ||
|
||
sourcesDirectories.forEach(System.out::println); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a left-over?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oupss
|
||
WorkspaceModule getMainModule(); | ||
|
||
Set<WorkspaceModule> getAllModule(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be plural, i.e. getAllModules
03fa3c6
to
a58138d
Compare
@aloubyansky, I fixed the gradle windows issue. It was a problem with the CI should be ok now :) |
bom/application/pom.xml
Outdated
@@ -201,6 +201,7 @@ | |||
<webjars-locator-core.version>0.46</webjars-locator-core.version> | |||
<log4j2-jboss-logmanager.version>1.0.0.Beta1</log4j2-jboss-logmanager.version> | |||
<avro.version>1.10.0</avro.version> | |||
<gradle-tooling.version>6.5</gradle-tooling.version> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this property could be removed from this pom. But let's see if there are other things to change in this PR first.
} | ||
appArtifact.setPaths(paths.build()); | ||
} | ||
throw new AppModelResolverException("Requested artifact does not match loaded model"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'd be good to include the conflicting artifacts into the message.
} | ||
|
||
final Set<ResolvedDependency> resolvedChildren = d.getChildren(); | ||
if (!resolvedChildren.isEmpty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had addChildExtension
and walked the whole tree because we also used to collect all the extension properties. Given that you are doing it elsewhere, I think you could have changed this if to addChildExtension && !resolvedChildren.isEmpty()
. I don't think you need firstLevel
arg in your impl.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I.e. you could have removed addChildExtension
too. We are simply collecting the first met extension dependencies but not its children.
gradlePluginPortal() | ||
} | ||
plugins { | ||
id 'io.quarkus' version '999-SNAPSHOT' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't be using specific quarkus versions in the test configs. This will break the release process.
gradlePluginPortal() | ||
} | ||
plugins { | ||
id 'io.quarkus' version '999-SNAPSHOT' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here as well.
if (Files.exists(currentPath.resolve(BuildTool.MAVEN.getBuildFile()))) { | ||
return true; | ||
} | ||
currentPath = currentPath.getParent(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you copy this from somewhere? This is not a good idea. What kind of path is expected to be passed in? Project root or any path inside a project?
A little bit better version would be checking each directory for all the recognizable build files instead of walking up to the root of the FS for each build file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes I copier that from here:
Line 217 in 42dbdd0
private static Path locateCurrentProjectPom(Path path, boolean required) throws BootstrapMavenException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, that path is derived from a class name (that is in the classes dir of a project) or is a project root.
|
||
public static QuarkusModel enableGradleAppModel(Path projectRoot, String mode) | ||
throws IOException, AppModelResolverException { | ||
if (isMavenProject(projectRoot)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If projectRoot is actually the project root we shouldn't be walking up to the root of the FS looking for the pom.xml.
public class WorkspaceImpl implements Workspace, Serializable { | ||
|
||
public ArtifactCoords mainModuleKey; | ||
public Set<WorkspaceModule> modules; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WorkspaceModuleImpl does not implement hashCode/equals. It would probably be better to have a map instead here. Also given that there is getModule(key)
Map<AppArtifactKey, AppDependency> versionMap = new HashMap<>(); | ||
model.getAppDependencies().stream().map(QuarkusModelHelper::toAppDependency).forEach(appDependency -> { | ||
userDeps.add(appDependency); | ||
versionMap.put(appArtifact.getKey(), appDependency); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you need appDependency.getArtifact().getKey() or something here.
} | ||
} | ||
} | ||
if (!userDeps.contains(appDep)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not correct. You need to be comparing the keys instead. Otherwise, you are not aligning versions here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is actually done like this in the current model, should i update it to use the appDep.getArtifact()
instead? (
quarkus/devtools/gradle/src/main/java/io/quarkus/gradle/AppModelGradleResolver.java
Line 189 in 23b3d64
if (!userDeps.contains(dependency)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, that's clearly a bug. It should be appDep.getArtifact().getKey()
@@ -4,6 +4,7 @@ plugins { | |||
|
|||
dependencies { | |||
implementation project(":runtime") | |||
implementation project(":deployment") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, applications can't depend on the deployment artifact.
@@ -168,6 +170,12 @@ private ExtensionState doJavaStart(ExtensionContext context, Class<? extends Qua | |||
rootBuilder.add(appResourcesLocation); | |||
} | |||
|
|||
Path root = Paths.get("").normalize().toAbsolutePath(); | |||
// If gradle project running directly with IDE | |||
if (System.getProperty(BootstrapConstants.SERIALIZED_APP_MODEL) == null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is this property set? I see it in exportModel
but has it been called by this point?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could already have been set by the gradle plugin in the before test
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll need a delegating impl of AppModelResolver. For now it's ok, I think.
a58138d
to
9735fad
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. We'll need to refactor some bootstrap API and setup later to have a cleaner Maven/Gradle bootstrap integration.
This branch aims to expose a custom model containing project structure. This model is generating using the gradle API.
This allows gradle users to:
Quarkus.run
(simple / multi-module)This branch closes:
@aloubyansky can you have a look? this should not evolve more (excepts with review comment and some test additions)