---
title: Validate project structure
description: Validate the package structure of all projects with the validatePackageStructure task.
icon: package-check
---

In a multi-project setup, you typically want a distinct package for each project. An example:

| Gradle project path                     | Absolute package name                      |
| --------------------------------------- | ------------------------------------------ |
| `:certificate:domain`                   | `com.company.project.certificate.domain`   |
| `:certificate:web-api`                  | `com.company.project.certificate.webapi`   |
| `:accounting:domain`                    | `com.company.project.accounting.domain`    |
| `:accounting:web-api`                   | `com.company.project.accounting.webapi`    |
| `:accounting:payment-provider-adapter`  | `com.company.project.accounting.ppa`       |

Most of these mappings follow Arciphant's defaults (lower case, hyphens removed — e.g. `web-api` → `webapi`). A custom
fragment like `ppa` is configured with
[`mapComponentNamesToPackageFragments`](#mapcomponentnamestopackagefragments).

Arciphant provides the [task `validatePackageStructure`](/tasks#validatepackagestructure) to validate correct package
structure. The task is registered on every project; the root project's task aggregates the validation of all
subprojects, so a single invocation on the root project validates the whole build.

The validation follows the _actual_ source directories of the project's source sets, so
[customized source directories](/component-layouts#customizing-source-directories) — and relocated `srcDirs` in
general — are validated at their configured location. Files under `src/` that do not belong to any source set are
reported as well.

To configure it, add a `packageStructureValidation` block to the _arciphant_ configuration, for example:

```kotlin settings.gradle.kts {4-6}
arciphant {
  // …

  packageStructureValidation {
    basePackageName("ch.ergon.arciphant.example")
  }
}
```

If no configuration is provided, default values are applied.

## Configuration options

The `packageStructureValidation` block provides the following configuration options (see also
`PackageStructureValidationDsl`) to customize the desired package structure:

| Option                                | Description                                                                                                                                                                                                                                                                                    |
|---------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `basePackageName`                     | The base package name for the whole project.<br />Example: `basePackageName("com.company.project")`                                                                                                                                                                                            |
| `disableUseLowerCase`                 | By default, upper case letters are converted to lower case when mapping project names to corresponding package fragments.<br />Example: project name `FileStore` is mapped to package fragment `filestore`.<br />Use `disableUseLowerCase()` to deactivate this behavior.                      |
| `disableRemoveUnderscore`             | By default, underscores '\_' are removed when mapping project name to corresponding package fragment.<br />Example: project name `file_store` is mapped to package fragment `filestore`.<br />Use `disableRemoveUnderscore()` to deactivate this behavior.                                     |
| `disableRemoveHyphen`                 | By default, hyphens '-' are removed when mapping project name to corresponding package fragment.<br />Example: project name `file-store` is mapped to package fragment `filestore`.<br />Use `disableRemoveHyphen()` to deactivate this behavior.                                              |
| `mapModuleNamesToPackageFragments`    | Configure mappings for specific module names. See detailed description [below](#mapmodulenamestopackagefragments).                                                                                                                                                                             |
| `mapComponentNamesToPackageFragments` | Configure mappings for specific component names. See detailed description [below](#mapcomponentnamestopackagefragments).                                                                                                                                                                       |
| `mapProjectPathsToAbsolutePackages`   | Completely overrides the package name for the given Gradle project path. See detailed description [below](#mapprojectpathstoabsolutepackages).                                                                                                                                                 |
| `excludeProjectPath`                  | Excludes a specific project from package validation.<br />Example: `excludeProjectPath(":specific:project:path")`                                                                                                                                                                              |
| `excludeResourcesFolder`              | By default, all folders in the `src`-folder of each project are validated.<br />Use `excludeResourcesFolder()` to exclude the resources folders of all source sets (e.g. `src/main/resources`) from validation.                                                                                |
| `excludeSrcFolders`                   | By default, all folders in the src-folder of each project are validated.<br />Use `excludeSrcFolders()` to exclude specific folders.<br />Examples: To exclude `src/generated` use `excludeSrcFolders("generated")`, to exclude `src/main/generated` use `excludeSrcFolders("main/generated")` |

### `mapModuleNamesToPackageFragments` [#mapmodulenamestopackagefragments]

Configure mappings for specific module names. The mappings apply only to the names of arciphant modules (in both
component layouts) — not to components, [base path](/additional-settings#custom-base-path) segments or other projects.
The `basePackageName` is still used. The configured value replaces only the package fragment related to the specified
module.

### `mapComponentNamesToPackageFragments` [#mapcomponentnamestopackagefragments]

The same as [`mapModuleNamesToPackageFragments`](#mapmodulenamestopackagefragments), but for component names —
regardless of whether the component is a Gradle project (project layout) or a source set (source set layout).

An example using both mappings:

```kotlin settings.gradle.kts {7-8}
arciphant {
  // …

  packageStructureValidation {
    basePackageName("com.company.project")

    mapModuleNamesToPackageFragments("financial-accounting" to "accounting")
    mapComponentNamesToPackageFragments("payment-provider-adapter" to "ppa")
  }
}
```

The above config results in the following mapping:

| Gradle project path                               | Absolute package name                    |
| ------------------------------------------------- | ---------------------------------------- |
| `:financial-accounting:domain`                    | `com.company.project.accounting.domain`  |
| `:financial-accounting:web-api`                   | `com.company.project.accounting.webapi`  |
| `:financial-accounting:payment-provider-adapter`  | `com.company.project.accounting.ppa`     |

### `mapProjectPathsToAbsolutePackages` [#mapprojectpathstoabsolutepackages]

Completely overrides the package name for the given Gradle project path. Unlike the name mappings, the
`basePackageName` is _not_ used.

Example:

```kotlin settings.gradle.kts {7-10}
arciphant {
  // …

  packageStructureValidation {
    basePackageName("com.company.project")

    mapProjectPathsToAbsolutePackages(
      ":specific:project:path" to "com.specific.package.name",
      ":any:other:path" to "com.any.other.package.name",
    )
  }
}
```

Overriding a module path (e.g. `:orders`) also applies to the components of the module: their package fragments are
still appended (e.g. `com.specific.package.name.domain` for the `domain` component). In the project layout, a component
project path (e.g. `:orders:domain`) can be overridden as well; this takes precedence over the override of its module.
