Support alternative markup for Apache Maven POM files

Overview

Overview

Polyglot for Maven is a set of extensions for Maven 3.3.1+ that allows the POM model to be written in dialects other than XML. Several of the dialects also allow inlined plugins: the Ruby, Groovy and Scala dialects allow this.

License

Maven Central

Takari Slack

Here's an example POM written in the Ruby dialect:

project 'Polyglot :: Aggregator' do

  model_version '4.0.0'
  id 'io.tesla.polyglot:tesla-polyglot:0.0.1-SNAPSHOT'
  inherit 'io.tesla:tesla:4'
  packaging 'pom'

  properties( 'sisuInjectVersion' => '0.0.0.M2a',
              'teslaVersion' => '3.1.0' )

  modules [ 'tesla-polyglot-common',
            'tesla-polyglot-atom',
            'tesla-polyglot-ruby',
            'tesla-polyglot-groovy',
            'tesla-polyglot-yaml',
            'tesla-polyglot-clojure',
            'tesla-polyglot-scala',
            'tesla-polyglot-java',
            'tesla-polyglot-xml',
            'tesla-polyglot-cli',
            'tesla-polyglot-maven-plugin' ]

  overrides do
    jar 'org.eclipse.sisu:org.eclipse.sisu.inject:${sisuInjectVersion}'
    jar 'org.eclipse.sisu:org.eclipse.sisu.plexus:${sisuInjectVersion}'
    jar 'org.apache.maven:maven-model-builder:3.1.0'
    jar 'org.apache.maven:maven-embedder:3.1.0'
    jar( 'junit:junit:4.11', :scope => 'test' )

  end

  plugin 'org.codehaus.plexus:plexus-component-metadata:1.5.4' do
    execute_goals 'generate-metadata', 'generate-test-metadata'
  end

  build do
    execute("first", :validate) do |context|
      puts "Hello from JRuby!"
    end
  end
end

Requirements

Usage

To use Polyglot for Maven you need to edit ${maven.multiModuleProjectDirectory}/.mvn/extensions.xml and add the appropriate language extension.

The scala dialect supports a separate configuration parameter polyglot.scala.outputdir to specify a different output directory. This avoids the deletion during a Maven clean phase run, when set to a different folder such as .polyglot-cache instead of the default target. Inspect polyglot-maven-examples/scala/.mvn/maven.config for an example setup.

Available Languages

The available languages, in alphabetical order, with their artifact id are:

Language Artifact Id
Atom polyglot-atom
Groovy polyglot-groovy
Clojure polyglot-clojure
Kotlin polyglot-kotlin
Ruby polyglot-ruby
Scala polyglot-scala
YAML polyglot-yaml
Java polyglot-java
XML polyglot-xml

The groupId value is io.takari.polyglot.

Update extensions.xml

Edit the extensions.xml file and add the following, replacing ARTIFACTID with the artifactId for your chosen language.

<?xml version="1.0" encoding="UTF-8"?>
<extensions>
  <extension>
    <groupId>io.takari.polyglot</groupId>
    <artifactId>ARTIFACTID</artifactId>
    <version>0.4.6</version>
  </extension>
</extensions>

Convert existing POM

We have created a simple Maven plugin that will help you convert any existing pom.xml files:

mvn io.takari.polyglot:polyglot-translate-plugin:translate \
  -Dinput=pom.xml -Doutput=pom.{format}

Where the supported formats are rb, groovy, scala, yaml, atom, java and of course xml. See here for more info. You can even convert back to xml or cross-convert between all supported formats.

Known Limitations and Issues

Interoperability

The whole interoperability story has not been worked out but you can create a XML-formatted POM from the Polyglot version. Currently mixing different dialects within a reactor is not supported.

A pom.xml will currently not be installed or deployed except for the Ruby DSL and the Scala DSL but we are working towards this feature for all DSLs.

Tooling

