diver_down 0.0.1.alpha16 → 0.0.1.alpha18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 88a43fc4236cb489ca44a9105db9ad3750f53a2929a9153db564e20d3f4e2fee
4
- data.tar.gz: 589ab5cce7bfdee343a4c3d967a7aece57ff1d389d3700af222579c450a13a42
3
+ metadata.gz: 8bf67c52d7bafe08d7dfd22e48f2fedcec23c2d5410da3968d6e697edeaeb68b
4
+ data.tar.gz: 7319431059c715b0d83cf7b577522d47115ff1fe7d77ac04faa543355468f024
5
5
  SHA512:
6
- metadata.gz: eda67006560b775d12e582afa991b789d727f2d947ad82cab470408690ab682133c34d433309467ae67637472de1cc82f246e6618c4cbc36f2a5e7f8d6bb555f
7
- data.tar.gz: e116e4edbcd125c4a56e8641cbda5b6427ce4c6beaa86935a1339fabb9ff3db14d6bd9319538cf2643d270d1b8ee6019b74bc70089e14820511f05c7578f2079
6
+ metadata.gz: 659ab2212ababae04182c7cdf23d56dfb79877aeab7ae4ff419c417f56602fc6c446bdf94ce338944abf28b6f01b720ba3cb595bb7006d9f6cf3479ceb785869
7
+ data.tar.gz: 71118322b5bb69d6014f72f545957bd401de06ef5f695fec7273a0465f34fce3cdfb699e4130d263c4fc1031475549f1b137f53ceeef894f2840212669308401
data/exe/diver_down_web CHANGED
@@ -6,6 +6,7 @@ require 'rack/contrib'
6
6
  require 'diver_down'
7
7
  require 'diver_down-web'
8
8
  require 'optparse'
9
+ require 'tempfile'
9
10
 
10
11
  options = {}
11
12
  option_parser = OptionParser.new do |opts|
@@ -3,34 +3,41 @@
3
3
  module DiverDown
4
4
  module Trace
5
5
  class IgnoredMethodIds
6
+ VALID_VALUE = %i[
7
+ single
8
+ all
9
+ ].freeze
10
+
6
11
  def initialize(ignored_methods)
7
12
  # Ignore all methods in the module
8
- # Hash{ Module => Boolean }
13
+ # Hash{ Module => Symbol }
9
14
  @ignored_modules = {}
10
15
 
11
16
  # Ignore all methods in the class
12
- # Hash{ Module => Hash{ Symbol => Boolean } }
17
+ # Hash{ Module => Hash{ Symbol => Symbol } }
13
18
  @ignored_class_method_id = Hash.new { |h, k| h[k] = {} }
14
19
 
15
20
  # Ignore all methods in the instance
16
- # Hash{ Module => Hash{ Symbol => Boolean } }
21
+ # Hash{ Module => Hash{ Symbol => Symbol } }
17
22
  @ignored_instance_method_id = Hash.new { |h, k| h[k] = {} }
18
23
 
19
- ignored_methods.each do |ignored_method|
24
+ ignored_methods.each do |ignored_method, value|
25
+ raise ArgumentError, "Invalid value: #{value}. valid values are #{VALID_VALUE}" unless VALID_VALUE.include?(value)
26
+
20
27
  if ignored_method.include?('.')
21
28
  # instance method
22
29
  class_name, method_id = ignored_method.split('.')
23
30
  mod = DiverDown::Helper.constantize(class_name)
24
- @ignored_class_method_id[mod][method_id.to_sym] = true
31
+ @ignored_class_method_id[mod][method_id.to_sym] = value
25
32
  elsif ignored_method.include?('#')
26
33
  # class method
27
34
  class_name, method_id = ignored_method.split('#')
28
35
  mod = DiverDown::Helper.constantize(class_name)
29
- @ignored_instance_method_id[mod][method_id.to_sym] = true
36
+ @ignored_instance_method_id[mod][method_id.to_sym] = value
30
37
  else
31
38
  # module
32
39
  mod = DiverDown::Helper.constantize(ignored_method)
