Giter Site home page Giter Site logo

pante / elementary Goto Github PK

View Code? Open in Web Editor NEW
36.0 4.0 5.0 1.23 MB

A suite of libraries that simplify creating and unit testing annotation processors.

License: MIT License

Java 100.00%
annotation-processors java java-11 junit5-extension junit-extension junit5 testing annotation-processor annotation-tool java-compiler

elementary's Introduction

Just your friendly neighbourhood software engineer πŸ‘€

I'm one of the co-founders of Forus Labs, having previously created & worked on TimeBloc until the application's acquisition, and Essential. I'm also currently studying at NTU.

Open Source Projects:

  • Sugar, an extension to Dart's standard library, including datetimes & timezones.
  • Chimera, a static code generation tool for generating commands in Spigot plugins.
  • Elementary, JUnit 5 extensions for testing annotation processors.
  • Readling List, a curated list of blogs/articles/papers.

I also occasionally write articles on Medium.

Pante's stats

elementary's People

Contributors

cc007 avatar dependabot-preview[bot] avatar dependabot[bot] avatar keddie avatar pante avatar renovate[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

elementary's Issues

[BUG] Repo missing in elementary/README.md

Describe the bug
The README tells me that I have to use https://repo.karuslabs.com/repository/elementary-releases, but the parent pom (com.karuslabs:elementary-project:1.1.2) references annotations-4.9.0-SNAPSHOT which is only available from https://repo.karuslabs.com/repository/chimera-snapshots.

To Reproduce
Will provide reproduction steps on request.

Expected behavior
mvn test with the sources from the https://dzone.com/articles/the-problem-with-annotation-processors article should run tests.
(It fails because is cannot find annotations-4.9.0-SNAPSHOT.jar.)

Note that there is another problem with the article: The links to the files ValidCase.java and InvalidCase.java are broken.

Environment (please complete the following information):

  • Java Version: 17
  • Platform: Gradle 5 (does not matter much I believe).

Additional context
Downloading the sources failed, with this Gradle message:

Execution failed for task ':beangen-processor:DownloadSources'.
> Could not resolve all files for configuration ':beangen-processor:downloadSources_46ce9bab-8af4-4bd4-b96f-be93fa4f8943'.
   > Could not find annotations-4.9.0-SNAPSHOT-sources.jar (com.karuslabs:annotations:4.9.0-SNAPSHOT:20210609.075259-113).
     Searched in the following locations:
         https://repo.karuslabs.com/repository/chimera-snapshots/com/karuslabs/annotations/4.9.0-SNAPSHOT/annotations-4.9.0-20210609.075259-113-sources.jar

[FEATURE REQUEST] Rename @Case to something better

Is your feature request related to a problem? Please describe.

Naming it "Case" is misleading developers into thinking that it is some case distinction (as in "cases of a switch statement").

Describe the solution you'd like

Deprecate @interface Case and add a new annotation with a better name.

Suggestions:

  • @Anchor - borrows from (old) terminology for HTML <a href="#anchor_name">, where the actual anchor is <a name="anchor_name">.
    Both syntax and terminology have been deprecated, today it woud be just the id, as in <span id="anchor_id">.
  • @Element - today's terminology for an anchor, as any HTML element can now be an anchor. The word is pretty content-less though, it's highlighting the least relevant aspect of what we're pointing to: an element inside a body of text (or code, for Elementary).
  • @CodeElement - variation of the above, but making it clearer what kind of element it's supposed to mark.
  • @Marker, @Tag - on-point terminology. Unfortunately, @Tag is also a JUnit 5 annotation.
    • Elementary.Tag, i.e. embed @interface Tag in the Elementary @interface. Now people can just import @Tag, and any who use JUnit's @Tag can still import Elementary and get @Elementary.Tag.
      The record-builder project does this to define @RecordBuilder.Include, @RecordBuilder.Options, and RecordBuilder.Template.
  • @Target or @Focus - meaning it's a point that the test will be looking at.

Just suggestions, if you have a better idea then please use that :-)

Documentation lacks sufficient setup information to prevent missing class error.

I'm using Java 21 to compile a Maven project that uses Java 17. After working around #293, I started trying to create a bare-bones test that does nothing except print things so I can get an idea of what is going on.

Ultimately I just need access to an Element for a method so I can make sure my library finds the right annotations on the method.

Inside Eclipse 2023-12 I created a unit test MyTest in src/test/java/com/example/MyTest.java (the expected location in Maven for unit tests). I started out with the most basic possible:

@ExtendWith(ToolsExtension.class)
@Introspect
public class MyTest {

  @Test
  void test() {
  }
}

Trying to run this, both in inside Eclipse and from Maven on the command line, gives:

