• Stars
    star
    116
  • Rank 303,894 (Top 6 %)
  • Language
    Java
  • License
    Apache License 2.0
  • Created almost 6 years ago
  • Updated 10 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

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

ArchUnit Maven plugin

Build Status Coverage Status Maven Central

ArchUnit Maven plugin is a simple Maven wrapper around 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

How to use ArchUnit Maven plugin ?

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

<plugin>
	<groupId>com.societegenerale.commons</groupId>
    <artifactId>arch-unit-maven-plugin</artifactId>
    <version>3.0.0</version>
    <configuration>
        <properties>
            <archunit.propertyName>propertyValue</archunit.propertyName>
        </properties>
		<rules>
			<preConfiguredRules>
				<rule>com.societegenerale.commons.plugin.rules.NoStandardStreamRuleTest</rule>
				<rule>com.societegenerale.commons.plugin.rules.NoJunitAssertRuleTest</rule>
				<rule>com.societegenerale.commons.plugin.rules.NoJodaTimeRuleTest</rule>
				<rule>com.societegenerale.commons.plugin.rules.NoJavaUtilDateRuleTest</rule>
				<rule>com.societegenerale.commons.plugin.rules.NoPowerMockRuleTest</rule>
				<rule>com.societegenerale.commons.plugin.rules.NoPrefixForInterfacesRuleTest</rule>
				<rule>com.societegenerale.commons.plugin.rules.NoPublicFieldRuleTest</rule>
				
				<!-- you may want to use one of the below rules, but not both at same time -->
				<rule>com.societegenerale.commons.plugin.rules.NoTestIgnoreRuleTest</rule>
				<rule>com.societegenerale.commons.plugin.rules.NoTestIgnoreWithoutCommentRuleTest</rule>

				<rule>com.societegenerale.commons.plugin.rules.NoInjectedFieldTest</rule>
				<rule>com.societegenerale.commons.plugin.rules.NoAutowiredFieldTest</rule>
			</preConfiguredRules>
		</rules>
	</configuration>
	<executions>
		<execution>
			<phase>test</phase>
			<goals>
				<goal>arch-test</goal>
			</goals>
		</execution>
	</executions>
    <dependencies>
       <dependency>
           <!-- 
                A version of the core jar is included by default, but don't hesitate 
                to upgrade to a later one if you need :
                we will be able to add rules and behavior in arch-unit-build-plugin-core
                without releasing a new version of arch-unit-maven-plugin
            -->
            <groupId>com.societegenerale.commons</groupId>
            <artifactId>arch-unit-build-plugin-core</artifactId>
            <version>SOME_CORE_VERSION_GREATER_THAN_THE_PLUGIN</version>
       </dependency>
    </dependencies>
</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 , so that we can build a Maven or a Gradle plugin on top of a (common) core logic.

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 <rule> with its fully qualified name the <rules> block, so that ArchUnit Maven plugin can instantiate it and run it.

So your config would become something like :

<plugin>
    <groupId>com.societegenerale.commons</groupId>
    <artifactId>arch-unit-maven-plugin</artifactId>
    <version>3.0.0</version>
    <configuration>

        <!-- optional - you can avoid build fail if there is issue. True to avoid build failure, default is false -->
        <noFailOnError>true</noFailOnError>

        <!-- optional - you can exclude classes that have a path containing any of the mentioned paths -->
        <excludedPaths>
            <excludedPath>my/package/to/exclude</excludedPath>
        </excludedPaths>

        <rules>
            <!-- using a rule available out of the box... -->
            <preConfiguredRules>
                <rule>com.societegenerale.commons.plugin.rules.NoJunitAssertRuleTest</rule>
            </preConfiguredRules>
            <!-- ... and a custom one, coming from a dependency of the plugin -->
            <configurableRules>
                <configurableRule>
                    <rule>com.tngtech.archunit.library.GeneralCodingRules</rule>
                    <applyOn>
                        <packageName>com.myproject.mypackage</packageName>
                        <!-- scope can be "main" or "test" -->
                        <scope>main</scope>
                    </applyOn>

                    <checks>
       	 	        <!-- otherwise you can specify either field or method names here. If no checks block is defined, all are executed -->
       	 		    <check>NO_CLASSES_SHOULD_ACCESS_STANDARD_STREAMS</check>
       	 	    </checks>
            </configurableRule>
       </configurableRules>

    </rules>
  </configuration>
  <executions>
    <execution>
      <phase>test</phase>
      <goals>
        <goal>arch-test</goal>
      </goals>
    </execution>
  </executions>
  <dependencies>
    <dependency>
        <!-- dependency contains com.mycompany.rules.CustomArchRule -->
        <groupId>com.myCompany</groupId>
        <artifactId>custom-quality-rules</artifactId>
        <version>1.0.0</version>
    </dependency>
  </dependencies>