33
- @ignored_modules[mod] = true
40
+ @ignored_modules[mod] = value
34
41
  end
35
42
  end
36
43
  end
@@ -38,14 +45,14 @@ module DiverDown
38
45
  # @param mod [Module]
39
46
  # @param is_class [Boolean] class is true, instance is false
40
47
  # @param method_id [Symbol]
41
- # @return [Boolean]
42
- def ignored?(mod, is_class, method_id)
43
- ignored_module?(mod) || ignored_method?(mod, is_class, method_id)
48
+ # @return [Symbol, false] VALID_VALUE
49
+ def ignored(mod, is_class, method_id)
50
+ ignored_module(mod) || ignored_method(mod, is_class, method_id)
44
51
  end
45
52
 
46
53
  private
47
54
 
48
- def ignored_module?(mod)
55
+ def ignored_module(mod)
49
56
  unless @ignored_modules.key?(mod)
50
57
  dig_superclass(mod)
51
58
  end
@@ -53,7 +60,7 @@ module DiverDown
53
60
  @ignored_modules.fetch(mod)
54
61
  end
55
62
 
56
- def ignored_method?(mod, is_class, method_id)
63
+ def ignored_method(mod, is_class, method_id)
57
64
  store = if is_class
58
65
  # class methods
59
66
  @ignored_class_method_id
@@ -96,10 +103,8 @@ module DiverDown
96
103
  end
97
104
 
98
105
  # Convert nil to boolean
99
- ignored = !!ignored
100
-
101
106
  stack.each do
102
- @ignored_modules[_1] = ignored
107
+ @ignored_modules[_1] = ignored || false
103
108
  end
104
109
  end
105
110
 
@@ -125,10 +130,8 @@ module DiverDown
125
130
  end
126
131
 
127
132
  # Convert nil to boolean
128
- ignored = !!ignored
129
-
130
133
  stack.each do
131
- store[_1][method_id] = ignored
134
+ store[_1][method_id] = ignored || false
132
135
  end
133
136
  end
134
137
  end
@@ -38,13 +38,15 @@ module DiverDown
38
38
  private
39
39
 
40
40
  def build_trace_point
41
- call_stack = DiverDown::Trace::CallStack.new
41
+ call_stacks = {}
42
42
 
43
43
  TracePoint.new(*DiverDown::Trace::Tracer.trace_events) do |tp|
44
44
  # Skip the trace of the library itself
45
45
  next if tp.path&.start_with?(DiverDown::LIB_DIR)
46
46
  next if TracePoint == tp.defined_class
47
47
 
48
+ call_stack = call_stacks[Thread.current] ||= DiverDown::Trace::CallStack.new
49
+
48
50
  case tp.event
49
51
  when :b_call
50
52
  call_stack.push
@@ -64,9 +66,12 @@ module DiverDown
64
66
  next
65
67
  end
66
68
 
67
- if !@ignored_method_ids.nil? && @ignored_method_ids.ignored?(mod, DiverDown::Helper.module?(tp.self), tp.method_id)
68
- # If this method is ignored, the call stack is ignored until the method returns.
69
- call_stack.push(ignored: true)
69
+ ignored = @ignored_method_ids.ignored(mod, DiverDown::Helper.module?(tp.self), tp.method_id) if @ignored_method_ids
70
+
71
+ if ignored
72
+ # If ignored is :all, the call stack is ignored until the method returns.
73
+ # If ignored is :single, the call stack is ignored only current call.
74
+ call_stack.push(ignored: ignored == :all)
70
75
  next
71
76
  end
72
77
 
@@ -24,7 +24,7 @@ module DiverDown
24
24
 
25
25
  # @param module_set [DiverDown::Trace::ModuleSet, Array<Module, String>]
26
26
  # @param caller_paths [Array<String>, nil] if nil, trace all files
27
- # @param ignored_method_ids [Array<String>]
27
+ # @param ignored_method_ids [Hash{ String => Symbol }, nil]
28
28
  # @param filter_method_id_path [#call, nil] filter method_id.path
