ruby_memcheck 1.3.1 → 2.0.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: d7a2965241d52c1a38ece5788f2e029a6424fbd34f0b18ffc3dcc35253a45377
4
- data.tar.gz: 4949a4a3357647895f61bc85353342a6257b329d970f854ca7105fd85843b4b8
3
+ metadata.gz: 16ee16450f130947ac172a2a7f7dcc7c0161fb3f7a851cd525e908533fed0ebc
4
+ data.tar.gz: d3de0b6abf7d4c0e0226983fe45aa86403d0cfa3d28171d288c5ed29b0e276fb
5
5
  SHA512:
6
- metadata.gz: bdc2918a24c74f5b238bc67a86d071006abc24df8a8ac613c5d555ad8de8c27a147c63bb85f42cfa6c13f1a14c3599c61329e93d324da741f5373d562d602a3a
7
- data.tar.gz: b2f8a27e88f0ab7347429eda0fc484ffba7eecf01b29e7411a6d1cdafb7fac31dfed10d826ae5259b089102cd984c93f94196e346851b8b0aab2842dc02b7821
6
+ metadata.gz: aa62176e0585fecb9988d7f874b4207088317b1f97fa00a6b7d17e6336cabe0955a19957b34e6ce6efb496ee75a837b8eca3cc857733da6d7ecfe01e9ac05394
7
+ data.tar.gz: 0e11133ec13c7e186aadb3bbcc99f85e0248c8891a66379bae6bd98836f4fc75f2928918382f94d14da650362c36a8283756e3a83ba37aff0e98ab226e6c17cb
@@ -0,0 +1,23 @@
1
+ # .github/workflows/cla.yml
2
+ name: Contributor License Agreement (CLA)
3
+
4
+ on:
5
+ pull_request_target:
6
+ types: [opened, synchronize]
7
+ issue_comment:
8
+ types: [created]
9
+
10
+ jobs:
11
+ cla:
12
+ runs-on: ubuntu-latest
13
+ if: |
14
+ (github.event.issue.pull_request
15
+ && !github.event.issue.pull_request.merged_at
16
+ && contains(github.event.comment.body, 'signed')
17
+ )
18
+ || (github.event.pull_request && !github.event.pull_request.merged)
19
+ steps:
20
+ - uses: Shopify/shopify-cla-action@v1
21
+ with:
22
+ github-token: ${{ secrets.GITHUB_TOKEN }}
23
+ cla-token: ${{ secrets.CLA_TOKEN }}
@@ -7,7 +7,6 @@ jobs:
7
7
  fail-fast: false
8
8
  matrix:
9
9
  entry:
10
- - { ruby: '2.7', allowed-failure: false }
11
10
  - { ruby: '3.0', allowed-failure: false }
12
11
  - { ruby: '3.1', allowed-failure: false }
