appmap 0.31.0

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.
Files changed (259) hide show
  1. checksums.yaml +7 -0
  2. data/.dockerignore +5 -0
  3. data/.gitignore +17 -0
  4. data/.rubocop.yml +27 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +44 -0
  7. data/CHANGELOG.md +199 -0
  8. data/Dockerfile.appmap +5 -0
  9. data/Gemfile +5 -0
  10. data/LICENSE.txt +21 -0
  11. data/README.md +300 -0
  12. data/Rakefile +132 -0
  13. data/appmap.gemspec +44 -0
  14. data/appmap.yml +8 -0
  15. data/examples/install.rb +76 -0
  16. data/examples/mock_webapp/Gemfile +1 -0
  17. data/examples/mock_webapp/appmap.yml +2 -0
  18. data/examples/mock_webapp/exe/mock_webapp_request +12 -0
  19. data/examples/mock_webapp/lib/mock_webapp/controller.rb +23 -0
  20. data/examples/mock_webapp/lib/mock_webapp/request.rb +12 -0
  21. data/examples/mock_webapp/lib/mock_webapp/user.rb +18 -0
  22. data/exe/appmap +154 -0
  23. data/lib/appmap.rb +87 -0
  24. data/lib/appmap/algorithm/prune_class_map.rb +67 -0
  25. data/lib/appmap/algorithm/stats.rb +91 -0
  26. data/lib/appmap/class_map.rb +135 -0
  27. data/lib/appmap/command/record.rb +38 -0
  28. data/lib/appmap/command/stats.rb +14 -0
  29. data/lib/appmap/config.rb +91 -0
  30. data/lib/appmap/cucumber.rb +89 -0
  31. data/lib/appmap/event.rb +168 -0
  32. data/lib/appmap/hook.rb +130 -0
  33. data/lib/appmap/metadata.rb +62 -0
  34. data/lib/appmap/middleware/remote_recording.rb +114 -0
  35. data/lib/appmap/minitest.rb +141 -0
  36. data/lib/appmap/rails/action_handler.rb +91 -0
  37. data/lib/appmap/rails/sql_handler.rb +145 -0
  38. data/lib/appmap/railtie.rb +45 -0
  39. data/lib/appmap/record.rb +27 -0
  40. data/lib/appmap/rspec.rb +301 -0
  41. data/lib/appmap/trace.rb +96 -0
  42. data/lib/appmap/util.rb +40 -0
  43. data/lib/appmap/version.rb +9 -0
  44. data/lore/pages/2019-05-21-install-and-record/index.pug +51 -0
  45. data/lore/pages/2019-05-21-install-and-record/install_example_appmap.png +0 -0
  46. data/lore/pages/2019-05-21-install-and-record/metadata.yml +5 -0
  47. data/lore/pages/layout.pug +66 -0
  48. data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-grid.css +1912 -0
  49. data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-grid.css.map +1 -0
  50. data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-grid.min.css +7 -0
  51. data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-grid.min.css.map +1 -0
  52. data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-reboot.css +331 -0
  53. data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-reboot.css.map +1 -0
  54. data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-reboot.min.css +8 -0
  55. data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-reboot.min.css.map +1 -0
  56. data/lore/public/lib/bootstrap-4.1.3/css/bootstrap.css +9030 -0
  57. data/lore/public/lib/bootstrap-4.1.3/css/bootstrap.css.map +1 -0
  58. data/lore/public/lib/bootstrap-4.1.3/css/bootstrap.min.css +7 -0
  59. data/lore/public/lib/bootstrap-4.1.3/css/bootstrap.min.css.map +1 -0
  60. data/lore/public/stylesheets/style.css +8 -0
  61. data/package-lock.json +1064 -0
  62. data/package.json +24 -0
  63. data/spec/abstract_controller4_base_spec.rb +67 -0
  64. data/spec/abstract_controller_base_spec.rb +72 -0
  65. data/spec/config_spec.rb +25 -0
  66. data/spec/fixtures/hook/attr_accessor.rb +5 -0
  67. data/spec/fixtures/hook/compare.rb +7 -0
  68. data/spec/fixtures/hook/constructor.rb +7 -0
  69. data/spec/fixtures/hook/exception_method.rb +11 -0
  70. data/spec/fixtures/hook/instance_method.rb +23 -0
  71. data/spec/fixtures/hook/openssl_sign.rb +87 -0
  72. data/spec/fixtures/hook/singleton_method.rb +54 -0
  73. data/spec/fixtures/rack_users_app/.dockerignore +2 -0
  74. data/spec/fixtures/rack_users_app/.gitignore +2 -0
  75. data/spec/fixtures/rack_users_app/Dockerfile +32 -0
  76. data/spec/fixtures/rack_users_app/Gemfile +10 -0
  77. data/spec/fixtures/rack_users_app/appmap.yml +3 -0
  78. data/spec/fixtures/rack_users_app/config.ru +2 -0
  79. data/spec/fixtures/rack_users_app/docker-compose.yml +9 -0
  80. data/spec/fixtures/rack_users_app/lib/app.rb +36 -0
  81. data/spec/fixtures/rails4_users_app/.gitignore +13 -0
  82. data/spec/fixtures/rails4_users_app/.rbenv-gemsets +2 -0
  83. data/spec/fixtures/rails4_users_app/.ruby-version +1 -0
  84. data/spec/fixtures/rails4_users_app/Dockerfile +30 -0
  85. data/spec/fixtures/rails4_users_app/Dockerfile.pg +3 -0
  86. data/spec/fixtures/rails4_users_app/Gemfile +77 -0
  87. data/spec/fixtures/rails4_users_app/README.rdoc +28 -0
  88. data/spec/fixtures/rails4_users_app/Rakefile +6 -0
  89. data/spec/fixtures/rails4_users_app/app/assets/images/.keep +0 -0
  90. data/spec/fixtures/rails4_users_app/app/assets/javascripts/application.js +16 -0
  91. data/spec/fixtures/rails4_users_app/app/assets/stylesheets/application.css +15 -0
  92. data/spec/fixtures/rails4_users_app/app/controllers/api/users_controller.rb +27 -0
  93. data/spec/fixtures/rails4_users_app/app/controllers/application_controller.rb +5 -0
  94. data/spec/fixtures/rails4_users_app/app/controllers/concerns/.keep +0 -0
  95. data/spec/fixtures/rails4_users_app/app/controllers/health_controller.rb +5 -0
  96. data/spec/fixtures/rails4_users_app/app/controllers/users_controller.rb +5 -0
  97. data/spec/fixtures/rails4_users_app/app/helpers/application_helper.rb +2 -0
  98. data/spec/fixtures/rails4_users_app/app/mailers/.keep +0 -0
  99. data/spec/fixtures/rails4_users_app/app/models/.keep +0 -0
  100. data/spec/fixtures/rails4_users_app/app/models/concerns/.keep +0 -0
  101. data/spec/fixtures/rails4_users_app/app/models/user.rb +18 -0
  102. data/spec/fixtures/rails4_users_app/app/views/layouts/application.html.haml +7 -0
  103. data/spec/fixtures/rails4_users_app/app/views/users/index.html.haml +7 -0
  104. data/spec/fixtures/rails4_users_app/appmap.yml +3 -0
  105. data/spec/fixtures/rails4_users_app/bin/rails +9 -0
  106. data/spec/fixtures/rails4_users_app/bin/setup +29 -0
  107. data/spec/fixtures/rails4_users_app/bin/spring +17 -0
  108. data/spec/fixtures/rails4_users_app/config.ru +4 -0
  109. data/spec/fixtures/rails4_users_app/config/application.rb +26 -0
  110. data/spec/fixtures/rails4_users_app/config/boot.rb +3 -0
  111. data/spec/fixtures/rails4_users_app/config/database.yml +18 -0
  112. data/spec/fixtures/rails4_users_app/config/environment.rb +5 -0
  113. data/spec/fixtures/rails4_users_app/config/environments/development.rb +41 -0
  114. data/spec/fixtures/rails4_users_app/config/environments/production.rb +79 -0
  115. data/spec/fixtures/rails4_users_app/config/environments/test.rb +42 -0
  116. data/spec/fixtures/rails4_users_app/config/initializers/assets.rb +11 -0
  117. data/spec/fixtures/rails4_users_app/config/initializers/backtrace_silencers.rb +7 -0
  118. data/spec/fixtures/rails4_users_app/config/initializers/cookies_serializer.rb +3 -0
  119. data/spec/fixtures/rails4_users_app/config/initializers/filter_parameter_logging.rb +4 -0
  120. data/spec/fixtures/rails4_users_app/config/initializers/inflections.rb +16 -0
  121. data/spec/fixtures/rails4_users_app/config/initializers/mime_types.rb +4 -0
  122. data/spec/fixtures/rails4_users_app/config/initializers/session_store.rb +3 -0
  123. data/spec/fixtures/rails4_users_app/config/initializers/to_time_preserves_timezone.rb +10 -0
  124. data/spec/fixtures/rails4_users_app/config/initializers/wrap_parameters.rb +14 -0
  125. data/spec/fixtures/rails4_users_app/config/locales/en.yml +23 -0
  126. data/spec/fixtures/rails4_users_app/config/routes.rb +12 -0
  127. data/spec/fixtures/rails4_users_app/config/secrets.yml +22 -0
  128. data/spec/fixtures/rails4_users_app/create_app +23 -0
  129. data/spec/fixtures/rails4_users_app/db/migrate/20191127112304_create_users.rb +10 -0
  130. data/spec/fixtures/rails4_users_app/db/schema.rb +26 -0
  131. data/spec/fixtures/rails4_users_app/db/seeds.rb +7 -0
  132. data/spec/fixtures/rails4_users_app/docker-compose.yml +26 -0
  133. data/spec/fixtures/rails4_users_app/lib/assets/.keep +0 -0
  134. data/spec/fixtures/rails4_users_app/lib/tasks/.keep +0 -0
  135. data/spec/fixtures/rails4_users_app/log/.keep +0 -0
  136. data/spec/fixtures/rails4_users_app/public/404.html +67 -0
  137. data/spec/fixtures/rails4_users_app/public/422.html +67 -0
  138. data/spec/fixtures/rails4_users_app/public/500.html +66 -0
  139. data/spec/fixtures/rails4_users_app/public/favicon.ico +0 -0
  140. data/spec/fixtures/rails4_users_app/public/robots.txt +5 -0
  141. data/spec/fixtures/rails4_users_app/spec/controllers/users_controller_api_spec.rb +49 -0
  142. data/spec/fixtures/rails4_users_app/spec/rails_helper.rb +95 -0
  143. data/spec/fixtures/rails4_users_app/spec/spec_helper.rb +96 -0
  144. data/spec/fixtures/rails4_users_app/test/fixtures/users.yml +9 -0
  145. data/spec/fixtures/rails_users_app/.dockerignore +1 -0
  146. data/spec/fixtures/rails_users_app/.gitignore +39 -0
  147. data/spec/fixtures/rails_users_app/.rspec +1 -0
  148. data/spec/fixtures/rails_users_app/.ruby-version +1 -0
  149. data/spec/fixtures/rails_users_app/Dockerfile +29 -0
  150. data/spec/fixtures/rails_users_app/Dockerfile.pg +3 -0
  151. data/spec/fixtures/rails_users_app/Gemfile +52 -0
  152. data/spec/fixtures/rails_users_app/Rakefile +6 -0
  153. data/spec/fixtures/rails_users_app/app/controllers/api/users_controller.rb +27 -0
  154. data/spec/fixtures/rails_users_app/app/controllers/application_controller.rb +2 -0
  155. data/spec/fixtures/rails_users_app/app/controllers/concerns/.keep +0 -0
  156. data/spec/fixtures/rails_users_app/app/controllers/health_controller.rb +5 -0
  157. data/spec/fixtures/rails_users_app/app/controllers/users_controller.rb +5 -0
  158. data/spec/fixtures/rails_users_app/app/models/activerecord/user.rb +18 -0
  159. data/spec/fixtures/rails_users_app/app/models/concerns/.keep +0 -0
  160. data/spec/fixtures/rails_users_app/app/models/sequel/user.rb +25 -0
  161. data/spec/fixtures/rails_users_app/app/views/layouts/application.html.haml +7 -0
  162. data/spec/fixtures/rails_users_app/app/views/users/index.html.haml +7 -0
  163. data/spec/fixtures/rails_users_app/appmap.yml +3 -0
  164. data/spec/fixtures/rails_users_app/bin/appmap +29 -0
  165. data/spec/fixtures/rails_users_app/bin/byebug +29 -0
  166. data/spec/fixtures/rails_users_app/bin/gli +29 -0
  167. data/spec/fixtures/rails_users_app/bin/htmldiff +29 -0
  168. data/spec/fixtures/rails_users_app/bin/ldiff +29 -0
  169. data/spec/fixtures/rails_users_app/bin/nokogiri +29 -0
  170. data/spec/fixtures/rails_users_app/bin/rackup +29 -0
  171. data/spec/fixtures/rails_users_app/bin/rails +4 -0
  172. data/spec/fixtures/rails_users_app/bin/rake +29 -0
  173. data/spec/fixtures/rails_users_app/bin/rspec +29 -0
  174. data/spec/fixtures/rails_users_app/bin/ruby-parse +29 -0
  175. data/spec/fixtures/rails_users_app/bin/ruby-rewrite +29 -0
  176. data/spec/fixtures/rails_users_app/bin/sequel +29 -0
  177. data/spec/fixtures/rails_users_app/bin/setup +25 -0
  178. data/spec/fixtures/rails_users_app/bin/sprockets +29 -0
  179. data/spec/fixtures/rails_users_app/bin/thor +29 -0
  180. data/spec/fixtures/rails_users_app/bin/update +25 -0
  181. data/spec/fixtures/rails_users_app/config.ru +5 -0
  182. data/spec/fixtures/rails_users_app/config/application.rb +51 -0
  183. data/spec/fixtures/rails_users_app/config/boot.rb +3 -0
  184. data/spec/fixtures/rails_users_app/config/credentials.yml.enc +1 -0
  185. data/spec/fixtures/rails_users_app/config/database.yml +18 -0
  186. data/spec/fixtures/rails_users_app/config/environment.rb +5 -0
  187. data/spec/fixtures/rails_users_app/config/environments/development.rb +40 -0
  188. data/spec/fixtures/rails_users_app/config/environments/production.rb +68 -0
  189. data/spec/fixtures/rails_users_app/config/environments/test.rb +36 -0
  190. data/spec/fixtures/rails_users_app/config/initializers/application_controller_renderer.rb +8 -0
  191. data/spec/fixtures/rails_users_app/config/initializers/backtrace_silencers.rb +7 -0
  192. data/spec/fixtures/rails_users_app/config/initializers/cors.rb +16 -0
  193. data/spec/fixtures/rails_users_app/config/initializers/filter_parameter_logging.rb +4 -0
  194. data/spec/fixtures/rails_users_app/config/initializers/inflections.rb +16 -0
  195. data/spec/fixtures/rails_users_app/config/initializers/mime_types.rb +4 -0
  196. data/spec/fixtures/rails_users_app/config/initializers/record_button.rb +3 -0
  197. data/spec/fixtures/rails_users_app/config/initializers/wrap_parameters.rb +9 -0
  198. data/spec/fixtures/rails_users_app/config/locales/en.yml +33 -0
  199. data/spec/fixtures/rails_users_app/config/routes.rb +11 -0
  200. data/spec/fixtures/rails_users_app/create_app +27 -0
  201. data/spec/fixtures/rails_users_app/db/migrate/20190728211408_create_users.rb +9 -0
  202. data/spec/fixtures/rails_users_app/db/schema.rb +23 -0
  203. data/spec/fixtures/rails_users_app/docker-compose.yml +28 -0
  204. data/spec/fixtures/rails_users_app/features/api_users.feature +13 -0
  205. data/spec/fixtures/rails_users_app/features/support/env.rb +4 -0
  206. data/spec/fixtures/rails_users_app/features/support/hooks.rb +11 -0
  207. data/spec/fixtures/rails_users_app/features/support/steps.rb +18 -0
  208. data/spec/fixtures/rails_users_app/lib/tasks/.keep +0 -0
  209. data/spec/fixtures/rails_users_app/log/.keep +0 -0
  210. data/spec/fixtures/rails_users_app/public/robots.txt +1 -0
  211. data/spec/fixtures/rails_users_app/spec/controllers/users_controller_api_spec.rb +29 -0
  212. data/spec/fixtures/rails_users_app/spec/models/user_spec.rb +39 -0
  213. data/spec/fixtures/rails_users_app/spec/rails_helper.rb +66 -0
  214. data/spec/fixtures/rails_users_app/spec/spec_helper.rb +96 -0
  215. data/spec/fixtures/rails_users_app/users_app/.gitignore +20 -0
  216. data/spec/hook_spec.rb +576 -0
  217. data/spec/rails_spec_helper.rb +60 -0
  218. data/spec/railtie_spec.rb +44 -0
  219. data/spec/record_sql_rails4_pg_spec.rb +76 -0
  220. data/spec/record_sql_rails_pg_spec.rb +68 -0
  221. data/spec/remote_recording_spec.rb +117 -0
  222. data/spec/rspec_feature_metadata_spec.rb +32 -0
  223. data/spec/spec_helper.rb +15 -0
  224. data/spec/util_spec.rb +21 -0
  225. data/test/cli_test.rb +116 -0
  226. data/test/cucumber_test.rb +72 -0
  227. data/test/fixtures/cli_record_test/appmap.yml +3 -0
  228. data/test/fixtures/cli_record_test/lib/cli_record_test/main.rb +9 -0
  229. data/test/fixtures/cucumber4_recorder/Gemfile +5 -0
  230. data/test/fixtures/cucumber4_recorder/appmap.yml +3 -0
  231. data/test/fixtures/cucumber4_recorder/features/say_hello.feature +5 -0
  232. data/test/fixtures/cucumber4_recorder/features/support/env.rb +5 -0
  233. data/test/fixtures/cucumber4_recorder/features/support/hooks.rb +11 -0
  234. data/test/fixtures/cucumber4_recorder/features/support/steps.rb +9 -0
  235. data/test/fixtures/cucumber4_recorder/lib/hello.rb +7 -0
  236. data/test/fixtures/cucumber_recorder/Gemfile +5 -0
  237. data/test/fixtures/cucumber_recorder/appmap.yml +3 -0
  238. data/test/fixtures/cucumber_recorder/features/say_hello.feature +5 -0
  239. data/test/fixtures/cucumber_recorder/features/support/env.rb +5 -0
  240. data/test/fixtures/cucumber_recorder/features/support/hooks.rb +11 -0
  241. data/test/fixtures/cucumber_recorder/features/support/steps.rb +9 -0
  242. data/test/fixtures/cucumber_recorder/lib/hello.rb +7 -0
  243. data/test/fixtures/minitest_recorder/Gemfile +5 -0
  244. data/test/fixtures/minitest_recorder/appmap.yml +3 -0
  245. data/test/fixtures/minitest_recorder/lib/hello.rb +5 -0
  246. data/test/fixtures/minitest_recorder/test/hello_test.rb +12 -0
  247. data/test/fixtures/process_recorder/appmap.yml +3 -0
  248. data/test/fixtures/process_recorder/hello.rb +9 -0
  249. data/test/fixtures/rspec_recorder/Gemfile +5 -0
  250. data/test/fixtures/rspec_recorder/appmap.yml +3 -0
  251. data/test/fixtures/rspec_recorder/lib/hello.rb +5 -0
  252. data/test/fixtures/rspec_recorder/spec/decorated_hello_spec.rb +21 -0
  253. data/test/fixtures/rspec_recorder/spec/labeled_hello_spec.rb +9 -0
  254. data/test/fixtures/rspec_recorder/spec/plain_hello_spec.rb +9 -0
  255. data/test/minitest_test.rb +38 -0
  256. data/test/record_process_test.rb +35 -0
  257. data/test/rspec_test.rb +82 -0
  258. data/test/test_helper.rb +4 -0
  259. metadata +525 -0