29
29
  # @param module_set [DiverDown::Trace::ModuleSet, nil] for optimization
30
30
  def initialize(module_set: {}, caller_paths: nil, ignored_method_ids: nil, filter_method_id_path: nil)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DiverDown
4
- VERSION = '0.0.1.alpha16'
4
+ VERSION = '0.0.1.alpha18'
5
5
  end
@@ -21,9 +21,8 @@ module DiverDown
21
21
  def initialize(store:, metadata:)
22
22
  @store = store
23
23
  @metadata = metadata
24
- @source_alias_resolver = DiverDown::Web::SourceAliasResolver.new(@metadata.source_alias)
25
- @module_dependency_map = nil
26
- @module_dependency_map_cache_id = nil
24
+
25
+ reload
27
26
  end
28
27
 
29
28
  # GET /api/source_aliases.json
@@ -125,6 +124,7 @@ module DiverDown
125
124
  {
126
125
  source_name: dependency.source_name,
127
126
  module: @metadata.source(dependency.source_name).module,
127
+ dependency_type: @metadata.source(source.source_name).dependency_type(dependency.source_name),
128
128
  method_ids: dependency.method_ids.sort.map do |method_id|
129
129
  {
130
130
  context: method_id.context,
@@ -145,13 +145,7 @@ module DiverDown
145
145
  {
146
146
  source_name: dependency.source_name,
147
147
  module: @metadata.source(dependency.source_name).module,
148
- method_ids: dependency.method_ids.sort.map do |method_id|
149
- {
150
- context: method_id.context,
151
- name: method_id.name,
152
- paths: method_id.paths.sort,
153
- }
154
- end,
148
+ dependency_type: @metadata.source(source.source_name).dependency_type(dependency.source_name),
155
149
  }
156
150
  end,
157
151
  }
@@ -192,6 +186,44 @@ module DiverDown
192
186
  )
193
187
  end
194
188
 
189
+ # POST /api/modules/:from_module/dependency_types/:to_module.json
190
+ def update_module_dependency_type(from_module, to_module, dependency_type)
191
+ module_dependency_map = fetch_module_dependency_map
192
+
193
+ unless module_dependency_map.key?(from_module) && module_dependency_map.key?(to_module)
194
+ return not_found
195
+ end
196
+
197
+ module_dependency = module_dependency_map.fetch(from_module)
198
+ module_dependency.sources.each do |source|
199
+ source_metadata = @metadata.source(source.source_name)
200
+
201
+ source.dependencies.each do |dependency|
202
+ next unless @metadata.source(dependency.source_name).module == to_module
203
+
204
+ source_metadata.update_dependency_type(dependency.source_name, dependency_type)
205
+ end
206
+ end
207
+
208
+ @metadata.flush
209
+
210
+ json({})
211
+ end
212
+
213
+ # POST /api/sources/:from_source_name/dependency_types/:to_source_name.json
214
+ def update_source_dependency_type(from_source_name, to_source_name, dependency_type)
215
+ source = @metadata.source(from_source_name)
216
+
217
+ begin
218
+ source.update_dependency_type(to_source_name, dependency_type)
219
+ rescue ArgumentError => e
220
+ return json_error(e.message)
221
+ end
222
+
223
+ @metadata.flush
224
+ json({})
225
+ end
226
+
195
227
  # GET /api/pid.json
196
228
  def pid
