//
// Copyright (c) 2020 - Yupiik SAS - https://www.yupiik.com
// 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
//
//  http://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.
//

= Yupiik Tools Maven Plugin

image:https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Fjvm-repo-rebuild%2Freproducible-central%2Fmaster%2Fcontent%2Fio%2Fyupiik%2Fmaven%2Fplugin%2Fbadge.json[Reproducible Builds,float="right",link=https://github.com/jvm-repo-rebuild/reproducible-central/blob/master/content/io/yupiik/maven/plugin/README.md]
image:https://github.com/yupiik/tools-maven-plugin/workflows/Java%20CI%20with%20Maven/badge.svg[Github CI,float="right"]
image:https://img.shields.io/maven-central/v/io.yupiik.maven/yupiik-tools-maven-plugin-parent?color=00b2ef&label=Last%20Release&logoColor=00b2ef&logo=data%3Aimage%2Fpng%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAACAAAAAqCAYAAADS4VmSAAAAAXNSR0IArs4c6QAABGdJREFUWEedmF2I3FQUx%2F9nZrYzq7ttMtuK32B90WpFEbtUW2T7UqqbjIgM%2BKQP%2BmAfBUEFP0H7oo%2BiIgg%2BqRUqk%2BwWRXTFj9UWoVIp7UN1H9QitTvJMtpOd3dydDI7k9zk3syd5C25557zO1%2F3I4S8z3xzJzp0MpweBDfioanf86iiPJPCOY7HwlzbzKUr1yQ4XgAgOZdhm4VRHcoLIHrft5ojCqMDiKF%2FGlQkcOfNgecjQowGcKS5ByX6NmUsDrXOe%2FFw9TvdVIwGEDdUNiawn%2F4NDR0%2BP4HKWCtPFPQBXP8EmO9UGonDEf0My7hLJwr6AHEDqjzryCSo9ACEtuM%2FYVevl3rneH8D2LoxptWWugBR2w2r8hGjMBxAaDt6BrbxRmZuHf81gJ%2FXLchsgEbzQRDN6SobyMWhmWdRq86roLMB4ooKVMWs4Q0Uuf4jYP4kfKfONKytxwdjR1vbsL5%2BXgdcDeD6J8G8U6vtukLJ2hDb8hdYxh2yKKgBsorJ9QJwYjMiMKzEZqRRkHKAhrcKwliPmC7ANrYN6A%2Bf2oTKtZelOW1%2FUUK93oml6RKYK%2BE7Yw01c1NyXhpggSto%2BZe0Qh%2FgMQBFFPC%2BlvykMY4Zasch0gBC4RUfx%2BzmDwYT5lem0Ql%2BTBkTWjW4HfbUqVhHvALgRRWgCDDXmkGw%2FpWWN%2BXLE9h%2FdW8z%2BtQzUETUIVkFWSjtw%2BzkQt%2BGCBD3pG2UUKcon43mCRBpbkZYhGXeF9UNj6PiX5Q5FgE4zUWAdmt5n2czEtLEP8Cu3huWeCxX6vVenHwadnWHtAsc7zcAN43iRA9gmAGNftZ05A8A18UBCQtcQstf06JmfhS16kdS7%2FsfHf9ZgA9p6Zs0xkjwngsHUNvyWeTNch0ofKxUpiIRNiO6BzXjp4Fow38OxK9HXZC8YDAfRK36dio1JaOCB0i%2BAiZBjvx1FcbKn8MyxWOZ670MxkviQuR4vwLYnnKG2QeRsfG9A9ssZYY%2Ba9BpXgRoPCVCWOwVoXvhFnDxtFLHsFOQTirS1rfDNpbSS3HD64Agv2JR8VZYm88MKcJ9AH8plWEEqJlFMQVq%2Bq8B3K8Y%2Fga2KY45XrfQ7s6Ea%2F9zBeo3RBud5IIJzPmmePJZ2QUOjuXKf6GzA0FpL8DvqjpJTIG7%2FCq48EIoTPQULOMdwXCyY%2BRU6eO4cDrCDCyzG92eGaUBWeE5%2FlsAH8yMBvMh1KrRqbgvrFhNIwDXOwfGNdJQOZ4PYMtIaWAso2b2LynJHxrHYZvTsQgwwfG7Px16T9f7bi0E3FQbDZ4ECu%2BF490lmuhDpWz%2FIiuJgmQzoiWAox1N1LoK2yyHn5zlJ2IA0dnf9dfArFq0ugeYK%2BOOSgAkfhBcWKYt1osCoC%2Fk%2BsfAvCszbbZJQwCC3bCnojNgXJsqAkmLzsoBIDgqBRkAuP5ZMN88EGqfK6N%2B22omvS5AX8nCUgUtI74IfQ%2Fb3DP8cqqiGBVAoSc%2FQFiIG%2F8K825W%2F%2Bv4D2sg4qMfRFPFAAAAAElFTkSuQmCC[float="right"]

:toc:

== Introduction

A set of goals at Yupiik colors and easing automation.

IMPORTANT: documentation is available online at https://yupiik.io/tools-maven-plugin/.

Plugin definition:

[source,xml]
----
<plugin>
  <groupId>io.yupiik.maven</groupId>
  <artifactId>yupiik-tools-maven-plugin</artifactId>
  <version>${yupiik-tools.version}</version>
</plugin>
----

TIP: `yupiik-tools-cli` enables to run the slides and minisite tools without maven, run `help` on the fat jar (`java -jar yupiik-tools-cli-<version>-fatjar.jar`) to see the configuration.

== Goals

IMPORTANT: you can also consult out link:_documentation/yupiik-tools-maven-plugin.adoc[generated] documentation, it will contain a more exhaustive content.

=== Git Report

Use a `.git` folder to generate an asciidoc report listing commits.

Simplest setup is to define the plugin and create a file `src/main/pdf/index.adoc`, then simply render it with:

[source,sh]
----
 mvn yupiik-tools:git-report
----

==== Configuration

[options="header",cols="1,m,m,m,1"]
|====
|Name|Type|Default|Property|Description
|dotGit|File|-|yupiik.git-report.dotGit|Where is `.git` folder to render.
|target|File|-|yupiik.git-report.target|Where to render the asciidoc report.
|title|String|Report|yupiik.git-report.title|The report title.
|overwrite|boolean|true|yupiik.git-report.overwrite|If `true` and the output already exists it is overwritten, else it would fail.
|renderers|list of Renderer|DEFAULT|-|How to generate the document (see after).
|filters|GitLogFilter|-|-|How to filter git logs to generate the document content, depends on the renderers configured (see after).
|logFormat|GitLogFormat|-|-|How to render a git log line (see after).
|====

===== Renderers

DEFAULT:: alias for `REPOSITORY_METADATA, COMMITS_PER_NAME_PREFIX_CHRONOLOGICAL`.
REPOSITORY_METADATA:: creates a part with the repository URL and name, uses `origin` remote repository if possible.
COMMITS:: simply logs all commits in reverse order (date) using the configured formatter (`logFormat`).
COMMITS_CHRONOLOGICAL:: simply logs all commits in order (date) using the configured formatter (`logFormat`).
COMMITS_PER_EMAIL_PREFIX:: same as `COMMITS` but groups each log lines in a part dedicated to the `email` associated to the commit.
COMMITS_PER_EMAIL_PREFIX_CHRONOLOGICAL:: same as `COMMITS_PER_EMAIL_PREFIX` but sorted by date.
COMMITS_PER_NAME_PREFIX:: same as `COMMITS` but groups each log lines in a part dedicated to the `name` associated to the commit.
COMMITS_PER_NAME_PREFIX_CHRONOLOGICAL:: same as `COMMITS_PER_NAME_PREFIX` but sorted by date.

===== Filters

from:: date in `yyyy-MM-dd` format to include commits from (inclusive).
to:: date in `yyyy-MM-dd` format to include commits to (inclusive).
mailRegex:: java regex to filter commits per email, it can be used to include only the commits from members of a company for example.

===== Log Format

STAR:: renders `*`.
BACKQUOTE:: renders ```.
COLON:: renders `:`.
SPACE:: renders a space.
OPEN_BRACKET:: renders `[`.
CLOSE_BRACKET:: renders `]`.
OPEN_PARENTHESIS:: renders `(`.
CLOSE_PARENTHESIS:: renders `)`.
SHA:: renders commit short sha (abbreviated to 7 chars).
DATE:: renders commit date.
AUTHOR:: renders committer name.
MAIL:: renders committer email.
MESSAGE:: renders commit short message.
FULL_MESSAGE:: renders commit full message.

===== TIP

TIP: this goal can be chained with PDF one to render the log in one command (adjust the version, the sample uses the minimal one):
[source,bash]
----
mvn \
  io.yupiik.maven:yupiik-tools-maven-plugin:1.0.23:git-report \
  io.yupiik.maven:yupiik-tools-maven-plugin:1.0.23-SNAPSHOT:pdf \
  -Dyupiik.workDir=work \
  -Dyupiik.git-report.dotGit=/path/to/project/.git \
  -Dyupiik.git-report.target=log.adoc
  -Dyupiik.pdf.source=log.adoc \
  -Dyupiik.pdf.target=.
----

=== PDF

Render an asciidoctor file in PDF.

Simplest setup is to define the plugin and create a file `src/main/pdf/index.adoc`, then simply render it with:

[source,sh]
----
 mvn yupiik-tools:pdf
----

TIP: `watch-pdf` goal exists and just keeps re-rendering your `adoc` to `pdf` when something changed in the source directories. You can exit it with `Ctrl+C` command.

TIP: some default roles are defined in the theme and can be used to color the icons (`icon:xxx[role=<name>]`).
Here are the default ones:
[source,yaml]
----
  red:
    font-color: #ff00ff
  green:
    font-color: #00ff00
  blue:
    font-color: #0000ff
  red-darker:
    font-color: #cc0000
  green-darker:
    font-color: #006600
  yupiik:
    font-color: #0075bb
  yupiik_dark:
    font-color: #054470
----

==== Configuration

[options="header",cols="1,m,m,m,1"]
|====
|Name|Type|Default|Property|Description
|attributes|Map|-|-|Custom attributes.
|customCss|File|-|yupiik.slides.customCss|Custom css if needed, overrides default one for revealjs (as intended by the backend) and append it to yupiik one for bespoke.
|mode|Mode|DEFAULT|yupiik.slides.mode|Which execution mode to use, WATCH and SERVE are for dev purposes.
|port|int|4200|yupiik.slides.serve.port|For SERVE mode, which port to bind.
|source|File|${project.basedir}/src/main/pdf/index.adoc|yupiik.slides.source|Slide deck source file.
|targetDirectory|File|${project.build.directory}/yupiik/pdf|yupiik.slides.target|Where to render the slide deck.
|workDir|File|${project.build.directory}/yupiik-workdir|yupiik.workDir|Where to extract files needed for the rendering.
|====

==== PDF and formula

Stem/Math formulas Asciidoctor integration is done through _mathematical_ gem which uses native bindings not supported by JRuby.
Therefore you can't use it with PDF.
To workaround this issue, PDF plugin provides `jlatexmath` (open block macro, i.e. delimited with `--`) and `jmath` (inline macro) allowing you to use inline LaTeX formulas.

To activate it you must add jlatexmath dependency:

[source,xml]
----
<plugin>
  <groupId>io.yupiik.maven</groupId>
  <artifactId>yupiik-tools-maven-plugin</artifactId>
  <configuration>
    <!-- ... -->
  </configuration>
  <dependencies>
    <dependency>
      <groupId>org.scilab.forge</groupId>
      <artifactId>jlatexmath</artifactId>
      <version>1.0.7</version>
    </dependency>
  </dependencies>
</plugin>
----

Example:

[source,asciidoc]
----

[jlatexmath]
--
x = a + b
--

This formula (jmath:_[a + b]) is cool.
----

==== Use without a pom.xml

IMPORTANT: this feature is available from version 1.0.22.

[source,bash]
----
mvn \
  io.yupiik.maven:yupiik-tools-maven-plugin:$VERSION:pdf \
  -Dyupiik.pdf.source=content.adoc \
  -Dyupiik.pdf.target=.
----

=== Slides

Render an asciidoctor reveal.js slide deck in HTML.

Simplest setup is to define the plugin and create a file `src/main/slides/index.adoc`, then simply render it with:

[source,sh]
----
mvn yupiik-tools:slides
----

You can also pass in HTTP mode with:

[source,sh]
----
mvn yupiik-tools:serve-slides
----

TIP: to convert slides to PDF, you can use decktape. Launch the slides HTTP server and then run `docker run --rm -t --net=host -v $PWD:/slides astefanutti/decktape http://localhost:4200 slides.pdf`.

==== Configuration

[options="header",cols="1,m,m,m,1"]
|====
|Name|Type|Default|Property|Description
|attributes|Map|-|-|Custom attributes. By default _partials and images folders are set to partialsdir and imagesdir attributes.
|sourceDirectory|File|${project.basedir}/src/main/pdf|yupiik.pdf.source|Source directory or file to render, if a directory all files with extension .adoc will be selected.
|targetDirectory|File|${project.build.directory}/yupiik/pdf|yupiik.pdf.target|Where to render the asciidoc files to.
|themeDir|File|-|yupiik.pdf.themeDir|Theme directory (name of the theme is yupiik), let it null to inherit from the default theme.
|workDir|File|${project.build.directory}/yupiik-workdir|yupiik.workDir|Where to extract files needed for the rendering.
|slider|Slider|BESPOKE|yupiik.slides.slidere|Which renderer to use for slides, reveal.js or bespoke.js.
|synchronizationFolders|List of source,target|-|-|List of synchronization folder for the output, source will be taken (file) and copied relatively to target directory, appending target value before the relative path of the file.
|====

=== Audit

Audit mojo uses the fact the plugins are "Maven aware" to generate an audit report inheriting from PDF mojo.
It uses the same configuration but works on a reactor.

TIP: it is recommended to set `source` relative to multiple module dir and not project basedir since this one can be random.

Here is a sample execution from the CLI:

[source,sh]
----
$ mvn io.yupiik.maven:yupiik-tools-maven-plugin:${plugin.version}:audit \
    -Dyupiik.pdf.source=$PWD/report.adoc \
    -Dyupiik.pdf.target=/tmp/report
[...]
mvn io.yupiik.maven:yupiik-tools-maven-plugin:1.0.0-SNAPSHOT:audit -Dyupiik.pdf.source=report.adoc -Dyupiik.pdf.target=/tmp/report.pdf
[INFO] --- yupiik-tools-maven-plugin:1.0.0-SNAPSHOT:audit (default-cli) @ my-module ---
[INFO] Generating audit report
[INFO] Rendered 'report.adoc'
----

A more complete example to skip a module, skip some plugins and ensure dependencies are available can be:

[source,sh]
----
 mvn \
    compile -Dcompiler.skip=true  \ <1>
    io.yupiik.maven:yupiik-tools-maven-plugin:${plugin.version}:audit \ <2>
    -Dyupiik.pdf.source=$PWD/report.adoc -Dyupiik.pdf.target=/tmp/report \
    -Dlicense.skip=true -Dfront.build.skip=true \ <3>
    -pl -documentation <4>
----

<1> go through compile phase (skipping it) to ensure compile dependencies are resolved,
<2> our audit plugin *after* the resolution plugins,
<3> skip license and front plugins (depends your plugins),
<4> skip documentation module.

Report will be in `/tmp/report/report.pdf`.

NOTE: report does not have to be in the project ;).

