Project

diver_down

0.0
The project is in a healthy, maintained state
DiverDown is a tool designed to dynamically analyze application dependencies and generate a comprehensive dependency map. It is particularly useful for analyzing Ruby applications, aiding significantly in large-scale refactoring projects or transitions towards a modular monolith architecture.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Runtime

 Project Readme

DiverDown

DiverDown is a tool designed to dynamically analyze application dependencies and generate a comprehensive dependency map. It is particularly useful for analyzing Ruby applications, aiding significantly in large-scale refactoring projects or transitions towards a modular monolith architecture.

Features

  • Dependency Mapping: Analyze and generate an application dependencies.
  • Module Categorization: Organizes file-by-file associations into specific groups, facilitating deeper modular monolith architectural analysis and understanding.

Getting Started

Add this line to your application's Gemfile:

gem 'diver_down'

And then execute:

$ bundle

Or install it yourself as:

$ gem install diver_down

Usage

divert_down is mainly divided into the DiverDown::Trace for dynamic analysing ruby code, and the DiverDown::Web for viewing the result on the browser.

DiverDown::Trace

The DiverDown::Trace module analyzes the execution of Ruby code and outputs the results as DiverDown::Definition objects.

tracer = DiverDown::Trace::Tracer.new

# Analyze the processing in the block.
definition = tracer.trace do
  # do something
end

# Or, analyze the processing without block.
session = tracer.new_session

session.start
# do something
session.stop

definition = session.definition
# Analysis results can be titled.
# And if specified the `definition_group`, the results can be grouped when viewed in a browser.
tracer = DiverDown::Trace::Tracer.new

tracer.trace(title: 'title', definition_group: 'group name') do
  # do something
end

Options

When analyzing user applications, it is recommended to specify the option.

name type description example default
module_set Hash{
modules: Array<Module, String> | Set<Module, String> | nil,
paths: Array<String> | Set<String> | nil
}
| DiverDown::Trace::ModuleSet
Specify the class/module to be included in the analysis results.

If you know the module name:
{ modules: [ModA, ModB] }

If you know module path:
{ paths: ['/path/to/rails/app/models/mod_a.rb'] }
{ paths: Dir["app/**/*.rb"] } nil. All class/modul are target.
caller_paths Array<String> | nil Specifies a list of allowed paths as caller paths. By specifying the user application path in this list of paths and excluding paths under the gem, the caller path is identified back to the user application path. Dir["app/**/*.rb"] nil. All paths are target.
filter_method_id_path #call | nil lambda to convert the caller path. ->(path) { path.remove(Rails.root) } nil. No conversion.

Example

# Your rails application paths
application_paths = [
  *Dir['app/**/*.rb'], 
  *Dir['lib/**/*.rb'],
].map { File.expand_path(_1) }

ignored_application_paths = [
  'app/models/application_record.rb',
].map { File.expand_path(_1) }

module_set = DiverDown::Trace::ModuleSet.new(modules: modules - ignored_modules)

filter_method_id_path = ->(path) { path.remove("#{Rails.root}/") }

tracer = DiverDown::Trace::Tracer.new(
  caller_paths: application_paths,
  module_set: {
    paths: (application_paths - ignored_application_paths)
  },
  filter_method_id_path:
)

definition = tracer.trace do
  # do something
end

Output Results

The analysis results are intended to be saved to a specific directory in either .json or .yaml format. These files are compatible with DiverDown::Web, which can read and display the results.

dir = 'tmp/diver_down'

definition = tracer.trace do
  # do something
end

File.write(File.join(dir, "#{definition.title}.json"), definition.to_h.to_json)
File.write(File.join(dir, "#{definition.title}.yaml"), definition.to_h.to_yaml)

DiverDown::Web

View the analysis results in a browser.

This gem is specifically designed to analyze large applications with a modular monolithic architecture. It allows users to categorize each analyzed file into specified modules directly through the web interface.

  • --definition-dir Specifies the directory where the analysis results are stored.
  • --module-store-path Designates a path to save the results that include details on which module each file belongs to. If this option is not specified, the results will be temporarily stored in a default temporary file.
bundle exec diver_down_web --definition-dir tmp/diver_down --module-store-path tmp/module_store.yml
open http://localhost:8080

Development

  1. Checking out the repo git clone https://github.com/alpaca-tc/diver_down
  2. Install dependencies.
  1. Run the tests/static code analyzer.
  • Ruby: bundle exec rspec, bundle exec rubocop
  • TypeScript: pnpm run test, pnpm run lint

Development DiverDown::Web

If you want to develop DiverDown::Web locally, set up a server for development.

# Start server for frontend
$ pnpm install
$ pnpm run dev

# Start server for backend
$ bundle install
$ DIVER_DOWN_DIR=/path/to/definitions_dir DIVER_DOWN_MODULE_STORE=/path/to/module_store.yml bundle exec puma

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/alpaca-tc/diver_down. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the 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 DiverDown project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.