0.0
The project is in a healthy, maintained state
A Ruby gem to validate architectural layer dependencies based on YAML configuration
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

~> 13.0
~> 3.0

Runtime

~> 3.0
 Project Readme

Layer Checker

This project was made with a little help of vibe-coding.

A Ruby gem to validate architectural layer dependencies in your projects based on YAML configuration files.

Installation

Add this line to your application's Gemfile:

gem 'layer_checker'

And then execute:

bundle install

Or install it yourself as:

gem install layer_checker

Usage

1. Create a Configuration File

Create a project_layers.yml file in your project root:

version: 1

modules:
  controller:
    paths:
      - app/controllers/**
    depends_on:
      - service
      - presenter

  service:
    paths:
      - app/services/**
    depends_on:
      - model

  model:
    paths:
      - app/models/**
    depends_on: []

  presenter:
    paths:
      - app/presenters/**
    depends_on: []

options:
  fail_on_violation: true
  unassigned_behavior: warn
  allow_external_constants:
    - ActiveRecord::Base
    - ApplicationController

2. Run the Checker

Command Line

layer_checker

With options:

layer_checker --config custom_config.yml --format json

In Rails (Rake Task)

rake layer_checker:check

With environment variables:

CONFIG=custom_config.yml FORMAT=json rake layer_checker:check

Programmatically

require 'layer_checker'

checker = LayerChecker::Checker.new(
  config_path: 'project_layers.yml',
  project_root: Dir.pwd
)

result = checker.check
checker.report(format: :console)

if result[:success]
  puts "All good!"
else
  puts "Found #{result[:violations].size} violations"
end

Configuration

Module Structure

Simple Modules

modules:
  controller:
    paths:
      - app/controllers/**
    depends_on:
      - service

Nested Modules (DDD Style)

modules:
  billing:
    modules:
      domain:
        paths:
          - app/billing/domain/**
        depends_on: []
      
      application:
        paths:
          - app/billing/application/**
        depends_on:
          - domain
      
      infrastructure:
        paths:
          - app/billing/infrastructure/**
        depends_on:
          - application
          - domain

Feature-Based Modules

modules:
  authentication:
    modules:
      controller:
        paths:
          - app/authentication/controllers/**
        depends_on:
          - service
      
      service:
        paths:
          - app/authentication/services/**
        depends_on:
          - model
      
      model:
        paths:
          - app/authentication/models/**
        depends_on: []

Options

  • fail_on_violation (boolean, default: false): Exit with error code 1 if violations are found
  • unassigned_behavior (string, default: warn): How to handle files that don't belong to any module
    • warn: Just warn about unassigned files
    • fail: Treat unassigned files as violations
    • ignore: Ignore unassigned files
  • allow_external_constants (array, default: []): List of external constants that are allowed (e.g., Rails framework classes)

Examples

See the examples/ directory for complete configuration examples:

How It Works

  1. Load Configuration: Parses the YAML file to understand your architecture
  2. Scan Code: Finds all Ruby files in your project
  3. Extract Dependencies: Uses AST parsing to detect:
    • Constant references (e.g., UserService, User::Profile)
    • Method calls (e.g., UserService.new)
    • Class inheritance (e.g., class Controller < ApplicationController)
  4. Validate: Checks if each dependency is allowed according to your configuration
  5. Report: Shows violations with file locations and line numbers

Output Formats

Console (Default)

================================================================================
Layer Checker Results
================================================================================
✗ Found 2 violation(s)

Violations found:

  controller:
    app/controllers/users_controller.rb:15
      → controller cannot depend on model
      → Referenced: User

  service:
    app/services/billing_service.rb:23
      → service cannot depend on presenter
      → Referenced: InvoicePresenter

================================================================================
Summary:
  Total violations: 2
  Modules affected: 2
================================================================================

JSON

{
  "success": false,
  "message": "Found 2 violation(s)",
  "violations": [
    {
      "source_file": "app/controllers/users_controller.rb",
      "source_module": "controller",
      "target_constant": "User",
      "target_module": "model",
      "line_number": 15,
      "violation_type": "forbidden_dependency"
    }
  ],
  "summary": {
    "total_violations": 2,
    "modules_affected": 2
  }
}

CLI Options

Usage: layer_checker [options]
    -c, --config PATH                Path to config file (default: project_layers.yml)
    -p, --project PATH               Project root directory (default: current directory)
    -f, --format FORMAT              Output format: console or json (default: console)
    -h, --help                       Show this help message
    -v, --version                    Show version

Integration with CI/CD

Add to your CI pipeline:

# .github/workflows/ci.yml
- name: Check Layer Architecture
  run: bundle exec layer_checker

Or with Rake:

- name: Check Layer Architecture
  run: bundle exec rake layer_checker:check

Set fail_on_violation: true in your config to fail the build on violations.

Development

After checking out the repo, run:

bundle install

To build the gem:

gem build layer_checker.gemspec

To install locally:

gem install ./layer_checker-0.1.0.gem

Contributing

Bug reports and pull requests are welcome on GitHub.

License

The gem is available as open source under the terms of the MIT License.