Here is a sample report:

[listing]
....
= Report

== Dependencies

[maven_dependencies,scope=compile_only,aggregated=true] <1>
--
--
....

<1> the `aggregated=true` enables to generate a single report for all the reactor at once.


=== Minisite

Minisite enables to render a static website with a generic Yupiik template or a custom one with some configuration.
It comes with its companion serve goal to have a live preview.

TIP: as all plugins it requires Java 11 but if you want to use it with Java 8 you can use `minisite-core` module with `exec-maven-plugin` since version 1.1.1.

[source,sh]
----
 mvn yupiik-tools:minisite
 mvn yupiik-tools:serve-minisite
----

==== Configuration

[options="header",cols="1,m,m,m,1"]
|====
|Name|Type|Default|Property|Description
|attributes|Map|-|-|Custom attributes.
|source|File|${project.basedir}/src/main/minisite|yupiik.minisite.source|Source directory or file to render.
|target|File|${project.build.directory}/${project.build.finalName}|yupiik.minisite.target|Where to render the minisite.
|title|String|Yupiik|yupiik.minisite.title|Default title if page has no title.
|description|String|Yupiik Minisite|yupiik.minisite.description|Default description if page has no title.
|siteBase|String|`http://localhost:4200`|yupiik.minisite.siteBase|Base of the site.
|searchIndexName|String|search.json|yupiik.minisite.generateSearchIndex|Should search.json be generated and if not `none` its name.
|generateIndex|boolean|true|yupiik.minisite.generateIndex|Should index be generated from the pages.
|generateSiteMap|boolean|true|yupiik.minisite.generateSiteMap|Should sitemap be generated.
|templatePrefixes|List<String>|default|-|List of html templates to prepend to the content.
|templateAddLeftMenu|boolean|true|yupiik.minisite.addLeftMenu|Should a left menu inheriting from index logic be generated.
|templateSuffixes|List<String>|default|-|List of html templates to append to the content.
|useDefaultAssets|boolean|true|yupiik.minisite.useDefaultAssets|Should default css/js be extracted and added to the website.
|customHead|String|-|yupiik.minisite.customHead|String injected at the end of head tag of html pages.
|customScripts|String|-|yupiik.minisite.customScripts|String injected at the end of script tags of html pages.
|customMenu|String|-|yupiik.minisite.customMenu|String injected on the top left of the menu (just before the search).
|logoText|String|-|yupiik.minisite.logoText|Logo text for default theme (text next to the logo).
|indexText|String|-|yupiik.minisite.indexText|Index homepage (when generated) content title.
|indexSubTitle|String|-|yupiik.minisite.indexSubTitle|Index home page (when generated) subtitle.
|copyright|String|Yupiik &copy;|yupiik.minisite.copyright|Footer copyright for the default theme.
|linkedInCompany|String|yupiik|yupiik.minisite.linkedInCompany|Name of the company as on linkedin link.
|logo|String|yupiik logo|yupiik.minisite.logo|Logo url.
|preActions|String|-|-|List of pre actions to execute before the rendering (`{type:xxx,configuration:{}}`).
|reverseBlogOrder|boolean|true|yupiik.minisite.reverseBlogOrder|Sort by reversed published date the posts on index pages.
|injectBlogMeta|boolean|false|yupiik.minisite.injectBlogMeta|Add to the top of blog posts the author names (with link to their page), published date and reading time.
|blogPublicationDate|String|today|yupiik.minisite.blogPublicationDate|Max publication date supported for posts, enables to preview future posts in "writing" mode.
|blogPageSize|String|10|yupiik.minisite.blogPageSize|How many post to put on a single index/list page.
|addIndexRegistrationPerCategory|boolean|false|yupiik.minisite.addIndexRegistrationPerCategory|Should categories be added to home page.
|skipIndexTitleDocumentationText|boolean|false|yupiik.minisite.skipIndexTitleDocumentationText|Should ` Documentation` be appended to index text.
|logoSideText|String|Docs|yupiik.minisite.logoSideText|Text next logo text, generally the subproject or just `Docs`.
|injectYupiikTemplateExtensionPoints|boolean|true|yupiik.minisite.injectYupiikTemplateExtensionPoints|Should Yupiik custom points be used (alias for multiple custom extension points, only override missing ones).
|templateExtensionPoints|Map<String,String>|-|yupiik.minisite.templateExtensionPoints|Values for custom template extension points like `socialLinks` and `copyrightLine`. Note that these templates can also be put in `templates/extension-points` folder (with `.html` extension appended to their name).
|gravatar|GravatarConfiguration|-|-|An object where gravatar URL pattern can be configured. Default is equivalent to: `<gravatar><url>https://www.gravatar.com/avatar/%s?d=identicon&size=40</url></gravatar>`.
|====

