ariadne 0.0.3 → 0.0.5

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: 9c5b693660af05c17570b71a98e6ed6899932f9b2571fd6f8e4fd7d66d61e4fc
4
- data.tar.gz: 8a3697425b580d3f40568b8b5a33d80e6d149197b0ede9fa2d35042b5ad90c8a
3
+ metadata.gz: a71929c19a3e8fff0abc484843c1762edf12ecf6f45d90a6e0394cb4743aa243
4
+ data.tar.gz: e5959ac737aaf0392957164769dcb56e72ca73362da8431fcbb4a9d47fcc835b
5
5
  SHA512:
6
- metadata.gz: 9d41649519721ea428249d049823a82ecaf4530dc436b27b4bd643e815e12f70eec38895e752b46ca57154ed7e9b5c9133bc799903b69479876c6d9c3577732f
7
- data.tar.gz: 70555aa75a6656cf16e199abb1b3b29ce960f806b3b68846edbf378072d7a4129c3268cfd2d8e06d44dde667f2682b9cee8766d63f9e98138df6f190b8a1ea7f
6
+ metadata.gz: 1bec945c8243605fb555b88e817c9cfe84268e06b4ae110ef2c5b472f86360deb5c91d4cfa3a8e3cf9220f90259bddcfe902fcd829fbe53d2090722bb6f454d9
7
+ data.tar.gz: fbb773617d74362a76c461c0c01283239175fea01d8915e3b810299b13b7849863cdefb1f8875592c3421da5a19945236736c7ec2df296a0d4fc72f8d666082c
data/lib/ariadne/log.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "open3"
4
- require "ariadne/text"
4
+ require "ariadne/string/color"
5
5
 
6
6
  module Ariadne
7
7
  class Log
@@ -22,50 +22,68 @@ module Ariadne
22
22
 
23
23
  def text
24
24
  @text ||=
25
- Text.new(
26
- [rank, " ", offset, " ", offset_dashes, class_name, prefix, method_name]
27
- .tap { add_parameters(_1) }
28
- .join
29
- ).truncate(200)
25
+ [
26
+ rank,
27
+ " ",
28
+ depth_dashes,
29
+ class_name,
30
+ prefix,
31
+ method_name,
32
+ parameters,
33
+ return_value_type
34
+ ].join
30
35
  end
31
36
 
32
37
  def rank
33
- Text.new(@seam.rank.to_s.rjust(4)).gray
38
+ @seam.rank.to_s.rjust(4).gray
34
39
  end
35
40
 
36
- def offset
37
- Text.new("(#{@seam.offset})").gray
38
- end
39
-
40
- def offset_dashes
41
- Text.new("-" * @seam.offset).gray.tap { _1 << " " if @seam.offset.positive? }
41
+ def depth_dashes
42
+ ("-" * @seam.depth).gray.tap { _1 << " " if @seam.depth.positive? }
42
43
  end
43
44
 
44
45
  def class_name
45
- Text.new(@seam.class_name).green
46
+ @seam.klass.name.green
46
47
  end
47
48
 
48
49
  def prefix
49
- Text.new(@seam.prefix).gray
50
+ @seam.prefix.gray
50
51
  end
51
52
 
52
53
  def method_name
53
- Text.new(@seam.method_name).cyan
54
+ @seam.method_name.to_s.cyan
54
55
  end
55
56
 
56
- def add_parameters(str)
57
- return if parameters == ""
58
-
59
- str << Text.new("(#{parameters})").magenta
57
+ def return_value_type
58
+ value = type(@seam.return_value)
59
+ " -> #{value}".yellow
60
60
  end
61
61
 
62
62
  def parameters
