Skip to content

Commit

Permalink
added graalpy (#2531)
Browse files Browse the repository at this point in the history
* added micronaut graalpy feature

* rename feature to Graalpy

* add packages to allow override in guide

* Add GraalPy feature

* Restrict GraalPy feature to Maven and JDK 21

---------

Co-authored-by: Sergio del Amo <[email protected]>
Co-authored-by: stepan <[email protected]>
  • Loading branch information
3 people authored Nov 8, 2024
1 parent 95bedb7 commit 9e9d864
Show file tree
Hide file tree
Showing 5 changed files with 255 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public final class MicronautDependencyUtils {
public static final String GROUP_ID_MICRONAUT_ECLIPSESTORE = "io.micronaut.eclipsestore";
public static final String GROUP_ID_MICRONAUT_GCP = "io.micronaut.gcp";
public static final String GROUP_ID_MICRONAUT_JSON_SCHEMA = "io.micronaut.jsonschema";
public static final String GROUP_ID_MICRONAUT_GRAAL_LANGUAGES = "io.micronaut.graal-languages";
public static final String GROUP_ID_MICRONAUT_KAFKA = "io.micronaut.kafka";
public static final String GROUP_ID_MICRONAUT_OCI = "io.micronaut.oraclecloud";
public static final String GROUP_ID_MICRONAUT_OPENSEARCH = "io.micronaut.opensearch";
Expand Down Expand Up @@ -227,6 +228,11 @@ public static Dependency.Builder gcpDependency() {
return micronautDependency(GROUP_ID_MICRONAUT_GCP);
}

@NonNull
public static Dependency.Builder graalLanguagesDependency() {
return micronautDependency(GROUP_ID_MICRONAUT_GRAAL_LANGUAGES);
}

@NonNull
public static Dependency.Builder jsonSchemaDependency() {
return micronautDependency(GROUP_ID_MICRONAUT_JSON_SCHEMA);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* Copyright 2017-2024 original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.micronaut.starter.feature.graallanguages;

import io.micronaut.starter.application.ApplicationType;
import io.micronaut.starter.application.generator.GeneratorContext;
import io.micronaut.starter.build.BuildProperties;
import io.micronaut.starter.build.dependencies.CoordinateResolver;
import io.micronaut.starter.build.dependencies.Dependency;
import io.micronaut.starter.build.dependencies.MicronautDependencyUtils;
import io.micronaut.starter.build.maven.MavenPlugin;
import io.micronaut.starter.feature.Category;
import io.micronaut.starter.feature.MavenSpecificFeature;
import io.micronaut.starter.feature.MinJdkFeature;
import io.micronaut.starter.feature.graallanguages.templates.graalPyMavenPlugin;
import io.micronaut.starter.options.BuildTool;
import io.micronaut.starter.options.JdkVersion;
import io.micronaut.starter.template.RockerWritable;
import jakarta.inject.Singleton;

import java.util.Collections;
import java.util.List;

@Singleton
public class Graalpy implements MinJdkFeature, MavenSpecificFeature {
public static final String NAME = "graalpy";

private static final String GROUP_ID_GRAALVM_PYTHON = "org.graalvm.python";
private static final String ARTIFACT_ID_GRAALPY_MAVEN_PLUGIN = "graalpy-maven-plugin";
private static final String ARTIFACT_ID_MICRONAUT_GRAALPY = "micronaut-graalpy";
private static final Dependency MICRONAUT_GRAALPY_DEPENDENCY = MicronautDependencyUtils.graalLanguagesDependency()
.artifactId(ARTIFACT_ID_MICRONAUT_GRAALPY)
.compile()
.build();

private final CoordinateResolver coordinateResolver;

public Graalpy(CoordinateResolver coordinateResolver) {
this.coordinateResolver = coordinateResolver;
}

@Override
public String getName() {
return NAME;
}

@Override
public String getTitle() {
return "Micronaut GraalPy Extension";
}

@Override
public String getDescription() {
return "Adds support for Python using GraalPy";
}

@Override
public boolean supports(ApplicationType applicationType) {
return true;
}

@Override
public String getCategory() {
return Category.LANGUAGES;
}

@Override
public void apply(GeneratorContext generatorContext) {
addDependencies(generatorContext);
if (generatorContext.getBuildTool() == BuildTool.MAVEN) {
addGraalPyMavenPlugin(generatorContext);
}
}

private void addGraalPyMavenPlugin(GeneratorContext generatorContext) {
BuildProperties buildProperties = generatorContext.getBuildProperties();
generatorContext.addBuildPlugin(graalpyMavenPlugin());
}

protected MavenPlugin graalpyMavenPlugin() {
return MavenPlugin.builder()
.groupId(GROUP_ID_GRAALVM_PYTHON)
.artifactId(ARTIFACT_ID_GRAALPY_MAVEN_PLUGIN)
.extension(new RockerWritable(graalPyMavenPlugin.template(pythonPackages())))
.build();
}

protected List<String> pythonPackages() {
return Collections.emptyList();
}

protected void addDependencies(GeneratorContext generatorContext) {
generatorContext.addDependency(MICRONAUT_GRAALPY_DEPENDENCY);
}

@Override
public String getThirdPartyDocumentation() {
return "https://graalvm.org/python";
}

@Override
public String getMicronautDocumentation() {
return "https://micronaut-projects.github.io/micronaut-graal-languages/latest/guide/";
}

@Override
public JdkVersion minJdk() {
return JdkVersion.JDK_21;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
@import java.util.List
@args (List<String> packages)
<!-- tag::graalpy-maven-plugin[] -->
<plugin>
<groupId>org.graalvm.python</groupId>
<artifactId>graalpy-maven-plugin</artifactId>
@if(!packages.isEmpty()) {
<configuration>
<packages>
@for (String pkg : packages) {
<package>@(pkg)</package>
}
</packages>
</configuration>
}
<executions>
<execution>
<goals>
<goal>process-graalpy-resources</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- end::graalpy-maven-plugin[] -->
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,11 @@ class FeatureSpec extends BeanContextSpec {
// because it's valid when using Spock framework too
language = Language.GROOVY
}
Options options = new Options(language, TestFramework.JUNIT, BuildTool.GRADLE, javaVersion)
def buildTool = BuildTool.GRADLE
if (feature instanceof MavenSpecificFeature) {
buildTool = BuildTool.MAVEN
}
Options options = new Options(language, TestFramework.JUNIT, buildTool, javaVersion)
List<String> features = [feature.getName()]

if (feature instanceof JAsyncSQLFeature) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package io.micronaut.starter.feature.graallaguages

import io.micronaut.starter.ApplicationContextSpec
import io.micronaut.starter.BuildBuilder
import io.micronaut.starter.application.ApplicationType
import io.micronaut.starter.build.BuildTestUtil
import io.micronaut.starter.build.BuildTestVerifier
import io.micronaut.starter.build.dependencies.Scope
import io.micronaut.starter.feature.Category
import io.micronaut.starter.feature.graallanguages.Graalpy
import io.micronaut.starter.fixture.CommandOutputFixture
import io.micronaut.starter.options.BuildTool
import io.micronaut.starter.options.JdkVersion
import io.micronaut.starter.options.Language
import io.micronaut.starter.options.Options
import io.micronaut.starter.options.TestFramework
import spock.lang.Shared
import spock.lang.Subject

class GraalpySpec extends ApplicationContextSpec implements CommandOutputFixture {

@Shared
@Subject
Graalpy micronautGraalPyFeature = beanContext.getBean(Graalpy)

void 'readme.md with feature micronaut-graalpy contains links to docs'() {
when:
Map<String, String> output = generate(ApplicationType.DEFAULT, new Options(Language.JAVA, TestFramework.JUNIT, BuildTool.MAVEN, JdkVersion.JDK_21), [Graalpy.NAME])
String readme = output["README.md"]

then:
readme
readme.contains("https://micronaut-projects.github.io/micronaut-graal-languages/latest/guide");
readme.contains("https://graalvm.org/python");
}

void "micronaut-graalpy belongs to LANGUAGES category"() {
expect:
Category.LANGUAGES == micronautGraalPyFeature.category
}

void "micronaut-graalpy supports application type = #applicationType"(ApplicationType applicationType) {
expect:
micronautGraalPyFeature.supports(applicationType)

where:
applicationType << ApplicationType.values()
}

void "micronaut-graalpy feature adds micronaut-graalpy dependency for Java and Maven "() {
when:
String template = new BuildBuilder(beanContext, BuildTool.MAVEN)
.features([Graalpy.NAME])
.language(Language.JAVA)
.render()
BuildTestVerifier verifier = BuildTestUtil.verifier(BuildTool.MAVEN, Language.JAVA, template)

then:
template
verifier.hasDependency("io.micronaut.graal-languages", "micronaut-graalpy", Scope.COMPILE)
}

void "micronaut-graalpy feature adds maven-graalvm-plugin for language=java buildTool=maven "() {
when:
String template = new BuildBuilder(beanContext, BuildTool.MAVEN)
.features([Graalpy.NAME])
.language(Language.JAVA)
.render()

then:
template
template.contains("<artifactId>graalpy-maven-plugin</artifactId>")
}

void "micronaut-graalpy feature requires java 21"() {
when:
new BuildBuilder(beanContext, BuildTool.MAVEN)
.jdkVersion(JdkVersion.JDK_17)
.features([Graalpy.NAME])
.render()

then:
IllegalArgumentException ex = thrown()
ex.message == "The selected feature graalpy requires at latest Java 21"
}

void 'test feature graalpy is only supported for Maven'() {
given:
String featureName = 'graalpy'
when:
getFeatures([featureName], new Options(Language.JAVA, TestFramework.JUNIT, BuildTool.GRADLE, JdkVersion.JDK_21))

then:
IllegalArgumentException ex = thrown()
ex.message.contains("Feature only supported by Maven")
}
}

0 comments on commit 9e9d864

Please sign in to comment.