TIP: most of texts can be deduced from `logText` and `indexSubTitle` so ensure to set these two to contextualize your minisite.

The configuration also supports a `ftp` entry if you want to upload to a FTP server the generated website:

[options="header",cols="1,m,m,m,1"]
|====
|Name|Type|Description
|username|String|Username if serverId is not set.
|password|String|Password if serverId is not set.
|serverId|String|ServerID to use to get username/password from settings.xml.
|url|String|FTP url (`ftp://host:port/dir`).
|ignore|boolean|Enables to set a maven variable to ignore it conditionally.
|====

The configuration also supports a `git` entry if you want to upload to a Git branch the generated website (like `gh-pages`):

[options="header",cols="1,m,2"]
|====
|Name|Type|Description
|branch|String|Git branch to update (default to `refs/heads/gh-pages`).
|username|String|Username if serverId is not set.
|password|String|Password if serverId is not set.
|serverId|String|ServerID to use to get username/password from settings.xml - default to `project.scm.url`. If not set it fallbacks on the git url host. If using a git url which is a SSH one, you can set passphrase and privateKey location in the server.
|url|String|Git url.
|ignore|boolean|Should the execution be skipped - enables to set a maven variable.
|prefix|String|Prefix prepended to file in the git repo (ex: `public/`).
|noJekyll|boolean|Will force a `.nojekyll` file presence if `true`.
|envBase64SshKey|String|Environment variable the private key will be read as base64 encoded from - useful on CI. note that `<value>_PH` environment variable must contain the associated passphrase.
|====