63
- @parameters ||=
64
- @seam.parameters.map do |parameter|
65
- arg = Text.new(parameter.stringified_arg).truncate(50)
66
- arg = parameter.type ? "<#{parameter.type}> #{arg}" : arg
67
- "#{parameter.param}: #{arg}"
68
- end.join(", ")
63
+ return if @seam.parameters.empty?
64
+
65
+ [
66
+ "(",
67
+ @seam.parameters.flat_map { "#{_1.param}: #{arg(_1)}" }.join(", "),
68
+ ")"
69
+ ].join.magenta
70
+ end
71
+
72
+ def arg(parameter)
73
+ if parameter.type == :rest || %i[* ** &].include?(parameter.param)
74
+ parameter.arg.map { type(_1) }.join(", ")
75
+ else
76
+ type(parameter.arg)
77
+ end
78
+ end
79
+
80
+ def type(arg)
81
+ case arg
82
+ when "<?>" then "<?>"
83
+ when TrueClass, FalseClass then "Boolean"
84
+ when NilClass then "nil"
85
+ else arg.class.to_s
86
+ end
69
87
  end
70
88
  end
71
89
  end
data/lib/ariadne/seam.rb CHANGED
@@ -1,40 +1,79 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "open3"
4
- require "ariadne/parameter"
5
4
 
6
5
  module Ariadne
7
- class Seam < SimpleDelegator
8
- attr_reader :rank, :offset
6
+ class Seam
7
+ attr_reader :rank, :depth, :klass, :method_name, :prefix, :parameters, :return_value, :binding, :path
9
8
 
10
- def initialize(tracepoint, rank:, offset:)
11
- super(tracepoint)
12
- @rank = rank
13
- @offset = offset
14
- end
9
+ Parameter = Struct.new(:type, :param, :arg)
10
+
11
+ class << self
12
+ # We cannot make public methods because accessing the TracePoint
13
+ # after it has been disabled would raise a RunTimeError
14
+ # with message "access from outside".
15
+ # We need to set the values while the TracePoint is enabled.
16
+ def build(tracepoint, rank:, depth:)
17
+ raise "tracepoint is disabled" unless tracepoint.enabled?
15
18
 
16
- # Seam.new(@rank, class_name(tp), prefix(tp), tp.method_id, parameters, @seams.size)
17
- def class_name
18
- if __getobj__.self.is_a?(Module)
19
- __getobj__.self.name
20
- else
21
- __getobj__.self.class.name
19
+ new(rank: rank, depth: depth).tap do |seam|
20
+ seam.instance_variable_set(:@klass, klass(tracepoint))
21
+ seam.instance_variable_set(:@prefix, prefix(tracepoint))
22
+ seam.instance_variable_set(:@method_name, method_name(tracepoint))
23
+ seam.instance_variable_set(:@parameters, parameters(tracepoint))
24
+ seam.instance_variable_set(:@path, path(tracepoint))
25
+ end
22
26
  end
23
- end
24
27
 
25
- def method_name
26
- method_id
27
- end
28
+ private
28
29
 
29
- def prefix
30
- __getobj__.self.is_a?(Module) ? "." : "#"
31
- end
30
+ def klass(tracepoint)
31
+ if tracepoint.self.is_a?(Module)
32
+ tracepoint.self
33
+ else
34
+ tracepoint.self.class
35
+ end
36
+ end
32
37
 
33
- def parameters
34
- method = __getobj__.self.method(method_name)
35
- method.parameters.map do |parameter|
36
- Parameter.new(parameter, binding: binding)
38
+ def method_name(tracepoint)
39
+ tracepoint.method_id
37
40
  end
41
+
42
+ def prefix(tracepoint)
43
+ tracepoint.self.is_a?(Module) ? "." : "#"
44
+ end
45
+
46
+ def parameters(tracepoint)
47
+ method = tracepoint.self.method(tracepoint.method_id)
48
+ if forwarded_parameters?(method)
49
+ [Parameter.new(:rest, "...", ["<?>"])]
50
+ else
51
+ method.parameters.flat_map do |parameter|
52
+ type = parameter.first
53
+ param = parameter.last
54
+ arg = %i[* ** &].include?(param) ? ["<?>"] : tracepoint.binding.local_variable_get(param)
55
+ Parameter.new(type, param, arg)
56
+ rescue NameError
57
+ Parameter.new(type, param, type == :rest ? ["<?>"] : "<?>")
58
+ end
59
+ end
60
+ end
61
+
62
+ # return true if method's signature is like `def my_method(...)`
63
+ def forwarded_parameters?(method)
64
+ method.parameters == [%i[rest *], %i[block &]]
65
+ end
66
+
67
+ def path(tracepoint)
68
+ tracepoint.path
69
+ end
70
+ end
71
+
72
+ private
73
+
74
+ def initialize(rank:, depth:)
75
+ @rank = rank
76
+ @depth = depth
38
77
  end
39
78
  end
40
79
  end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ariadne
4
+ module String
5
+ module Color
6
+ COLORS = %w[
7
+ black
8
+ red
9
+ green
10
+ yellow
11
+ blue
12
+ magenta
13
+ cyan
14
+ gray
15
+ ].freeze
16
+
17
+ COLORS.each.with_index do |color, index|
18
+ code = index + 30
19
+ define_method(color) do
20
+ "\e[#{code}m#{bleach}\e[0m"
21
+ end
22
+ bg_code = index + 40
23
+ define_method("bg_#{color}") do
24
+ "\e[#{bg_code}m#{bleach}\e[0m"
25
+ end
26
+ end
27
+
28
+ def bleach
29
+ gsub(/\e\[\d{1,2}m/, "")
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ String.include Ariadne::String::Color
@@ -6,44 +6,86 @@ require "ariadne/log"
6
6
 
7
7
  module Ariadne
8
8
  class Thread
9
+ attr_reader :seams
10
+
9
11
  LOG_FILE = "thread.log"
10
12
  DEFAULT_INCLUDE_PATHS = Open3.capture3("pwd").first.strip
11
13
  DEFAULT_EXCLUDE_PATHS = [].freeze
12
14
 
13
15
  def initialize(include_paths: nil, exclude_paths: nil)
14
- @include_paths = include_paths || DEFAULT_INCLUDE_PATHS
15
- @exclude_paths = exclude_paths || DEFAULT_EXCLUDE_PATHS
16
+ @include_paths = Array(include_paths) || DEFAULT_INCLUDE_PATHS
17
+ @exclude_paths = Array(exclude_paths) || DEFAULT_EXCLUDE_PATHS
18
+ @seams = []
16
19
  end
17
20
 
18
21
  def call
19
- @rank = 0
20
- @seams = []
21
- file = File.open(LOG_FILE, "w")
22
- trace = build_trace
22
+ prepare
23
+ open_file
23
24
  trace.enable
24
25
  yield
25
26
  ensure
26
27
  trace.disable
27
- file.close
28
+ log
29
+ close_file
28
30
  end
29
31
 
30
32
  private
31
33
 
32
- def build_trace
33
- TracePoint.new(:call, :return) do |tp|
34
- next if @include_paths.none? { tp.path.include?(_1) }
35
- next if @exclude_paths.any? { tp.path.include?(_1) }
36
-
37
- case tp.event
38
- when :call
39
- seam = Seam.new(tp, rank: @rank, offset: @seams.size)
40
- @seams << seam
41
- @rank += 1
42
- Log.new(seam).call
43
- when :return
44
- @seams.pop
34
+ def prepare
35
+ @rank = 0
36
+ @depth = 0
37
+ @seams = []
38
+ end
39
+
40
+ def open_file
41
+ @file = File.open(LOG_FILE, "w")
42
+ end
43
+
44
+ def close_file
45
+ @file.close
46
+ end
47
+
48
+ def trace
49
+ @trace ||=
50
+ TracePoint.new(:call, :return) do |tracepoint|
51
+ next if tracepoint.self.is_a?(TracePoint)
52
+
53
+ case tracepoint.event
54
+ when :call
55
+ on_call(tracepoint)
56
+ when :return
57
+ on_return(tracepoint)
58
+ end
45
59
  end
46
- end
60
+ end
61
+
62
+ def on_call(tracepoint)
63
+ return unless selected?(tracepoint)
64
+
65
+ seam = Seam.build(tracepoint, rank: @rank, depth: @depth)
66
+ @seams << seam
67
+
68
+ @rank += 1
69
+ @depth += 1
70
+ end
71
+
72
+ def on_return(tracepoint)
73
+ return unless selected?(tracepoint)
74
+
75
+ @depth -= 1
76
+
77
+ seam = @seams.reverse.find { _1.depth == @depth }
78
+ seam&.instance_variable_set(:@return_value, tracepoint.return_value)
79
+ seam&.instance_variable_set(:@binding, tracepoint.binding)
80
+ end
81
+
82
+ def selected?(tracepoint)
83
+ @include_paths.any? { tracepoint.path.include?(_1) } &&
84
+ @exclude_paths.none? { tracepoint.path.include?(_1) }
85
+ end
86
+
87
+ def log
88
+ @seams.each { Log.new(_1).call }
47
89
  end
48
90
  end
49
91
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ariadne
4
- VERSION = "0.0.3"
4
+ VERSION = "0.0.5"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ariadne
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Edouard Piron
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-02-23 00:00:00.000000000 Z
11
+ date: 2023-02-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -80,20 +80,6 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: simplecov
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
83
  - !ruby/object:Gem::Dependency
98
84
  name: yard
99
85
  requirement: !ruby/object:Gem::Requirement
@@ -117,9 +103,8 @@ extra_rdoc_files: []
117
103
  files:
118
104
  - lib/ariadne.rb
119
105
  - lib/ariadne/log.rb
120
- - lib/ariadne/parameter.rb
121
106
  - lib/ariadne/seam.rb
122
- - lib/ariadne/text.rb
107
+ - lib/ariadne/string/color.rb
123
108
  - lib/ariadne/thread.rb
124
109
  - lib/ariadne/version.rb
125
110
  homepage: https://github.com/BigBigDoudou/ariadne
@@ -1,59 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "open3"
4
- require "ariadne/text"
5
-
6
- module Ariadne
7
- class Parameter < SimpleDelegator
8
- RUBY_LITERALS = [
9
- NilClass,
10
- String,
11
- Integer,
12
- Float,
13
- Proc,
14
- TrueClass,
15
- FalseClass,
16
- Symbol,
17
- Array,
18
- Range,
19
- Regexp,
20
- Hash
21
- ].freeze
22
-
23
- def initialize(parameter, binding:)
24
- super(parameter)
25
- @binding = binding
26
- end
27
-
28
- def param
29
- last
30
- end
31
-
32
- def arg
33
- @binding.local_variable_get(last)
34
- rescue NameError
35
- "?"
36
- end
37
-
38
- def type
39
- return if arg.is_a?(Class) || RUBY_LITERALS.include?(arg.class)
40
-
41
- arg.class.name
42
- end
43
-
44
- def stringified_arg
45
- case arg
46
- when NilClass
47
- "nil"
48
- when Proc
49
- "#<Proc>"
50
- when Class
51
- arg.name
52
- when String
53
- "\"#{arg}\""
54
- else
55
- arg.to_s
56
- end
57
- end
58
- end
59
- end
data/lib/ariadne/text.rb DELETED
@@ -1,43 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Ariadne
4
- class Text < String
5
- COLORS = %w[
6
- black
7
- red
8
- green
9
- yellow
10
- blue
11
- magenta
12
- cyan
13
- gray
14
- ].freeze
15
-
16
- COLORS.each.with_index do |color, index|
17
- code = index + 30
18
- define_method(color) do
19
- "\e[#{code}m#{bleach}\e[0m"
20
- end
21
- bg_code = index + 40
22
- define_method("bg_#{color}") do
23
- "\e[#{bg_code}m#{bleach}\e[0m"
24
- end
25
- end
26
-
27
- def initialize(str)
28
- super(str.to_s)
29
- end
30
-
31
- def truncate(size)
32
- if self.size > size
33
- Text.new("#{self[..size]}...")
34
- else
35
- self
36
- end
37
- end
38
-
39
- def bleach
40
- gsub(/\e\[\d{1,2}m/, "")
41
- end
42
- end
43
- end