appmap 0.54.2 → 0.57.0

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: b5368ab640de6fdf14f35502a5c756b7c6f681ee8d9a87c5fd9cd13d2b1036d9
4
- data.tar.gz: 15806ff9cfa6256bb29c9ed2d8cb7d4ff5f62cfc3354e313e3b6f52b4cd96c12
3
+ metadata.gz: 442ca8673e42cd8bea0db1ba97a533e7a38965f3d27707bd8e4379b578ee85cb
4
+ data.tar.gz: 1174d299f1446c8c3e16403437682196ce794bad27b7c6dd69d712f9bd59e36a
5
5
  SHA512:
6
- metadata.gz: d078fcb6e1bf1942462be38f2547b73e34c6f9a0313aabdd8919070218701937bd53bec4207c34c48c37e7b67f69500fbd6339f6fc26ad11eed86e2027ca4acf
7
- data.tar.gz: f5493735794a3385287721a30021996bc66ac44e19bc4e2214823eb78a730f07213989c93dadf8f38f0163c6c21fc39d375511b4ccd87b33974a54e667898b22
6
+ metadata.gz: 73bb23b5ac1401565c57ffbd833fe266ddebfe71271926ca0afaa08b92c88ffd47f5c92f6e91f213b8066729e6607a1b0f99731449eecf7bd68ab125a0f5de3f
7
+ data.tar.gz: f72d956ed6c6a46aebe12724a910d5cbdec1aee3d8b61f300e8b2a679873b25db245cca4407c02a03df1588fd3734d616472aed69c2741898e60bc04f6d04b33
data/.travis.yml CHANGED
@@ -34,27 +34,29 @@ before_install:
34
34
  - |
35
35
  nvm install --lts \
36
36
  && nvm use --lts
37
-
37
+
38
38
  # GEM_ALTERNATIVE_NAME only needed for deployment
39
39
  jobs:
40
40
  include:
41
41
  - stage: test
42
42
  script:
43
+ - set -e
43
44
  - mkdir tmp
44
- - GEM_ALTERNATIVE_NAME='' bundle exec rake test
45
+ - npm i -g yarn
46
+ - GEM_ALTERNATIVE_NAME='' bundle exec rake gem:build test
45
47
 
46
48
  before_deploy:
47
49
  - |
48
- nvm install --lts \
49
- && nvm use --lts \
50
- && npm i -g \
51
- semantic-release \
52
- @semantic-release/git \
53
- @semantic-release/changelog \
54
- semantic-release-rubygem
50
+ npm i -g \
51
+ yarn \
52
+ semantic-release \
53
+ @semantic-release/git \
54
+ @semantic-release/changelog \
55
+ semantic-release-rubygem
55
56
 
56
57
  deploy:
57
58
  - provider: script
58
59
  script: ./release.sh
59
60
  on:
60
61
  branch: master