The configuration also supports an experimental Atlassian Confluence export support.
It only works using the default template and require a configuration similar to `git` or `ftp` exports:

[source,xml]
----
<profile> <!--  mvn clean package -Pconfluence  -->
  <id>confluence</id>
  <build>
    <plugins>
      <plugin>
        <groupId>io.yupiik.maven</groupId>
        <artifactId>yupiik-tools-maven-plugin</artifactId>
        <executions>
          <execution>
            <id>confluence</id>
            <phase>prepare-package</phase>
            <goals>
              <goal>minisite</goal>
            </goals>
            <configuration>
              <confluence>
                <ignore>false</ignore>
                <url>https://base.atlassian.net/wiki/</url> <!-- for cloud, for an on premise instance the /wiki/ is not always needed -->
                <authorization>Basic base64_value_of(your mail:your token)></authorization>
                <space>YOURSPACE</space>
                <skipIndex>false</skipIndex> <!-- if true, will skip all index.html files -->
              </confluence>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</profile>
----

IMPORTANT: the nested support of this exporter is very experimental, and we recommend you to keep only one level of `.adoc` files using it.

===== Confluence Limitations

* Assets are not uploaded so ensure to configure Asciidoctor to embed all assets in HTML,
* It only works with the default theme since we extract metadata from there to enable to update the space,
* To look nice, you can need to tune the Confluence space CSS to import admonitions, codeblocks, ... styling (can require some admin permissions).

