appmap 0.53.0 → 0.54.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +16 -10
  3. data/CHANGELOG.md +41 -0
  4. data/Rakefile +13 -4
  5. data/appmap.gemspec +1 -0
  6. data/lib/appmap.rb +31 -112
  7. data/lib/appmap/agent.rb +115 -0
  8. data/lib/appmap/class_map.rb +2 -2
  9. data/lib/appmap/config.rb +11 -3
  10. data/lib/appmap/handler/net_http.rb +3 -2
  11. data/lib/appmap/handler/rails/request_handler.rb +2 -1
  12. data/lib/appmap/handler/rails/template.rb +2 -1
  13. data/lib/appmap/hook.rb +7 -3
  14. data/lib/appmap/hook/method.rb +36 -28
  15. data/lib/appmap/metadata.rb +4 -2
  16. data/lib/appmap/minitest.rb +2 -0
  17. data/lib/appmap/railtie.rb +2 -2
  18. data/lib/appmap/rspec.rb +5 -3
  19. data/lib/appmap/swagger.rb +2 -0
  20. data/lib/appmap/swagger/configuration.rb +70 -0
  21. data/lib/appmap/swagger/markdown_descriptions.rb +43 -0
  22. data/lib/appmap/swagger/rake_tasks.rb +43 -0
  23. data/lib/appmap/swagger/stable.rb +37 -0
  24. data/lib/appmap/trace.rb +2 -0
  25. data/lib/appmap/util.rb +17 -1
  26. data/lib/appmap/version.rb +1 -1
  27. data/package.json +0 -1
  28. data/release.sh +0 -1
  29. data/spec/config_spec.rb +0 -1
  30. data/spec/fixtures/hook/.gitignore +2 -0
  31. data/spec/fixtures/hook/app/controllers/api/api_keys_controller.rb +1 -0
  32. data/spec/fixtures/hook/app/controllers/organizations_controller.rb +1 -0
  33. data/spec/fixtures/hook/app/models/api_key.rb +1 -0
  34. data/spec/fixtures/hook/app/models/configuration.rb +1 -0
  35. data/spec/fixtures/hook/app/models/show.rb +1 -0
  36. data/spec/fixtures/hook/app/models/user.rb +1 -0
  37. data/spec/fixtures/hook/kwargs.rb +11 -0
  38. data/spec/fixtures/hook/revoke_api_key.appmap.json +847 -0
  39. data/spec/fixtures/hook/spec/api_spec.rb +1 -0
  40. data/spec/fixtures/hook/spec/user_spec.rb +1 -0
  41. data/spec/fixtures/hook/user_page_scenario.appmap.json +1722 -0
  42. data/spec/fixtures/rails5_users_app/config/environments/test.rb +3 -0
  43. data/spec/fixtures/rails6_users_app/Dockerfile +0 -1
  44. data/spec/fixtures/rails6_users_app/appmap.yml +3 -1
  45. data/spec/fixtures/rails6_users_app/config/environments/test.rb +3 -0
  46. data/spec/fixtures/rails6_users_app/lib/tasks/appmap.rake +13 -0
  47. data/spec/hook_spec.rb +9 -0
  48. data/spec/rails_recording_spec.rb +1 -1
  49. data/spec/record_net_http_spec.rb +1 -0
  50. data/spec/swagger/swagger_spec.rb +47 -0
  51. data/test/gem_test.rb +1 -0
  52. metadata +36 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 69fc6d5fce636d669cb33a9564a3c504eb255cb13a81985154589eb7cc6f9879
4
- data.tar.gz: f2400bbda425b4e0f8d72b52d7edfcf761c8356638691074c79b72fdbca9f086
3
+ metadata.gz: 13450fa6c0ff3576dc48e27f35355e3eb4bd4ed70aac677af1235b8b8b8ce793
4
+ data.tar.gz: 2c08a504d3e6a467d212630290205ecab9391c64a33831574df43cb8526ab0ad
5
5
  SHA512:
6
- metadata.gz: 17016392e9b2931c961bf1cdb3c7f832af15896201b395995c124befb7de1987ee43997f9186c329f9fe6474101158c06a0772e8bf0bd6bbd9b9b4ddd84defeb
7
- data.tar.gz: 29fe408c9a44ec5cf8ffd410f732d6cc5959e045480c94406a4f9cc4abc2badbc1843f449bba0b8cd5e2b6269c71f8e5d603b9e99a902e63e6692d16af0e4c6f
6
+ metadata.gz: 49585b5fba1c9b7a0aabffd6dfc44fb051532fd9fe96d35a0176c6bcf382a51df948bfac8f1f0d3db474917f5587dbf07e90de9c9097d3de9a1650a1632f8fd6
7
+ data.tar.gz: aa489a3dc598dfc2c16ee3a6167e53683e5564870c3b1ed0552e9e0ba0d758da2d1c442059bee3efbe57206f9088a98ca7c271d8550f52ed5d18d0aa2a039635
data/.travis.yml CHANGED
@@ -1,5 +1,10 @@
1
1
  language: ruby
