remkop / picocli

Picocli is a modern framework for building powerful, user-friendly, GraalVM-enabled command line apps with ease. It supports colors, autocompletion, subcommands, and more. In 1 source file so apps can include as source & avoid adding a dependency. Written in Java, usable from Groovy, Kotlin, Scala, etc.
https://picocli.info
Apache License 2.0
4.87k stars 419 forks source link

Dynamic version from Maven with GraalVM #2018

Open delanym opened 1 year ago

delanym commented 1 year ago

hi. How can I use the Maven version when compiling on GraalVM?

Noted: https://github.com/remkop/picocli/issues/850#issuecomment-548993798

My current approach doesn't work with GraalVM. When I run the executable with -V there is no output and no error.

@CommandLine.Command(
    versionProvider = CommandLineInterface.ManifestVersionProvider.class,
    //    version = "1.0.0-SNAPSHOT",
    name = "raes2zip",
    mixinStandardHelpOptions = true)
public class CommandLineInterface implements Callable<Integer> {

...

static class ManifestVersionProvider implements CommandLine.IVersionProvider {

    public String[] getVersion() throws Exception {
      Enumeration<URL> resources =
          CommandLine.class.getClassLoader().getResources("META-INF/MANIFEST.MF");
      while (resources.hasMoreElements()) {
        URL url = resources.nextElement();
        try {
          Manifest manifest = new Manifest(url.openStream());
          if (isApplicableManifest(manifest)) {
            Attributes attr = manifest.getMainAttributes();
            return new String[] {
              get(attr, "Implementation-Title")
                  + " version \""
                  + get(attr, "Implementation-Version")
                  + "\""
            };
          }
        } catch (IOException ex) {
          return new String[] {"Unable to read from " + url + ": " + ex};
        }
      }
      return new String[0];
    }

    private boolean isApplicableManifest(Manifest manifest) {
      Attributes attributes = manifest.getMainAttributes();
      return "raes2zip".equals(get(attributes, "Implementation-Title"));
    }

    private static Object get(Attributes attributes, String key) {
      return attributes.get(new Attributes.Name(key));
    }
  }
remkop commented 1 year ago

Did you ensure that the META-INF/MANIFEST.MF resource is included in the executable?

The annotation processor includes the resource bundle specified in the @Command annotation; See https://github.com/remkop/picocli/tree/main/picocli-codegen#generate-graalvm-configurations-with-the-annotation-processor,

But the manifest file is not included by default.

See https://github.com/remkop/picocli/tree/main/picocli-codegen#resourceconfiggenerator for manually generating the necessary GraalVM configuration file.

The --pattern option can be used to specify Java regular expressions that match additional resource(s) to be included in the image.

remkop commented 1 year ago

Also, I would recommend adding some debug tracing to your version provider implementation (using picocli's Tracing API), to help you zoom in to the cause of the issue.

remkop commented 1 year ago

@delanym Did you have a chance to investigate my suggestions?

delanym commented 1 year ago

Hi @remko. I haven't yet - still intend to. Feel free to close. Thank you for answering

On Sun, 27 Aug 2023, 10:30 Remko Popma, @.***> wrote:

@delanym https://github.com/delanym Did you have a chance to investigate my suggestions?

— Reply to this email directly, view it on GitHub https://github.com/remkop/picocli/issues/2018#issuecomment-1694606058, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABIQOHS6EZRUAPFSPH4PPN3XXMAS7ANCNFSM6AAAAAAXWYZ4N4 . You are receiving this because you were mentioned.Message ID: @.***>