===== Blog

Blog is supported if pages contain at least one block metadata.
Here is the list of available attributes you can use:

* `:minisite-blog-published-date: yyyy-MM-dd`: when the page will be rendered (if not set it is always rendered).
* `:minisite-blog-categories: c1,c2`: comma separated list of categories of this post
* `:minisite-blog-authors: My, Myself`: comma separated list of author names
* `:minisite-blog-summary: Some short description.`: the summary of this post used on post list pages.

Blog page example:

[source,asciidoc]
----
= My Post
:minisite-blog-published-date: 2021-02-16T16:00
:minisite-blog-categories: others,simple
:minisite-blog-authors: Romain Manni-Bucau
:minisite-blog-summary: Second post.

Bla bla
----

===== Pre-Action

Pre actions enables to generate some content from the project.
It is typically used to generate configuration from code or things like that.
It uses the documentation module classpath.
Actions must implement `Runnable` and can have some (public) constructor parameters (we use parameter names to match so ensure to enable `-parameters` in maven compiler plugin):

* `configuration` (`Map<String, String>`): the action configuration, it enables to reuse it if needed or write generic actions
* `sourceBase` (`Path`): the base directory you can generate `.adoc` into (generally where you sources are, tip: use `generated` folder to be able to exclude it in `.gitignore` if desired)
* `outputBase` (`Path`): the base directory you can generate direct html assets