</plugin>

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

<properties>
  <archunit.customrule.skip>false</archunit.customrule.skip>
</properties>
<!-- and inside your plugin's configuration -->
<configurableRule>
  <rule>com.mycompany.rules.CustomArchRule</rule>
  <skip>${archunit.customrule.skip}</skip>
  <!-- detailed configuration omitted -->
</configurableRule>

and then your slow-to-be-fixed-artifacts my override the property <archunit.customrule.skip>true</archunit.customrule.skip>

Skipping the whole plugin

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

<properties>
    <archunit.skip>false</archunit.skip>
</properties>
        <!-- and then inside the ArchUnit Maven plugin -->
<configuration>
<skip>${archunit.skip}</skip>
</configuration>

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

Using archunit.properties file

ArchUnit loads its configuration once 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 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.

Using Maven <properties> 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 for use in a multi-module project, you can enable store creation and set the location relative to each module:

<plugin>
    <groupId>com.societegenerale.commons</groupId>
    <artifactId>arch-unit-maven-plugin</artifactId>
    <configuration>
        <properties>
            <freeze.store.default.allowStoreCreation>true</freeze.store.default.allowStoreCreation>
            <freeze.store.default.path>${project.basedir}/src/archunit/</freeze.store.default.path>
        </properties>
        <rules>
        ...
        </rules>
    </configuration>
</plugin>

See here 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 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 #44 for more details

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 , it's very easy to add one.

Official maintainers

  • Arpit Garg
  • Vincent Fuchs

More Repositories

1

swordphish-awareness

Swordphish Phishing Awareness Tool
Python
220
star
2

github-crawler

a utility to crawl all your repositories and find the information you need - now also working for Gitlab !
Kotlin
106
star
3

rabbitmq-advanced-spring-boot-starter

A generic library for messaging with rabbit mq with extension on spring boot amqp
Java
89
star
4

os-factory

OS Factory for Public Cloud & Private Cloud
Python
33
star
5

arch-unit-build-plugin-core

The core logic for Maven or Gradle ArchUnit plugin
Java
31
star
6

core-nlg

CoreNLG is an easy to use and productivity oriented Python library for Natural Language Generation. It aims to provide the essential tools for developers to structure and write NLG projects.
Python
27
star
7

aikit

Automated machine learning package
Python
27
star
8

arch-unit-gradle-plugin

A Gradle wrapper around ArchUnit, to easily share and enforce architecture rules across projects
Java
26
star
9

code2pg

Tool to help migrate application code from Oracle to PostgreSQL
Perl
24
star
10

react-loopback-generator

React Loopback project generator. We glue all that together for you.
JavaScript
24
star
11

ci-droid

The dev team best buddy, taking care of all the housekeeping for your repositories
Java
21
star
12

cloud-innovation-platform

Cloud Innovation Platform, by Société Générale
Python
16
star
13

OCTANE

Securize the exposure of web applications through cloud service provider (currently AWS)
Shell
13
star
14

GreenCircle

Coding Challenge created by Societe Generale for CodinGame
Java
11
star
15

failover

A generic lib to manage the failover on external referential service
Java
7
star
16

spintest

Functional scenario interpreter for API testing
Python
5
star
17

societe-generale.github.io

societe-generale.github.io
HTML
5
star
18

healthcheck-app

An Express application for monitoring apps with logs
JavaScript
5
star
19

OCTANE-AZURE

Securize the exposure of web applications through cloud service provider (currently AZURE)
HCL
4
star
20

pysgconnect

A python script to ease SG Connect integration for our clients
Python
4
star
21

sg-openapi-plugin

Société Générale's OpenAPI ruleset
Java
3
star
22

ci-droid-tasks-consumer

CI-droid consumer, receiving tasks to perform
Java
2
star
23

ci-droid-run

an example of running CI-droid on your machine
Shell
1
star
24

Kawatta

Allows you to get a human readable log of the changes between two Python structures
Python
1
star
25

slf4j-metrics-publisher

a utils library to easily publish metrics through LogstashAppender and SLF4J
Java
1
star
26

ci-droid-internal-api

APIs used internally by CI-droid - useful to decouple the core from the extensions
Java
1
star
27

GRL_transactional_graphs

Python
1
star