diff --git a/README.md b/README.md
index 6b893a8..b6e3d82 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,13 @@
# DiverDown
-`divertdown` is a tool that dynamically analyzes application dependencies and creates a dependency map.
-This tool was created to analyze Ruby applications for use in large-scale refactoring such as moduler monolith.
+`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.
-The results of the analysis can be viewed the dependency map graph, and and since the file-by-file association can be categorized into specific groups, you can deepen your architectural consideration.
+## Features
-## Installation
+- **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:
@@ -27,7 +29,7 @@ Or install it yourself as:
### `DiverDown::Trace`
-Analyzes the processing of ruby code and outputs the analysis results as `DiverDown::Definition`.
+The `DiverDown::Trace` module analyzes the execution of Ruby code and outputs the results as `DiverDown::Definition` objects.
```ruby
tracer = DiverDown::Trace::Tracer.new
@@ -57,8 +59,49 @@ tracer.trace(title: 'title', definition_group: 'group name') do
end
```
-The analysis results should be output to a specific directory.
-Files saved in `.json` or `.yaml` can be read by `DiverDown::Web`.
+**Options**
+
+When analyzing user applications, it is recommended to specify the option.
+
+|name|type|description|example|default|
+| --- | --- | --- | --- | --- |
+| `module_set` | Hash{
modules: Array \| Set \| nil,
paths: Array\ \| Set\ \| 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 \| 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**
+
+```ruby
+# 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.
```ruby
dir = 'tmp/diver_down'
@@ -71,19 +114,14 @@ 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)
```
-**Options**
-
-TODO
-
### `DiverDown::Web`
View the analysis results in a browser.
-This gem is designed to consider large application with a modular monolithic architecture.
-Each file in the analysis can be specified to belong to a module you specify on the 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` will store the results specifying which module each file belongs to. If not specified, the specified results are stored in tempfile.
+- `--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.
```sh
bundle exec diver_down_web --definition-dir tmp/diver_down --module-store-path tmp/module_store.yml
@@ -102,7 +140,7 @@ open http://localhost:8080
- Ruby: `bundle exec rspec`, `bundle exec rubocop`
- TypeScript: `pnpm run test`, `pnpm run lint`
-### Development DiverDown::Web
+### Development `DiverDown::Web`
If you want to develop `DiverDown::Web` locally, set up a server for development.
@@ -113,8 +151,6 @@ $ pnpm run dev
# Start server for backend
$ bundle install
-# DIVER_DOWN_DIR specifies the directory where the analysis results are stored.
-# DIVER_DOWN_MODULE_STORE specifies a yaml file that defines which module the file belongs to, but this file is newly created, so it works even if the file does not exist.
$ DIVER_DOWN_DIR=/path/to/definitions_dir DIVER_DOWN_MODULE_STORE=/path/to/module_store.yml bundle exec puma
```
diff --git a/diver_down.gemspec b/diver_down.gemspec
index b466fe8..4d1051b 100644
--- a/diver_down.gemspec
+++ b/diver_down.gemspec
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
spec.authors = ['alpaca-tc']
spec.email = ['alpaca-tc@alpaca.tc']
- spec.summary = 'Tool to dynamically analyze applications and create dependency maps'
- spec.description = ''
+ spec.summary = 'dynamically analyze application dependencies and generate a comprehensive dependency map'
+ spec.description = '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.'
spec.homepage = 'https://github.com/alpaca-tc/diver_down'
spec.license = 'MIT'
spec.required_ruby_version = '>= 3.2.0'
diff --git a/lib/diver_down/trace/session.rb b/lib/diver_down/trace/session.rb
index c2566d5..57c3b8d 100644
--- a/lib/diver_down/trace/session.rb
+++ b/lib/diver_down/trace/session.rb
@@ -16,10 +16,10 @@ class Session
# @param [DiverDown::Trace::IgnoredMethodIds, nil] ignored_method_ids
# @param [Set, nil] List of paths to finish traversing when searching for a caller. If nil, all paths are finished.
# @param [#call, nil] filter_method_id_path
- def initialize(module_set: DiverDown::Trace::ModuleSet.new, ignored_method_ids: nil, target_file_set: nil, filter_method_id_path: nil, definition: DiverDown::Definition.new)
+ def initialize(module_set: DiverDown::Trace::ModuleSet.new, ignored_method_ids: nil, caller_paths: nil, filter_method_id_path: nil, definition: DiverDown::Definition.new)
@module_set = module_set
@ignored_method_ids = ignored_method_ids
- @target_file_set = target_file_set
+ @caller_paths = caller_paths
@filter_method_id_path = filter_method_id_path
@definition = definition
@trace_point = build_trace_point
@@ -99,7 +99,7 @@ def build_trace_point
caller_location = find_neast_caller_location(maximum_back_stack_size)
- # `caller_location` is nil if it is filtered by target_files
+ # `caller_location` is nil if it is filtered by caller_paths
if caller_location
pushed = true
source = @definition.find_or_build_source(source_name)
@@ -130,12 +130,12 @@ def find_neast_caller_location(stack_size)
finished_frame_size = excluded_frame_size + stack_size + 1
frame_pos = 1
- # If @target_file_set is nil, return the caller location.
- return caller_locations(excluded_frame_size + 1, excluded_frame_size + 1)[0] if @target_file_set.nil?
+ # If @caller_paths is nil, return the caller location.
+ return caller_locations(excluded_frame_size + 1, excluded_frame_size + 1)[0] if @caller_paths.nil?
Thread.each_caller_location do
break if finished_frame_size < frame_pos
- return _1 if @target_file_set.include?(_1.path)
+ return _1 if @caller_paths.include?(_1.path)
frame_pos += 1
end
diff --git a/lib/diver_down/trace/tracer.rb b/lib/diver_down/trace/tracer.rb
index 7f87534..0eb2fc4 100644
--- a/lib/diver_down/trace/tracer.rb
+++ b/lib/diver_down/trace/tracer.rb
@@ -14,13 +14,13 @@ class << self
end
# @param module_set [DiverDown::Trace::ModuleSet, Array]
- # @param target_files [Array, nil] if nil, trace all files
+ # @param caller_paths [Array, nil] if nil, trace all files
# @param ignored_method_ids [Array]
# @param filter_method_id_path [#call, nil] filter method_id.path
# @param module_set [DiverDown::Trace::ModuleSet, nil] for optimization
- def initialize(module_set: {}, target_files: nil, ignored_method_ids: nil, filter_method_id_path: nil)
- if target_files && !target_files.all? { Pathname.new(_1).absolute? }
- raise ArgumentError, "target_files must be absolute path(#{target_files})"
+ def initialize(module_set: {}, caller_paths: nil, ignored_method_ids: nil, filter_method_id_path: nil)
+ if caller_paths && !caller_paths.all? { Pathname.new(_1).absolute? }
+ raise ArgumentError, "caller_paths must be absolute path(#{caller_paths})"
end
@module_set = if module_set.is_a?(DiverDown::Trace::ModuleSet)
@@ -46,7 +46,7 @@ def initialize(module_set: {}, target_files: nil, ignored_method_ids: nil, filte
DiverDown::Trace::IgnoredMethodIds.new(ignored_method_ids)
end
- @target_file_set = target_files&.to_set
+ @caller_paths = caller_paths&.to_set
@filter_method_id_path = filter_method_id_path
end
@@ -77,7 +77,7 @@ def new_session(title: SecureRandom.uuid, definition_group: nil)
DiverDown::Trace::Session.new(
module_set: @module_set,
ignored_method_ids: @ignored_method_ids,
- target_file_set: @target_file_set,
+ caller_paths: @caller_paths,
filter_method_id_path: @filter_method_id_path,
definition: DiverDown::Definition.new(
title:,
diff --git a/spec/diver_down/trace/tracer_spec.rb b/spec/diver_down/trace/tracer_spec.rb
index cddec96..c1ab3fd 100644
--- a/spec/diver_down/trace/tracer_spec.rb
+++ b/spec/diver_down/trace/tracer_spec.rb
@@ -17,13 +17,13 @@ def fill_default(hash)
end
describe '#initialize' do
- describe 'with relative path target_files' do
+ describe 'with relative path caller_paths' do
it 'raises ArgumentError' do
expect {
described_class.new(
- target_files: ['relative/path']
+ caller_paths: ['relative/path']
)
- }.to raise_error(ArgumentError, /target_files must be absolute path/)
+ }.to raise_error(ArgumentError, /caller_paths must be absolute path/)
end
end
@@ -104,7 +104,7 @@ def self.call
describe 'when tracing script' do
# @param path [String]
# @return [DiverDown::Definition]
- def trace_fixture(path, module_set: {}, target_files: nil, ignored_method_ids: [], filter_method_id_path: nil, definition_group: nil)
+ def trace_fixture(path, module_set: {}, caller_paths: nil, ignored_method_ids: [], filter_method_id_path: nil, definition_group: nil)
# NOTE: Script need to define .run method
script = fixture_path(path)
load script, AntipollutionModule
@@ -112,7 +112,7 @@ def trace_fixture(path, module_set: {}, target_files: nil, ignored_method_ids: [
tracer = described_class.new(
module_set:,
- target_files:,
+ caller_paths:,
ignored_method_ids:,
filter_method_id_path:
)
@@ -242,7 +242,7 @@ def trace_fixture(path, module_set: {}, target_files: nil, ignored_method_ids: [
))
end
- it 'traces tracer_module.rb with target_files' do
+ it 'traces tracer_module.rb with caller_paths' do
definition = trace_fixture(
'tracer_module.rb',
module_set: {
@@ -252,7 +252,7 @@ def trace_fixture(path, module_set: {}, target_files: nil, ignored_method_ids: [
'AntipollutionModule::C',
],
},
- target_files: []
+ caller_paths: []
)
expect(definition.to_h).to match(fill_default(
@@ -542,7 +542,7 @@ def trace_fixture(path, module_set: {}, target_files: nil, ignored_method_ids: [
'::C',
],
},
- target_files: [
+ caller_paths: [
fixture_path('tracer_separated_file.rb'),
]
)
@@ -588,7 +588,7 @@ def trace_fixture(path, module_set: {}, target_files: nil, ignored_method_ids: [
'AntipollutionModule::D',
],
},
- target_files: [
+ caller_paths: [
fixture_path('tracer_ignored_call_stack.rb'),
]
)
@@ -691,7 +691,7 @@ def self.call
module_set: {
modules: [A, B, C],
},
- target_files: [File.join(dir, 'a.rb'), File.join(dir, 'c.rb')]
+ caller_paths: [File.join(dir, 'a.rb'), File.join(dir, 'c.rb')]
)
definition = A.call do
@@ -739,7 +739,7 @@ def self.call
module_set: {
modules: [A, B],
},
- target_files: [File.join(dir, 'b.rb')]
+ caller_paths: [File.join(dir, 'b.rb')]
)
definition = tracer.trace(title: 'title') do