====== Maven Plugin

Using `type=maven-plugin` (recommended) or `type=io.yupiik.maven.service.action.builtin.MojoDocumentationGeneration` you can get a `plugin.xml` file parsed to generate:

. One file per goal with some usage, the goal description and parameters (named `<goal>.adoc`)
. One file listing all goals (named `<goal-prefix>-maven-plugin.adoc`)

The configuration of this action is:

. `pluginXml`: file path or resource to find the `plugin.xml` file.
. `toBase`: where to generate the `adoc`.
. `description`: a global plugin description for the "listing" page (default is empty and page will just list goals).

====== Copy

Using `type=copy` (recommended) or `type=io.yupiik.maven.service.action.builtin.CopyFile` will copy a file from a source to a destination:
It is typically useful for assets (`openapi.json` for example).

. `from`: source file.
. `to`: destination.

====== JSON-Schema

Using `type=jsonschema` (recommended) or `type=io.yupiik.maven.service.action.builtin.JsonSchemaGenerator` will generate a JSON-Schema from a class:

. `class`: the class to generate the schema from.
. `to`: destination of the schema.
. `type`: `JSON` for a raw JSON-Schema (default) or `ADOC` for a textual, asciidoctor output.
. `setClassAsTitle`: `true` to force object title to be the class name.
. `useReflectionForDefaults`: `true` to force reflection to try to extract defaults of attributes.
. `pretty` when type=JSON, should the JSON be prettified or not (default=true).
. `levelPrefix` when type=ADOC, a title prefix (`==` for example), `=` by default.
. `title` and `description` enable to set class title/description for its json schema. It is required for type=ADOC.
. `annotationOnlyProvidesTheDescription` enable to never take the title from an annotation (`@Description(value)` case).

NOTE: the model classes can use a custom `@Description(title,description)` annotation (note that `@Doc` is also supported and `value` method can be used instead of `description`).
See `JsonDocExtractor` for more details.

====== OpenMetrics renderer

Using `type=openmetrics2adoc` (recommended) or `type=io.yupiik.tools.minisite.action.builtin.OpenMetricsToAsciidoc` will generate an asciidoctor form from an OpenMetrics export.

. `source`: path of the openmetrics dump.
. `to`: destination of the asciidoc generated from `source`.
. `levelPrefix`: a prefix set before the part title (`== ` by default for a second level title).
. `legend`: should tables have a legend (name of the metric), default to `true`.
. `header`: prefix the whole rendering (enables to set a title and some options if needed).

====== Yupiik Batch simple-configuration renderer

Using `type=simple-configuration` (recommended) or `type=io.yupiik.tools.minisite.action.builtin.SimpleConfigurationGenerator` will generate an asciidoctor from a configuration class passed in `class` `<configuration>` option.

. `class`: root configuration fully qualified name.
. `output`: where to generate the `.adoc` to.

====== Replace string in file

Using `type=replace-in-file` (recommended) or `type=io.yupiik.tools.minisite.action.builtin.ReplaceInFile` will rewrite a text file replacing a string by another one.

. `source`: file to rewrite.
. `token`: text to replace.
. `replacement`: text replacing `token`.

TIP: using `regex{xxx}` as `token` will use a java regex to do the replacement.

===== Example

[source,xml]
----
<plugin>
  <groupId>io.yupiik.maven</groupId>
  <artifactId>yupiik-tools-maven-plugin</artifactId>
  <executions>
    <execution>
      <id>build-and-deploy-doc</id>
      <phase>package</phase>
      <goals>
        <goal>minisite</goal>
      </goals>
      <configuration>
        <siteBase>https://yupiik.github.io/${project.artifactId}</siteBase>
        <logoText>My Product</logoText>
        <indexSubTitle>The top product.</indexSubTitle>
        <ftp>
          <serverId>http://mini.yupiik.net</serverId> <!-- default is siteBase -->
          <url>ftp://ftpupload.net/htdocs</url>
        </ftp>
      </configuration>
    </execution>
  </executions>
</plugin>
----

===== Page attributes

