Home

Awesome

CI Codecov Go Reference Go Report Card <img align="center" src="logo.png" alt="Arch-Go" title="Arch-Go" width="600px"/>

Arch-Go

Architecture checks for Go projects

Supported rules

Dependencies Checks

Supports defining import rules

Package Content Checks

Allows you to define the contents of a set of packages, e.g. you can define that a desired package should only contain interfaces definitions. The supported checks are:

Function checks

Checks some functions properties, like the following:

Naming rules checks

Checks some naming rules, like the following:

Configuration

File arch-go.yml

version: 1
threshold:
  compliance: 100
  coverage: 100
dependenciesRules:
  - package: "**.impl.*"
    shouldOnlyDependsOn:
      internal:
          - "**.foo.*"
          - "*.bar.*"
    shouldNotDependsOn: 
      internal: ["**.model.**"]
  - package: "**.utils.**"
    shouldOnlyDependsOn:
      - "**.model.**"
  - package: "**.foobar.**"
    shouldOnlyDependsOn:
      external:
        - "gopkg.in/yaml.v3"
  - package: "**.example.**"
    shouldNotDependsOn:
      external:
        - "github.com/foobar/example-module"
contentsRules:
  - package: "**.impl.model"
    shouldNotContainInterfaces: true
  - package: "**.impl.configuration"
    shouldOnlyContainFunctions: true
  - package: "**.impl.dependencies"
    shouldNotContainStructs: true
    shouldNotContainInterfaces: true
    shouldNotContainMethods: true
    shouldNotContainFunctions: true
functionsRules:
  - package: "**.impl.**"
    maxParameters: 3
    maxReturnValues: 2
    maxPublicFunctionPerFile: 1
    maxLines: 50
namingRules:
  - package: "**.arch-go.**"
    interfaceImplementationNamingRule:
      structsThatImplement: "*Connection"
      shouldHaveSimpleNameEndingWith: "Connection"

Package name patterns

The package name can be defined as a fixed value or using * special character, to create a simple pattern.

ExampleDescription
*.namePackage should end with name and anything before, supporting only one level (for example foo/name, but no foo/bar/name)
**.namePackage should end with name and anything before, supporting multiple levels (for example either foo/name and foo/bar/name)
**.*namePackage should end with suffix name and anything before, supporting multiple levels (for example either foo/examplename and foo/bar/examplename)
**.name*Package should start with prefix name and anything before, supporting multiple levels (for example either foo/nameexample and foo/bar/nameexample)
name.*Package should start with name and anything before, supporting only one level (for example name/foo, but no name/foo/bar)
name.**Package should start with name and anything before, supporting multiple levels (for example either name/foo and name/foo/bar)
**.name.**Package should contain name, supporting multiple levels before and after (for example both foo/name/x/y/z, foo/bar/name and foo/bar/name/x)
**.foo/bar.**Package should contain foo/bar, supporting multiple levels before and after (for example both x/y/foo/bar/w/z, foo/bar/name and x/y/foo/bar)
foo.**.barPackage should start with foo, and ends with bar, and can have anything between them. (for example foo/bar, foo/test/blah/bar and foo/ok/bar)
foo.*.barPackage should start with foo, and ends with bar, and can have only one level between them. (for example foo/bar and foo/ok/bar, but no foo/test/blah/bar)

Threshold configuration

Current version supports threshold configuration for compliance and coverage rate. By default both limits are set to 100%.

Compliance rate threshold

Represents how much the compliance level of the module is considering all the rules defined in the arch-go.yml file. For example, if there are 4 rules and the module meets 3 of them, then its compliance level will be 75%.

Arch-Go will check that the compliance level of your module must be equals or greater than the compliance threshold defined in your arch-go.yml file, if not then the verification will fail.

Coverage rate threshold

Represents how many packages in this module were evaluated by at least one rule.

Arch-Go will check that the coverage level of your module must be equals or greater than the threshold defined in your arch-go.yml file, if not then the verification will fail.

Usage

Using Arch-Go in command line

To install Arch-Go, run

$ go install -v github.com/arch-go/arch-go@latest

To execute this tool you have to be in the module path

$ cd [path-to-your-module]

Now you can execute Arch-Go tool

$ arch-go [flags]

Describing your architecture guidelines

Arch-Go includes a command to describe the architecture rules from arch-go.yml file.

$ arch-go describe

The output of the describe command is similar to:

$ arch-go describe
Dependency Rules
        * Packages that match pattern '**.cmd.*',
                * Should only depends on packages that matches:
                        - '**.arch-go.**'
Function Rules
        * Packages that match pattern '**.arch-go.**' should comply with the following rules:
                * Functions should not have more than 50 lines
                * Functions should not have more than 4 parameters
                * Functions should not have more than 2 return values
                * Files should not have more than 5 public functions
Content Rules
        * Packages that match pattern '**.impl.model' should not contain functions or methods
        * Packages that match pattern '**.impl.config' should only contain functions
Naming Rules
        * Packages that match pattern '**.arch-go.**' should comply with:
                * Structs that implement interfaces matching name '*Verification' should have simple name ending with 'Verification'
Threshold Rules
        * The module must comply with at least 100% of the rules described above.
        * The rules described above must cover at least 100% of the packages in this module.

Time: 0.000 seconds

Supported flags

FlagDescription
--colorIf not set (default: auto) in a tty the colors are printed. If set to yes or no the default is overridden. This can be useful in the CI.
--verboseIncludes detailed information while the command is running. The shorthand is -v
--htmlGenerates an HTML report with the evaluation result. The HTML report is generated in .arch-go/report.html
--jsonGenerates a JSON report with the evaluation result. The JSON report is generated in .arch-go/report.json

Examples

$ arch-go 
$ arch-go -v
$ arch-go --verbose
$ arch-go --html
$ arch-go --json
$ arch-go --color
$ arch-go describe

Using Arch-Go programmatically

The current version of Arch-Go allows us to include architecture checks as part of the tests run by the go test tool.

You need to include Arch-Go as a dependency in your project, using

go get github.com/arch-go/arch-go@latest

Then you need to create Architecture Tests, there is an example of a simple test case:

package architecture_test

import (
	"testing"

	archgo "github.com/arch-go/arch-go/api"
	config "github.com/arch-go/arch-go/api/configuration"
)

func TestArchitecture(t *testing.T) {
	configuration := config.Config{
		DependenciesRules: []*config.DependenciesRule{
			{
				Package: "**.cmd.**",
				ShouldOnlyDependsOn: &config.Dependencies{
					Internal: []string{
						"**.cmd.**",
						"**.internal.**",
					},
				},
			},
		},
	}
	moduleInfo := config.Load("github.com/arch-go/my-go-project")

	result := archgo.CheckArchitecture(moduleInfo, configuration)

	if !result.Pass {
		t.Fatal("Project doesn't pass architecture tests")
	}
}

The result variable will store more than the verification result, including details for each rule type and analyzed packages, so then you can access all this data to create assertions as you need.

Contributions

Feel free to contribute.