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
- 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
Add this line to your application's Gemfile:
And then execute:
Or install it yourself as:
$ gem install mudguard
$ 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 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
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
X -> Y meaning "X depends on Y". See following examples:
||Module A can depend on module or constant B|
||Module Infrastructure can depend on Rails|
||Module Infrastructure and its submodules can depend on ActiveRecord|
||Any module can depend on class Exception|
Any dependency for which Mudguard doesn't find a matching policy is reported as an impermissible dependency.
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?
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.
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.