Some specific attributes enables to customize the generation. Here is their list:

* `minisite-skip=[true|false]` enables to skip a `.adoc` rendering even if not in `_partials` directory.
* `minisite-path=<string>` enables to force the relative path of the file, for example a file name foo-bar.adoc with the attribute `minisite-path` set to `foo/bar.html` will output a `foo/bar.html` file instead of `foo-bar.html`. Note however it does not rewrite the links to ensure to use `link:.....html[]` instead of `ref` to link this page then.
* `minisite-highlightjs-skip` enables to not setup highlight.js for the page (useful with swagger-ui for example).

===== Index generation

To include a page in the index it must contain `minisite-index` attribute.
Its value is the order of the entry in the index tiles.

TIP: ensure to not use `1`, `2`, `3`, ... but rather `100`, `200`, ... to easily insert an item later.

* `minisite-index-title` attribute enables to override link text.
* `minisite-index-icon` attribute enables to override font awesome icon (without `fa-` prefix).
* `minisite-index-description` attribute enables to override the text in the index tile for the page entry.

=== Synchronize Releases

Fetch versions of the defined artifacts on a nexus and ensures it is set as github release artifacts.

Name: `synchronize-github-releases`.

TIP: if you use maven central you need to await for the synchronization to run this goal, using directly OSS sonatype release repository avoids it.

==== Configuration

[options="header",cols="1,m,2"]
|====
|Name|Type|Description
|githubServerId|String|Github serverId to use (from your settings.xml) to get the token to use to call github API.
|nexusServerId|String|Nexus serverId to use (from your settings.xml) to get the token to use to call nexus, not needed if mavenRepositoryBaseUrl is central (default).
|mavenRepositoryBaseUrl|String|Maven repository base url - where `maven-metadata.xml` will be read.
|githubRepository|String|Which github repository to synchronize (`org/repo` syntax).
|githubBaseApi|String|Base API url for github REST API (default on public one).
|artifacts|ArtifactSpec[]|List of artifacts to synchronize (`{groupId,artifactId,artifacts}` with artifacts a list of artifact `{type=jar,classifier=""}`).
|attachIfExists|boolean|If release already exists the default behavior is to skip it, this flag enables to still try to attach artifacts to this release anyway.
|tagPattern|String|Tag name to link to the release, default uses `{artifactId}-{version}` pattern.
|====

==== Example


[source,xml]
----
<plugin>
  <groupId>io.yupiik.maven</groupId>
  <artifactId>yupiik-tools-maven-plugin</artifactId>
  <executions>
    <execution>
      <id>default-cli</id>
      <phase>none</phase>
      <goals>
        <goal>synchronize-github-releases</goal>
      </goals>
      <configuration>
        <!-- defaults so optional -->
        <githubServerId>github.com</githubServerId>
        <nexusServerId />
        <mavenRepositoryBaseUrl>https://repo.maven.apache.org/maven2/</mavenRepositoryBaseUrl>
        <!-- required configuration -->
        <githubRepository>yupiik/tools-maven-plugin</githubRepository>
        <artifacts>
          <artifact>
            <groupId>io.yupiik.maven</groupId>
            <artifactId>yupiik-tools-maven-plugin</artifactId>
            <artifacts>
              <artifact>
                <type>jar</type>
                <classifier />
              </artifact>
              <artifact>
                <type>pom</type>
                <classifier />
              </artifact>
              <artifact>
                <type>jar</type>
                <classifier>sources</classifier>
              </artifact>
              <artifact>
                <type>jar</type>
                <classifier>javadoc</classifier>
              </artifact>
            </artifacts>
          </artifact>
        </artifacts>
      </configuration>
    </execution>
  </executions>
</plugin>
----

Then run `mvn yupiik-tools:synchronize-github-releases`.

=== Cucumber to Asciidoc

Convert cucumber JSON report(s) into an asciidoc file which can be rendered with PDF or HTML goals.

Name: `cucumber2asciidoc`.

==== Configuration

[options="header",cols="1,m,2"]
|====
|Name|Type|Property|Description
|source|File|yupiik.cucumber.source|Input JSON file or directory path containing report files (cucumber JSON format) - matched by their `.json` extension. Default: `${project.build.directory/cucumber-reports/`.
|target|File|yupiik.cucumber.target|Output asciidoc file path. Default: `${project.build.directory}/generated-adoc/cucumber.report.adoc`.
|prefix|String|yupiik.cucumber.prefix|Header (top, i.e. before report) of the document.
|suffix|String|yupiik.cucumber.suffix|Footer (end, i.e. after report) of the document.
|====

==== Example