org.junit.jupiter.api.extension.TestInstantiationException: TestInstanceFactory [com.karuslabs.elementary.junit.ToolsExtension] failed to instantiate test class [com.example.MyTest]: "com/example/MyTest.java" does not exist on the current classpath
	at java.base/java.util.Optional.orElseGet(Optional.java:364)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Caused by: java.lang.IllegalArgumentException: "com/example/MyTest.java" does not exist on the current classpath
	at com.karuslabs.elementary.file.FileObjects.ofResource(FileObjects.java:157)
	at com.karuslabs.elementary.file.FileObjects.ofClass(FileObjects.java:140)
	at com.karuslabs.elementary.file.FileObjects.scan(FileObjects.java:60)
	at com.karuslabs.elementary.junit.DaemonCompiler.of(DaemonCompiler.java:66)
	at com.karuslabs.elementary.junit.Daemon.initialize(Daemon.java:91)
	at com.karuslabs.elementary.junit.Daemon.createTestInstance(Daemon.java:68)
	at com.karuslabs.elementary.junit.ToolsExtension.createTestInstance(ToolsExtension.java:54)
	... 3 more

My guess is that it's looking for the source code of MyTest and can't find itβ€”but I can't imagine why, as it's in the standard location for unit tests.

I removed @Introspect and it crashed spectacularly:

org.junit.jupiter.api.extension.TestInstantiationException: TestInstanceFactory [com.karuslabs.elementary.junit.ToolsExtension] failed to instantiate test class [com.example.MyTest]: com.karuslabs.elementary.CompilationException: javac either crashed or failed to start.
	at java.base/java.util.Optional.orElseGet(Optional.java:364)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Caused by: java.util.concurrent.CompletionException: com.karuslabs.elementary.CompilationException: javac either crashed or failed to start.
	at java.base/java.util.concurrent.CompletableFuture.reportJoin(CompletableFuture.java:413)
	at java.base/java.util.concurrent.CompletableFuture.join(CompletableFuture.java:2118)
	at com.karuslabs.elementary.junit.DaemonCompiler.environment(DaemonCompiler.java:114)
	at com.karuslabs.elementary.junit.Daemon.initialize(Daemon.java:97)
	at com.karuslabs.elementary.junit.Daemon.createTestInstance(Daemon.java:68)
	at com.karuslabs.elementary.junit.ToolsExtension.createTestInstance(ToolsExtension.java:54)
	... 3 more
Caused by: com.karuslabs.elementary.CompilationException: javac either crashed or failed to start.
	at com.karuslabs.elementary.junit.DaemonCompiler.run(DaemonCompiler.java:99)
Caused by: java.lang.RuntimeException: java.lang.NoClassDefFoundError: com/karuslabs/utilitary/type/TypeMirrors
	at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.invocationHelper(JavacTaskImpl.java:168)
	at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:100)
	at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:94)
	at com.karuslabs.elementary.Compiler.compile(Compiler.java:98)
	at com.karuslabs.elementary.junit.DaemonCompiler.run(DaemonCompiler.java:96)
Caused by: java.lang.NoClassDefFoundError: com/karuslabs/utilitary/type/TypeMirrors
	at com.karuslabs.elementary.junit.DaemonCompiler$Environment.<init>(DaemonCompiler.java:187)
	at com.karuslabs.elementary.junit.DaemonCompiler$DaemonProcessor.process(DaemonCompiler.java:148)
	at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:1023)
	at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:939)
	at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1267)
	at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1382)
	at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1234)
	at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:916)
	at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.lambda$doCall$0(JavacTaskImpl.java:104)
	at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.invocationHelper(JavacTaskImpl.java:152)
	... 4 more
Caused by: java.lang.ClassNotFoundException: com.karuslabs.utilitary.type.TypeMirrors
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
	... 14 more

I hope I'm missing something simple. This library seemed to have so much potential.

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/build.yaml
  • actions/checkout v4
  • actions/setup-java v4
.github/workflows/deploy_maven_central.yaml
  • actions/checkout v4
  • actions/setup-java v4
.github/workflows/label_pr.yaml
  • actions/labeler v5
maven
elementary/pom.xml
  • com.karuslabs:elementary-project 2.0.1
  • org.apache.maven.plugins:maven-resources-plugin 3.3.1
pom.xml
  • org.junit:junit-bom 5.10.2
  • org.mockito:mockito-bom 5.11.0
  • org.checkerframework:checker-qual 3.42.0
  • org.apache.maven.plugins:maven-compiler-plugin 3.13.0
  • org.apache.maven.plugins:maven-surefire-plugin 3.2.5
  • org.apache.maven.plugins:maven-checkstyle-plugin 3.3.1
  • com.puppycrawl.tools:checkstyle 10.15.0
  • org.apache.maven.plugins:maven-shade-plugin 3.5.3
  • org.jacoco:jacoco-maven-plugin 0.8.12
  • org.apache.maven.plugins:maven-source-plugin 3.3.1
  • org.apache.maven.plugins:maven-javadoc-plugin 3.6.3
  • org.apache.maven.plugins:maven-deploy-plugin 3.1.2
  • org.jreleaser:jreleaser-maven-plugin 1.11.0
  • org.apache.maven.plugins:maven-site-plugin 3.12.1
  • org.apache.maven.wagon:wagon-webdav-jackrabbit 3.5.3