2
2
 
3
+ rbenv:
4
+ - 2.5
5
+ - 2.6
6
+ - 2.7
7
+
3
8
  addons:
4
9
  apt:
5
10
  packages:
@@ -29,28 +34,29 @@ before_install:
29
34
  - |
30
35
  nvm install --lts \
31
36
  && nvm use --lts
32
-
37
+
33
38
  # GEM_ALTERNATIVE_NAME only needed for deployment
34
39
  jobs:
35
40
  include:
36
41
  - stage: test
37
42
  script:
43
+ - set -e
38
44
  - mkdir tmp
39
- - GEM_ALTERNATIVE_NAME='' bundle exec rake test
45
+ - npm i -g yarn
46
+ - GEM_ALTERNATIVE_NAME='' bundle exec rake gem:build test
40
47
 
41
-
42
48
  before_deploy:
43
49
  - |
44
- nvm install --lts \
45
- && nvm use --lts \
46
- && npm i -g \
47
- semantic-release \
48
- @semantic-release/git \
49
- @semantic-release/changelog \
50
- semantic-release-rubygem
50
+ npm i -g \
51
+ yarn \
52
+ semantic-release \
53
+ @semantic-release/git \
54
+ @semantic-release/changelog \
55
+ semantic-release-rubygem
51
56
 
52
57
  deploy:
53
58
  - provider: script
54
59
  script: ./release.sh
55
60
  on:
56
61
  branch: master