[source,xml]
----
<plugin>
  <groupId>io.yupiik.maven</groupId>
  <artifactId>yupiik-tools-maven-plugin</artifactId>
  <executions>
    <execution>
      <id>default-cli</id>
      <phase>none</phase>
      <goals>
        <goal>cucumber2asciidoc</goal>
      </goals>
      <configuration>
        <prefix>= My Cucumber Report</prefix>
        <suffix></suffix>
        <source>${project.build.directory}/cucumber-reports/</source>
        <target>${project.build.directory}/generated-adoc/cucumber.report.adoc</target>
      </configuration>
    </execution>
  </executions>
</plugin>
----

Then run `mvn yupiik-tools:cucumber2asciidoc`.

TIP: indeed it can be chained with `yupiik-tools:pdf`.

=== Bash CLI Skeleton

This MOJO enables to initialize a folder with a Bash CLI structure.

Usage:

[source,bash]
----
mvn yupiik-tools:script-cli-skeleton -Dyupiik.script-cli-skeleton.directory=/path/to/skeleton
----

==== Configuration

[options="header",cols="1,m,2"]
|====
|Name|Type|Property|Description
|directory|File|yupiik.script-cli-skeleton.directory|Where to bootstrap the CLI.
|generateHelloWorldCommand|boolean|yupiik.script-cli-skeleton.generateHelloWorldCommand|Should a default command be added or not.
|====

TIP: can be used on a pomless project: `mvn io.yupiik.maven:yupiik-tools-maven-plugin:<version>:script-cli-skeleton -Dyupiik.script-cli-skeleton.directory=/path/to/script-project` (version >= 1.0.26).

==== Usage

To add a command:

. Create an `index.sh` containing the command script in `commands` folder
. (optional) create a `commands/<your command name>/_cli/help.txt` file containing the help description.

== Maven Asciidoctor Macro

The project adds asciidoc macros to get back some maven build information.
Note that it must be executed in the right lifecycle phase if using some project metadata (plugin does not require any resolution to be usable standalone).

=== maven_dependencies

Enables to list the project dependencies.

==== Usage

[listing]
....
[maven_dependencies,scope=compile]
--
--
....

Scope can be:

- compile
- runtime
- compile+runtime
- runtime+system
- test
- provided_only
- compile_only
- test_only
- system_only
- runtime_only

The optional attribute `groupId` is also supported and take a list (comma separated) of groupId to include.

== Yupiik OSS extension

This extension sets up the equivalent of a parent pom but enables to inherit or not from another parent and to benefit from upgrades for free.

It is configured in the root project through maven properties:

[source,xml]
----
<properties>
  <!-- REQUIRED: enable the extension -->
  <yupiik.oss.enabled>true</yupiik.oss.enabled>
  <!-- OPTIONAL: defaults -->
  <yupiik.oss.java.version>11</yupiik.oss.enabled>
  <yupiik.oss.encoding>UTF-8</yupiik.oss.enabled>
  <yupiik.oss.javadoc.doclint>none</yupiik.oss.enabled>
  <yupiik.oss..sign.skip>none</yupiik.oss.enabled>
</properties>
----

Just enabling this extension will upgrade a few plugin, enforce the encoding and java version, enforce license check and much more.

See `io.yupiik.maven.extension.YupiikOSSExtension.afterProjectsRead` for details.

=== Example

[source,xml]
----
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <!-- ... -->

  <properties>
    <yupiik.oss.enabled>true</yupiik.oss.enabled>
  </properties>

  <build>
    <extensions>
      <extension>
        <groupId>io.yupiik.maven</groupId>
        <artifactId>yupiik-tools-maven-plugin</artifactId>
        <version>${yupiik-tools.version}</version>
      </extension>
    </extensions>
  </build>

  <profiles>
    <profile>
      <id>release</id>
    </profile>
  </profiles>
</project>
----

== Inline pom contributor extension

It enables to put in each module a `YupiikContributor.java` file which will be compiled and executed in `afterProjectRead(MavenSession)` callback.

Example:

[source,java]
----
import org.apache.maven.AbstractMavenLifecycleParticipant;
import org.apache.maven.execution.MavenSession;
import org.codehaus.plexus.component.annotations.Component;

@Component(role = AbstractMavenLifecycleParticipant.class, hint = "my-module-customizer")
public class YupiikContributor extends AbstractMavenLifecycleParticipant {
    @Override
    public void afterProjectsRead(final MavenSession session) {
        System.out.println(">>>> hello: " + session);
    }
}
----

This enables to programmatically handle the pom (mainly intended for plugins since dependencies are not synchronized in maven poms when contributed this way).

To enable it, enable the related extension:

[source,xml]
----
<build>
  <extensions>
    <extension>
      <groupId>io.yupiik.maven</groupId>
      <artifactId>yupiik-tools-maven-plugin</artifactId>
      <version>${yupiik-tools-maven-plugin.version}</version>
    </extension>
  </extensions>
</build>
----

TIP: see `io.yupiik.maven.extension.YupiikOSSExtension` for a more complex participant example.
