appmap 0.51.1 → 0.51.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8a51a7f69ebbca275fd9a215a52cd3e4d8db739e8e6cecf3eb522871f23295b5
4
- data.tar.gz: 58f033b5c4f8756532dd3dbe83c631b36560e3215a342f804916de205f53cb56
3
+ metadata.gz: 194f53c7e13b466fef13720503fe9f8c1ee149af724884224ce03753cc0d658f
4
+ data.tar.gz: e9c7d5578da6d9e80d9c06e70deaa32fe7da785ab94840a09739e474601a8cac
5
5
  SHA512:
6
- metadata.gz: e52a4b23f708892b12c3ca68a2b5e3c13a2c9b1d1b52057ede1548faa7c7d03914296ebb1402c7c1cd1f0540df1d6182ffa09de2cf3558410d499703bc8b352f
7
- data.tar.gz: 32201a386bc48ef35395e702a46661f78b12c4b15cab6214203e91e3599537cc53742f5ef2848ecf3d73b3c6c007413b55b4ea22bc4f8c83131733b9b2ace4a3
6
+ metadata.gz: 82da50065460e83bbbd0f35bdce8e04924d9e0388f1da9ba30cea0637594dce2d8dc3a9364c55e1492924e73dfb91cf163eac7fe7028e4b48eb5cb3c34a96c92
7
+ data.tar.gz: 96198ca1c1f3c5bdcd4d75ce275f8e76a39ff9c36cbaf314c642d91dac54403426a28b54c5a478a58295560af804dc3f44ac33ff9b1b710b1d401fab4c72cb75
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## [0.51.2](https://github.com/applandinc/appmap-ruby/compare/v0.51.1...v0.51.2) (2021-06-22)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * Be less verbose when logging config messages ([fba2fd0](https://github.com/applandinc/appmap-ruby/commit/fba2fd01dbb7b1830194b49285654d6657d1c786))
7
+ * Method objects must support eql? and hash to ensure they are unique in a Set ([f4d5b11](https://github.com/applandinc/appmap-ruby/commit/f4d5b11db90aa50bdd1f768e039927833e83c30f))
8
+ * Require rails, then appmap/railtie ([07967a1](https://github.com/applandinc/appmap-ruby/commit/07967a14609891544a7dd874c648b7ef5a505f21))
9
+ * Use a hybrid strategy to auto-requiring appmap modules ([6fb09b8](https://github.com/applandinc/appmap-ruby/commit/6fb09b8c0bd55b1e29967d459ce1e2bd5b1ba9fe))
10
+
1
11
  ## [0.51.1](https://github.com/applandinc/appmap-ruby/compare/v0.51.0...v0.51.1) (2021-06-21)
2
12
 
3
13
 
data/appmap.gemspec CHANGED
@@ -22,6 +22,9 @@ Gem::Specification.new do |spec|
22
22
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
23
  spec.files = `git ls-files --no-deleted`.split("
24
24
  ")
25
+ spec.bindir = 'exe'
26
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
+
25
28
  spec.extensions << "ext/appmap/extconf.rb"
26
29
 
27
30
  spec.require_paths = ['lib']
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'gli'
5
+
6
+ require 'appmap'
7
+
8
+ class App
9
+ extend GLI::App
10
+
11
+ program_desc 'CLI tool to be used by IDEs for AppMap setup and configuration'
12
+
13
+ version AppMap::VERSION
14
+
15
+ subcommand_option_handling :normal
16
+ arguments :strict
17
+ preserve_argv true
18
+
19
+ desc 'AppMap configuration file name'
20
+ default_value ENV['APPMAP_CONFIG'] || AppMap::DEFAULT_CONFIG_FILE_PATH
21
+ arg_name 'filename'
22
+ flag %i[c config]
23
+
24
+ desc 'Creates base configuration file for the current project'
25
+ command :init do |c|
26
+ c.action do
27
+ require 'appmap/command/init'
28
+ AppMap::Command::Init.new(@config_file).perform
29
+ end
30
+ end
31
+
32
+ pre do |global, _, _, _|
33
+ @config_file = global[:config]
34
+ @config = interpret_config_option(@config_file) if File.exist?(@config_file)
35
+ true
36
+ end
37
+
38
+ class << self
39
+ protected
40
+
41
+ def interpret_config_option(fname)
42
+ AppMap::Config.load_from_file fname
43
+ end
44
+ end
45
+ end
46
+
47
+ exit App.run(ARGV)
data/lib/appmap.rb CHANGED
@@ -51,7 +51,7 @@ module AppMap
51
51
  # Call this function before the program code is loaded by the Ruby VM, otherwise
52
52
  # the load events won't be seen and the hooks won't activate.
53
53
  def initialize_configuration(config_file_path = default_config_file_path)
54
- warn "Configuring AppMap from path #{config_file_path}"
54
+ startup_message "Configuring AppMap from path #{config_file_path}"
55
55
  Config.load_from_file(config_file_path).tap do |configuration|
56
56
  self.configuration = configuration
57
57
  Hook.new(configuration).enable
@@ -109,20 +109,60 @@ module AppMap
109
109
  @metadata ||= Metadata.detect.freeze
110
110
  @metadata.deep_dup
111
111
  end
112
+
113
+ def startup_message(msg)
114
+ if defined?(::Rails) && defined?(::Rails.logger) && ::Rails.logger
115
+ ::Rails.logger.debug msg
116
+ elsif ENV['DEBUG'] == 'true'
117
+ warn msg
118
+ end
119
+ end
112
120
  end
113
121
  end
114
122
 
115
- if defined?(::Rails::Railtie)
116
- require 'appmap/railtie'
117
- end
123
+ lambda do
124
+ Initializer = Struct.new(:class_name, :module_name, :gem_module_name)
118
125
 
119
- if defined?(::RSpec)
120
- require 'appmap/rspec'
121
- end
126
+ INITIALIZERS = {
127
+ 'Rails::Railtie' => Initializer.new('AppMap::Railtie', 'appmap/railtie', 'railtie'),
128
+ 'RSpec' => Initializer.new('AppMap::RSpec', 'appmap/rspec', 'rspec-core'),
129
+ 'Minitest::Unit::TestCase' => Initializer.new('AppMap::Minitest', 'appmap/minitest', 'minitest')
130
+ }
122
131
 
123
- # defined?(::Minitest) returns nil...
124
- if Gem.loaded_specs['minitest']
125
- require 'appmap/minitest'
126
- end
132
+ TracePoint.new(:class) do |tp|
133
+ cls_name = tp.self.name
134
+ initializers = INITIALIZERS.delete(cls_name)
135
+ if initializers
136
+ initializers = [ initializers ] unless initializers.is_a?(Array)
137
+ next if Object.const_defined?(initializers.first.class_name)
138
+
139
+ gem_module_name = initializers.first.gem_module_name
140
+
141
+ AppMap.startup_message AppMap::Util.color(<<~LOAD_MSG, :magenta)
142
+ When 'appmap' was loaded, '#{gem_module_name}' had not been loaded yet. Now '#{gem_module_name}' has
143
+ just been loaded, so the following AppMap modules will be automatically required:
144
+
145
+ #{initializers.map(&:module_name).join("\n")}
146
+
147
+ To suppress this message, ensure '#{gem_module_name}' appears before 'appmap' in your Gemfile.
148
+ LOAD_MSG
149
+ initializers.each do |init|
150
+ require init.module_name
151
+ end
152
+ end
153
+ end.enable
154
+
155
+ if defined?(::Rails::Railtie)
156
+ require 'appmap/railtie'
157
+ end
158
+
159
+ if defined?(::RSpec)
160
+ require 'appmap/rspec'
161
+ end
162
+
163
+ if defined?(::Minitest)
164
+ require 'appmap/minitest'
165
+ end
166
+ end.call
127
167
 
128
168
  AppMap.initialize_configuration if ENV['APPMAP'] == 'true'
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+ require 'appmap/service/guesser'
5
+ require 'appmap/util'
6
+
7
+ module AppMap
8
+ module Command
9
+ InitStruct = Struct.new(:config_file)
10
+
11
+ class Init < InitStruct
12
+ def perform
13
+ if File.exist?(config_file)
14
+ puts AppMap::Util.color(%(The AppMap config file #{config_file} already exists.), :magenta)
15
+ return
16
+ end
17
+
18
+ ensure_directory_exists
19
+
20
+ config = {
21
+ 'name' => Service::Guesser.guess_name,
22
+ 'packages' => Service::Guesser.guess_paths.map { |path| { 'path' => path } }
23
+ }
24
+ content = YAML.dump(config).gsub("---\n", '')
25
+
26
+ File.write(config_file, content)
27
+ puts AppMap::Util.color(
28
+ %(The following AppMap config file #{config_file} has been created:),
29
+ :green
30
+ )
31
+ puts content
32
+ end
33
+
34
+ private
35
+
36
+ def ensure_directory_exists
37
+ dirname = File.dirname(config_file)
38
+ FileUtils.mkdir_p(dirname) unless File.directory?(dirname)
39
+ end
40
+ end
41
+ end
42
+ end
data/lib/appmap/config.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  require 'yaml'
4
4
  require 'appmap/handler/net_http'
5
5
  require 'appmap/handler/rails/template'
6
+ require 'appmap/service/guesser'
6
7
 
7
8
  module AppMap
8
9
  class Config
@@ -284,7 +285,7 @@ module AppMap
284
285
  settings, the appmap gem will try and guess some reasonable defaults.
285
286
  To suppress this message, create the file:
286
287
 
287
- #{Pathname.new(config_file_name).expand_path}.
288
+ #{Pathname.new(config_file_name).expand_path}
288
289
 
289
290
  Here are the default settings that will be used in the meantime. You can
290
291
  copy and paste this example to start your appmap.yml.
@@ -308,7 +309,7 @@ module AppMap
308
309
 
309
310
  # Loads configuration from a Hash.
310
311
  def load(config_data)
311
- name = config_data['name'] || guess_name
312
+ name = config_data['name'] || Service::Guesser.guess_name
312
313
  config_params = {
313
314
  exclude: config_data['exclude']
314
315
  }.compact
@@ -344,33 +345,13 @@ module AppMap
344
345
  end
345
346
  end.compact
346
347
  else
347
- Array(guess_paths).map do |path|
348
+ Array(Service::Guesser.guess_paths).map do |path|
348
349
  Package.build_from_path(path)
349
350
  end
350
351
  end
351
352
 
352
353
  Config.new name, config_params
353
354
  end
354
-
355
- def guess_name
356
- reponame = lambda do
357
- next unless File.directory?('.git')
358
-
359
- repo_name = `git config --get remote.origin.url`.strip
360
- repo_name.split('/').last.split('.').first unless repo_name == ''
361
- end
362
- dirname = -> { Dir.pwd.split('/').last }
363
-
364
- reponame.() || dirname.()
365
- end
366
-
367
- def guess_paths
368
- if defined?(::Rails)
369
- %w[app/controllers app/models]
370
- elsif File.directory?('lib')
371
- %w[lib]
372
- end
373
- end
374
355
  end
375
356
 
376
357
  def to_h
@@ -14,16 +14,30 @@ module AppMap
14
14
  # The class name is generated from the template path. The package name is
15
15
  # 'app/views', and the method name is 'render'. The source location of the method
16
16
  # is, of course, the path to the view template.
17
- TemplateMethod = Struct.new(:path) do
18
- private_instance_methods :path
17
+ class TemplateMethod
19
18
  attr_reader :class_name
20
-
19
+
20
+ attr_reader :path
21
+ private_instance_methods :path
22
+
21
23
  def initialize(path)
22
- super
24
+ @path = path
23
25
 
24
26
  @class_name = path.parameterize.underscore
25
27
  end
26
-
28
+
29
+ def id
30
+ [ package, path, name ]
31
+ end
32
+
33
+ def hash
34
+ id.hash
35
+ end
36
+
37
+ def eql?(other)
38
+ other.is_a?(TemplateMethod) && id.eql?(other.id)
39
+ end
40
+
27
41
  def package
28
42
  'app/views'
29
43
  end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AppMap
4
+ module Service
5
+ class Guesser
6
+ POSSIBLE_PATHS = %w[app/controllers app/models lib]
7
+ class << self
8
+ def guess_name
9
+ reponame = lambda do
10
+ next unless File.directory?('.git')
11
+
12
+ repo_name = `git config --get remote.origin.url`.strip
13
+ repo_name.split('/').last.split('.').first unless repo_name == ''
14
+ end
15
+ dirname = -> { Dir.pwd.split('/').last }
16
+
17
+ reponame.() || dirname.()
18
+ end
19
+
20
+ def guess_paths
21
+ POSSIBLE_PATHS.select { |path| File.directory?(path) }
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
data/lib/appmap/trace.rb CHANGED
@@ -2,10 +2,12 @@
2
2
 
3
3
  module AppMap
4
4
  module Trace
5
- class RubyMethod
5
+ class RubyMethod < SimpleDelegator
6
6
  attr_reader :class_name, :static
7
7
 
8
8
  def initialize(package, class_name, method, static)
9
+ super(method)
10
+
9
11
  @package = package
10
12
  @class_name = class_name
11
13
  @method = method
@@ -111,7 +113,7 @@ module AppMap
111
113
  @last_package_for_thread[Thread.current.object_id] = package if package
112
114
  @events << event
113
115
  static = event.static if event.respond_to?(:static)
114
- @methods << Trace::RubyMethod.new(package, defined_class, method, static) \
116
+ record_method Trace::RubyMethod.new(package, defined_class, method, static) \
115
117
  if package && defined_class && method && (event.event == :call)
116
118
  end
117
119
 
@@ -3,9 +3,10 @@
3
3
  module AppMap
4
4
  URL = 'https://github.com/applandinc/appmap-ruby'
5
5
 
6
- VERSION = '0.51.1'
6
+ VERSION = '0.51.2'
7
7
 
8
8
  APPMAP_FORMAT_VERSION = '1.5.1'
9
9
 
10
10
  DEFAULT_APPMAP_DIR = 'tmp/appmap'.freeze
11
+ DEFAULT_CONFIG_FILE_PATH = 'appmap.yml'.freeze
11
12
  end
data/test/cli_test.rb ADDED
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'test_helper'
5
+
6
+ class CLITest < Minitest::Test
7
+ CONFIG_FILENAME = '123.yml'
8
+ SUBFOLDER_CONFIG_FILEPATH = 'conf/123.yml'
9
+ EXPECTED_CONFIG_CONTENT = %(name: appmap-ruby
10
+ packages:
11
+ - path: lib
12
+ )
13
+
14
+ def test_init_when_config_exists
15
+ output = `./exe/appmap-agent-setup init`
16
+ assert_equal 0, $CHILD_STATUS.exitstatus
17
+ assert_includes output, 'The AppMap config file appmap.yml already exists.'
18
+ end
19
+
20
+ def test_init_with_custom_config_filename
21
+ output = `./exe/appmap-agent-setup -c #{CONFIG_FILENAME} init`
22
+ assert_equal 0, $CHILD_STATUS.exitstatus
23
+ assert_includes output, "The following AppMap config file #{CONFIG_FILENAME} has been created:"
24
+ assert_equal EXPECTED_CONFIG_CONTENT, File.read(CONFIG_FILENAME)
25
+ ensure
26
+ File.delete(CONFIG_FILENAME) if File.exist?(CONFIG_FILENAME)
27
+ end
28
+
29
+ def test_init_with_custom_config_file_in_subfolder
30
+ output = `./exe/appmap-agent-setup -c #{SUBFOLDER_CONFIG_FILEPATH} init`
31
+ assert_equal 0, $CHILD_STATUS.exitstatus
32
+ assert_includes output, "The following AppMap config file #{SUBFOLDER_CONFIG_FILEPATH} has been created:"
33
+ assert_equal EXPECTED_CONFIG_CONTENT, File.read(SUBFOLDER_CONFIG_FILEPATH)
34
+ ensure
35
+ File.delete(SUBFOLDER_CONFIG_FILEPATH) if File.exist?(SUBFOLDER_CONFIG_FILEPATH)
36
+ end
37
+ end
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.51.1
4
+ version: 0.51.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Gilpin
8
8
  autorequire:
9
- bindir: bin
9
+ bindir: exe
10
10
  cert_chain: []
11
- date: 2021-06-21 00:00:00.000000000 Z
11
+ date: 2021-06-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -307,7 +307,8 @@ dependencies:
307
307
  description:
308
308
  email:
309
309
  - kgilpin@gmail.com
310
- executables: []
310
+ executables:
311
+ - appmap-agent-setup
311
312
  extensions:
312
313
  - ext/appmap/extconf.rb
313
314
  extra_rdoc_files: []
@@ -335,12 +336,14 @@ files:
335
336
  - examples/mock_webapp/lib/mock_webapp/controller.rb
336
337
  - examples/mock_webapp/lib/mock_webapp/request.rb
337
338
  - examples/mock_webapp/lib/mock_webapp/user.rb
339
+ - exe/appmap-agent-setup
338
340
  - ext/appmap/appmap.c
339
341
  - ext/appmap/extconf.rb
340
342
  - lib/appmap.rb
341
343
  - lib/appmap/algorithm/prune_class_map.rb
342
344
  - lib/appmap/algorithm/stats.rb
343
345
  - lib/appmap/class_map.rb
346
+ - lib/appmap/command/init.rb
344
347
  - lib/appmap/command/record.rb
345
348
  - lib/appmap/command/stats.rb
346
349
  - lib/appmap/config.rb
@@ -360,6 +363,7 @@ files:
360
363
  - lib/appmap/railtie.rb
361
364
  - lib/appmap/record.rb
362
365
  - lib/appmap/rspec.rb
366
+ - lib/appmap/service/guesser.rb
363
367
  - lib/appmap/trace.rb
364
368
  - lib/appmap/util.rb
365
369
  - lib/appmap/version.rb
@@ -556,6 +560,7 @@ files:
556
560
  - spec/spec_helper.rb
557
561
  - spec/util_spec.rb
558
562
  - test/bundle_vendor_test.rb
563
+ - test/cli_test.rb
559
564
  - test/cucumber_test.rb
560
565
  - test/expectations/openssl_test_key_sign1.json
561
566
  - test/expectations/openssl_test_key_sign2.json