13
12
  - { ruby: '3.2', allowed-failure: false }
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2021 Peter Zhu
3
+ Copyright 2021-present, Shopify Inc.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -84,12 +84,6 @@ The easiest way to use this gem is to use it on your test suite (minitest or RSp
84
84
  require "ruby_memcheck/rspec/rake_task"
85
85
  ```
86
86
 
87
- 1. Configure the gem by calling `RubyMemcheck.config`. You must pass it your binary name. This is the same value you passed into `create_makefile` in your `extconf.rb` file. Make sure this value is correct or it will filter out almost everything as a false-positive!
88
-
89
- ```ruby
90
- RubyMemcheck.config(binary_name: "your_binary_name")
91
- ```
92
-
93
87
  1. Setup the test task for your test framework.
94
88
  - **minitest**
95
89
 
@@ -145,18 +139,17 @@ The easiest way to use this gem is to use it on your test suite (minitest or RSp
145
139
 
146
140
  ## Configuration
147
141
 
148
- When you run `RubyMemcheck.config`, you are creating a default `RubyMemcheck::Configuration`. By default, the Rake tasks for minitest and RSpec will use this configuration. You can also manually pass in a `Configuration` object as the first argument to the constructor of `RubyMemcheck::TestTask` or `RubyMemcheck::RSpec::RakeTask` to use a different `Configuration` object rather than the default one.
142
+ If you want to override any of the default configurations you can call `RubyMemcheck.config` after `require "ruby_memcheck"`. This will create a default `RubyMemcheck::Configuration`. By default, the Rake tasks for minitest and RSpec will use this configuration. You can also manually pass in a `Configuration` object as the first argument to the constructor of `RubyMemcheck::TestTask` or `RubyMemcheck::RSpec::RakeTask` to use a different `Configuration` object rather than the default one.
149
143
 
150
144
  `RubyMemcheck::Configuration` accepts a variety of keyword arguments. Here are all the arguments:
151
145
 
152
- - `binary_name`: Required. The binary name of your native extension gem. This is the same value you passed into `create_makefile` in your `extconf.rb` file.
153
146
  - `ruby`: Optional. The command to run to invoke Ruby. Defaults to the Ruby that is currently being used.
154
147
  - `valgrind`: Optional. The command to run to invoke Valgrind. Defaults to the string `"valgrind"`.
155
148
  - `valgrind_options`: Optional. Array of options to pass into Valgrind. This is only present as an escape hatch, so avoid using it. This may be deprecated or removed in future versions.
156
149
  - `valgrind_suppressions_dir`: Optional. The string path of the directory that stores suppression files for Valgrind. See the [`Suppression files`](#suppression-files) section for more details. Defaults to `suppressions`.
157
150
  - `valgrind_generate_suppressions`: Optional. Whether suppressions should also be outputted along with the errors. the [`Suppression files`](#suppression-files) section for more details. Defaults to `false`.
158
151
  - `skipped_ruby_functions`: Optional. Ruby functions that are ignored because they are considered a call back into Ruby. This is only present as an escape hatch, so avoid using it. If you find another Ruby function that is a false positive because it calls back into Ruby, please send a patch into this repo. Otherwise, use a Valgrind suppression file.
159
- - `valgrind_xml_dir`: Optional. The directory to store temporary XML files for Valgrind. It defaults to a temporary directory. This is present for development debugging, so you shouldn't have to use it.
152
+ - `temp_dir`: Optional. The directory to store temporary files. It defaults to a temporary directory. This is present for development debugging, so you shouldn't have to use it.
160
153
  - `output_io`: Optional. The `IO` object to output Valgrind errors to. Defaults to standard error.
161
154
  - `filter_all_errors`: Optional. Whether to filter all kinds of Valgrind errors (not just memory leaks). This feature should only be used if you're encountering a large number of illegal memory accesses coming from Ruby. If you need to use this feature, you may have found a bug inside of Ruby. Consider reporting it to the [Ruby bug tracker](https://bugs.ruby-lang.org/projects/ruby-master/issues/new). Defaults to `false`.
162
155
 
@@ -188,6 +181,9 @@ Let's celebrate wins from this gem! If this gem was useful for you, please share
188
181
  - [`yarp`](https://github.com/shopify/yarp):
189
182
  - Found 6 memory leaks and 1 memory error: [#292](https://github.com/Shopify/yarp/pull/304), [#292](https://github.com/Shopify/yarp/pull/292)
190
183
  - Running on CI: [#293](https://github.com/Shopify/yarp/pull/293)
184
+ - [`libxml2`](https://gitlab.gnome.org/GNOME/libxml2):
185
+ - Found 1 memory leak: [memory leak from \`xmlSchemaValidateStream\` in v2.11.x (#530)](https://gitlab.gnome.org/GNOME/libxml2/-/issues/530)
186
+ - Running in Nokogiri's CI pipeline: [#2868](https://github.com/sparklemotion/nokogiri/pull/2868)
191
187
 
192
188
  ## License
193
189
 
data/Rakefile CHANGED
@@ -11,9 +11,16 @@ Rake::TestTask.new(test: "test:compile") do |t|
11
11
  end
12
12
 
13
13
  namespace :test do
14
- Rake::ExtensionTask.new("ruby_memcheck_c_test") do |ext|
14
+ Rake::ExtensionTask.new("ruby_memcheck_c_test_one") do |ext|
15
15
  ext.ext_dir = "test/ruby_memcheck/ext"
16
16
  ext.lib_dir = "test/ruby_memcheck/ext"
17
+ ext.config_script = "extconf_one.rb"
18
+ end
19
+
20
+ Rake::ExtensionTask.new("ruby_memcheck_c_test_two") do |ext|
21
+ ext.ext_dir = "test/ruby_memcheck/ext"
22
+ ext.lib_dir = "test/ruby_memcheck/ext"
23
+ ext.config_script = "extconf_two.rb"
17
24
  end
18
25
  end
19
26
 
@@ -31,14 +31,14 @@ module RubyMemcheck
31
31
  /\Arb_yield/,
32
32
  ].freeze
33
33
 
34
- attr_reader :binary_name
35
34
  attr_reader :ruby
36
35
  attr_reader :valgrind
37
36
  attr_reader :valgrind_options
38
37
  attr_reader :valgrind_suppression_files
39
38
  attr_reader :valgrind_generate_suppressions
40
39
  attr_reader :skipped_ruby_functions
41
- attr_reader :valgrind_xml_dir
40
+ attr_reader :temp_dir
41
+ attr_reader :loaded_features_file
42
42
  attr_reader :output_io
43
43
  attr_reader :filter_all_errors
44
44
 
@@ -46,18 +46,19 @@ module RubyMemcheck
46
46
  alias_method :filter_all_errors?, :filter_all_errors
47
47
 
48
48
  def initialize(
49
- binary_name:,
49
+ binary_name: nil,
50
50
  ruby: FileUtils::RUBY,
51
51
  valgrind: DEFAULT_VALGRIND,
52
52
  valgrind_options: DEFAULT_VALGRIND_OPTIONS,
53
53
  valgrind_suppressions_dir: DEFAULT_VALGRIND_SUPPRESSIONS_DIR,
54
54
  valgrind_generate_suppressions: false,
55
55
  skipped_ruby_functions: DEFAULT_SKIPPED_RUBY_FUNCTIONS,
56
- valgrind_xml_dir: Dir.mktmpdir,
56
+ temp_dir: Dir.mktmpdir,
57
57
  output_io: $stderr,
58
58
  filter_all_errors: false
59
59
  )
60
- @binary_name = binary_name
60
+ warn("ruby_memcheck: binary_name is no longer required for configuration") if binary_name
61
+
61
62
  @ruby = ruby
62
63
  @valgrind = valgrind
63
64
  @valgrind_options = valgrind_options
@@ -69,18 +70,18 @@ module RubyMemcheck
69
70
  @output_io = output_io
70
71
  @filter_all_errors = filter_all_errors
71
72
 
72
- if valgrind_xml_dir
73
- valgrind_xml_dir = File.expand_path(valgrind_xml_dir)
74
- FileUtils.mkdir_p(valgrind_xml_dir)
75
- @valgrind_xml_dir = valgrind_xml_dir
76
- @valgrind_options += [
77
- "--xml=yes",
78
- # %p will be replaced with the PID
79
- # This prevents forking and shelling out from generating a corrupted XML
80
- # See --log-file from https://valgrind.org/docs/manual/manual-core.html
81
- "--xml-file=#{File.join(valgrind_xml_dir, "%p.out")}",
82
- ]
83
- end
73
+ temp_dir = File.expand_path(temp_dir)
74
+ FileUtils.mkdir_p(temp_dir)
75
+ @temp_dir = temp_dir
76
+ @valgrind_options += [
77
+ "--xml=yes",
78
+ # %p will be replaced with the PID
79
+ # This prevents forking and shelling out from generating a corrupted XML
80
+ # See --log-file from https://valgrind.org/docs/manual/manual-core.html
81
+ "--xml-file=#{File.join(temp_dir, "%p.xml")}",
82
+ ]
83
+
84
+ @loaded_features_file = Tempfile.create("", @temp_dir)
84
85
  end
85
86
 
86
87
  def command(*args)
@@ -97,6 +98,7 @@ module RubyMemcheck
97
98
  valgrind_suppression_files.map { |f| "--suppressions=#{f}" },
98
99
  valgrind_generate_suppressions ? "--gen-suppressions=all" : "",
99
100
  ruby,
101
+ "-r" + File.expand_path(File.join(__dir__, "test_helper.rb")),
100
102
  args,
101
103
  ].flatten.join(" ")
102
104
  end
@@ -112,14 +114,7 @@ module RubyMemcheck
112
114
  versions << RUBY_ENGINE
113
115
 
114
116
  versions.map do |version|
115
- old_format_files = Dir[File.join(dir, "#{binary_name}_#{version}.supp")]
116
-
117
- unless old_format_files.empty?
118
- warn("ruby_memcheck: please migrate your suppression filenames from " \
119
- "`gem_name_ruby-3.1.0.supp` to `ruby-3.1.0.supp` (drop the gem name from the filename)")
120
- end
121
-
122
- old_format_files + Dir[File.join(dir, "#{version}.supp")]
117
+ Dir[File.join(dir, "#{version}.supp")]
123
118
  end.flatten
124
119
  end
125
120
  end
@@ -2,10 +2,12 @@
2
2
 
3
3
  module RubyMemcheck
4
4
  class Frame
5
- attr_reader :configuration, :fn, :obj, :file, :line
5
+ attr_reader :configuration, :loaded_binaries, :fn, :obj, :file, :line
6
6
 
7
- def initialize(configuration, frame_xml)
7
+ def initialize(configuration, loaded_binaries, frame_xml)
8
8
  @configuration = configuration
9
+ @loaded_binaries = loaded_binaries
10
+
9
11
  @fn = frame_xml.at_xpath("fn")&.content
10
12
  @obj = frame_xml.at_xpath("obj")&.content
11
13
  # file and line may not be available
@@ -24,8 +26,14 @@ module RubyMemcheck
24
26
  def in_binary?
25
27
  return false unless obj
26
28
 
27
- binary_name_without_ext = File.join(File.dirname(obj), File.basename(obj, ".*"))
28
- binary_name_without_ext.end_with?(File.join("", configuration.binary_name))
29
+ loaded_binaries.include?(obj)
30
+ end
31
+
32
+ def binary_init_func?
33
+ return false unless in_binary?
34
+
35
+ binary_name = File.basename(obj, ".*")
36
+ fn == "Init_#{binary_name}"
29
37
  end
30
38
 
31
39
  def to_s
@@ -5,9 +5,8 @@ require "rspec/core/rake_task"
5
5
  module RubyMemcheck
6
6
  module RSpec
7
7
  class RakeTask < ::RSpec::Core::RakeTask
8
- include TestTaskReporter
9
-
10
8
  attr_reader :configuration
9
+ attr_reader :reporter
11
10
 
12
11
  def initialize(*args)
13
12
  @configuration =
@@ -23,15 +22,14 @@ module RubyMemcheck
23
22
  def run_task(verbose)
24
23
  error = nil
25
24
 
26
- begin
25
+ @reporter = TestTaskReporter.new(configuration)
26
+ @reporter.run_ruby_with_valgrind do
27
27
  # RSpec::Core::RakeTask#run_task calls Kernel.exit on failure
28
28
  super
29
29
  rescue SystemExit => e
30
30
  error = e
31
31
  end
32
32
 
33
- report_valgrind_errors
34
-
35
33
  raise error if error
36
34
  end
37
35
 
@@ -40,7 +38,6 @@ module RubyMemcheck
40
38
  def spec_command
41
39
  # First part of command is Ruby
42
40
  args = super.split(" ")[1..]
43
- args.unshift("-r" + File.expand_path(File.join(__dir__, "../test_helper.rb")))
44
41
 
45
42
  configuration.command(args)
46
43
  end
@@ -4,30 +4,28 @@ module RubyMemcheck
4
4
  class Stack
5
5
  attr_reader :configuration, :frames
6
6
 
7
- def initialize(configuration, stack_xml)
7
+ def initialize(configuration, loaded_binaries, stack_xml)
8
8
  @configuration = configuration
9
- @frames = stack_xml.xpath("frame").map { |frame| Frame.new(configuration, frame) }
9
+ @frames = stack_xml.xpath("frame").map { |frame| Frame.new(configuration, loaded_binaries, frame) }
10
10
  end
11
11
 
12
12
  def skip?
13
13
  in_binary = false
14
14
 
15
15
  frames.each do |frame|
16
- fn = frame.fn
17
-
18
16
  if frame.in_ruby?
19
17
  # If a stack from from the binary was encountered first, then this
20
18
  # memory leak did not occur from Ruby
21
19
  unless in_binary
22
20
  # Skip this stack because it was called from Ruby
23
- return true if configuration.skipped_ruby_functions.any? { |r| r.match?(fn) }
21
+ return true if configuration.skipped_ruby_functions.any? { |r| r.match?(frame.fn) }
24
22
  end
25
23
  elsif frame.in_binary?
26
24
  in_binary = true
27
25
 
28
26
  # Skip the Init function because it is only ever called once, so
29
27
  # leaks in it cannot cause memory bloat
30
- return true if fn == "Init_#{configuration.binary_name}"
28
+ return true if frame.binary_init_func?
31
29
  end
32
30
  end
33
31
 
@@ -1,3 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- at_exit { GC.start }
3
+ at_exit do
4
+ File.open(ENV["RUBY_MEMCHECK_LOADED_FEATURES_FILE"], "w") do |f|
5
+ f.write($LOADED_FEATURES.join("\n"))
6
+ end
7
+
8
+ GC.start
9
+ end
@@ -2,9 +2,8 @@
2
2
 
3
3
  module RubyMemcheck
4
4
  class TestTask < Rake::TestTask
5
- include TestTaskReporter
6
-
7
5
  attr_reader :configuration
6
+ attr_reader :reporter
8
7
 
9
8
  def initialize(*args)
10
9
  @configuration =
@@ -18,10 +17,14 @@ module RubyMemcheck
18
17
  end
19
18
 
20
19
  def ruby(*args, **options, &block)
21
- args.unshift("-r" + File.expand_path(File.join(__dir__, "test_helper.rb")))
22
20
  command = configuration.command(args)
21
+
22
+ @reporter = TestTaskReporter.new(configuration)
23
+
24
+ @reporter.setup
25
+
23
26
  sh(command, **options) do |ok, res|
24
- report_valgrind_errors
27
+ @reporter.report_valgrind_errors
25
28
 
26
29
  yield ok, res if block_given?
27
30
  end
@@ -1,41 +1,70 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RubyMemcheck
4
- module TestTaskReporter
4
+ class TestTaskReporter
5
5
  VALGRIND_REPORT_MSG = "Valgrind reported errors (e.g. memory leak or use-after-free)"
6
6
 
7
+ attr_reader :configuration
7
8
  attr_reader :errors
8
9
 
9
- private
10
+ def initialize(configuration)
11
+ @configuration = configuration
12
+ @loaded_binaries = nil
13
+ end
14
+
15
+ def run_ruby_with_valgrind(&block)
16
+ setup
17
+ yield
18
+ report_valgrind_errors
19
+ end
20
+
21
+ def setup
22
+ ENV["RUBY_MEMCHECK_LOADED_FEATURES_FILE"] = File.expand_path(configuration.loaded_features_file)
23
+ ENV["RUBY_MEMCHECK_RUNNING"] = "1"
24
+ end
10
25
 
11
26
  def report_valgrind_errors
12
- if configuration.valgrind_xml_dir
13
- xml_files = valgrind_xml_files
14
- parse_valgrind_output(xml_files)
15
- remove_valgrind_xml_files(xml_files)
16
-
17
- unless errors.empty?
18
- output_valgrind_errors
19
- raise VALGRIND_REPORT_MSG
20
- end
27
+ parse_valgrind_output
28
+ remove_valgrind_xml_files
29
+
30
+ unless errors.empty?
31
+ output_valgrind_errors
32
+ raise VALGRIND_REPORT_MSG
21
33
  end
22
34
  end
23
35
 
36
+ private
37
+
38
+ def loaded_binaries
39
+ return @loaded_binaries if @loaded_binaries
40
+
41
+ loaded_features = File.readlines(configuration.loaded_features_file, chomp: true)
42
+ @loaded_binaries = loaded_features.keep_if do |feat|
43
+ # Keep only binaries (ignore Ruby files).
44
+ File.extname(feat) == ".so"
45
+ end.freeze
46
+
47
+ @loaded_binaries
48
+ end
49
+
24
50
  def valgrind_xml_files
25
- Dir[File.join(configuration.valgrind_xml_dir, "*")]
51
+ @valgrind_xml_files ||= Dir[File.join(configuration.temp_dir, "*.xml")].freeze
26
52
  end
27
53
 
28
- def parse_valgrind_output(xml_files)
54
+ def parse_valgrind_output
29
55
  require "nokogiri"
30
56
 
31
57
  @errors = []
32
58
 
33
- xml_files.each do |file|
34
- Nokogiri::XML::Reader(File.open(file)).each do |node|
59
+ valgrind_xml_files.each do |file|
60
+ reader = Nokogiri::XML::Reader(File.open(file)) do |config| # rubocop:disable Style/SymbolProc
61
+ config.huge
62
+ end
63
+ reader.each do |node|
35
64
  next unless node.name == "error" && node.node_type == Nokogiri::XML::Reader::TYPE_ELEMENT
36
65
 
37
66
  error_xml = Nokogiri::XML::Document.parse(node.outer_xml).root
38
- error = ValgrindError.new(configuration, error_xml)
67
+ error = ValgrindError.new(configuration, loaded_binaries, error_xml)
39
68
  next if error.skip?
40
69
 
41
70
  @errors << error
@@ -43,8 +72,8 @@ module RubyMemcheck
43
72
  end
44
73
  end
45
74
 
46
- def remove_valgrind_xml_files(xml_files)
47
- xml_files.each do |file|
75
+ def remove_valgrind_xml_files
76
+ valgrind_xml_files.each do |file|
48
77
  File.delete(file)
49
78
  end
50
79
  end
@@ -7,7 +7,7 @@ module RubyMemcheck
7
7
 
8
8
  attr_reader :kind, :msg, :stack, :suppression
9
9
 
10
- def initialize(configuration, error)
10
+ def initialize(configuration, loaded_binaries, error)
11
11
  @kind = error.at_xpath("kind").content
12
12
  @msg =
13
13
  if kind_leak?
@@ -15,7 +15,7 @@ module RubyMemcheck
15
15
  else
16
16
  error.at_xpath("what").content
17
17
  end
18
- @stack = Stack.new(configuration, error.at_xpath("stack"))
18
+ @stack = Stack.new(configuration, loaded_binaries, error.at_xpath("stack"))
19
19
  @configuration = configuration
20
20
 
21
21
  suppression_node = error.at_xpath("suppression")
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RubyMemcheck
4
- VERSION = "1.3.1"
4
+ VERSION = "2.0.0"
5
5
  end
data/lib/ruby_memcheck.rb CHANGED
@@ -19,11 +19,7 @@ module RubyMemcheck
19
19
  end
20
20
 
21
21
  def default_configuration
22
- unless @default_configuration
23
- raise "RubyMemcheck is not configured with a default configuration. "\
24
- "Please run RubyMemcheck.config before using it."
25
- end
26
- @default_configuration
22
+ @default_configuration ||= config
27
23
  end
28
24
  end
29
25
  end
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
9
9
  spec.email = ["peter@peterzhu.ca"]
10
10
 
11
11
  spec.summary = "Use Valgrind memcheck without going crazy"
12
- spec.homepage = "https://github.com/peterzhu2118/ruby_memcheck"
12
+ spec.homepage = "https://github.com/Shopify/ruby_memcheck"
13
13
  spec.license = "MIT"
14
14
  spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
15
15
 
@@ -50,3 +50,11 @@
50
50
  fun:*try_statx*
51
51
  ...
52
52
  }
53
+ {
54
+ strscan_do_scan in strscan.c will sometimes replace the ptr of the regex, which can be reported as a memory leak if the regex is stored in an iseq. https://github.com/ruby/ruby/pull/8136
55
+ Memcheck:Leak
56
+ ...
57
+ fun:rb_reg_prepare_re
58
+ fun:strscan_do_scan
59
+ ...
60
+ }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_memcheck
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Zhu
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-04-05 00:00:00.000000000 Z
11
+ date: 2023-08-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -129,6 +129,7 @@ executables: []
129
129
  extensions: []
130
130
  extra_rdoc_files: []
131
131
  files:
132
+ - ".github/workflows/cla.yml"
132
133
  - ".github/workflows/lint.yml"
133
134
  - ".github/workflows/test.yml"
134
135
  - ".gitignore"
@@ -150,11 +151,11 @@ files:
150
151
  - lib/ruby_memcheck/version.rb
151
152
  - ruby_memcheck.gemspec
152
153
  - suppressions/ruby.supp
153
- homepage: https://github.com/peterzhu2118/ruby_memcheck
154
+ homepage: https://github.com/Shopify/ruby_memcheck
154
155
  licenses:
155
156
  - MIT
156
157
  metadata:
157
- homepage_uri: https://github.com/peterzhu2118/ruby_memcheck
158
+ homepage_uri: https://github.com/Shopify/ruby_memcheck
158
159
  post_install_message:
159
160
  rdoc_options: []
160
161
  require_paths: