appmap 0.102.2 → 0.103.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +6 -0
- data/.standard.yml +1 -0
- data/.travis.yml +2 -2
- data/CHANGELOG.md +17 -0
- data/appmap.gemspec +35 -36
- data/lib/appmap/agent.rb +28 -24
- data/lib/appmap/class_map.rb +36 -31
- data/lib/appmap/config.rb +132 -110
- data/lib/appmap/cucumber.rb +25 -25
- data/lib/appmap/detect_enabled.rb +30 -28
- data/lib/appmap/gem_hooks/activejob.yml +0 -1
- data/lib/appmap/hook/method/ruby2.rb +19 -8
- data/lib/appmap/hook/method/ruby3.rb +20 -13
- data/lib/appmap/hook/method.rb +27 -27
- data/lib/appmap/hook/record_around.rb +77 -0
- data/lib/appmap/hook.rb +74 -44
- data/lib/appmap/metadata.rb +6 -18
- data/lib/appmap/middleware/remote_recording.rb +26 -27
- data/lib/appmap/minitest.rb +27 -27
- data/lib/appmap/rspec.rb +37 -37
- data/lib/appmap/trace.rb +14 -12
- data/lib/appmap/util.rb +71 -61
- data/lib/appmap/version.rb +1 -1
- metadata +5 -16
data/lib/appmap/rspec.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
4
|
-
require_relative
|
5
|
-
require_relative
|
6
|
-
require
|
7
|
-
require
|
3
|
+
require_relative "../appmap"
|
4
|
+
require_relative "util"
|
5
|
+
require_relative "detect_enabled"
|
6
|
+
require "set"
|
7
|
+
require "fileutils"
|
8
8
|
|
9
9
|
module AppMap
|
10
10
|
module RSpec
|
11
|
-
APPMAP_OUTPUT_DIR =
|
12
|
-
LOG = (ENV[
|
11
|
+
APPMAP_OUTPUT_DIR = File.join(AppMap.output_dir, "rspec")
|
12
|
+
LOG = (ENV["APPMAP_DEBUG"] == "true" || ENV["DEBUG"] == "true")
|
13
13
|
|
14
14
|
def self.metadata
|
15
15
|
AppMap.detect_metadata
|
@@ -52,7 +52,7 @@ module AppMap
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def description
|
55
|
-
description? ? description_args.join(
|
55
|
+
description? ? description_args.join(" ") : nil
|
56
56
|
end
|
57
57
|
|
58
58
|
def parent
|
@@ -69,7 +69,7 @@ module AppMap
|
|
69
69
|
example_group.parent_groups.first
|
70
70
|
end
|
71
71
|
|
72
|
-
example_group_parent == example_group ? nil : ScopeExampleGroup.new(example_group_parent)
|
72
|
+
(example_group_parent == example_group) ? nil : ScopeExampleGroup.new(example_group_parent)
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
@@ -83,7 +83,7 @@ module AppMap
|
|
83
83
|
# This is the ugliest thing ever but I don't want to lose it.
|
84
84
|
# All the WebDriver calls are getting app-mapped and it's really unclear
|
85
85
|
# what they are.
|
86
|
-
page.driver.options[:http_client].instance_variable_get(
|
86
|
+
page.driver.options[:http_client].instance_variable_get(:@server_url).port
|
87
87
|
end
|
88
88
|
|
89
89
|
warn "Starting recording of example #{example}@#{source_location}" if AppMap::RSpec::LOG
|
@@ -92,14 +92,14 @@ module AppMap
|
|
92
92
|
end
|
93
93
|
|
94
94
|
def source_location
|
95
|
-
result = example.location_rerun_argument.split(
|
96
|
-
result = result[2..-1] if result.index(
|
95
|
+
result = example.location_rerun_argument.split(":")[0]
|
96
|
+
result = result[2..-1] if result.index("./") == 0
|
97
97
|
result
|
98
98
|
end
|
99
99
|
|
100
100
|
def finish(failure, exception)
|
101
101
|
failed = true if failure || exception
|
102
|
-
warn "Finishing recording of #{failed ?
|
102
|
+
warn "Finishing recording of #{failed ? "failed " : ""} example #{example}" if AppMap::RSpec::LOG
|
103
103
|
warn "Exception: #{exception}" if exception && AppMap::RSpec::LOG
|
104
104
|
|
105
105
|
if failed
|
@@ -130,21 +130,21 @@ module AppMap
|
|
130
130
|
description.reverse!
|
131
131
|
|
132
132
|
normalize = lambda do |desc|
|
133
|
-
desc.gsub(
|
134
|
-
|
135
|
-
|
136
|
-
|
133
|
+
desc.gsub("it should behave like", "")
|
134
|
+
.gsub(/Controller$/, "")
|
135
|
+
.gsub(/\s+/, " ")
|
136
|
+
.strip
|
137
137
|
end
|
138
138
|
|
139
|
-
full_description = normalize.call(description.join(
|
139
|
+
full_description = normalize.call(description.join(" "))
|
140
140
|
|
141
141
|
AppMap::RSpec.save name: full_description,
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
142
|
+
class_map: class_map,
|
143
|
+
source_location: source_location,
|
144
|
+
test_status: exception ? "failed" : "succeeded",
|
145
|
+
test_failure: test_failure,
|
146
|
+
exception: exception,
|
147
|
+
events: events
|
148
148
|
end
|
149
149
|
end
|
150
150
|
|
@@ -169,10 +169,10 @@ module AppMap
|
|
169
169
|
# The example is empty except for assertions. So RSwag has its own recorder, and RSpec
|
170
170
|
# recording is disabled so it won't clobber the AppMap with empty data.
|
171
171
|
recording = if example.metadata[:appmap] == false || example.metadata[:rswag]
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
172
|
+
:disabled
|
173
|
+
else
|
174
|
+
Recording.new(example)
|
175
|
+
end
|
176
176
|
|
177
177
|
@recordings_by_example[example] = recording
|
178
178
|
end
|
@@ -185,7 +185,7 @@ module AppMap
|
|
185
185
|
end
|
186
186
|
|
187
187
|
def config
|
188
|
-
@config or raise
|
188
|
+
@config or raise "AppMap is not configured"
|
189
189
|
end
|
190
190
|
|
191
191
|
def add_event_methods(event_methods)
|
@@ -193,20 +193,20 @@ module AppMap
|
|
193
193
|
end
|
194
194
|
|
195
195
|
def save(name:, class_map:, source_location:, test_status:, test_failure:, exception:, events:, frameworks: [],
|
196
|
-
|
196
|
+
recorder: nil)
|
197
197
|
metadata = AppMap::RSpec.metadata.tap do |m|
|
198
198
|
m[:name] = name
|
199
199
|
m[:source_location] = source_location
|
200
200
|
m[:app] = AppMap.configuration.name
|
201
201
|
m[:frameworks] ||= []
|
202
202
|
m[:frameworks] << {
|
203
|
-
name:
|
204
|
-
version: Gem.loaded_specs[
|
203
|
+
name: "rspec",
|
204
|
+
version: Gem.loaded_specs["rspec-core"]&.version&.to_s
|
205
205
|
}
|
206
206
|
m[:frameworks] += frameworks
|
207
207
|
m[:recorder] = recorder || {
|
208
|
-
name:
|
209
|
-
type:
|
208
|
+
name: "rspec",
|
209
|
+
type: "tests"
|
210
210
|
}
|
211
211
|
m[:test_status] = test_status
|
212
212
|
m[:test_failure] = test_failure if test_failure
|
@@ -242,9 +242,9 @@ module AppMap
|
|
242
242
|
end
|
243
243
|
|
244
244
|
if AppMap::RSpec.enabled?
|
245
|
-
require
|
246
|
-
require
|
247
|
-
require
|
245
|
+
require "active_support/inflector/transliterate"
|
246
|
+
require "rspec/core"
|
247
|
+
require "rspec/core/example"
|
248
248
|
|
249
249
|
module RSpec
|
250
250
|
module Core
|
data/lib/appmap/trace.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "delegate"
|
4
4
|
|
5
5
|
module AppMap
|
6
6
|
module Trace
|
@@ -21,7 +21,7 @@ module AppMap
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def comment
|
24
|
-
return nil if source_location.nil? || source_location.first.start_with?(
|
24
|
+
return nil if source_location.nil? || source_location.first.start_with?("<")
|
25
25
|
|
26
26
|
# Do not use method_source's comment method because it's slow
|
27
27
|
@comment ||= RubyMethod.last_comment(*source_location)
|
@@ -71,8 +71,8 @@ module AppMap
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
-
def enabled?
|
75
|
-
@tracers.any?
|
74
|
+
def enabled?(thread_id: nil)
|
75
|
+
@tracers.any? { |t| t.enabled?(thread_id: thread_id) }
|
76
76
|
end
|
77
77
|
|
78
78
|
def last_package_for_current_thread
|
@@ -103,11 +103,11 @@ module AppMap
|
|
103
103
|
class StackPrinter
|
104
104
|
class << self
|
105
105
|
def enabled?
|
106
|
-
ENV[
|
106
|
+
ENV["APPMAP_PRINT_STACKS"] == "true"
|
107
107
|
end
|
108
108
|
|
109
109
|
def depth
|
110
|
-
(ENV[
|
110
|
+
(ENV["APPMAP_STACK_DEPTH"] || 20).to_i
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
@@ -116,21 +116,21 @@ module AppMap
|
|
116
116
|
end
|
117
117
|
|
118
118
|
def record(event)
|
119
|
-
stack = caller.select { |line| !line.index(
|
119
|
+
stack = caller.select { |line| !line.index("/lib/appmap/") }[0...StackPrinter.depth].join("\n ")
|
120
120
|
stack_hash = Digest::SHA256.hexdigest(stack)
|
121
121
|
return if @@stacks[stack_hash]
|
122
122
|
|
123
123
|
@@stacks[stack_hash] = stack
|
124
124
|
puts
|
125
|
-
puts
|
126
|
-
puts
|
125
|
+
puts "Event: " + event.to_h.map { |k, v| ["#{k}: #{v}"] }.join(", ")
|
126
|
+
puts " " + stack
|
127
127
|
puts
|
128
128
|
end
|
129
129
|
end
|
130
130
|
|
131
131
|
class Tracer
|
132
132
|
attr_accessor :stacks
|
133
|
-
attr_reader
|
133
|
+
attr_reader :thread_id, :events
|
134
134
|
|
135
135
|
# Records the events which happen in a program.
|
136
136
|
def initialize(thread_id: nil)
|
@@ -146,8 +146,10 @@ module AppMap
|
|
146
146
|
@enabled = true
|
147
147
|
end
|
148
148
|
|
149
|
-
def enabled?
|
150
|
-
@enabled
|
149
|
+
def enabled?(thread_id: nil)
|
150
|
+
return false unless @enabled
|
151
|
+
|
152
|
+
thread_id.nil? || @thread_id.nil? || @thread_id == thread_id
|
151
153
|
end
|
152
154
|
|
153
155
|
# Private function. Use AppMap.tracing#delete.
|
data/lib/appmap/util.rb
CHANGED
@@ -1,88 +1,92 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "bundler"
|
4
|
+
require "fileutils"
|
5
5
|
|
6
|
+
# rubocop:disable Metrics/MethodLength
|
7
|
+
# rubocop:disable Metrics/ModuleLength
|
8
|
+
# rubocop:disable Metrics/ClassLength
|
9
|
+
# rubocop:disable Metrics/AbcSize
|
6
10
|
module AppMap
|
7
11
|
module Util
|
8
12
|
# https://wynnnetherland.com/journal/a-stylesheet-author-s-guide-to-terminal-colors/
|
9
13
|
# Embed in a String to clear all previous ANSI sequences.
|
10
|
-
CLEAR
|
11
|
-
BOLD
|
14
|
+
CLEAR = "\e[0m"
|
15
|
+
BOLD = "\e[1m"
|
12
16
|
|
13
17
|
# Colors
|
14
|
-
BLACK
|
15
|
-
RED
|
16
|
-
GREEN
|
17
|
-
YELLOW
|
18
|
-
BLUE
|
18
|
+
BLACK = "\e[30m"
|
19
|
+
RED = "\e[31m"
|
20
|
+
GREEN = "\e[32m"
|
21
|
+
YELLOW = "\e[33m"
|
22
|
+
BLUE = "\e[34m"
|
19
23
|
MAGENTA = "\e[35m"
|
20
|
-
CYAN
|
21
|
-
WHITE
|
24
|
+
CYAN = "\e[36m"
|
25
|
+
WHITE = "\e[37m"
|
22
26
|
|
23
27
|
class << self
|
24
28
|
def parse_function_name(name)
|
25
|
-
package_tokens = name.split(
|
29
|
+
package_tokens = name.split("/")
|
26
30
|
|
27
31
|
class_and_name = package_tokens.pop
|
28
|
-
class_name, function_name, static = if class_and_name.include?(
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
class_name, function_name, static = if class_and_name.include?(".")
|
33
|
+
class_and_name.split(".",
|
34
|
+
2) + [true]
|
35
|
+
else
|
36
|
+
class_and_name.split(
|
37
|
+
"#", 2
|
38
|
+
) + [false]
|
39
|
+
end
|
36
40
|
|
37
41
|
raise "Malformed fully-qualified function name #{name}" unless function_name
|
38
42
|
|
39
|
-
[
|
43
|
+
[package_tokens.empty? ? "ruby" : package_tokens.join("/"), class_name, static, function_name]
|
40
44
|
end
|
41
45
|
|
42
46
|
# scenario_filename builds a suitable file name from a scenario name.
|
43
47
|
# Special characters are removed, and the file name is truncated to fit within
|
44
48
|
# shell limitations.
|
45
|
-
def scenario_filename(name, max_length: 255, separator:
|
49
|
+
def scenario_filename(name, max_length: 255, separator: "_", extension: ".appmap.json")
|
46
50
|
# Cribbed from v5 version of ActiveSupport:Inflector#parameterize:
|
47
51
|
# https://github.com/rails/rails/blob/v5.2.4/activesupport/lib/active_support/inflector/transliterate.rb#L92
|
48
52
|
# Replace accented chars with their ASCII equivalents.
|
49
53
|
|
50
|
-
fname = name.encode(
|
54
|
+
fname = name.encode("utf-8", invalid: :replace, undef: :replace, replace: "_")
|
51
55
|
|
52
56
|
# Turn unwanted chars into the separator.
|
53
57
|
fname.gsub!(/[^a-z0-9\-_]+/i, separator)
|
54
58
|
|
55
59
|
re_sep = Regexp.escape(separator)
|
56
|
-
re_duplicate_separator
|
60
|
+
re_duplicate_separator = /#{re_sep}{2,}/
|
57
61
|
re_leading_trailing_separator = /^#{re_sep}|#{re_sep}$/i
|
58
62
|
|
59
63
|
# No more than one of the separator in a row.
|
60
64
|
fname.gsub!(re_duplicate_separator, separator)
|
61
65
|
|
62
66
|
# Finally, Remove leading/trailing separator.
|
63
|
-
fname.gsub!(re_leading_trailing_separator,
|
67
|
+
fname.gsub!(re_leading_trailing_separator, "")
|
64
68
|
|
65
69
|
if (fname.length + extension.length) > max_length
|
66
|
-
require
|
67
|
-
require
|
70
|
+
require "base64"
|
71
|
+
require "digest"
|
68
72
|
fname_digest = Base64.urlsafe_encode64 Digest::MD5.digest(fname), padding: false
|
69
|
-
fname[max_length - fname_digest.length - extension.length - 1..-1] = [
|
73
|
+
fname[max_length - fname_digest.length - extension.length - 1..-1] = ["-", fname_digest].join
|
70
74
|
end
|
71
75
|
|
72
|
-
[
|
76
|
+
[fname, extension].join
|
73
77
|
end
|
74
78
|
|
75
79
|
# sanitize_paths removes ephemeral values from objects with
|
76
80
|
# embedded paths (e.g. an event or a classmap), making events
|
77
81
|
# easier to compare across runs.
|
78
82
|
def sanitize_paths(h)
|
79
|
-
require
|
83
|
+
require "hashie"
|
80
84
|
h.extend(Hashie::Extensions::DeepLocate)
|
81
85
|
keys = %i[path location]
|
82
86
|
h.deep_locate lambda { |k, _v, o|
|
83
87
|
next unless keys.include?(k)
|
84
88
|
|
85
|
-
fix = ->(v) { v.gsub(%r{#{Gem.dir}/gems/.*(?=lib)},
|
89
|
+
fix = ->(v) { v.gsub(%r{#{Gem.dir}/gems/.*(?=lib)}, "") }
|
86
90
|
keys.each { |k| o[k] = fix.call(o[k]) if o[k] }
|
87
91
|
}
|
88
92
|
|
@@ -105,8 +109,8 @@ module AppMap
|
|
105
109
|
headers = event.dig(field, :headers)
|
106
110
|
next unless headers
|
107
111
|
|
108
|
-
headers[
|
109
|
-
headers[
|
112
|
+
headers["Date"] = "<instanceof date>" if headers["Date"]
|
113
|
+
headers["Server"] = headers["Server"].match(/^(\w+)/)[0] if headers["Server"]
|
110
114
|
end
|
111
115
|
|
112
116
|
case event[:event]
|
@@ -122,8 +126,8 @@ module AppMap
|
|
122
126
|
blank?(headers) ? nil : headers
|
123
127
|
end
|
124
128
|
|
125
|
-
unless env[
|
126
|
-
warn
|
129
|
+
unless env["rack.version"]
|
130
|
+
warn "Request headers does not contain rack.version. HTTP_ prefix is not expected."
|
127
131
|
return finalize_headers.call(env.dup)
|
128
132
|
end
|
129
133
|
|
@@ -131,15 +135,15 @@ module AppMap
|
|
131
135
|
# Apparently, it's following the CGI spec in doing so.
|
132
136
|
# https://datatracker.ietf.org/doc/html/rfc3875#section-4.1.18
|
133
137
|
matching_headers = env
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
key = kv[0].sub(/^HTTP_/,
|
138
|
+
.select { |k, _v| k.to_s.start_with? "HTTP_" }
|
139
|
+
.merge(
|
140
|
+
"CONTENT_TYPE" => env["CONTENT_TYPE"],
|
141
|
+
"CONTENT_LENGTH" => env["CONTENT_LENGTH"],
|
142
|
+
"AUTHORIZATION" => env["AUTHORIZATION"]
|
143
|
+
)
|
144
|
+
.reject { |_k, v| blank?(v) }
|
145
|
+
.each_with_object({}) do |kv, memo|
|
146
|
+
key = kv[0].sub(/^HTTP_/, "").split("_").map(&:capitalize).join("-")
|
143
147
|
value = kv[1]
|
144
148
|
memo[key] = value
|
145
149
|
end
|
@@ -147,9 +151,9 @@ module AppMap
|
|
147
151
|
end
|
148
152
|
|
149
153
|
def normalize_path(path)
|
150
|
-
is_local_path
|
151
|
-
is_bundled_path
|
152
|
-
is_vendored_path = -> { path.index(File.join(Dir.pwd,
|
154
|
+
is_local_path = -> { path.index(Dir.pwd) == 0 }
|
155
|
+
is_bundled_path = -> { path.index(Bundler.bundle_path.to_s) == 0 }
|
156
|
+
is_vendored_path = -> { path.index(File.join(Dir.pwd, "vendor/bundle")) == 0 }
|
153
157
|
|
154
158
|
if is_local_path.call && !is_bundled_path.call && !is_vendored_path.call
|
155
159
|
path[Dir.pwd.length + 1..-1]
|
@@ -168,13 +172,13 @@ module AppMap
|
|
168
172
|
def extract_test_failure(exception)
|
169
173
|
return unless exception
|
170
174
|
|
171
|
-
{
|
175
|
+
{message: exception.message}.tap do |test_failure|
|
172
176
|
first_location = exception.backtrace_locations&.find do |location|
|
173
177
|
!Pathname.new(normalize_path(location.absolute_path || location.path)).absolute?
|
174
178
|
end
|
175
179
|
if first_location
|
176
180
|
test_failure[:location] =
|
177
|
-
[
|
181
|
+
[normalize_path(first_location.path), first_location.lineno].join(":")
|
178
182
|
end
|
179
183
|
end
|
180
184
|
end
|
@@ -182,21 +186,23 @@ module AppMap
|
|
182
186
|
# Convert a Rails-style path from /org/:org_id(.:format)
|
183
187
|
# to Swagger-style paths like /org/{org_id}
|
184
188
|
def swaggerize_path(path)
|
185
|
-
path = path.split(
|
186
|
-
tokens = path.split(
|
189
|
+
path = path.split("(.")[0]
|
190
|
+
tokens = path.split("/")
|
187
191
|
tokens.map do |token|
|
188
192
|
# stop matching if an ending ) is found
|
189
193
|
token.gsub(/^:(.*[^)])/, '{\1}')
|
190
|
-
end.join(
|
194
|
+
end.join("/")
|
191
195
|
end
|
192
196
|
|
193
197
|
# Atomically writes AppMap data to +filename+.
|
194
198
|
def write_appmap(filename, appmap)
|
195
|
-
require
|
199
|
+
require "tmpdir"
|
200
|
+
|
201
|
+
FileUtils.mkdir_p(File.dirname(filename))
|
196
202
|
|
197
203
|
# This is what Ruby Tempfile does; but we don't want the file to be unlinked.
|
198
204
|
mode = File::RDWR | File::CREAT | File::EXCL
|
199
|
-
::Dir::Tmpname.create([
|
205
|
+
::Dir::Tmpname.create(["appmap_", ".json"]) do |tmpname|
|
200
206
|
tempfile = File.open(tmpname, mode)
|
201
207
|
tempfile.write(JSON.generate(appmap))
|
202
208
|
tempfile.close
|
@@ -207,7 +213,7 @@ module AppMap
|
|
207
213
|
|
208
214
|
def color(text, color, bold: false)
|
209
215
|
color = Util.const_get(color.to_s.upcase) if color.is_a?(Symbol)
|
210
|
-
bold
|
216
|
+
bold = bold ? BOLD : ""
|
211
217
|
"#{bold}#{color}#{text}#{CLEAR}"
|
212
218
|
end
|
213
219
|
|
@@ -219,24 +225,24 @@ module AppMap
|
|
219
225
|
def underscore(camel_cased_word)
|
220
226
|
return camel_cased_word unless /[A-Z-]|::/.match?(camel_cased_word)
|
221
227
|
|
222
|
-
word = camel_cased_word.to_s.gsub(
|
228
|
+
word = camel_cased_word.to_s.gsub("::", "/")
|
223
229
|
# word.gsub!(inflections.acronyms_underscore_regex) { "#{$1 && '_' }#{$2.downcase}" }
|
224
230
|
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
|
225
231
|
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
226
|
-
word.tr!(
|
232
|
+
word.tr!("-", "_")
|
227
233
|
word.downcase!
|
228
234
|
word
|
229
235
|
end
|
230
236
|
|
231
237
|
def deep_dup(hash)
|
232
|
-
require
|
238
|
+
require "active_support/core_ext"
|
233
239
|
hash.deep_dup
|
234
240
|
end
|
235
241
|
|
236
242
|
def blank?(obj)
|
237
243
|
return true if obj.nil?
|
238
244
|
|
239
|
-
return true if obj.is_a?(String) && obj ==
|
245
|
+
return true if obj.is_a?(String) && obj == ""
|
240
246
|
|
241
247
|
return true if obj.respond_to?(:length) && obj.length == 0
|
242
248
|
|
@@ -257,7 +263,7 @@ module AppMap
|
|
257
263
|
def startup_message(msg)
|
258
264
|
if defined?(::Rails) && defined?(::Rails.logger) && ::Rails.logger
|
259
265
|
::Rails.logger.info msg
|
260
|
-
elsif ENV[
|
266
|
+
elsif ENV["DEBUG"] == "true"
|
261
267
|
warn msg
|
262
268
|
end
|
263
269
|
|
@@ -265,7 +271,7 @@ module AppMap
|
|
265
271
|
end
|
266
272
|
|
267
273
|
def ruby_minor_version
|
268
|
-
@ruby_minor_version ||= RUBY_VERSION.split(
|
274
|
+
@ruby_minor_version ||= RUBY_VERSION.split(".")[0..1].join(".").to_f
|
269
275
|
end
|
270
276
|
|
271
277
|
def gettime
|
@@ -274,3 +280,7 @@ module AppMap
|
|
274
280
|
end
|
275
281
|
end
|
276
282
|
end
|
283
|
+
# rubocop:enable Metrics/MethodLength
|
284
|
+
# rubocop:enable Metrics/ModuleLength
|
285
|
+
# rubocop:enable Metrics/ClassLength
|
286
|
+
# rubocop:enable Metrics/AbcSize
|
data/lib/appmap/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: appmap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.103.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Gilpin
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-12-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: method_source
|
@@ -150,20 +150,6 @@ dependencies:
|
|
150
150
|
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '0'
|
153
|
-
- !ruby/object:Gem::Dependency
|
154
|
-
name: standardrb
|
155
|
-
requirement: !ruby/object:Gem::Requirement
|
156
|
-
requirements:
|
157
|
-
- - "~>"
|
158
|
-
- !ruby/object:Gem::Version
|
159
|
-
version: '1.0'
|
160
|
-
type: :development
|
161
|
-
prerelease: false
|
162
|
-
version_requirements: !ruby/object:Gem::Requirement
|
163
|
-
requirements:
|
164
|
-
- - "~>"
|
165
|
-
- !ruby/object:Gem::Version
|
166
|
-
version: '1.0'
|
167
153
|
- !ruby/object:Gem::Dependency
|
168
154
|
name: climate_control
|
169
155
|
requirement: !ruby/object:Gem::Requirement
|
@@ -324,8 +310,10 @@ files:
|
|
324
310
|
- ".nvmrc"
|
325
311
|
- ".rbenv-gemsets"
|
326
312
|
- ".releaserc.yml"
|
313
|
+
- ".rubocop.yml"
|
327
314
|
- ".ruby-version"
|
328
315
|
- ".rufo"
|
316
|
+
- ".standard.yml"
|
329
317
|
- ".travis.yml"
|
330
318
|
- ARCHITECTURE.md
|
331
319
|
- CHANGELOG.md
|
@@ -414,6 +402,7 @@ files:
|
|
414
402
|
- lib/appmap/hook/method.rb
|
415
403
|
- lib/appmap/hook/method/ruby2.rb
|
416
404
|
- lib/appmap/hook/method/ruby3.rb
|
405
|
+
- lib/appmap/hook/record_around.rb
|
417
406
|
- lib/appmap/hook_log.rb
|
418
407
|
- lib/appmap/metadata.rb
|
419
408
|
- lib/appmap/middleware/remote_recording.rb
|