Some support in IDE's like IntelliJ IDEA and Eclipse exist and the different markup languages are understood by various syntax highlighters. However, full integration of the markup syntax and the specific Maven-related aspects is not available.

Limited Plugin Support

Maven plugins or Maven plugin goals that rely on the XML format are not supported, since they are either attempting to parse the XML directly or modify it in automated fashion do not work with Polyglot Maven. Examples are:

  • Maven Release Plugin
  • Maven Versions Plugin (goals that don't edit the pom.xml (like e.g. display-dependency-updates) work as expected though)

Fixes would have to be implemented in these plugins. Workarounds or replacement workflows for most usecases exist.

Polyglot Maven in Real Life

Despite the warning above, Polyglot Maven is pretty stable right now. Have a look at the integration tests for each dialect in this repository for some examples as well as our dedicated polyglot-maven-examples project.

Some dialect folder contain specific README files with futher instructions as as test code with example projects and more. Ensure to check the ones for your specific dialect out as well.

The following projects are real world usage examples that use Polyglot Maven in their regular development and release work:

Kotlin

Specific docs and more can be found in the Kotlin dialect specific readme.

Ruby

YAML

  • http://snakeyaml.org - Extensive usage of Polyglot YAML and contributions to the project from the team.

  • https://urbanise.com - Using Polyglot YAML for building next generation strata management platform.

Scala

Java Projects

  • LambdaTest - A simple Java project with a standalone pom.scala

  • CmdOption - A Java project with a top-level reactor project and an additional shared scala file included into both pom.scalas

Scala Projects

  • Domino - A simple project using Polyglot Scala.

  • Blended - A complex multi-project using Polyglot Scala. It's also an example where the #include feature is heavily used to share common configuration but avoid Maven parent poms, which are often problematic.

Please let us know of your usage by filing an issue so we can add it here.

Comments
  • Fix #50: add support for scope blocks

    Fix #50: add support for scope blocks

    This new change introduces scope blocks, that make it cleaner to list/group dependencies, like:

    project {
       modelVersion '4.0.0'
       groupId 'foo.bar'
       artifactId 'example'
       version '0.0.1-SNAPSHOT'
       dependencies {
          $test { //junit and mockito get the test scope
              dependency 'junit:junit:4.12'
              dependency 'org.mockito:mockito-core:1.10.19'
          }
          $compile {//list all compile scoped dependencies here
              dependency 'foo:bar:x.y.z'
              ...
           }
           dependency 'a:b:1.0.0' //also compile  scope
            ...
        } 
     }
    

    The following scoped blocks are supported:

    • $compile {...}
    • $import {...}
    • $test {...}
    • $provided{...}
    • $runtime {...}
    • $system {...}

    In the current implementation, dependencies can overwrite the outer scope like

    $provided {
        'foo:bar:x.y.z:test' //will have the test scope
    }
    

    Signed-off-by: Fred Bricon [email protected]

    enhancement groovy 
    opened by fbricon 28
  • polyglot-scala: Scala syntax friendly include preprocessor

    polyglot-scala: Scala syntax friendly include preprocessor

    This change adds an alternative preprocessor directive to the scala dialect.

    In addition to #include <file>, now also //##include <file> is supported. The motivation behind this is, to improve the editing experience. The latter added version produces syntax-correct scala files, which in turn improves editors and IDEs, e.g. parsing, formatting and highlighting. The former version does not.

    The unusual long prefix //## was choosen, to avoid confusion with a possibly commented out include (e.g. // #include).

    Also, this change adds a hint how to debug the pom.scala script to the error message in case of a compile error.

    opened by lefou 18
  • Getting

    Getting "Input contained no data" on Maven 3.6.2

    After upgrading to Maven 3.6.2, all my builds that use polyglot-maven get an error like the following:

    [FATAL] Non-readable POM /.../.polyglot.pom.kt: input contained no data @ 
    

    To determine whether this was language-specific I've translated a pom.xml to ruby, groovy, and kotlin, and all of of them get the same error on Maven 3.6.2: "input contained no data".

    I suspect this may be a bug in Maven due to the nature of the changes described in the release notes, but in my testing I've so far been unable to determine the exact cause of the failure.

    I upgraded my cloned copy of polyglot-maven to Maven 3.6.2 and tests that were previously passing are now failing due to an inability to find some required components, but that might be a separate issue.

    opened by thorntonrp 17
  • Hardened used pathes for #include preprocessor in scala files

    Hardened used pathes for #include preprocessor in scala files

    By using Twitters eval util, we also derive it's #include preprocessor, which by default is a bit unexact when it comes to potential source locations for includable files. Also the include path is unstable when Maven is run in (multi-project) reactor builds.

    This patch removes the ambiguities and also makes include pathes more stable when run in reactor builds.

    opened by lefou 16
  • Release Plugin

    Release Plugin

    I'm wondering how the POM manipulations that the release plugin does could work on a polyglot maven POM. Wouldn't this require a major update to the release plugin, so it provides hooks the polyglot extensions can use to do the actual changes? Or is it feasible to reverse-engineer the changes the plugin did and re-apply those to the polyglot model? If the version is somehow derived or stored in a custom manner, these hooks would have to be passed to the model code, so e.g. a groovy script can update that source.

    I'm writing this, because I have the exactly this problem with my pomx project and I'm wondering if you have already have some concept for this. I didn't find any.

    opened by t1 15
  • Added alternative translate-project goal

    Added alternative translate-project goal

    The motivation behind this second goal is to avoid inconveniences with the 'translate' goal, which works on the complete reactor but does not handle errors well.

    With this goal, the user can control in detail which projects should be translated and how errors are handled with the known mvn commandline options (e.g.: -N, -pl, -am, -amd, -fae)

    opened by lefou 15
  • Polyglot Kotlin with complete Maven model support and other goodies

    Polyglot Kotlin with complete Maven model support and other goodies

    This pull request leverages the previous work that was done and re-worked it to support the complete Maven model as well as the following features:

    • Updates Kotlin to 1.3.21
    • Full Maven model support (including support for previously unsupported elements)
    • Gets the classpath for the Kotlin script engine from the Maven ClassRealm
    • Includes support for execute tasks both with inline lambdas and external scripts.
    • Unit tests provide 100% coverage for the Maven model.
    • Adds integration tests
    • Resolves ClassRealm issues that affected IntelliJ IDEA
    opened by thorntonrp 14
  • .tesla.xxx.pom issues

    .tesla.xxx.pom issues

    As of commit bfc16c7, the creation of a .tesla.xxx.pom poses some new issues:

    • developers will be expected to have their scm ignore .tesla* files;
    • the encoding of a model to xml consumes more time vs using an xml directly; and most importantly
    • the encoded .tesla.xxx.pom must conform to any restrictions imposed on the pom it was produced from.

    I'm particularly concerned about the restriction conformance. For example on the tesla modules, the poms must have license headers. Generated poms do have such headers of course.

    The approach of generating a .tesla.xxx.pom is concerning. According to commit bfc16c7 it is because the install plugin requires a pom.xml to deploy. Perhaps there's another way to approach this e.g. have a translate occur as part of the install plugin and reference the updated install plugin as part of the tesla build. The pom.xxx file should also be installed alongside any pom.xml. This approach would also require pom.xxx files to have a higher priority than pom.xml (which I think is a good thing anyhow).

    opened by huntc 14
  • Use the improved Kotlin scripting implementation instead of JSR-223 ScriptEngine

    Use the improved Kotlin scripting implementation instead of JSR-223 ScriptEngine

    The current polyglot-kotlin implementation uses a JSR-223 ScriptEngine to evaluate the pom.kts file. Since Kotlin 1.3.x the scripting support was improved by using a dedicated scripting host. For details see this KEEP: https://github.com/Kotlin/KEEP/blob/scripting/proposals/scripting-support.md.

    In this PR I re-implemented the script evaluation for Kotlin to use the new scripting host. In the future JetBrains will add support to their IDE which will enable auto-completion support and syntax checking for the pom.kts script similiar to Gradle Kotlin scripts.

    I also fixed the integration test which referred to an older (non-existing) SNAPSHOT of the polyglot-kotlin core extension. Oddly enough the integration does pass when building because there is also a very basic pom.xml in the integration test which does build (I think having a pom.xml is required for the maven-invoker-plugin to work).

    Note that I removed the bindings for the MavenProject, MavenSession and Log classes. This is now impossible to implement because they are not (yet) available when building the Model the first time in the KotlinModelReader class. Initially I added them to the DSL class but Kotlin requires non-null instances of those classes which caused the compilation to fail. I've also tried to inject them using the Plexus container but for example the MavenProject is not available in the KotlinModelReader because the latter is used to create the MavenProject instance. To be honest I don't see why you would want to expose these instances in the Kotlin build script anyway, for me it feels like a smell. But please feel free to elaborate.

    opened by lion7 13
  • Support for maven-tiles; trying out `<extensions>true</extensions>` and multiple entries inside `<configuration>` by @talios

    Support for maven-tiles; trying out `true` and multiple entries inside `` by @talios

    maven-tiles https://github.com/repaint-io/maven-tiles allows to have parts of build definition in separate files. Having part of build in parts can enable quicker adoption of polyglot thinking, and skip problem of having to translate parts, e.g. when find an example of plugin configuration.

    Possibly this issue should sound like "support translating parts of pom"

    ref https://github.com/repaint-io/maven-tiles/issues/61

    opened by paulvi 13
  • Get GHA working on master

    Get GHA working on master

    I tried this for the first time, and it appears that the scala module is having issues.

    @mosabua is the scala module been having issues lately?

    My suggestion would be to put each of the modules that are not working on their own branch, and if anyone wants to tackle fixing them up they can.

    opened by jvanzyl 11
  • Bump snakeyaml from 1.17 to 1.32 in /polyglot-yaml

    Bump snakeyaml from 1.17 to 1.32 in /polyglot-yaml

    Bumps snakeyaml from 1.17 to 1.32.

    Commits
    • b8239ec Add warning about untrusted data on landing page
    • 2853420 Merge remote-tracking branch 'origin/master'
    • 4b3d996 Merged master into format-2
    • 4081e08 Reformat with IntelliJ
    • 0305c04 Reformat tests with IntelliJ
    • fedd984 Reformat with IntelliJ
    • e5985fa Reformat tests with IntelliJ
    • ebad791 Move formatting to Maven profile
    • 72dfa9f Set the limit for incoming data to prevent a CVE report in NIST
    • 5e56066 Improve error message for too big document
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • [YAML] Implement JSON schema

    [YAML] Implement JSON schema

    There is a schema description language for json and thus also yaml: http://json-schema.org/ Plus a public repository of community schemas: https://www.schemastore.org/

    IntelliJ IDEA even automatically picks this up. If there was one for pom.yml, we would get basic autocompletion and documentation inside the IDE.

    Anyone willing to give it a try for polyglot Maven pom.yml? :-)

    opened by dragetd 0
  • [YAML] [Structure] Alternative String form for dependencies

    [YAML] [Structure] Alternative String form for dependencies

    When defining dependencies, they are a dictionary with the different fields expected by maven. So far, so good. The examples use the flow-style of YAML to reduce the number of lines:

    https://github.com/takari/polyglot-maven/blob/master/poms/pom.yml#L37

    The flow-style is not that common in YAML. Even tho officially specified (https://yaml.org/spec/1.2.2/#chapter-7-flow-style-productions), people sometimes get confused about it. An example would be https://github.com/takari/polyglot-maven/issues/175 . It also resembles somewhat JSON without being JSON, which is even more confusing with the relation of YAML<->JSON.

    This is also the reasoning why the library 'strictyaml' forbids the usage of the flow-style. (Note: Flow-style is only curly braces, the squared braces of arrays are fine). See https://hitchdev.com/strictyaml/why/flow-style-removed/

    My suggestions would be:

    • Allow the node 'dependencies' to be either an array of dictionaries with the different fields as is, or with a string-field 'id' that represents the coordinates of the dependency.
    • This field is parsed by splitting it on every colon, expecting two or three elements representing the coordinates (group and artifactID, optional version)

    This would allow allow specifying dependencies like this

    dependencies:
      - id: "org.springframework.boot:spring-boot-starter-web"
      - id: "org.mapstruct:mapstruct:1.4.2.Final"
    

    which is not only cleaner and without the flow-style, but also has some resemblance to Gradle. Things like scope would still need an extra line.

    Some open questions are what happens if 'id' and the original fields are defined, but I think we could just choose one default behavior and document it.

    Alternative ideas:

    • encode possible extra settings completely in the string. The 'depencencies' array would then be an array of strings. But with optional fields, this is not very intuitive to add them to the coordinates. Also, with things like excludes, there is no canonical mapping. And when the array just has strings, then all elements would have to be strings. I do not think this is doable cleanly.

    Would you be open for such a feature? I might even give it a shot to implement it myself if you believe it could be of interest but have no time yourself. :)

    opened by dragetd 0
  • ExecuteMojo doesn't update Ruby classloader to plugin classloader

    ExecuteMojo doesn't update Ruby classloader to plugin classloader

    When using pom.rb, the Parser uses the coreExtension>io.takari.polyglot:polyglot-ruby classloader. When executing the mojos, the Thread context classloader is the plugin>io.takari.polyglot:polyglot-maven-plugin classloader with custom dependencies added, but JRuby still uses the "coreExtension" classloader.

    Ruby execute blocks should pick up dependencies added:

    # ...
    plugin!('io.takari.polyglot:polyglot-maven-plugin', VERSIONS[:polyglot_version]) do
        dependency( 'org.apache.maven.shared', 'maven-dependency-tree', '3.2.1')
    end
    
    execute :install_gems, :'initialize' do |ctx|
        org.apache.maven.shared.dependency.graph.DependencyGraphBuilder # => Exception!
    end
    # ...
    
    opened by byteit101 0
  • New Feature: Plugin lookup in execution contexts

    New Feature: Plugin lookup in execution contexts

    As execute blocks in languages (specifically Ruby that I'm interested in) can't declare java @Component annotations to access other maven plugins, this feature would allow a target language to use a new method on the ExecutionContex to retreive instances from the IoC container.

    Would need a bit of polish, but I'm gauging interest before I spend time finishing this.

    opened by byteit101 2
  • polyglot-kotlin docs still mention KT-27956

    polyglot-kotlin docs still mention KT-27956

    opened by seanf 2
Owner
null
The easiest way to integrate Maven into your project!

Maven Wrapper Ongoing Migration to Apache Maven The project codebase has been accepted to be included in the upstream Apache Maven project itself. Cur

null 1.6k Dec 23, 2022
Tripoli imports raw mass spectrometer data files and supports interactive review and archiving of isotopic data.

Tripoli imports raw mass spectrometer data files and supports interactive review and archiving of isotopic data. Tripoli facilitates visualization of temporal trends and scatter during measurement, statistically rigorous filtering of data, and calculation of statistical parameters.

CIRDLES 7 Dec 15, 2022
A plugin for the ja-netfilter, it can delete expired log files

A plugin for the ja-netfilter, it can delete expired log files

EFL 3 Feb 14, 2022
A Parser That parses OpenAPI definitions in JSON or YAML format and Generates Pact files That contain HTTP request/response interactions by parsing Given Open API specifications

This is a Parser That parses OpenAPI definitions in JSON or YAML format and Generates Pact files That contain HTTP request/response interactions by parsing Given Open API specifications.

dev-rgupta 2 Mar 19, 2022
This project is a specialized fork of Checkstyle to support older runtime environments of users who can't upgrade

checkstyle-backport-jre8 The latest release version can be found at GitHub releases or at Maven repo. This project is a specialized fork of Checkstyle

null 3 Apr 21, 2022
Mekanism Cables w/ GTCE(u) support

TemplateDevEnv Instructions: Click use this template at the top. Clone the repository you have created with this template.

Rongmario 3 Mar 2, 2022
Apache FOP is a print formatter driven by XSL formatting objects

Apache FOP is a print formatter driven by XSL formatting objects

The Apache Software Foundation 149 Jan 2, 2023
Apache OpenNLP library is a machine learning based toolkit for the processing of natural language text

Welcome to Apache OpenNLP! The Apache OpenNLP library is a machine learning based toolkit for the processing of natural language text. This toolkit is

The Apache Software Foundation 1.2k Dec 29, 2022
Cluster manager for Apache Doris

Apache Doris (incubating) Manager The repository contains Manager for Apache Doris (incubating) License Apache License, Version 2.0 Report issues or s

The Apache Software Foundation 96 Jan 4, 2023
Flink/Spark Connectors for Apache Doris

Flink/Spark Connectors for Apache Doris

The Apache Software Foundation 30 Dec 7, 2022
A maven plugin to include features from jmeter-plugins.org for JMeterPluginsCMD Command Line Tool to create graphs, export csv files from jmeter result files and Filter Result tool.

jmeter-graph-tool-maven-plugin A maven plugin to create graphs using the JMeter Plugins CMDRunner from JMeter result files (*.jtl or *.csv) or using F

Vincent DABURON 6 Nov 3, 2022
Object-Oriented Java primitives, as an alternative to Google Guava and Apache Commons

Project architect: @victornoel ATTENTION: We're still in a very early alpha version, the API may and will change frequently. Please, use it at your ow

Yegor Bugayenko 691 Dec 27, 2022
This is a Playwright Java Framework written in POM

Playwright Java Framework Main Objective of this Framework is to Build an Automation Framework that can be scalable, Easily Configurable and Ready to

AutoInfra 11 Oct 17, 2022
Usage Example using the Your-SB-Parent-POM

Your-SB-Parent-POM-Usage Requirements Java, preferred OpenJDK 17 Maven at least 3.6.3 Install the specify parent POM from the github project: Building

Jeff Schenk 1 Jan 21, 2022
Selenium Webdriver: Page Object Model (POM) With Page Factory

Prepare Web Testing Instance or Environment Selenium Webdriver: Page Object Model (POM) With Page Factory Prerequisite software Download & Install JDK

Hiro Mia 14 Oct 18, 2022
An HTML to PDF library for the JVM. Based on Flying Saucer and Apache PDF-BOX 2. With SVG image support. Now also with accessible PDF support (WCAG, Section 508, PDF/UA)!

OPEN HTML TO PDF OVERVIEW Open HTML to PDF is a pure-Java library for rendering arbitrary well-formed XML/XHTML (and even HTML5) using CSS 2.1 for lay

null 1.6k Dec 29, 2022
Paper-nms-maven-plugin - A maven plugin for using NMS on paper with Mojang mappings.

paper-nms-maven-plugin A maven plugin for using NMS on paper with Mojang mappings. This plugin will both create the mapped paper dependency and instal

null 56 Dec 28, 2022
maven plugin for making chmod +x jar files

To use it, add a plugin to your pom like <!-- You need to build an exectuable uberjar, I like Shade for that --> <plugin> <groupId>org.apache.mave

Brian McCallister 113 Dec 8, 2022
Maven plugin to help creating CHANGELOG by keeping one format and solving merge request conflicts problem by extraction of new CHANGELOG entries to seperate files.

keep-changelog-maven-plugin CHANGELOG.md is one of the most important files in a repository. It allows others to find out about the most important cha

Piotr Zmilczak 22 Aug 28, 2022