62
+ condition: "$TRAVIS_RUBY_VERSION = 2.7"
data/CHANGELOG.md CHANGED
@@ -1,3 +1,44 @@
1
+ ## [0.54.4](https://github.com/applandinc/appmap-ruby/compare/v0.54.3...v0.54.4) (2021-06-27)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * Only allow trace_end once per location ([10e48cf](https://github.com/applandinc/appmap-ruby/commit/10e48cf855907f9029479b4b7b63bc4d25d664ab))
7
+
8
+ ## [0.54.3](https://github.com/applandinc/appmap-ruby/compare/v0.54.2...v0.54.3) (2021-06-25)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * Get deployment working with packaging of NodeJS code ([733c5b8](https://github.com/applandinc/appmap-ruby/commit/733c5b85ec1a0c17ada81be524fa572f78f52500))
14
+
15
+ ## [0.54.2](https://github.com/applandinc/appmap-ruby/compare/v0.54.1...v0.54.2) (2021-06-25)
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * Require appmap/railtie if Rails is defined ([66b4cbd](https://github.com/applandinc/appmap-ruby/commit/66b4cbd4d418695b0e69150d253dfd5a6f9096cf))
21
+
22
+ ## [0.54.1](https://github.com/applandinc/appmap-ruby/compare/v0.54.0...v0.54.1) (2021-06-25)
23
+
24
+
25
+ ### Bug Fixes
26
+
27
+ * Add missing imports and remove deprecation warnings ([f1cb087](https://github.com/applandinc/appmap-ruby/commit/f1cb087f80cad88093227ebf8b4a4cd574853667))
28
+ * Workaround Ruby bug in 2.7.3 with kwrest ([26e34ca](https://github.com/applandinc/appmap-ruby/commit/26e34ca421fdae6602b27fee5653c8fe26b3793b))
29
+
30
+ # [0.54.0](https://github.com/applandinc/appmap-ruby/compare/v0.53.0...v0.54.0) (2021-06-24)
31
+
32
+
33
+ ### Bug Fixes
34
+
35
+ * Handle new behavior in RSpec ExampleGroup ([176d0df](https://github.com/applandinc/appmap-ruby/commit/176d0dfca0b2e4cc5a8908fa67c01dd0c79ef175))
36
+
37
+
38
+ ### Features
39
+
40
+ * Add swagger rake task ([0aaae49](https://github.com/applandinc/appmap-ruby/commit/0aaae4973f0df530c75ed92b93f8a1940a948091))
41
+
1
42
  # [0.53.0](https://github.com/applandinc/appmap-ruby/compare/v0.52.1...v0.53.0) (2021-06-23)
2
43
 
3
44
 
data/Rakefile CHANGED
@@ -6,8 +6,7 @@ require 'rake/testtask'
6
6
  require 'rdoc/task'
7
7
 
8
8
  require 'open3'
9
-
10
- require "rake/extensiontask"
9
+ require 'rake/extensiontask'
11
10
 
12
11
  desc 'build the native extension'
13
12
  Rake::ExtensionTask.new("appmap") do |ext|
@@ -26,7 +25,7 @@ namespace 'gem' do
26
25
  # ~/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/gem_helper.rb:39:in `install'
27
26
  def build_gem
28
27
  # Ensure that NPM packages are installed before building.
29
- sh('yarn install --prod'.shellsplit)
28
+ sh('yarn install --prod')
30
29
 
31
30
  default_build_gem
32
31
  end
@@ -34,7 +33,17 @@ namespace 'gem' do
34
33
  end
35
34
  end
36
35
 
37
- RUBY_VERSIONS=%w[2.5 2.6 2.7]
36
+ RUBY_VERSIONS=%w[2.5 2.6 2.7].select do |version|
37
+ travis_ruby_version = ENV['TRAVIS_RUBY_VERSION']
38
+ next true unless travis_ruby_version
39
+
40
+ if travis_ruby_version.index(version) == 0
41
+ warn "Testing Ruby version #{version}, since it matches TRAVIS_RUBY_VERSION=#{travis_ruby_version}"
42
+ next true
43
+ end
44
+
45
+ false
46
+ end
38
47
  FIXTURE_APPS=%w[rack_users_app rails6_users_app rails5_users_app]
39
48
 
40
49
  def run_cmd(*cmd)
data/appmap.gemspec CHANGED
@@ -54,4 +54,5 @@ Gem::Specification.new do |spec|
54
54
  spec.add_development_dependency 'webdrivers', '~> 4.0'
55
55
  spec.add_development_dependency 'timecop'
56
56
  spec.add_development_dependency 'hashie'
57
+ spec.add_development_dependency 'webrick'
57
58
  end
data/lib/appmap.rb CHANGED
@@ -1,124 +1,38 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- begin
4
- require 'active_support'
5
- require 'active_support/core_ext'
6
- rescue NameError
7
- warn 'active_support is not available. AppMap execution will continue optimistically without it...'
8
- end
3
+ # This is the file that's loaded when you require 'appmap'.
4
+ # If you require this file, we assume that you want to automatically activate all
5
+ # the AppMap functionality that seems suitable for your project.
6
+ # For example, if your project is a Rails project, the Railtie will be loaded.
7
+ # If your bundle includes rspec, the appmap/rspec will be loaded.
8
+ #
9
+ # If you don't want this "all-in" behavior, then you can use the 'require' option
10
+ # in your Gemfile to selectively activate just the AppMap features that you want. Then
11
+ # you can manually configure/require other features, elsewhere in your code.
12
+ # Note that you should always require 'appmap/agent' as early as possible, so that it can
13
+ # observe and hook as much code loading as possible.
14
+ #
15
+ # Modules that you can load independently include:
16
+ # - appmap/agent
17
+ # - appmap/railtie
18
+ # - appmap/rspec
19
+ # - appmap/minitest
20
+ # - appmap/swagger (Rake task)
9
21
 
10
22
  require 'appmap/version'
11
- require 'appmap/util'
12
- require 'appmap/hook'
13
- require 'appmap/config'
14
- require 'appmap/trace'
15
- require 'appmap/class_map'
16
- require 'appmap/metadata'
17
- require 'appmap/open'
18
-
19
- # load extension
20
- require 'appmap/appmap'
21
-
22
- module AppMap
23
- class << self
24
- @configuration = nil
25
- @configuration_file_path = nil
26
-
27
- # Gets the configuration. If there is no configuration, the default
28
- # configuration is initialized.
29
- def configuration
30
- @configuration ||= initialize_configuration
31
- end
32
-
33
- # Sets the configuration. This is only expected to happen once per
34
- # Ruby process.
35
- def configuration=(config)
36
- warn 'AppMap is already configured' if @configuration && config
37
-
38
- @configuration = config
39
- end
40
-
41
- def default_config_file_path
42
- ENV['APPMAP_CONFIG_FILE'] || 'appmap.yml'
43
- end
44
-
45
- # Configures AppMap for recording. Default behavior is to configure from
46
- # APPMAP_CONFIG_FILE, or 'appmap.yml'. If no config file is available, a
47
- # configuration will be automatically generated and used - and the user is prompted
48
- # to create the config file.
49
- #
50
- # This method also activates the code hooks which record function calls as trace events.
51
- # Call this function before the program code is loaded by the Ruby VM, otherwise
52
- # the load events won't be seen and the hooks won't activate.
53
- def initialize_configuration(config_file_path = default_config_file_path)
54
- Util.startup_message "Configuring AppMap from path #{config_file_path}"
55
- Config.load_from_file(config_file_path).tap do |configuration|
56
- self.configuration = configuration
57
- Hook.new(configuration).enable
58
- end
59
- end
60
-
61
- def info(msg)
62
- if defined?(::Rails) && defined?(::Rails.logger)
63
- ::Rails.logger.info msg
64
- else
65
- warn msg
66
- end
67
- end
68
-
69
- # Used to start tracing, stop tracing, and record events.
70
- def tracing
71
- @tracing ||= Trace::Tracing.new
72
- end
73
-
74
- # Records the events which occur while processing a block,
75
- # and returns an AppMap as a Hash.
76
- def record
77
- tracer = tracing.trace
78
- begin
79
- yield
80
- ensure
81
- tracing.delete(tracer)
82
- end
83
-
84
- events = [].tap do |event_list|
85
- event_list << tracer.next_event.to_h while tracer.event?
86
- end
87
- {
88
- 'version' => AppMap::APPMAP_FORMAT_VERSION,
89
- 'metadata' => detect_metadata,
90
- 'classMap' => class_map(tracer.event_methods),
91
- 'events' => events
92
- }
93
- end
94
-
95
- # Uploads an AppMap to the AppLand website and displays it.
96
- def open(appmap = nil, &block)
97
- appmap ||= AppMap.record(&block)
98
- AppMap::Open.new(appmap).perform
99
- end
100
-
101
- # Builds a class map from a config and a list of Ruby methods.
102
- def class_map(methods)
103
- ClassMap.build_from_methods(methods)
104
- end
105
-
106
- # Returns default metadata detected from the Ruby system and from the
107
- # filesystem.
108
- def detect_metadata
109
- @metadata ||= Metadata.detect.freeze
110
- @metadata.deep_dup
111
- end
112
- end
113
- end
23
+ require 'appmap/agent'
114
24
 
115
25
  lambda do
116
26
  Initializer = Struct.new(:class_name, :module_name, :gem_module_name)
117
27
 
118
28
  INITIALIZERS = {
119
- 'Rails::Railtie' => Initializer.new('AppMap::Railtie', 'appmap/railtie', 'railtie'),
29
+ # In a Rails app, Rails is always defined by the time the other gems are loaded. Therefore, we
30
+ # don't try and trap the loading of Rails itself here.
120
31
  'RSpec' => Initializer.new('AppMap::RSpec', 'appmap/rspec', 'rspec-core'),
121
- 'Minitest::Unit::TestCase' => Initializer.new('AppMap::Minitest', 'appmap/minitest', 'minitest')
32
+ 'Minitest::Unit::TestCase' => Initializer.new('AppMap::Minitest', 'appmap/minitest', 'minitest'),
33
+ 'Rake' => [
34
+ Initializer.new('AppMap::Swagger', 'appmap/swagger', 'rake')
35
+ ]
122
36
  }
123
37
 
124
38
  TracePoint.new(:class) do |tp|
@@ -144,7 +58,7 @@ lambda do
144
58
  end
145
59
  end.enable
146
60
 
147
- if defined?(::Rails::Railtie)
61
+ if defined?(::Rails)
148
62
  require 'appmap/railtie'
149
63
  end
150
64
 
@@ -155,6 +69,11 @@ lambda do
155
69
  if defined?(::Minitest)
156
70
  require 'appmap/minitest'
157
71
  end
72
+
73
+ if defined?(::Rake)
74
+ require 'appmap/swagger'
75
+ end
76
+
158
77
  end.call
159
78
 
160
79
  AppMap.initialize_configuration if ENV['APPMAP'] == 'true'
@@ -0,0 +1,115 @@
1
+ require_relative 'version'
2
+ require_relative 'hook'
3
+ require_relative 'config'
4
+ require_relative 'trace'
5
+ require_relative 'class_map'
6
+ require_relative 'metadata'
7
+ require_relative 'util'
8
+ require_relative 'open'
9
+
10
+ # load extension
11
+ require_relative 'appmap'
12
+
13
+ module AppMap
14
+ class << self
15
+ @configuration = nil
16
+ @configuration_file_path = nil
17
+
18
+ # Gets the configuration. If there is no configuration, the default
19
+ # configuration is initialized.
20
+ def configuration
21
+ @configuration ||= initialize_configuration
22
+ end
23
+
24
+ # Sets the configuration. This is only expected to happen once per
25
+ # Ruby process.
26
+ def configuration=(config)
27
+ warn 'AppMap is already configured' if @configuration && config
28
+
29
+ @configuration = config
30
+ end
31
+
32
+ def default_config_file_path
33
+ ENV['APPMAP_CONFIG_FILE'] || 'appmap.yml'
34
+ end
35
+
36
+ # Configures AppMap for recording. Default behavior is to configure from
37
+ # APPMAP_CONFIG_FILE, or 'appmap.yml'. If no config file is available, a
38
+ # configuration will be automatically generated and used - and the user is prompted
39
+ # to create the config file.
40
+ #
41
+ # This method also activates the code hooks which record function calls as trace events.
42
+ # Call this function before the program code is loaded by the Ruby VM, otherwise
43
+ # the load events won't be seen and the hooks won't activate.
44
+ def initialize_configuration(config_file_path = default_config_file_path)
45
+ Util.startup_message "Configuring AppMap from path #{config_file_path}"
46
+ Config.load_from_file(config_file_path).tap do |configuration|
47
+ self.configuration = configuration
48
+ Hook.new(configuration).enable
49
+ end
50
+ end
51
+
52
+ def info(msg)
53
+ if defined?(::Rails) && defined?(::Rails.logger)
54
+ ::Rails.logger.info msg
55
+ else
56
+ warn msg
57
+ end
58
+ end
59
+
60
+ def config_message(msg)
61
+ logger = if defined?(::Rails) && ::Rails.logger
62
+ ::Rails.logger
63
+ elsif ENV['DEBUG'] == 'true'
64
+ method(:warn)
65
+ else
66
+ ->(msg) { }
67
+ end
68
+ logger.call(msg)
69
+ end
70
+
71
+ # Used to start tracing, stop tracing, and record events.
72
+ def tracing
73
+ @tracing ||= Trace::Tracing.new
74
+ end
75
+
76
+ # Records the events which occur while processing a block,
77
+ # and returns an AppMap as a Hash.
78
+ def record
79
+ tracer = tracing.trace
80
+ begin
81
+ yield
82
+ ensure
83
+ tracing.delete(tracer)
84
+ end
85
+
86
+ events = [].tap do |event_list|
87
+ event_list << tracer.next_event.to_h while tracer.event?
88
+ end
89
+ {
90
+ 'version' => AppMap::APPMAP_FORMAT_VERSION,
91
+ 'metadata' => detect_metadata,
92
+ 'classMap' => class_map(tracer.event_methods),
93
+ 'events' => events
94
+ }
95
+ end
96
+
97
+ # Uploads an AppMap to the AppLand website and displays it.
98
+ def open(appmap = nil, &block)
99
+ appmap ||= AppMap.record(&block)
100
+ AppMap::Open.new(appmap).perform
101
+ end
102
+
103
+ # Builds a class map from a config and a list of Ruby methods.
104
+ def class_map(methods)
105
+ ClassMap.build_from_methods(methods)
106
+ end
107
+
108
+ # Returns default metadata detected from the Ruby system and from the
109
+ # filesystem.
110
+ def detect_metadata
111
+ @metadata ||= Metadata.detect.freeze
112
+ Util.deep_dup(@metadata)
113
+ end
114
+ end
115
+ end
@@ -111,7 +111,7 @@ module AppMap
111
111
  end
112
112
 
113
113
  comment = method.comment
114
- function_info[:comment] = comment unless comment.blank?
114
+ function_info[:comment] = comment unless Util.blank?(comment)
115
115
 
116
116
  function_info[:labels] = parse_labels(comment) + (method.labels || [])
117
117
  object_infos << function_info
@@ -119,7 +119,7 @@ module AppMap
119
119
  parent = root
120
120
  object_infos.each do |info|
121
121
  parent = find_or_create parent.children, info do
122
- Types.const_get(info[:type].classify).new(info[:name].to_s).tap do |type|
122
+ Types.const_get(Util.classify(info[:type])).new(info[:name].to_s).tap do |type|
123
123
  info.keys.tap do |keys|
124
124
  keys.delete(:name)
125
125
  keys.delete(:type)