62
+ condition: "$TRAVIS_RUBY_VERSION = 2.7"
data/CHANGELOG.md CHANGED
@@ -1,3 +1,47 @@
1
+ # [0.57.0](https://github.com/applandinc/appmap-ruby/compare/v0.56.0...v0.57.0) (2021-06-29)
2
+
3
+
4
+ ### Features
5
+
6
+ * Update init command to return JSON ([1f93e89](https://github.com/applandinc/appmap-ruby/commit/1f93e8909684e1018f513d69adfde2a5d0bf6bc9))
7
+
8
+ # [0.56.0](https://github.com/applandinc/appmap-ruby/compare/v0.55.0...v0.56.0) (2021-06-28)
9
+
10
+
11
+ ### Features
12
+
13
+ * add appmap-agent-status executable with config/project properties ([043f845](https://github.com/applandinc/appmap-ruby/commit/043f8453a2533a6e172d1cd23fcde04f19e73173))
14
+
15
+ # [0.55.0](https://github.com/applandinc/appmap-ruby/compare/v0.54.4...v0.55.0) (2021-06-28)
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * Avoid calling == ([f30ed9f](https://github.com/applandinc/appmap-ruby/commit/f30ed9f309753252df35e372d925db3b914260d4))
21
+ * Log dynamic loading of appmap helpers at info level ([15dcd3c](https://github.com/applandinc/appmap-ruby/commit/15dcd3c913fa1c32aea034b28ddae59668efa217))
22
+ * Remove dynamic loading of rake and rspec helpers ([6790970](https://github.com/applandinc/appmap-ruby/commit/67909702f3c8a52081ef1e23a87c292908883334))
23
+
24
+
25
+ ### Features
26
+
27
+ * APPMAP_PROFILE_DISPLAY_STRING and APPMAP_OBJECT_STRING ([3f5daa8](https://github.com/applandinc/appmap-ruby/commit/3f5daa890bfbfd39b7f825794d0c43da509b3201))
28
+ * Package name to require can be specified when hooking a gem ([fcc5eb6](https://github.com/applandinc/appmap-ruby/commit/fcc5eb691a0330444560eb4c2afe7fc3c4c8afa8))
29
+ * Profile packaging hooking ([c020a31](https://github.com/applandinc/appmap-ruby/commit/c020a312f4545348ec7cc302443269c57a7fc026))
30
+
31
+ ## [0.54.4](https://github.com/applandinc/appmap-ruby/compare/v0.54.3...v0.54.4) (2021-06-27)
32
+
33
+
34
+ ### Bug Fixes
35
+
36
+ * Only allow trace_end once per location ([10e48cf](https://github.com/applandinc/appmap-ruby/commit/10e48cf855907f9029479b4b7b63bc4d25d664ab))
37
+
38
+ ## [0.54.3](https://github.com/applandinc/appmap-ruby/compare/v0.54.2...v0.54.3) (2021-06-25)
39
+
40
+
41
+ ### Bug Fixes
42
+
43
+ * Get deployment working with packaging of NodeJS code ([733c5b8](https://github.com/applandinc/appmap-ruby/commit/733c5b85ec1a0c17ada81be524fa572f78f52500))
44
+
1
45
  ## [0.54.2](https://github.com/applandinc/appmap-ruby/compare/v0.54.1...v0.54.2) (2021-06-25)
2
46
 
3
47
 
@@ -5,10 +5,10 @@ require 'optparse'
5
5
  require 'appmap'
6
6
  require 'appmap/command/agent_setup/init'
7
7
 
8
- @options = {:config_file => AppMap::DEFAULT_CONFIG_FILE_PATH}
8
+ @options = { config_file: AppMap::DEFAULT_CONFIG_FILE_PATH }
9
9
 
10
10
  OptionParser.new do |parser|
11
- parser.banner = 'Usage: bundle exec exe/appmap-agent-init [options]'
11
+ parser.banner = 'Usage: appmap-agent-init [options]'
12
12
 
13
13
  description = "AppMap configuration file path (default: #{AppMap::DEFAULT_CONFIG_FILE_PATH})"
14
14
  parser.on('-c', '--config=FILEPATH', description) do |filepath|
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'optparse'
5
+ require 'appmap'
6
+ require 'appmap/command/agent_setup/status'
7
+
8
+ @options = { config_file: AppMap::DEFAULT_CONFIG_FILE_PATH }
9
+
10
+ OptionParser.new do |parser|
11
+ parser.banner = 'Usage: appmap-agent-status [options]'
12
+
13
+ description = "AppMap configuration file path (default: #{AppMap::DEFAULT_CONFIG_FILE_PATH})"
14
+ parser.on('-c', '--config=FILEPATH', description) do |filepath|
15
+ @options[:config_file] = filepath
16
+ end
17
+ end.parse!
18
+
19
+ AppMap::Command::AgentSetup::Status.new(@options[:config_file]).perform
data/lib/appmap.rb CHANGED
@@ -28,11 +28,9 @@ lambda do
28
28
  INITIALIZERS = {
29
29
  # In a Rails app, Rails is always defined by the time the other gems are loaded. Therefore, we
30
30
  # don't try and trap the loading of Rails itself here.
31
- 'RSpec' => Initializer.new('AppMap::RSpec', 'appmap/rspec', 'rspec-core'),
31
+ # Emperically, Rake and RSpec are also defined before appmap is loaded whenever a Rake task or
32
+ # RSpec tests are being run. Therefore, the only hook we need here is Minitest.
32
33
  'Minitest::Unit::TestCase' => Initializer.new('AppMap::Minitest', 'appmap/minitest', 'minitest'),
33
- 'Rake' => [
34
- Initializer.new('AppMap::Swagger', 'appmap/swagger', 'rake')
35
- ]
36
34
  }
37
35
 
38
36
  TracePoint.new(:class) do |tp|
@@ -1,8 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fileutils'
3
+ require 'json'
4
4
  require 'appmap/service/guesser'
5
- require 'appmap/util'
6
5
 
7
6
  module AppMap
8
7
  module Command
@@ -11,32 +10,19 @@ module AppMap
11
10
 
12
11
  class Init < InitStruct
13
12
  def perform
14
- if File.exist?(config_file)
15
- puts AppMap::Util.color(%(The AppMap config file #{config_file} already exists.), :magenta)
16
- return
17
- end
18
-
19
- ensure_directory_exists
20
-
21
13
  config = {
22
14
  'name' => Service::Guesser.guess_name,
23
15
  'packages' => Service::Guesser.guess_paths.map { |path| { 'path' => path } }
24
16
  }
25
- content = YAML.dump(config).gsub("---\n", '')
26
17
 
27
- File.write(config_file, content)
28
- puts AppMap::Util.color(
29
- %(The following AppMap config file #{config_file} has been created:),
30
- :green
31
- )
32
- puts content
33
- end
34
-
35
- private
18
+ result = {
19
+ configuration: {
20
+ filename: config_file,
21
+ contents: YAML.dump(config)
22
+ }
23
+ }
36
24
 
37
- def ensure_directory_exists
38
- dirname = File.dirname(config_file)
39
- FileUtils.mkdir_p(dirname) unless File.directory?(dirname)
25
+ puts JSON.pretty_generate(result)
40
26
  end
41
27
  end
42
28
  end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'appmap/service/config_analyzer'
5
+
6
+ module AppMap
7
+ module Command
8
+ module AgentSetup
9
+ StatusStruct = Struct.new(:config_file)
10
+
11
+ class Status < StatusStruct
12
+ def perform
13
+ status = {
14
+ :properties => {
15
+ :config => {
16
+ :app => config_analyzer.app_name,
17
+ :present => config_analyzer.present?,
18
+ :valid => config_analyzer.valid?
19
+ },
20
+ :project => {
21
+ :agentVersionProject => AppMap::VERSION,
22
+ :language => 'ruby',
23
+ :remoteRecordingCapable => Gem.loaded_specs.has_key?('rails'),
24
+ :integrationTests => false #TODO
25
+ }
26
+ }
27
+ }
28
+
29
+ puts status.to_json
30
+ end
31
+
32
+ private
33
+
34
+ def config_analyzer
35
+ @config_analyzer ||= Service::ConfigAnalyzer.new(config_file)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
data/lib/appmap/config.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'set'
3
4
  require 'yaml'
4
5
  require 'appmap/util'
5
6
  require 'appmap/handler/net_http'
@@ -343,7 +344,7 @@ module AppMap
343
344
  shallow = package['shallow']
344
345
  # shallow is true by default for gems
345
346
  shallow = true if shallow.nil?
346
- Package.build_from_gem(gem, exclude: package['exclude'] || [], shallow: shallow)
347
+ Package.build_from_gem(gem, package_name: package['package'], exclude: package['exclude'] || [], shallow: shallow)
347
348
  else
348
349
  Package.build_from_path(path, exclude: package['exclude'] || [], shallow: package['shallow'])
349
350
  end
data/lib/appmap/event.rb CHANGED
@@ -29,11 +29,31 @@ module AppMap
29
29
 
30
30
  # Gets a display string for a value. This is not meant to be a machine deserializable value.
31
31
  def display_string(value)
32
- return nil unless value
32
+ return nil if value.equal?(nil)
33
33
 
34
+ # With setting APPMAP_PROFILE_DISPLAY_STRING, stringifying this class is shown to take 9 seconds(!) of a 17 second test run.
35
+ return nil if best_class_name(value) == 'ActiveSupport::Callbacks::Filters::Environment'
36
+
37
+ if @times.nil? && ENV['APPMAP_PROFILE_DISPLAY_STRING'] == 'true'
38
+ @times = Hash.new {|memo,key| memo[key] = 0}
39
+ Thread.new do
40
+ sleep 0.5
41
+ while true
42
+ warn @times.to_a.sort{|a,b| b[1] <=> a[1]}[0..9].join("\n")
43
+ sleep 3
44
+ end
45
+ end
46
+ end
47
+
48
+ start = Time.now
34
49
  value_string = custom_display_string(value) || default_display_string(value)
35
50
 
36
- (value_string||'')[0...LIMIT].encode('utf-8', invalid: :replace, undef: :replace, replace: '_')
51
+ if @times
52
+ elapsed = Time.now - start
53
+ @times[best_class_name(value)] += elapsed
54
+ end
55
+
56
+ encode_dislay_string(value_string)
37
57
  end
38
58
 
39
59
  def object_properties(hash_like)
@@ -57,8 +77,16 @@ module AppMap
57
77
  value_cls.name
58
78
  end
59
79
 
80
+ def encode_dislay_string(value)
81
+ (value||'')[0...LIMIT].encode('utf-8', invalid: :replace, undef: :replace, replace: '_')
82
+ end
83
+
60
84
  def custom_display_string(value)
61
85
  case value
86
+ when NilClass, TrueClass, FalseClass, Numeric, Time, Date
87
+ value.to_s
88
+ when String
89
+ value[0...LIMIT].encode('utf-8', invalid: :replace, undef: :replace, replace: '_')
62
90
  when File
63
91
  "#{value.class}[path=#{value.path}]"
64
92
  when Net::HTTP
@@ -71,6 +99,8 @@ module AppMap
71
99
  end
72
100
 
73
101
  def default_display_string(value)
102
+ return nil if ENV['APPMAP_OBJECT_STRING'] == 'false'
103
+
74
104
  last_resort_string = lambda do
75
105
  warn "AppMap encountered an error inspecting a #{value.class.name}: #{$!.message}"
76
106
  '*Error inspecting variable*'
data/lib/appmap/hook.rb CHANGED
@@ -9,6 +9,7 @@ module AppMap
9
9
 
10
10
  OBJECT_INSTANCE_METHODS = %i[! != !~ <=> == === =~ __id__ __send__ class clone define_singleton_method display dup enum_for eql? equal? extend freeze frozen? hash inspect instance_eval instance_exec instance_of? instance_variable_defined? instance_variable_get instance_variable_set instance_variables is_a? itself kind_of? method methods nil? object_id private_methods protected_methods public_method public_methods public_send remove_instance_variable respond_to? send singleton_class singleton_method singleton_methods taint tainted? tap then to_enum to_s to_h to_a trust untaint untrust untrusted? yield_self].freeze
11
11
  OBJECT_STATIC_METHODS = %i[! != !~ < <= <=> == === =~ > >= __id__ __send__ alias_method allocate ancestors attr attr_accessor attr_reader attr_writer autoload autoload? class class_eval class_exec class_variable_defined? class_variable_get class_variable_set class_variables clone const_defined? const_get const_missing const_set constants define_method define_singleton_method deprecate_constant display dup enum_for eql? equal? extend freeze frozen? hash include include? included_modules inspect instance_eval instance_exec instance_method instance_methods instance_of? instance_variable_defined? instance_variable_get instance_variable_set instance_variables is_a? itself kind_of? method method_defined? methods module_eval module_exec name new nil? object_id prepend private_class_method private_constant private_instance_methods private_method_defined? private_methods protected_instance_methods protected_method_defined? protected_methods public_class_method public_constant public_instance_method public_instance_methods public_method public_method_defined? public_methods public_send remove_class_variable remove_instance_variable remove_method respond_to? send singleton_class singleton_class? singleton_method singleton_methods superclass taint tainted? tap then to_enum to_s trust undef_method untaint untrust untrusted? yield_self].freeze
12
+ SLOW_PACKAGE_THRESHOLD = 0.05
12
13
 
13
14
  @unbound_method_arity = ::UnboundMethod.instance_method(:arity)
14
15
  @method_arity = ::Method.instance_method(:arity)
@@ -37,8 +38,6 @@ module AppMap
37
38
  def initialize(config)
38
39
  @config = config
39
40
  @trace_enabled = []
40
- # Paths that are known to be non-tracing
41
- @notrace_paths = Set.new
42
41
  end
43
42
 
44
43
  # Observe class loading and hook all methods which match the config.
@@ -47,6 +46,32 @@ module AppMap
47
46
 
48
47
  hook_builtins
49
48
 
49
+ # Paths that are known to be non-tracing.
50
+ @notrace_paths = Set.new
51
+ # Locations that have already been visited.
52
+ @trace_locations = Set.new
53
+ @module_load_times = Hash.new {|memo,k| memo[k] = 0}
54
+ @slow_packages = Set.new
55
+
56
+ if ENV['APPMAP_PROFILE_HOOK'] == 'true'
57
+ Thread.new do
58
+ sleep 1
59
+ while true
60
+ @module_load_times
61
+ .keys
62
+ .select { |key| !@slow_packages.member?(key) }
63
+ .each do |key|
64
+ elapsed = @module_load_times[key]
65
+ if elapsed >= SLOW_PACKAGE_THRESHOLD
66
+ @slow_packages.add(key)
67
+ warn "AppMap: Package #{key} took #{@module_load_times[key]} seconds to hook"
68
+ end
69
+ end
70
+ sleep 5
71
+ end
72
+ end
73
+ end
74
+
50
75
  @trace_end = TracePoint.new(:end, &method(:trace_end))
51
76
  @trace_end.enable(&block)
52
77
  end
@@ -99,7 +124,9 @@ module AppMap
99
124
  end
100
125
 
101
126
  def trace_end(trace_point)
102
- warn "Class or module ends at location #{trace_location(trace_point)}" if Hook::LOG || Hook::LOG_HOOK
127
+ location = trace_location(trace_point)
128
+ warn "Class or module ends at location #{location}" if Hook::LOG || Hook::LOG_HOOK
129
+ return unless @trace_locations.add?(location)
103
130
 
104
131
  path = trace_point.path
105
132
  enabled = !@notrace_paths.member?(path) && config.path_enabled?(path)
@@ -152,6 +179,7 @@ module AppMap
152
179
  end
153
180
  end
154
181
 
182
+ start = Time.now
155
183
  instance_methods.each(&hook.(cls))
156
184
  begin
157
185
  # NoMethodError: private method `singleton_class' called for Rack::MiniProfiler:Class
@@ -161,6 +189,11 @@ module AppMap
161
189
  # uninitialized constant Faraday::Connection
162
190
  warn "NameError in #{__FILE__}: #{$!.message}"
163
191
  end
192
+ elapsed = Time.now - start
193
+ if location.index(Bundler.bundle_path.to_s) == 0
194
+ package_tokens = location[Bundler.bundle_path.to_s.length + 1..-1].split('/')
195
+ @module_load_times[package_tokens[1]] += elapsed
196
+ end
164
197
  end
165
198
  end
166
199
  end
@@ -49,9 +49,14 @@ module AppMap
49
49
 
50
50
  hook_method_def = Proc.new do |*args, &block|
51
51
  instance_method = hook_method.bind(self).to_proc
52
+
53
+ is_array_containing_empty_hash = ->(obj) {
54
+ obj.is_a?(Array) && obj.length == 1 && obj[0].is_a?(Hash) && obj[0].size == 0
55
+ }
56
+
52
57
  call_instance_method = -> {
53
58
  # https://github.com/applandinc/appmap-ruby/issues/153
54
- if Util.ruby_minor_version >= 2.7 && args == ARRAY_OF_EMPTY_HASH && hook_method.arity == 1
59
+ if Util.ruby_minor_version >= 2.7 && is_array_containing_empty_hash.(args) && hook_method.arity == 1
55
60
  instance_method.call({}, &block)
56
61
  else
57
62
  instance_method.call(*args, &block)
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AppMap
4
+ module Service
5
+ class ConfigAnalyzer
6
+ attr_reader :config_error
7
+
8
+ def initialize(config_file)
9
+ @config_file = config_file
10
+ @config = load_config
11
+ end
12
+
13
+ def app_name
14
+ @config.to_h[:name] if present?
15
+ end
16
+
17
+ def present?
18
+ File.exist?(@config_file)
19
+ end
20
+
21
+ def valid?
22
+ present? && @config.to_h.key?(:name) && @config.to_h.key?(:packages)
23
+ end
24
+
25
+ private
26
+
27
+ def load_config
28
+ AppMap::Config.load_from_file @config_file if present?
29
+ rescue
30
+ nil
31
+ end
32
+ end
33
+ end
34
+ end
data/lib/appmap/util.rb CHANGED
@@ -185,7 +185,7 @@ module AppMap
185
185
 
186
186
  def startup_message(msg)
187
187
  if defined?(::Rails) && defined?(::Rails.logger) && ::Rails.logger
188
- ::Rails.logger.debug msg
188
+ ::Rails.logger.info msg
189
189
  elsif ENV['DEBUG'] == 'true'
190
190
  warn msg
191
191
  end
@@ -3,7 +3,7 @@
3
3
  module AppMap
4
4
  URL = 'https://github.com/applandinc/appmap-ruby'
5
5
 
6
- VERSION = '0.54.2'
6
+ VERSION = '0.57.0'
7
7
 
8
8
  APPMAP_FORMAT_VERSION = '1.5.1'
9
9
 
data/release.sh CHANGED
@@ -14,4 +14,3 @@ fi
14
14
 
15
15
  set -x
16
16
  exec semantic-release $RELEASE_FLAGS
17
-
@@ -0,0 +1 @@
1
+ name: app
@@ -0,0 +1,2 @@
1
+ name: -123- %
2
+ packages: ~{}~ ''
@@ -0,0 +1,3 @@
1
+ name: appmap
2
+ packages:
3
+ - path: app/models
data/spec/hook_spec.rb CHANGED
@@ -970,7 +970,7 @@ describe 'AppMap class Hooking', docker: false do
970
970
  tz = ENV['TZ']
971
971
  ENV['TZ'] = 'UTC'
972
972
  Timecop.freeze(Time.utc('2020-01-01')) do
973
- expect(Time).to receive(:now).exactly(3).times.and_call_original
973
+ expect(Time).to receive(:now).at_least(3).times.and_call_original
974
974
  expect(InstanceMethod.new.say_the_time).to be
975
975
  end
976
976
  ensure
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'appmap/service/config_analyzer'
5
+
6
+ describe AppMap::Service::ConfigAnalyzer do
7
+ subject { described_class.new(config_file) }
8
+
9
+ context 'with non-existing config' do
10
+ let(:config_file) { 'spec/fixtures/config/non_existing_config.yml'}
11
+
12
+ describe '.app_name' do
13
+ it 'returns nil' do
14
+ expect(subject.app_name).to be_nil
15
+ end
16
+ end
17
+
18
+ describe '.is_valid?' do
19
+ it 'returns false' do
20
+ expect(subject.valid?).to be_falsey
21
+ end
22
+ end
23
+
24
+ describe '.is_present?' do
25
+ it 'returns false' do
26
+ expect(subject.present?).to be_falsey
27
+ end
28
+ end
29
+ end
30
+
31
+ context 'with valid config' do
32
+ let(:config_file) { 'spec/fixtures/config/valid_config.yml'}
33
+
34
+ describe '.app_name' do
35
+ it 'returns app name value from config' do
36
+ expect(subject.app_name).to eq('appmap')
37
+ end
38
+ end
39
+
40
+ describe '.is_valid?' do
41
+ it 'returns true' do
42
+ expect(subject.valid?).to be_truthy
43
+ end
44
+ end
45
+
46
+ describe '.is_present?' do
47
+ it 'returns true' do
48
+ expect(subject.present?).to be_truthy
49
+ end
50
+ end
51
+ end
52
+
53
+ context 'with invalid YAML config' do
54
+ let(:config_file) { 'spec/fixtures/config/invalid_config.yml'}
55
+
56
+ describe '.app_name' do
57
+ it 'returns app name value from config' do
58
+ expect(subject.app_name).to be_nil
59
+ end
60
+ end
61
+
62
+ describe '.is_valid?' do
63
+ it 'returns false' do
64
+ expect(subject.valid?).to be_falsey
65
+ end
66
+ end
67
+
68
+ describe '.is_present?' do
69
+ it 'return true' do
70
+ expect(subject.present?).to be_truthy
71
+ end
72
+ end
73
+ end
74
+
75
+ context 'with incomplete config' do
76
+ let(:config_file) { 'spec/fixtures/config/incomplete_config.yml'}
77
+
78
+ describe '.app_name' do
79
+ it 'returns nil' do
80
+ expect(subject.app_name).to eq('app')
81
+ end
82
+ end
83
+
84
+ describe '.is_valid?' do
85
+ it 'guesses paths and returns true ' do
86
+ expect(subject.valid?).to be_truthy
87
+ end
88
+ end
89
+
90
+ describe '.is_present?' do
91
+ it 'returns true' do
92
+ expect(subject.present?).to be_truthy
93
+ end
94
+ end
95
+ end
96
+ end
@@ -5,8 +5,8 @@ require 'test_helper'
5
5
 
6
6
  class AgentSetupInitTest < Minitest::Test
7
7
  CONFIG_FILENAME = '123.yml'
8
- SUBFOLDER_CONFIG_FILEPATH = 'conf/123.yml'
9
- EXPECTED_CONFIG_CONTENT = %(name: appmap-ruby
8
+ EXPECTED_CONFIG_CONTENT = %(---
9
+ name: appmap-ruby
10
10
  packages:
11
11
  - path: lib
12
12
  )
@@ -14,24 +14,24 @@ packages:
14
14
  def test_init_when_config_exists
15
15
  output = `./exe/appmap-agent-init`
16
16
  assert_equal 0, $CHILD_STATUS.exitstatus
17
- assert_includes output, 'The AppMap config file appmap.yml already exists.'
17
+ expected = JSON.pretty_generate({
18
+ configuration: {
19
+ filename: 'appmap.yml',
20
+ contents: EXPECTED_CONFIG_CONTENT
21
+ }
22
+ })
23
+ assert_equal expected, output.strip
18
24
  end
19
25
 
20
26
  def test_init_with_custom_config_filename
21
27
  output = `./exe/appmap-agent-init -c #{CONFIG_FILENAME}`
22
28
  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-init --config=#{SUBFOLDER_CONFIG_FILEPATH}`
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)
29
+ expected = JSON.pretty_generate({
30
+ configuration: {
31
+ filename: CONFIG_FILENAME,
32
+ contents: EXPECTED_CONFIG_CONTENT
33
+ }
34
+ })
35
+ assert_equal expected, output.strip
36
36
  end
37
37
  end
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'test_helper'
5
+
6
+ class AgentSetupInitTest < Minitest::Test
7
+ def test_status
8
+ output = `./exe/appmap-agent-status`
9
+ assert_equal 0, $CHILD_STATUS.exitstatus
10
+ expected = {
11
+ :properties => {
12
+ :config => {
13
+ :app => 'AppMap Rubygem',
14
+ :present => true,
15
+ :valid => true
16
+ },
17
+ :project => {
18
+ :agentVersionProject => AppMap::VERSION,
19
+ :language => 'ruby',
20
+ :remoteRecordingCapable => false,
21
+ :integrationTests => false
22
+ }
23
+ }
24
+ }.to_json
25
+ assert_equal expected, output.strip
26
+ end
27
+ 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.54.2
4
+ version: 0.57.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: 2021-06-25 00:00:00.000000000 Z
11
+ date: 2021-06-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -295,6 +295,7 @@ email:
295
295
  - kgilpin@gmail.com
296
296
  executables:
297
297
  - appmap-agent-init
298
+ - appmap-agent-status
298
299
  - appmap-inspect
299
300
  extensions:
300
301
  - ext/appmap/extconf.rb
@@ -324,6 +325,7 @@ files:
324
325
  - examples/mock_webapp/lib/mock_webapp/request.rb
325
326
  - examples/mock_webapp/lib/mock_webapp/user.rb
326
327
  - exe/appmap-agent-init
328
+ - exe/appmap-agent-status
327
329
  - exe/appmap-inspect
328
330
  - ext/appmap/appmap.c
329
331
  - ext/appmap/extconf.rb
@@ -331,6 +333,7 @@ files:
331
333
  - lib/appmap/agent.rb
332
334
  - lib/appmap/class_map.rb
333
335
  - lib/appmap/command/agent_setup/init.rb
336
+ - lib/appmap/command/agent_setup/status.rb
334
337
  - lib/appmap/command/inspect.rb
335
338
  - lib/appmap/command_error.rb
336
339
  - lib/appmap/config.rb
@@ -351,6 +354,7 @@ files:
351
354
  - lib/appmap/railtie.rb
352
355
  - lib/appmap/record.rb
353
356
  - lib/appmap/rspec.rb
357
+ - lib/appmap/service/config_analyzer.rb
354
358
  - lib/appmap/service/guesser.rb
355
359
  - lib/appmap/swagger.rb
356
360
  - lib/appmap/swagger/configuration.rb
@@ -364,6 +368,9 @@ files:
364
368
  - release.sh
365
369
  - spec/class_map_spec.rb
366
370
  - spec/config_spec.rb
371
+ - spec/fixtures/config/incomplete_config.yml
372
+ - spec/fixtures/config/invalid_config.yml
373
+ - spec/fixtures/config/valid_config.yml
367
374
  - spec/fixtures/hook/.gitignore
368
375
  - spec/fixtures/hook/app/controllers/api/api_keys_controller.rb
369
376
  - spec/fixtures/hook/app/controllers/organizations_controller.rb
@@ -545,10 +552,12 @@ files:
545
552
  - spec/record_net_http_spec.rb
546
553
  - spec/record_sql_rails_pg_spec.rb
547
554
  - spec/remote_recording_spec.rb
555
+ - spec/service/config_analyzer_spec.rb
548
556
  - spec/spec_helper.rb
549
557
  - spec/swagger/swagger_spec.rb
550
558
  - spec/util_spec.rb
551
559
  - test/agent_setup_init_test.rb
560
+ - test/agent_setup_status_test.rb
552
561
  - test/bundle_vendor_test.rb
553
562
  - test/cucumber_test.rb
554
563
  - test/expectations/openssl_test_key_sign1.json