An open API service indexing awesome lists of open source software.

https://github.com/societe-generale/arch-unit-maven-plugin

A maven wrapper around ArchUnit, to easily share and enforce architecture rules across projects
https://github.com/societe-generale/arch-unit-maven-plugin

Last synced: 5 months ago
JSON representation

A maven wrapper around ArchUnit, to easily share and enforce architecture rules across projects

Awesome Lists containing this project

README

          

# ArchUnit Maven plugin

![Build Status](https://github.com/societe-generale/arch-unit-maven-plugin/actions/workflows/build_workflow.yml/badge.svg)
[![codecov](https://codecov.io/github/societe-generale/arch-unit-maven-plugin/graph/badge.svg?token=XrRWdv5yfi)](https://codecov.io/github/societe-generale/arch-unit-maven-plugin)
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.societegenerale.commons/arch-unit-maven-plugin/badge.svg?style=plastic)](https://maven-badges.herokuapp.com/maven-central/com.societegenerale.commons/arch-unit-maven-plugin)

**ArchUnit Maven plugin** is a simple Maven wrapper
around [ArchUnit](https://github.com/TNG/ArchUnit) that enables you to easily make sure that all
your projects follow the same architecture rules.

ArchUnit is an awesome tool to implement some tricky checks that other static analysis tools can't
implement at all : these checks run as unit tests, and guarantee that build will break if any
violation is introduced, giving developers very fast feedback on their work.

Now, imagine you have 3 architecture rules, and you want 10 repositories to apply them... By
default, you'll have no choice but copy/paste the rules (ie unit tests) in the 10 repositories. And
if somebody removes one of these tests later, it may take months to realize it.

ArchUnit Maven plugin comes with a couple of rules out of the box (but you can add your own) : all
you need is a bit of Maven config in your root pom.xml to make sure the rules you want to enforce
are actually run at every build ! it then becomes very easy to have a proper governance on dozens of
repositories.

And if you want to have regular reporting on which projects are using ArchUnit Maven plugin, with
which rules, you can use our [GitHub crawler](https://github.com/societe-generale/github-crawler)

## How to use ArchUnit Maven plugin ?

Add below plugin in your root pom.xml : all available `````` are mentioned, so remove the ones
you don't need. If needed, specify in `````` property the path of the directory where
the rules will be asserted

```xml

com.societegenerale.commons
arch-unit-maven-plugin
5.0.0


propertyValue



com.societegenerale.commons.plugin.rules.NoStandardStreamRuleTest
com.societegenerale.commons.plugin.rules.NoJunitAssertRuleTest
com.societegenerale.commons.plugin.rules.NoJodaTimeRuleTest
com.societegenerale.commons.plugin.rules.NoJavaUtilDateRuleTest
com.societegenerale.commons.plugin.rules.NoPowerMockRuleTest
com.societegenerale.commons.plugin.rules.NoPrefixForInterfacesRuleTest
com.societegenerale.commons.plugin.rules.NoPublicFieldRuleTest


com.societegenerale.commons.plugin.rules.NoTestIgnoreRuleTest
com.societegenerale.commons.plugin.rules.NoTestIgnoreWithoutCommentRuleTest

com.societegenerale.commons.plugin.rules.NoInjectedFieldTest
com.societegenerale.commons.plugin.rules.NoAutowiredFieldTest





test

arch-test






com.societegenerale.commons
arch-unit-build-plugin-core
SOME_CORE_VERSION_GREATER_THAN_THE_PLUGIN

```

## Dependency on arch-unit-build-plugin-core

Since v2.3.0, a lot of the original code from this repository has been moved
to [https://github.com/societe-generale/arch-unit-build-plugin-core](https://github.com/societe-generale/arch-unit-build-plugin-core) ,
so that we can build a Maven or a Gradle plugin on top of a (
common) [core logic](https://github.com/societe-generale/arch-unit-build-plugin-core/tree/arch_unit_build_plugin_core_2.3.0).

Therefore, since then, this repository is greatly simplified as it contains only Maven specific code
and the adapters between Maven world and arch-unit-build-plugin-core.

This Maven plugin ships with a default version of arch-unit-build-plugin-core, but if new rules are
added in arch-unit-build-plugin-core, you'll need to declare it as a dependency (as in the example
above) to benefit from them. As long as there's no major change in the core API that would force us
to update the Maven plugin, we won't have to release a new version of the plugin.

## Adding custom rules

### Add a single rule, for a given project

If you need to add a rule that is specific to a project, just add a regular ArchUnit test, as
described on ArchUnit's homepage. You'll need to import yourself archUnit dependency, so please make
sure to use the same version as in the plugin, otherwise there may be strange behaviors. ArchUnit
Maven plugin will not be involved.

### Add a rule, and share it across projects

You can share custom rules by packaging the respective classes containing the rules in a jar.
Such classes can either contain fields of type `ArchRule` or methods taking a single parameter of
type
`JavaClasses` (compare JUnit support
at https://www.archunit.org/userguide/html/000_Index.html#_junit_4_5_support).
The classes those rules will be checked against are configured within the plugin.
Add the jar containing your classes to your classpath (by mentioning it as a plugin's dependency for
instance),
and then mention the `````` with its fully qualified name the `````` block,
so that ArchUnit Maven plugin can instantiate it and run it.

So your config would become something like :

```xml

com.societegenerale.commons
arch-unit-maven-plugin
5.0.0


true



my/package/to/exclude




com.societegenerale.commons.plugin.rules.NoJunitAssertRuleTest




com.tngtech.archunit.library.GeneralCodingRules

com.myproject.mypackage

main



NO_CLASSES_SHOULD_ACCESS_STANDARD_STREAMS







test

arch-test






com.myCompany
custom-quality-rules
1.0.0

```

## Skipping rules

In case of adding **ArchUnit Maven plugin** to a legacy code base you might not be able to enforce
all rules immediately.
You may add **ArchUnit Maven plugin** to a parent POM of your Maven artifacts and still be able to
skip execution in child
projects by using the skip-configuration.

### Skipping just one rule

Most of the time you add a new rule to your **ArchUnit Maven plugin** (which might immediately be
available in all of
your artifacts) but the issues **ArchUnit** reveals using your rule may not be fixed as soon as you
need to release the
next version of your artifacts.

To skip a rule temporarily, configure it like

```xml

false

com.mycompany.rules.CustomArchRule
${archunit.customrule.skip}

```

and then your slow-to-be-fixed-artifacts my override the property
`true`

### Skipping the whole plugin

If even skipping certain rules doesn't fit your needs, configure to skip the whole plugin execution:

```xml

false

${archunit.skip}

```

and then you can switch the parameter `archunit.skip` either on runtime (via `-Darchunit.skip=true`)
or statically in child modules.

## ArchUnit advanced configuration

Since v2.2.0, you can benefit from ArchUnit advanced configuration, as the plugin can find
`archunit.properties` file. More infos
in [ArchUnit's user guide](https://www.archunit.org/userguide/html/000_Index.html#_advanced_configuration)

### Using `archunit.properties` file

ArchUnit loads its
configuration [once](https://github.com/TNG/ArchUnit/blob/3df2e7d26c6b18b1c2d383088a37ac0f45020f78/archunit/src/main/java/com/tngtech/archunit/ArchConfiguration.java#L57)
using the first `archunit.properties` file found as a resource in the classpath, then it's cached
and reused.
This can cause surprises in multi-module Maven projects since the ArchUnit instance is in use takes
its configuration from the first module it's used with, and doesn't get reconfigured for each module
as might be expected.

For example, if you are packaging
a [freezing rule](https://www.archunit.org/userguide/html/000_Index.html#_freezing_arch_rules) for
use in a multi-module project,
the violation store location is configured once and isn't reconfigured for each module.
As a workaround the rule can be adapted to overwrite the configuration before triggering the
freezing rule, as described
in [#37](https://github.com/societe-generale/arch-unit-maven-plugin/issues/37#issuecomment-792115469).

### Using Maven `` configuration

Since v3.0.0, an alternative approach is to configure properties using the Maven plugin where
properties can be configured without writing to an `archunit.properties` file.
The plugin will reconfigure ArchUnit for each module, complete with standard maven property
expansion, before triggering the configured rules.

For example, if you are packaging
a [freezing rule](https://www.archunit.org/userguide/html/000_Index.html#_freezing_arch_rules) for
use in a multi-module project,
you can enable store creation and set the location relative to each module:

```xml

com.societegenerale.commons
arch-unit-maven-plugin


true
${project.basedir}/src/archunit/


...

```

See [here](https://github.com/societe-generale/arch-unit-maven-plugin/issues/37#issuecomment-792115469)
for a workaround : you need to overwrite the
store location value in the cached configuration before triggering the freezing rule.

## Excluding paths

Since v2.4.0, configuration can take an optional `excludedPaths` element. All classes that have a
location that contains one the mentioned Strings
will be excluded from the ArchUnit checks : can be useful in case some classes are generated (
Lombok, Mapstruct, ..) and you have little or no control
on what gets generated.

See [ExclusionImportOption.java](https://github.com/societe-generale/arch-unit-build-plugin-core/blob/2a6f5d009b96a7921bf2de65fcc0aad85edc006a/src/main/java/com/societegenerale/commons/plugin/utils/ExclusionImportOption.java)
for details on the (very simple) logic.

Since v2.8.0, we can exclude something like `generated-sources`, even if the code ends up in the
same package(S) as the regular code. See the
discussion in https://github.com/societe-generale/arch-unit-maven-plugin/pull/44 for more details

## Disable fallback for wrongly configured paths

When no class files have been found using the configured paths, all folders of the current maven
module are scanned for analysable classes. This could be a
problem in multi-modules projects when some modules do not contain analyzable code (e.g. for
packaging of web applications), if you don't want to override the plugin config (by disabling it
entirely) in some modules

This behavior can be disabled by setting the optional `fallbackToRootDirectory` element of the
configuration to `false`.

## Contribute !

If you want to make changes in the Maven specific behavior, don't hesitate to open on issue on this
repository and/or create a pull request.

If you don't want to package your rules separately and/or feel they could be useful to others, we
can make your rules part of
arch-unit-build-plugin-core, so that they can be used out of the box by anyone : don't hesitate to
send us a pull request ! have a look at
the [code](https://github.com/societe-generale/arch-unit-build-plugin-core/tree/arch_unit_build_plugin_core_2.3.0/src/main/java/com/societegenerale/commons/plugin/rules)
, it's very easy to add one.

## Official maintainers

- [Paul Williams](https://github.com/paul58914080)
- [Vincent Fuchs](https://github.com/vincent-fuchs)
- [Arpit Garg](https://github.com/arpitgarg9168)