satisfactory/pom.xml
  • com.karuslabs:elementary-project 2.0.1
  • org.jgrapht:jgrapht-core 1.5.2
  • org.apache.maven.plugins:maven-compiler-plugin 3.13.0
  • org.apache.maven.plugins:maven-resources-plugin 3.3.1
utilitary-itest/pom.xml
  • com.karuslabs:elementary-project 2.0.1
  • org.apache.maven.plugins:maven-resources-plugin 3.3.1
utilitary/pom.xml
  • com.karuslabs:elementary-project 2.0.1
  • org.apache.maven.plugins:maven-resources-plugin 3.3.1
maven-wrapper
.mvn/wrapper/maven-wrapper.properties
  • maven 3.9.6

  • Check this box to trigger a request for Renovate to run again on this repository

[BUG] Cannot use source with intentional compile errors for ToolsExtension

Describe the bug
Compiler errors will make ToolsExtension believe that the compiler didn't start, failing the test run.

To Reproduce
Set up a test class with @ExtendWith(ToolsExtension.class) and feed it source code that makes the annotation processor report errors.
The test run will fail, with the somewhat misleading message Failed to start javac (javac actually runs, it merely returns a compilation error)

Expected behavior

DaemonCompiler.run should not throw a CompilationException. (Though it's weird that the test will hang indefinitely if I make the Results object a success to prevent the run() function from throwing that exception. I didn't look deeper at what's happening there.)

I also have been hoping that the Java compiler will return a best-effort AST if it hits compilation errors, and that I can inspect it.
Maybe that hope was misguided though and you can't use ToolsExtension with intentionally-failing Java code.

[BUG] `MemoryFileManager ` does not handle modules correctly

Copied from: #147

Describe alternatives you've considered
Using the @Options annotation, but this leads to bugs for now.

Additional context
The bug I'm referring to has to do with the MemoryFileManager (line 59):

static URI of(Location location, String type, Kind kind) {
    return URI.create("mem:///" + location.getName() + "/" + type.replace('.', '/') + kind.extension);
}

This method throws an error if the location.getName() contains illegal URI characters (which it does in the case of modules, namely [ and ]).

[FEATURE REQUEST] Primitives for Module support

Is your feature request related to a problem? Please describe.
This issue discusses how to add low-level support for modules. This excludes anything in com.elementary.junit.*. High-level/user-facing changes is tracked in #147.

At the moment, Compiler and DaemonCompiler does not look at the module-path while compiling files. This causes files to be missing from compilation when using the @Introspect annotation in a project that uses modules.

At the moment Compiler has no concept of modules. All it does is accept a list of files and outputs the results of compiling said files. We need some mechanism of traversing the modules, and adding all files in those modules. However, how will this affect performance? Traversing all modules that the current module relies on doesn't sound cheap.

In the initial prototype, we accessed the classes by getting the module of the test class and subsequently traversing through them:

    public static DaemonCompiler of(Class<?> annotated) {
        var module = annotated.getModule();
        if (module.isNamed()) {
            var modules = module.getLayer().modules();
            // traverse modules and add to classpath
        }
        return of(scan(annotated));
    }

If done correctly, we might not need to expose annotations to use modules since it's done automatically.

Requires `org.junit.jupiter:junit-jupiter-params`.

I'm using Java 21 to compile a Maven project that uses Java 17. The Elementary documentation doesn't make clear that the org.junit.jupiter:junit-jupiter-params dependency is required. I tried following the example in a unit test, and it wouldn't build:

The type org.junit.jupiter.params.support.AnnotationConsumer cannot be resolved. It is indirectly referenced from required type com.karuslabs.elementary.junit.ToolsExtension …

I tried adding a dependency to org.junit.jupiter:junit-jupiter-api (which I thought I was including transitively anyway by using JUnit), but that didn't help.

I had to add the following to my POM to make this error go away:

<dependency>
  <groupId>org.junit.jupiter</groupId>
  <artifactId>junit-jupiter-params</artifactId>
  <scope>test</scope>
</dependency>

This needs to be added to the documentation. Perhaps you could also explain why this is needed, and why the library doesn't refer to it transitively already.

Your .dependabot/config.yml contained invalid details

Dependabot encountered the following error when parsing your .dependabot/config.yml:

The property '#/update_configs/0/update_schedule' value "live" did not match one of the following values: daily, weekly, monthly

Please update the config file to conform with Dependabot's specification using our docs and online validator.

[FEATURE REQUEST] Auto-format pull requests

Is your feature request related to a problem? Please describe.
Our code convention differs from most other projects. There will be less burden on both the reviewer and reviewee's sides if the code is automatically formatted before review.

Describe the solution you'd like
Set-up https://github.com/diffplug/spotless/tree/main/plugin-maven#java or some other auto-formatting tool as part of the project's CI/CD.

Describe alternatives you've considered
Continue manually formatting pull requests which generates more churn.

Documentation examples require Utilitary.

The examples in the documentation seem to assume that Utilitary is being included as a dependency (e.g. com.karuslabs.utilitary.type.TypeMirrors is imported), but nothing in the documentation indicates that I should have added com.karuslabs:utilitary as a dependency. I'm left wondering why the code copied from the documentation doesn't compile, and then I have to do Maven searches to find out where to get those classes.

The documentation should be updated to indicate that Utilitary is required.

<dependency>
  <groupId>com.karuslabs</groupId>
  <artifactId>utilitary</artifactId>
  <version>2.0.0</version>
  <scope>test</scope>
</dependency>

[FEATURE REQUEST] First-class module support in JUnit extensions

Is your feature request related to a problem? Please describe.
Right now it's a pain to configure the elementary compiler to run the test on a full module.

Describe the solution you'd like
Annotations specific to loading modules, like @Module, @ModulePath, @ModuleSourcePath (and @ProcessorPath would also be useful)

Describe alternatives you've considered
Using the @Options annotation, but this leads to bugs for now.

Additional context
The bug I'm referring to has to do with the MemoryFileManager (line 59):

static URI of(Location location, String type, Kind kind) {
    return URI.create("mem:///" + location.getName() + "/" + type.replace('.', '/') + kind.extension);
}

This method throws an error if the location.getName() contains illegal URI characters (which it does in the case of modules, namely [ and ]).

Deploy artifacts to maven central

Describe the bug

It seems version 1.1.2 on https://repo.karuslabs.com/ was re-uploaded with a new version - the files in my Gradle cache diverge from those on the Karuslabs repository; I am seeing differences in elementary, elementary-project, satisfactory, and there may be more.

This is going to throw off all build tools that depend on that repository; e.g. Maven will not re-download anything unless explicitly instructed to, while Gradle will delete unused files after (typically) 7 days of non-use and re-download them later.
I.e. depending on the caching specifics of any build tool, people will see some old version, or a new version, or a mixture of old and new; and they will see different artifacts from different versions of 1.1.2 depending on download history.

A screenshot that shows my Gradle cache (which happens to use the SHA1 hashes as directory names):
grafik

Expected behavior

Once a version is uploaded to a Maven repository, it is there for eternity; any modified uploads must use a new version number.

As an exception and as a last resort, one can delete an artifact version from a Maven repository. This can be necessary if a version accidentally contains passwords, private SSH keys, GDPR data, or trade secrets.

Suggestion

Publish your Maven artifacts to Maven Central.
This prevents not just overwrites, but also supply-chain attacks like "hack into https://repo.karuslabs.com/ and insert malware into the .jar files".

[BUG] com.karuslabs:satisfactory 1.1.3 is not available

Describe the bug
While trying to import the project, I noticed that the version 1.1.3 of satisfactory is not available

To Reproduce
Steps to reproduce the behavior:

  1. Navigate to: https://repo.karuslabs.com/#browse/browse:elementary-releases:com%2Fkaruslabs%2Fsatisfactory
  2. Confirm that the last version is 1.1.2

Expected behavior
I was expecting to see the last version of satisfactory to be aligned with all the other version given that this version is found on the README.

Screenshots

image

Environment (please complete the following information):

  • Java Version 17

Additional context
N/A

[BUG] `java.nio.file.FileSystemNotFoundException: Provider "mem" not installed`

Describe the bug
If an extension processor calls toURI on a FileObject, a FileSystemNotFoundException is thrown.

To Reproduce

Code like the following, in an extension processor under test, will show the problem:

   final Filer filer = processingEnv.getFiler();
   final FileObject tempResource;
            tempResource = filer.createResource("some_location", Constants.EMPTY, "some.tmp");
   final URI uri = tempResource.toUri();

A java.nio.file.FileSystemNotFoundException: Provider "mem" not installed exception will be thrown.

I'm able to work around the problem by writing a custom file system, and a custom file system provider, and registering it with the service loader:

image

However, it's
(a) a lot of boilerplate just to write some annotation processor tests; it feels like the Elementary codebase would be a more logical place for this test infrastructure code.
(b) not actually connected to the in-memory files created by the Elementary Filer. So far, nothing broke because of that, but it would be better if the mem: scheme didn't have a split-brain.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.