Project

mudguard

0.0
The project is in a healthy, maintained state
mudguard helps your ruby project not becoming a 'Big ball of mud'
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
 Project Readme

Mudguard

Mudguard is a Ruby static code analyzer that investigates the coupling of modules in your source code. Mudguard prevents your code from becoming a Big ball of mud and helps implementing and maintaining an intended design.

Mudguard is inspired by

  • Rubocop
  • Clean Architecture by Robert C. Martin (ISBN-13: 978-0-13-449416-6)
  • having seen many larger code bases in a sorrow state
  • my inability to efficiently break up application code into gems or rails engines

Installation

Add this line to your application's Gemfile:

gem 'mudguard'

And then execute:

$ bundle

Or install it yourself as:

$ gem install mudguard

Quickstart

$ cd my/cool/ruby/project
$ mudguard

Mudguard creates on it's first run a file called .mudguard.yml which is used to configure design policies governing your code. A .mudguard.yml could look like:

'./**/*.rb': # all code
  # all code can depend on siblings in same module or class
  - ^(::.+)(::[^:]+)* -> \1(::[^:]+)*$
  # all code can depend on certain types
  - .* -> ::(String|SecureRandom|Container|Time|Date|JSON|Object|Hash)$

  # in all code module Application can depend on module Domain
  - ^::Application(::[^:]+)* -> ::(Domain)(::[^:]+)*$
  # in all code module Infrastructure can depend on module Application
  - ^::Infrastructure(::[^:]+)* -> ::(Application)(::[^:]+)*$

'spec/**/*.rb': # spec code
  # Only in test code can we use RSpec, Timecop and Exception
  - .* -> ::(RSpec|Timecop|Exception)$

The .mudguard.yml

The .mudguard.yml defines scopes and policies. A policy defines which dependencies are inside that scope permissible:

scope1:
    - policy 1
    - policy 2
scope2:
    - policy 3

The scope is a glob-pattern and defines to which files a set of policies apply. For example a value lib/docker/**/*.rb defines a scope containing all Ruby files inside folder lib/docker.

A policy is a regular expression matching one or a set of dependencies that are permissible inside that scope. Mudguard represents a dependency as a symbol in form of X -> Y meaning "X depends on Y". See following examples:

Policy matched Dependency Explanation
^::A -> ::B$ ::A -> ::B Module A can depend on module or constant B
^::Infrastructure -> ::Rails$ ::Infrastructure -> ::Rails Module Infrastructure can depend on Rails
^::Infrastructure(::[^:]+)* -> ::ActiveRecord$ ::Infrastructure::Logger -> ::ActiveRecord or ::Infrastructure::Persistence -> ::ActiveRecord Module Infrastructure and its submodules can depend on ActiveRecord
.* -> ::Exception$ ::Api::Gateway -> ::Exception or ::Logger -> ::Gateway Any module can depend on class Exception

Any dependency for which Mudguard doesn't find a matching policy is reported as an impermissible dependency.

Outlook

Using regular expressions as policies is very flexible but difficult to use. Furthermore certain patterns used in the regular expressions do repeat. It might be useful to replace regular expressions in future with a specific language to describe permissible dependencies. Any thoughts on that?

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/Enceradeira/mudguard. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

License

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

Code of Conduct

Everyone interacting in the Mudguard project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.