@@ -0,0 +1,132 @@
1
+ require 'appmap/version'
2
+ GEM_VERSION = AppMap::VERSION
3
+
4
+ require 'rake/testtask'
5
+ require 'rdoc/task'
6
+
7
+ require 'open3'
8
+
9
+ namespace 'gem' do
10
+ require 'bundler/gem_tasks'
11
+ end
12
+
13
+ RUBY_VERSIONS=%w[2.5 2.6]
14
+ FIXTURE_APPS=%w[rack_users_app rails_users_app rails4_users_app]
15
+
16
+ def run_cmd(*cmd)
17
+ $stderr.puts "Running: #{cmd}"
18
+ out,s = Open3.capture2e(*cmd)
19
+ unless s.success?
20
+ $stderr.puts <<-END
21
+ Command failed:
22
+ <<< Output:
23
+ #{out}
24
+ >>> End of output
25
+ END
26
+ raise 'Docker build failed'
27
+ end
28
+ end
29
+
30
+ def build_base_image(ruby_version)
31
+ run_cmd "docker build" \
32
+ " --build-arg RUBY_VERSION=#{ruby_version} --build-arg GEM_VERSION=#{GEM_VERSION}" \
33
+ " -t appmap:#{GEM_VERSION} -f Dockerfile.appmap ."
34
+ end
35
+
36
+ def build_app_image(app, ruby_version)
37
+ Dir.chdir "spec/fixtures/#{app}" do
38
+ run_cmd( {"RUBY_VERSION" => ruby_version, "GEM_VERSION" => GEM_VERSION},
39
+ " docker-compose build" \
40
+ " --build-arg RUBY_VERSION=#{ruby_version}" \
41
+ " --build-arg GEM_VERSION=#{GEM_VERSION}")
42
+ end
43
+ end
44
+
45
+ namespace :build do
46
+ namespace :base do
47
+ RUBY_VERSIONS.each do |ruby_version|
48
+ desc ruby_version
49
+ task ruby_version => ["gem:build"] do
50
+ build_base_image(ruby_version)
51
+ end.tap do |t|
52
+ desc "Build all images"
53
+ task all: t
54
+ end
55
+ end
56
+ end
57
+
58
+ namespace :fixtures do
59
+ RUBY_VERSIONS.each do |ruby_version|
60
+ namespace ruby_version do
61
+ desc "build:fixtures:#{ruby_version}"
62
+ FIXTURE_APPS.each do |app|
63
+ desc app
64
+ task app => ["base:#{ruby_version}"] do
65
+ build_app_image(app, ruby_version)
66
+ end.tap do |t|
67
+ desc "Build all fixture images for #{ruby_version}"
68
+ task all: t
69
+ end
70
+ end
71
+ end
72
+
73
+ desc "Build all fixture images"
74
+ task all: ["#{ruby_version}:all"]
75
+ end
76
+ end
77
+
78
+ task all: ["fixtures:all"]
79
+ end
80
+
81
+ def run_specs(ruby_version, task_args)
82
+ require 'rspec/core/rake_task'
83
+ require 'climate_control'
84
+ # Define an rspec rake task for the specified Ruby version. It's hidden (i.e. doesn't have a
85
+ # description), because it's not intended to be invoked directly
86
+ RSpec::Core::RakeTask.new("rspec_#{ruby_version}", [:specs]) do |task, args|
87
+ task.exclude_pattern = 'spec/fixtures/**/*_spec.rb'
88
+ if args.count > 0
89
+ # There doesn't appear to be a value for +pattern+ that will
90
+ # cause it to be ignored. Setting it to '' or +nil+ causes an
91
+ # empty argument to get passed to rspec, which confuses it.
92
+ task.pattern = 'never match this'
93
+ task.rspec_opts = args.to_a.join(' ')
94
+ end
95
+ end
96
+
97
+ # Set up the environment, then execute the rspec task we
98
+ # created above.
99
+ ClimateControl.modify(RUBY_VERSION: ruby_version) do
100
+ Rake::Task["rspec_#{ruby_version}"].execute(task_args)
101
+ end
102
+ end
103
+
104
+ namespace :spec do
105
+ RUBY_VERSIONS.each do |ruby_version|
106
+ desc ruby_version
107
+ task ruby_version, [:specs] => ["build:fixtures:#{ruby_version}:all"] do |_, task_args|
108
+ run_specs(ruby_version, task_args)
109
+ end.tap do|t|
110
+ desc "Run all specs"
111
+ task :all, [:specs] => t
112
+ end
113
+ end
114
+ end
115
+
116
+ Rake::RDocTask.new do |rd|
117
+ rd.main = 'README.rdoc'
118
+ rd.rdoc_files.include(%w[README.rdoc lib/**/*.rb exe/**/*])
119
+ rd.title = 'AppMap'
120
+ end
121
+
122
+ Rake::TestTask.new(:minitest) do |t|
123
+ t.libs << 'test'
124
+ t.libs << 'lib'
125
+ t.test_files = FileList['test/*_test.rb']
126
+ end
127
+
128
+ task spec: "spec:all"
129
+
130
+ task test: %i[spec:all minitest]
131
+
132
+ task default: :test
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'appmap/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'appmap'
9
+ spec.version = AppMap::VERSION
10
+ spec.authors = ['Kevin Gilpin']
11
+ spec.email = ['kgilpin@gmail.com']
12
+
13
+ spec.summary = %q{Record the operation of a Ruby program, using the AppLand 'AppMap' format.}
14
+ spec.homepage = AppMap::URL
15
+ spec.license = 'MIT'
16
+
17
+ # Specify which files should be added to the gem when it is released.
18
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
19
+ spec.files = `git ls-files --no-deleted`.split("
20
+ ")
21
+ spec.bindir = 'exe'
22
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
+ spec.require_paths = ['lib']
24
+
25
+ spec.add_dependency 'activesupport'
26
+ spec.add_dependency 'faraday'
27
+ spec.add_dependency 'gli'
28
+ spec.add_dependency 'parser'
29
+
30
+ spec.add_development_dependency 'bundler', '~> 1.16'
31
+ spec.add_development_dependency 'minitest', '~> 5.0'
32
+ spec.add_development_dependency 'pry-byebug'
33
+ spec.add_development_dependency 'rake', '>= 12.3.3'
34
+ spec.add_development_dependency 'rdoc'
35
+ spec.add_development_dependency 'rubocop'
36
+
37
+ # Testing
38
+ spec.add_development_dependency 'climate_control'
39
+ spec.add_development_dependency 'diffy'
40
+ spec.add_development_dependency 'launchy'
41
+ spec.add_development_dependency 'rspec'
42
+ spec.add_development_dependency 'selenium-webdriver'
43
+ spec.add_development_dependency 'webdrivers', '~> 4.0'
44
+ end
@@ -0,0 +1,8 @@
1
+ name: AppMap Rubygem
2
+ packages:
3
+ - path: lib/appmap
4
+ exclude:
5
+ - server
6
+ - trace
7
+
8
+ - path: examples
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.join(__dir__)
4
+ require 'fileutils'
5
+
6
+ module Command
7
+ def run_command command
8
+ `#{command}`.tap do |_|
9
+ raise "Command failed: #{command}" unless $? == 0
10
+ end
11
+ end
12
+ end
13
+
14
+ class InProjectDirectory
15
+ attr_reader :project_dir
16
+
17
+ def initialize
18
+ @project_dir = File.expand_path('../tmp/install', __dir__)
19
+ end
20
+
21
+ def perform(&block)
22
+ FileUtils.rm_rf project_dir
23
+ FileUtils.mkdir_p project_dir
24
+ Dir.chdir project_dir, &block
25
+ end
26
+ end
27
+
28
+ class InstallExampleCode
29
+ def perform
30
+ FileUtils.cp_r File.join(__dir__, 'mock_webapp'), '.'
31
+ end
32
+ end
33
+
34
+ class InExampleDirectory
35
+ def perform(&block)
36
+ Dir.chdir 'mock_webapp', &block
37
+ end
38
+ end
39
+
40
+ class InstallAppmapGem
41
+ include Command
42
+
43
+ def perform
44
+ run_command 'bundle --local > /dev/null'
45
+ end
46
+ end
47
+
48
+ class InspectExampleProject
49
+ include Command
50
+
51
+ def perform
52
+ FileUtils.mkdir_p '.appmap'
53
+ run_command "bundle exec #{File.expand_path('../exe/appmap', __dir__)} inspect -o appmap.json"
54
+ end
55
+ end
56
+
57
+ class PrintInventory
58
+ def initialize(inventory)
59
+ @inventory = inventory
60
+ end
61
+
62
+ def perform
63
+ puts @inventory
64
+ end
65
+ end
66
+
67
+ InProjectDirectory.new.perform do
68
+ InstallExampleCode.new.perform
69
+ InExampleDirectory.new.perform do
70
+ InstallAppmapGem.new.perform
71
+
72
+ inventory = InspectExampleProject.new.perform
73
+ PrintInventory.new(inventory).perform
74
+ end
75
+ end
76
+
@@ -0,0 +1 @@
1
+ gem 'appmap', git: '../..', branch: `git rev-parse --abbrev-ref HEAD`.strip
@@ -0,0 +1,2 @@
1
+ packages:
2
+ - path: lib
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.join(__dir__, '..', 'lib')
4
+
5
+ require 'json'
6
+ require 'mock_webapp/user'
7
+ require 'mock_webapp/request'
8
+ require 'mock_webapp/controller'
9
+
10
+ include MockWebapp
11
+
12
+ puts JSON.pretty_generate Controller.instance.process(Request.new(id: 'alice'))
@@ -0,0 +1,23 @@
1
+ module MockWebapp
2
+ # Mock controller.
3
+ # @appmap
4
+ class Controller
5
+ @controller = nil
6
+
7
+ class << self
8
+ # Singleton factory method.
9
+ #
10
+ # @appmap
11
+ def instance
12
+ @controller ||= Controller.new
13
+ end
14
+ end
15
+
16
+ # @appmap
17
+ def process(request)
18
+ id = request.params[:id]
19
+ user = User.find(id)
20
+ user.to_h
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,12 @@
1
+ module MockWebapp
2
+ RequestStruct = Struct.new(:params)
3
+
4
+ # Mock request.
5
+ # @appmap
6
+ class Request < RequestStruct
7
+ # @appmap
8
+ def initialize(*args)
9
+ super
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,18 @@
1
+ module MockWebapp
2
+ UserStruct = Struct.new(:login)
3
+
4
+ # Mock model object.
5
+ # @appmap
6
+ class User < UserStruct
7
+ USERS = {
8
+ 'alice' => User.new('alice')
9
+ }.freeze
10
+
11
+ class << self
12
+ # @appmap
13
+ def find(id)
14
+ USERS[id] || raise("No such user #{id}")
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,154 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'gli'
5
+
6
+ ENV['APPMAP_INITIALIZE'] = 'false'
7
+
8
+ require 'appmap'
9
+ require 'appmap/version'
10
+
11
+ # AppMap CLI.
12
+ module AppMap
13
+ class App
14
+ extend GLI::App
15
+
16
+ program_desc 'AppMap client'
17
+
18
+ version AppMap::VERSION
19
+
20
+ subcommand_option_handling :normal
21
+ arguments :strict
22
+ preserve_argv true
23
+
24
+ class << self
25
+ protected
26
+
27
+ def default_appmap_file
28
+ ENV['APPMAP_FILE'] || 'appmap.json'
29
+ end
30
+
31
+ def output_file_flag(c, default_value: nil)
32
+ c.desc 'Name of the output file'
33
+ c.long_desc <<~DESC
34
+ Use a single dash '-' for stdout.
35
+ DESC
36
+ c.default_value default_value if default_value
37
+ c.arg_name 'filename'
38
+ c.flag %i[o output]
39
+ end
40
+ end
41
+
42
+ desc 'AppMap configuration file name'
43
+ default_value ENV['APPMAP_CONFIG'] || 'appmap.yml'
44
+ arg_name 'filename'
45
+ flag %i[c config]
46
+
47
+ desc 'Record the execution of a program and generate an AppMap.'
48
+ arg_name 'program'
49
+ command :record do |c|
50
+ output_file_flag(c, default_value: default_appmap_file)
51
+
52
+ c.action do |_, _, args|
53
+ # My subcommand name
54
+ ARGV.shift
55
+
56
+ # Consume the :output option, if provided
57
+ if %w[-o --output].find { |arg_name| ARGV[0] == arg_name.to_s }
58
+ ARGV.shift
59
+ ARGV.shift
60
+ end
61
+
62
+ # Name of the program to execute. GLI will ensure that it's present.
63
+ program = args.shift or help_now!("'program' argument is required")
64
+
65
+ # Also pop the program name from ARGV, because the command will use raw ARGV
66
+ # to load the extra arguments into this Ruby process.
67
+ ARGV.shift
68
+
69
+ require 'appmap/command/record'
70
+ AppMap::Command::Record.new(@config, program).perform do |version, metadata, class_map, events|
71
+ @output_file.write JSON.generate(version: version,
72
+ metadata: metadata,
73
+ classMap: class_map,
74
+ events: events)
75
+ end
76
+ end
77
+ end
78
+
79
+ desc 'Calculate and print statistics of scenario files.'
80
+ arg_name 'filename'
81
+ command :stats do |c|
82
+ output_file_flag(c, default_value: '-')
83
+
84
+ c.desc 'Display format for the result (text | json)'
85
+ c.default_value 'text'
86
+ c.flag %i[f format]
87
+
88
+ c.desc 'Maximum number of lines to display for each stat'
89
+ c.flag %i[l limit]
90
+
91
+ c.action do |_, options, args|
92
+ require 'appmap/command/stats'
93
+
94
+ limit = options[:limit].to_i if options[:limit]
95
+
96
+ # Name of the file to analyze. GLI will ensure that it's present.
97
+ filenames = args
98
+ help_now!("'filename' argument is required") if filenames.empty?
99
+
100
+ require 'appmap/algorithm/stats'
101
+ result = filenames.inject(::AppMap::Algorithm::Stats::Result.new([], [])) do |stats_result, filename|
102
+ appmap = begin
103
+ JSON.parse(File.read(filename))
104
+ rescue JSON::ParserError
105
+ STDERR.puts "#{filename} is not valid JSON : #{$!}"
106
+ nil
107
+ end
108
+ stats_result.tap do
109
+ if appmap
110
+ limit = options[:limit].to_i if options[:limit]
111
+ stats_for_file = AppMap::Command::Stats.new(appmap).perform(limit: limit)
112
+ stats_result.merge!(stats_for_file)
113
+ end
114
+ end
115
+ end
116
+
117
+ result.sort!
118
+ result.limit!(limit) if limit
119
+
120
+ display = case options[:format]
121
+ when 'json'
122
+ JSON.pretty_generate(result.as_json)
123
+ else
124
+ result.as_text
125
+ end
126
+ @output_file.write display
127
+ end
128
+ end
129
+
130
+ pre do |global, _, options, _|
131
+ @config = interpret_config_option(global[:config])
132
+ @output_file = interpret_output_file_option(options[:output])
133
+
134
+ true
135
+ end
136
+
137
+ class << self
138
+ protected
139
+
140
+ def interpret_config_option(fname)
141
+ AppMap.initialize fname
142
+ end
143
+
144
+ def interpret_output_file_option(file_name)
145
+ Hash.new { |_, fname| -> { File.new(fname, 'w') } }.tap do |open_output_file|
146
+ open_output_file[nil] = -> { nil }
147
+ open_output_file['-'] = -> { $stdout }
148
+ end[file_name].call
149
+ end
150
+ end
151
+ end
152
+ end
153
+
154
+ exit AppMap::App.run(ARGV)