197
229
  json(
@@ -327,6 +359,7 @@ module DiverDown
327
359
  if found_source
328
360
  @metadata.source(source_name).module = modulee
329
361
  @metadata.flush
362
+ reload
330
363
 
331
364
  json({})
332
365
  else
@@ -348,6 +381,7 @@ module DiverDown
348
381
  if found_source
349
382
  @metadata.source(source_name).memo = memo
350
383
  @metadata.flush
384
+ reload
351
385
 
352
386
  json({})
353
387
  else
@@ -355,6 +389,13 @@ module DiverDown
355
389
  end
356
390
  end
357
391
 
392
+ # @return [Array[Integer, Hash, Array]]
393
+ def reload_cache
394
+ @metadata.reload
395
+ reload
396
+ json({})
397
+ end
398
+
358
399
  # @return [Array[Integer, Hash, Array]]
359
400
  def not_found
360
401
  [404, { 'content-type' => 'text/plain' }, ['not found']]
@@ -445,6 +486,12 @@ module DiverDown
445
486
 
446
487
  @module_dependency_map
447
488
  end
489
+
490
+ def reload
491
+ @source_alias_resolver = DiverDown::Web::SourceAliasResolver.new(@metadata.source_alias)
492
+ @module_dependency_map = nil
493
+ @module_dependency_map_cache_id = nil
494
+ end
448
495
  end
449
496
  end
450
497
  end
@@ -64,11 +64,9 @@ module DiverDown
64
64
  end
65
65
 
66
66
  # Add source reverse dependencies
67
- definition_source = dependency_module_dependency.source_reverse_dependency_map[dependency.source_name] ||= DiverDown::Definition::Source.new(source_name: dependency.source_name)
68
- definition_dependency = definition_source.find_or_build_dependency(source.source_name)
69
- dependency.method_ids.each do |method_id|
70
- definition_dependency.find_or_build_method_id(name: method_id.name, context: method_id.context).add_path(*method_id.paths)
71
- end
67
+ # NOTE: Reverse dependencies's method_ids are not added because they are difficult to understand and not used.
68
+ definition_source = dependency_module_dependency.source_reverse_dependency_map[source.source_name] ||= DiverDown::Definition::Source.new(source_name: source.source_name)
69
+ definition_source.find_or_build_dependency(dependency.source_name)
72
70
  end
73
71
  end
74
72
 
@@ -9,13 +9,16 @@ module DiverDown
9
9
  private_constant(:BLANK_MEMO)
10
10
  private_constant(:BLANK_RE)
11
11
 
12
- attr_reader :memo, :module
12
+ DEPENDENCY_TYPES = %w[valid invalid todo ignore].freeze
13
+
14
+ attr_reader :memo, :module, :dependency_types
13
15
 
14
16
  # @param source_name [String]
15
17
  # NOTE: `module` is a reserved keyword in Ruby
16
- def initialize(memo: BLANK_MEMO, modulee: nil)
18
+ def initialize(memo: BLANK_MEMO, modulee: nil, dependency_types: {})
17
19
  @memo = memo
18
20
  @module = modulee
21
+ @dependency_types = dependency_types
19
22
  end
20
23
 
21
24
  # @param memo [String]
@@ -34,6 +37,35 @@ module DiverDown
34
37
  end
35
38
  end
36
39
 
40
+ # @param to_source [String]
41
+ # @return [String, nil]
42
+ def dependency_type(to_source)
43
+ @dependency_types[to_source]
44
+ end
45
+
46
+ # @param dependency_types [Hash]
47
+ # @return [void]
48
+ def dependency_types=(dependency_types)
49
+ @dependency_types.clear
50
+
51
+ dependency_types.each do |to_source, dependency_type|
52
+ update_dependency_type(to_source, dependency_type)
53
+ end
54
+ end
55
+
56
+ # @param to_source [String]
57
+ # @param dependency_type [String]
58
+ # @return [void]
59
+ def update_dependency_type(to_source, dependency_type)
60
+ if dependency_type.to_s.empty?
61
+ @dependency_types.delete(to_source)
62
+ else
63
+ raise ArgumentError, "invalid dependency_type: #{dependency_type}" unless DEPENDENCY_TYPES.include?(dependency_type)
64
+
65
+ @dependency_types[to_source] = dependency_type
66
+ end
67
+ end
68
+
37
69
  # @return [Boolean]
38
70
  def module?
39
71
  !@module.nil?
@@ -45,15 +77,10 @@ module DiverDown
45
77
 
46
78
  hash[:memo] = memo unless memo == BLANK_MEMO
47
79
  hash[:module] = @module unless @module.nil?
80
+ hash[:dependency_types] = @dependency_types unless @dependency_types.empty?
48
81
 
49
82
  hash
50
83
  end
51
-
52
- private
53
-
54
- def by_source_name(source_name)
55
- @store[source_name] ||= {}
56
- end
57
84
  end
58
85
  end
59
86
  end
@@ -6,12 +6,12 @@ module DiverDown
6
6
  require 'diver_down/web/metadata/source_metadata'
7
7
  require 'diver_down/web/metadata/source_alias'
8
8
 
9
- attr_reader :source_alias
9
+ attr_reader :path, :source_alias
10
10
 
11
11
  # @param path [String]
12
12
  def initialize(path)
13
13
  @path = path
14
- load
14
+ reload
15
15
  end
16
16
 
17
17
  # @param source_name [String]
@@ -41,25 +41,20 @@ module DiverDown
41
41
  File.write(@path, to_h.to_yaml)
42
42
  end
43
43
 
44
- private
45
-
46
- def load
44
+ # Reload metadata from file
45
+ # @return [void]
46
+ def reload
47
47
  @source_map = Hash.new { |h, source_name| h[source_name] = DiverDown::Web::Metadata::SourceMetadata.new }
48
48
  @source_alias = DiverDown::Web::Metadata::SourceAlias.new
49
49
 
50
- loaded = YAML.load_file(@path)
50
+ loaded = YAML.load_file(@path) if File.exist?(@path)
51
51
 
52
52
  return if loaded.nil?
53
53
 
54
- # NOTE: This is for backward compatibility. It will be removed in the future.
55
- (loaded[:sources] || loaded || []).each do |source_name, source_hash|
54
+ loaded[:sources]&.each do |source_name, source_hash|
56
55
  source(source_name).memo = source_hash[:memo] if source_hash[:memo]
57
-
58
- if source_hash[:modules].is_a?(Array)
59
- source(source_name).module = source_hash[:modules][0]
60
- elsif source_hash[:module]
61
- source(source_name).module = source_hash[:module]
62
- end
56
+ source(source_name).module = source_hash[:module] if source_hash[:module]
57
+ source(source_name).dependency_types = source_hash[:dependency_types] if source_hash[:dependency_types]
63
58
  end
64
59
 
65
60
  loaded[:source_alias]&.each do |alias_name, source_names|
@@ -78,6 +78,8 @@ module DiverDown
78
78
  in ['GET', %r{\A/api/sources/(?<source>[^/]+)\.json\z}]
79
79
  source = Regexp.last_match[:source]
80
80
  @action.source(source)
81
+ in ['GET', %r{\A/api/reload\.json\z}]
82
+ @action.reload_cache
81
83
  in ['POST', %r{\A/api/sources/(?<source>[^/]+)/module.json\z}]
82
84
  source = Regexp.last_match[:source]
83
85
  modulee = request.params['module'] || ''
@@ -86,6 +88,18 @@ module DiverDown
86
88
  source = Regexp.last_match[:source]
87
89
  memo = request.params['memo'] || ''
88
90
  @action.set_memo(source, memo)
91
+ in ['POST', %r{\A/api/modules/(?<from_module>[^/]+)/dependency_types/(?<to_module>[^/]+)\.json\z}]
92
+ from_module = CGI.unescape(Regexp.last_match[:from_module])
93
+ to_module = CGI.unescape(Regexp.last_match[:to_module])
94
+ dependency_type = request.params['dependency_type']
95
+
96
+ @action.update_module_dependency_type(from_module, to_module, dependency_type)
97
+ in ['POST', %r{\A/api/sources/(?<from_source>[^/]+)/dependency_types/(?<to_source>[^/]+)\.json\z}]
98
+ from_source = Regexp.last_match[:from_source]
99
+ to_source = Regexp.last_match[:to_source]
100
+ dependency_type = request.params['dependency_type']
101
+
102
+ @action.update_source_dependency_type(from_source, to_source, dependency_type)
89
103
  in ['GET', %r{\A/api/pid\.json\z}]
90
104
  @action.pid
91
105
  in ['GET', %r{\A/api/initialization_status\.json\z}]