• Stars
    star
    142
  • Rank 258,495 (Top 6 %)
  • Language
    Go
  • License
    MIT License
  • Created over 3 years ago
  • Updated 5 months ago

Reviews

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

Repository Details

Architecture checks for Go projects

Arch-Go

Architecture checks for Go projects

Supported rules

Dependencies Checks

Supports defining import rules

  • Allowed dependencies
    • internal dependencies (same module)
    • standard library dependencies
    • external dependencies (3rd party packages)
  • Not allowed dependencies
    • internal dependencies (same module)
    • standard library dependencies
    • external dependencies (3rd party packages)

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:

  • shouldNotContainInterfaces
  • shouldNotContainStructs
  • shouldNotContainFunctions
  • shouldNotContainMethods
  • shouldOnlyContainInterfaces
  • shouldOnlyContainStructs
  • shouldOnlyContainFunctions
  • shouldOnlyContainMethods

Cyclic Dependencies checks

Checks if a set of packages contains cyclic dependencies.

Function checks

Checks some functions properties, like the following:

  • Maximum number of parameters
  • Maximum number of return values
  • Maximum number of public functions per file
  • Maximum number of lines in the function body

Naming rules checks

Checks some naming rules, like the following:

  • If a struct implements an interface that match some name pattern, then it's name should starts or ends with a specific pattern. For example, all structs that implements 'Verificator' interface, should have a name that ends with 'Verificator'

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.v2"
  - package: "**.example.**"
    shouldNotDependsOn:
      external:
        - "github.com/foobar/example-module"

contentsRules:
  - package: "**.impl.model"
    shouldNotContainInterfaces: true
  - package: "**.impl.config"
    shouldOnlyContainFunctions: true
  - package: "**.impl.dependencies"
    shouldNotContainStructs: true
    shouldNotContainInterfaces: true
    shouldNotContainMethods: true
    shouldNotContainFunctions: true

functionsRules:
  - package: "**.impl.**"
    maxParameters: 3
    maxReturnValues: 2
    maxPublicFunctionPerFile: 1
    maxLines: 50

cyclesRules:
  - package: "**.cmd"
    shouldNotContainCycles: true

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.

Example Description
*.name Package should end with name and anything before, supporting only one level (for example foo/name, but no foo/bar/name)
**.name Package should end with name and anything before, supporting multiple levels (for example either foo/name and foo/bar/name)
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.**.bar Package 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.*.bar Package 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.

  • At this moment Arch-Go doesn't analize internal components as structs, interfaces, functions or methods, just verifies if a certain package complies with a rule package pattern, so then this rule is evaluated against this package

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

To install Arch-Go, run

$ go install -v github.com/fdaines/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'

Supported flags

Flag Description
--verbose Includes detailed information while the command is running. The shorthand is -v
--html Generates a simple HTL report with the evaluation result.

Examples

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

Contributions

Feel free to contribute.