track_open_instances 0.1.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.
- checksums.yaml +7 -0
- data/.husky/commit-msg +1 -0
- data/.markdownlint.yml +26 -0
- data/.qlty/qlty.toml +104 -0
- data/.rspec +3 -0
- data/.rubocop.yml +18 -0
- data/.yamllint.yml +12 -0
- data/.yardopts +9 -0
- data/CHANGELOG.md +19 -0
- data/CONTRIBUTING.md +107 -0
- data/LICENSE.txt +21 -0
- data/README.md +153 -0
- data/RELEASING.md +9 -0
- data/Rakefile +71 -0
- data/commitlint.config.js +30 -0
- data/lib/track_open_instances/version.rb +6 -0
- data/lib/track_open_instances.rb +249 -0
- data/package.json +11 -0
- data/pre-commit +26 -0
- metadata +243 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 264fbcefa796af11230c90bc8f1221363d3af1515975e8647a694a486499c874
|
4
|
+
data.tar.gz: 7a5129b04a6ff432a8b7641f80b0b18e98ea52a96b8bb45599ba991650558fea
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: '0963b6a2fcd9fb91f42dfadc663425365de598b82e1635d8178216ca05da85d19cf1ba8c0bf67807bf3ff650b73558717703ade5772bb516d357b2c2517e363c'
|
7
|
+
data.tar.gz: 57aa5b10f7fc3b96f062cab47985ac5e060aebff83a408293c91339809f68105414b34bff748a016a53f055b23bbf30f37ae3dde43ce05c24a660d59896382f4
|
data/.husky/commit-msg
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
npx --no-install commitlint --edit "$1"
|
data/.markdownlint.yml
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
---
|
2
|
+
default: true
|
3
|
+
|
4
|
+
# Unordered list indentation
|
5
|
+
MD007: { indent: 2 }
|
6
|
+
|
7
|
+
# Line length
|
8
|
+
MD013: { line_length: 90, tables: false, code_blocks: false }
|
9
|
+
|
10
|
+
# Heading duplication is allowed for non-sibling headings
|
11
|
+
MD024: { siblings_only: true }
|
12
|
+
|
13
|
+
# Do not allow the specified trailing punctuation in a header
|
14
|
+
MD026: { punctuation: ".,;:" }
|
15
|
+
|
16
|
+
# Order list items must have a prefix that increases in numerical order
|
17
|
+
MD029: { style: "ordered" }
|
18
|
+
|
19
|
+
# Lists do not need to be surrounded by blank lines
|
20
|
+
MD032: false
|
21
|
+
|
22
|
+
# Allow raw HTML in Markdown
|
23
|
+
MD033: false
|
24
|
+
|
25
|
+
# Allow emphasis to be used instead of a heading
|
26
|
+
MD036: false
|
data/.qlty/qlty.toml
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
# This file was automatically generated by `qlty init`.
|
2
|
+
# You can modify it to suit your needs.
|
3
|
+
# We recommend you to commit this file to your repository.
|
4
|
+
#
|
5
|
+
# This configuration is used by both Qlty CLI and Qlty Cloud.
|
6
|
+
#
|
7
|
+
# Qlty CLI -- Code quality toolkit for developers
|
8
|
+
# Qlty Cloud -- Fully automated Code Health Platform
|
9
|
+
#
|
10
|
+
# Try Qlty Cloud: https://qlty.sh
|
11
|
+
#
|
12
|
+
# For a guide to configuration, visit https://qlty.sh/d/config
|
13
|
+
# Or for a full reference, visit https://qlty.sh/d/qlty-toml
|
14
|
+
config_version = "0"
|
15
|
+
|
16
|
+
exclude_patterns = [
|
17
|
+
"*_min.*",
|
18
|
+
"*-min.*",
|
19
|
+
"*.min.*",
|
20
|
+
"**/*.d.ts",
|
21
|
+
"**/.yarn/**",
|
22
|
+
"**/bower_components/**",
|
23
|
+
"**/build/**",
|
24
|
+
"**/cache/**",
|
25
|
+
"**/config/**",
|
26
|
+
"**/db/**",
|
27
|
+
"**/deps/**",
|
28
|
+
"**/dist/**",
|
29
|
+
"**/extern/**",
|
30
|
+
"**/external/**",
|
31
|
+
"**/generated/**",
|
32
|
+
"**/Godeps/**",
|
33
|
+
"**/gradlew/**",
|
34
|
+
"**/mvnw/**",
|
35
|
+
"**/node_modules/**",
|
36
|
+
"**/protos/**",
|
37
|
+
"**/seed/**",
|
38
|
+
"**/target/**",
|
39
|
+
"**/testdata/**",
|
40
|
+
"**/vendor/**",
|
41
|
+
"**/assets/**",
|
42
|
+
]
|
43
|
+
|
44
|
+
test_patterns = [
|
45
|
+
"**/test/**",
|
46
|
+
"**/spec/**",
|
47
|
+
"**/*.test.*",
|
48
|
+
"**/*.spec.*",
|
49
|
+
"**/*_test.*",
|
50
|
+
"**/*_spec.*",
|
51
|
+
"**/test_*.*",
|
52
|
+
"**/spec_*.*",
|
53
|
+
]
|
54
|
+
|
55
|
+
[smells]
|
56
|
+
mode = "comment"
|
57
|
+
|
58
|
+
[[source]]
|
59
|
+
name = "default"
|
60
|
+
default = true
|
61
|
+
|
62
|
+
[[plugin]]
|
63
|
+
name = "actionlint"
|
64
|
+
|
65
|
+
[[plugin]]
|
66
|
+
name = "checkov"
|
67
|
+
|
68
|
+
[[plugin]]
|
69
|
+
name = "golangci-lint"
|
70
|
+
mode = "comment"
|
71
|
+
|
72
|
+
[[plugin]]
|
73
|
+
name = "markdownlint"
|
74
|
+
version = "0.41.0"
|
75
|
+
mode = "comment"
|
76
|
+
|
77
|
+
[[plugin]]
|
78
|
+
name = "prettier"
|
79
|
+
|
80
|
+
# [[plugin]]
|
81
|
+
# name = "radarlint-ruby"
|
82
|
+
|
83
|
+
[[plugin]]
|
84
|
+
name = "ripgrep"
|
85
|
+
mode = "comment"
|
86
|
+
|
87
|
+
# [[plugin]]
|
88
|
+
# name = "rubocop"
|
89
|
+
# version = "1.75.2"
|
90
|
+
# package_file = "Gemfile"
|
91
|
+
# package_filters = ["rubocop"]
|
92
|
+
|
93
|
+
[[plugin]]
|
94
|
+
name = "trivy"
|
95
|
+
drivers = [
|
96
|
+
"config",
|
97
|
+
"fs-vuln",
|
98
|
+
]
|
99
|
+
|
100
|
+
[[plugin]]
|
101
|
+
name = "trufflehog"
|
102
|
+
|
103
|
+
[[plugin]]
|
104
|
+
name = "yamllint"
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
---
|
2
|
+
inherit_gem:
|
3
|
+
main_branch_shared_rubocop_config: config/rubocop.yml
|
4
|
+
|
5
|
+
Metrics/MethodLength:
|
6
|
+
Exclude:
|
7
|
+
- "spec/spec_helper.rb"
|
8
|
+
- "spec/**/*_spec.rb"
|
9
|
+
|
10
|
+
Metrics/AbcSize:
|
11
|
+
Exclude:
|
12
|
+
- "spec/spec_helper.rb"
|
13
|
+
- "spec/**/*_spec.rb"
|
14
|
+
|
15
|
+
AllCops:
|
16
|
+
# Pin this project to Ruby 3.1 in case the shared config above is
|
17
|
+
# upgraded to 3.2 or later.
|
18
|
+
TargetRubyVersion: 3.1
|
data/.yamllint.yml
ADDED
data/.yardopts
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# Change Log
|
2
|
+
|
3
|
+
## v0.1.0 (2025-04-08)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/main-branch/track_open_instances/compare/f0fb459..v0.1.0)
|
6
|
+
|
7
|
+
Changes:
|
8
|
+
|
9
|
+
- f2d5318 chore: remove radarline-ruby from qlty checks
|
10
|
+
- 177eba8 chore: fix formatting errors reported by `qlty fmt`
|
11
|
+
- 943359f build: remove rubocop plugin from qlty
|
12
|
+
- 476f271 chore: integrate yamllint
|
13
|
+
- 56811ca fix: add qlty configuration in order to run qlty checks locally
|
14
|
+
- e83546a fix: fix continuous integration workflow issues reported by qlty.sh
|
15
|
+
- 6f67aed test: add predicate methods to determine the Ruby engine and platform
|
16
|
+
- 34e3829 build: generate JSON coverage report for qlty.sh coverage reporting
|
17
|
+
- 9db2052 docs: update README links
|
18
|
+
- 937a971 build: update code coverage reporting
|
19
|
+
- f0fb459 feat: initial implementation of TrackOpenInstances
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
# Contributing to track_open_instances
|
2
|
+
|
3
|
+
Thank you for your interest in contributing to the track_open_instances project!
|
4
|
+
|
5
|
+
This document gives the guidelines for contributing to this project.
|
6
|
+
These guidelines may not fit every situation. When contributing use your best
|
7
|
+
judgement.
|
8
|
+
|
9
|
+
Propose changes to these guidelines with a pull request.
|
10
|
+
|
11
|
+
## How to contribute to track_open_instances
|
12
|
+
|
13
|
+
You can contribute in two ways:
|
14
|
+
|
15
|
+
1. [Report an issue or make a feature request](#how-to-report-an-issue-or-make-a-feature-request)
|
16
|
+
2. [Submit a code or documentation change](#how-to-submit-a-code-or-documentation-change)
|
17
|
+
|
18
|
+
## How to report an issue or make a feature request
|
19
|
+
|
20
|
+
track_open_instances utilizes [GitHub Issues](https://help.github.com/en/github/managing-your-work-on-github/about-issues)
|
21
|
+
for issue tracking and feature requests.
|
22
|
+
|
23
|
+
Report an issue or feature request by [creating a track_open_instances Github issue](https://github.com/main-branch/track_open_instances/issues/new).
|
24
|
+
Fill in the template to describe the issue or feature request the best you can.
|
25
|
+
|
26
|
+
## How to submit a code or documentation change
|
27
|
+
|
28
|
+
There is three step process for code or documentation changes:
|
29
|
+
|
30
|
+
1. [Commit your changes to a fork of track_open_instances](#commit-changes-to-a-fork-of-track_open_instances)
|
31
|
+
2. [Create a pull request](#create-a-pull-request)
|
32
|
+
3. [Get your pull request reviewed](#get-your-pull-request-reviewed)
|
33
|
+
|
34
|
+
### Commit changes to a fork of track_open_instances
|
35
|
+
|
36
|
+
Make your changes in a fork of the track_open_instances repository.
|
37
|
+
|
38
|
+
### Create a pull request
|
39
|
+
|
40
|
+
See [this article](https://help.github.com/articles/about-pull-requests/) if you
|
41
|
+
are not familiar with GitHub Pull Requests.
|
42
|
+
|
43
|
+
Follow the instructions in the pull request template.
|
44
|
+
|
45
|
+
### Get your pull request reviewed
|
46
|
+
|
47
|
+
Code review takes place in a GitHub pull request using the
|
48
|
+
[the Github pull request review feature](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-request-reviews).
|
49
|
+
|
50
|
+
Once your pull request is ready for review, request a review from at least one of the
|
51
|
+
[code owners](https://github.com/orgs/main-branch/teams/track_open_instances-codeowners/members).
|
52
|
+
|
53
|
+
During the review process, you may need to make additional commits which would
|
54
|
+
need to be squashed. It may also be necessary to rebase to main again if other
|
55
|
+
changes are merged before your PR.
|
56
|
+
|
57
|
+
At least one approval is required from a project maintainer before your pull
|
58
|
+
request can be merged. The maintainer is responsible for ensuring that the pull
|
59
|
+
request meets [the project's coding standards](#coding-standards).
|
60
|
+
|
61
|
+
## Coding standards
|
62
|
+
|
63
|
+
All pull requests must meet these requirements:
|
64
|
+
|
65
|
+
### 1 PR = 1 Commit
|
66
|
+
|
67
|
+
- All commits for a PR must be squashed into one commit
|
68
|
+
- To avoid an extra merge commit, the PR must be able to be merged as [a fast forward merge](https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging)
|
69
|
+
- The easiest way to ensure a fast forward merge is to rebase your local branch
|
70
|
+
to the track_open_instances main branch
|
71
|
+
|
72
|
+
### Unit tests
|
73
|
+
|
74
|
+
- All changes must be accompanied by new or modified RSpec unit tests
|
75
|
+
- The entire test suite must pass when `bundle exec rake spec` is run from the
|
76
|
+
project's local working tree
|
77
|
+
- The unit test suite must maintain 100% code coverage to pass
|
78
|
+
|
79
|
+
### Documentation
|
80
|
+
|
81
|
+
- New and updated public methods must have [YARD](https://yardoc.org/)
|
82
|
+
documentation added to them
|
83
|
+
- [The YARD Cheatsheet](https://gist.github.com/thelastinuit/5984665e6ab69d3c0a413a03602c45be)
|
84
|
+
is a good reference
|
85
|
+
- New and updated public facing features should be documented in the project's
|
86
|
+
[README.md](README.md)
|
87
|
+
- All documentation must pass `yardstick` documentation analysis
|
88
|
+
- The documentation suite must maintain 100% documentation to pass
|
89
|
+
|
90
|
+
### Continuous Integration
|
91
|
+
|
92
|
+
- All tests must pass in the project's [Travis CI](https://travis-ci.org/main-branch/track_open_instances)
|
93
|
+
build before the pull request will be merged.
|
94
|
+
- You can simulate what happens in the Travis CI build by running `bundle exec rake` in
|
95
|
+
the projects root directory.
|
96
|
+
|
97
|
+
### Other Design Guidelines
|
98
|
+
|
99
|
+
- Use keyword args with defaults instead of an opts hash
|
100
|
+
|
101
|
+
## Licensing
|
102
|
+
|
103
|
+
track_open_instances uses [the MIT license](https://choosealicense.com/licenses/mit/) as
|
104
|
+
declared in the [LICENSE](LICENSE) file.
|
105
|
+
|
106
|
+
Licensing is very important to open source projects. It helps ensure the
|
107
|
+
software continues to be available under the terms that the author desired.
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2025 James Couball
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
# track_open_instances gem
|
2
|
+
|
3
|
+
[](https://badge.fury.io/rb/track_open_instances)
|
4
|
+
[](https://github.com/main-branch/track_open_instances/actions/workflows/continuous_integration.yml)
|
5
|
+
[](https://rubydoc.info/gems/track_open_instances/)
|
6
|
+
[](https://rubydoc.info/gems/track_open_instances/file/CHANGELOG.md)
|
7
|
+
[](https://qlty.sh/gh/main-branch/projects/track_open_instances)
|
8
|
+
[](https://qlty.sh/gh/main-branch/projects/track_open_instances)
|
9
|
+
[](https://main-branch.slack.com/archives/C01CHR7TMM2)
|
10
|
+
|
11
|
+
`TrackOpenInstances` is a Ruby mixin designed to help manage resources that require
|
12
|
+
explicit cleanup. It provides a simple mechanism to track instances of a
|
13
|
+
class from creation until they are explicitly closed or disposed of.
|
14
|
+
|
15
|
+
By including this module in classes that manage resources like files, network
|
16
|
+
connections, or temporary objects, you can easily monitor if any instances are left
|
17
|
+
open, potentially causing resource leaks. The module keeps an internal list
|
18
|
+
of all active instances and provides methods to check the count of open instances and
|
19
|
+
assert that no instances remain unclosed, which is particularly useful in test
|
20
|
+
suites. It also stores the call stack at the time of instance creation
|
21
|
+
to aid debugging.
|
22
|
+
|
23
|
+
## Installation
|
24
|
+
|
25
|
+
Add this line to your application's Gemfile:
|
26
|
+
|
27
|
+
```Ruby
|
28
|
+
gem 'track_open_instances'
|
29
|
+
```
|
30
|
+
|
31
|
+
And then execute:
|
32
|
+
|
33
|
+
```Ruby
|
34
|
+
bundle install
|
35
|
+
```
|
36
|
+
|
37
|
+
Or install it directly from the command line:
|
38
|
+
|
39
|
+
```Ruby
|
40
|
+
gem install track_open_instances
|
41
|
+
```
|
42
|
+
|
43
|
+
## Usage
|
44
|
+
|
45
|
+
Include the `TrackOpenInstances` module in any class where you need to track
|
46
|
+
instances that require explicit cleanup.
|
47
|
+
|
48
|
+
Call `add_open_instance` when an instance is created. This is typically done in
|
49
|
+
`initialize`.
|
50
|
+
|
51
|
+
Call `remove_open_instance` when it's cleaned up. This is typically done in a `close`
|
52
|
+
method.
|
53
|
+
|
54
|
+
```Ruby
|
55
|
+
require 'track_open_instances'
|
56
|
+
|
57
|
+
# Example class managing a resource
|
58
|
+
class ManagedResource
|
59
|
+
include TrackOpenInstances
|
60
|
+
|
61
|
+
attr_reader :id
|
62
|
+
|
63
|
+
def initialize(id)
|
64
|
+
@id = id
|
65
|
+
puts "Opening resource: #{id}"
|
66
|
+
# Register instance for tracking
|
67
|
+
self.class.add_open_instance(self) #
|
68
|
+
end
|
69
|
+
|
70
|
+
def close
|
71
|
+
puts "Closing resource: #{id}"
|
72
|
+
# Remove instance from tracking
|
73
|
+
self.class.remove_open_instance(self) #
|
74
|
+
end
|
75
|
+
end
|
76
|
+
```
|
77
|
+
|
78
|
+
With that integration, you will be able to keep track of all open instances.
|
79
|
+
|
80
|
+
```Ruby
|
81
|
+
# --- Basic Usage ---
|
82
|
+
|
83
|
+
res1 = ManagedResource.new('A')
|
84
|
+
res2 = ManagedResource.new('B')
|
85
|
+
|
86
|
+
puts "Open count: #{ManagedResource.open_instance_count}" #=> 2
|
87
|
+
|
88
|
+
res1.close #
|
89
|
+
|
90
|
+
puts "Open count: #{ManagedResource.open_instance_count}" #=> 1
|
91
|
+
|
92
|
+
# --- Checking for Leaks (e.g., in tests) ---
|
93
|
+
|
94
|
+
# Get a report of open instances
|
95
|
+
report = ManagedResource.open_instances_report
|
96
|
+
puts report if report #=>
|
97
|
+
# There is 1 open ManagedResource instance:
|
98
|
+
# - object_id=...
|
99
|
+
# Call stack when created:
|
100
|
+
# ... (caller stack lines) ...
|
101
|
+
|
102
|
+
# Assert no instances are open (raises RuntimeError if any are found)
|
103
|
+
begin
|
104
|
+
ManagedResource.assert_no_open_instances #
|
105
|
+
rescue RuntimeError => e
|
106
|
+
puts "Assertion failed: #{e.message}"
|
107
|
+
end
|
108
|
+
# Output: Assertion failed: There is 1 open ManagedResource instance:...
|
109
|
+
|
110
|
+
res2.close
|
111
|
+
|
112
|
+
# This assertion will now pass
|
113
|
+
ManagedResource.assert_no_open_instances #
|
114
|
+
puts "All resources closed successfully."
|
115
|
+
# Output: All resources closed successfully.
|
116
|
+
```
|
117
|
+
|
118
|
+
## Development
|
119
|
+
|
120
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
121
|
+
`bundle exec rake` to run tests, static analysis, and build the gem.
|
122
|
+
|
123
|
+
For experimentation, you can also run `bin/console` for an interactive (IRB) prompt that
|
124
|
+
automatically requires track_open_instances.
|
125
|
+
|
126
|
+
## Contributing
|
127
|
+
|
128
|
+
Bug reports and pull requests are welcome on GitHub at <https://github.com/main-branch/track_open_instances>.
|
129
|
+
|
130
|
+
### Commit message guidelines
|
131
|
+
|
132
|
+
All commit messages must follow the [Conventional Commits
|
133
|
+
standard](https://www.conventionalcommits.org/en/v1.0.0/). This helps us maintain a
|
134
|
+
clear and structured commit history, automate versioning, and generate changelogs
|
135
|
+
effectively.
|
136
|
+
|
137
|
+
To ensure compliance, this project includes:
|
138
|
+
|
139
|
+
- A git commit-msg hook that validates your commit messages before they are accepted.
|
140
|
+
|
141
|
+
To activate the hook, you must have node installed and run `npm install`.
|
142
|
+
|
143
|
+
- A GitHub Actions workflow that will enforce the Conventional Commit standard as
|
144
|
+
part of the continuous integration pipeline.
|
145
|
+
|
146
|
+
Any commit message that does not conform to the Conventional Commits standard will
|
147
|
+
cause the workflow to fail and not allow the PR to be merged.
|
148
|
+
|
149
|
+
### Pull request guidelines
|
150
|
+
|
151
|
+
All pull requests must be merged using rebase merges. This ensures that commit
|
152
|
+
messages from the feature branch are preserved in the release branch, keeping the
|
153
|
+
history clean and meaningful.
|
data/RELEASING.md
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
# How to release a new track_open_instances gem
|
2
|
+
|
3
|
+
Run `create-github-release <release-type>` in the root of a clean working tree.
|
4
|
+
|
5
|
+
Where `release-type` is `major`, `minor`, or `patch` depending on the nature of the
|
6
|
+
changes. Refer to the labels on each PR since the last release to determine which
|
7
|
+
semver release type to specify.
|
8
|
+
|
9
|
+
Follow the directions that `create-github-release` after it prepares the release PR.
|
data/Rakefile
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
desc 'Run the same tasks that the CI build will run'
|
4
|
+
if RUBY_PLATFORM == 'java'
|
5
|
+
task default: %w[spec rubocop bundle:audit build]
|
6
|
+
else
|
7
|
+
task default: %w[spec rubocop yard bundle:audit build]
|
8
|
+
end
|
9
|
+
|
10
|
+
# Bundler Audit
|
11
|
+
|
12
|
+
require 'bundler/audit/task'
|
13
|
+
Bundler::Audit::Task.new
|
14
|
+
|
15
|
+
# Bundler Gem Build
|
16
|
+
|
17
|
+
require 'bundler'
|
18
|
+
require 'bundler/gem_tasks'
|
19
|
+
|
20
|
+
# RSpec
|
21
|
+
|
22
|
+
require 'rspec/core/rake_task'
|
23
|
+
|
24
|
+
RSpec::Core::RakeTask.new
|
25
|
+
|
26
|
+
CLEAN << 'coverage'
|
27
|
+
CLEAN << '.rspec_status'
|
28
|
+
CLEAN << 'rspec-report.xml'
|
29
|
+
|
30
|
+
# Rubocop
|
31
|
+
|
32
|
+
require 'rubocop/rake_task'
|
33
|
+
|
34
|
+
RuboCop::RakeTask.new
|
35
|
+
|
36
|
+
# YARD
|
37
|
+
|
38
|
+
unless RUBY_PLATFORM == 'java'
|
39
|
+
# yard:build
|
40
|
+
|
41
|
+
require 'yard'
|
42
|
+
|
43
|
+
YARD::Rake::YardocTask.new('yard:build') do |t|
|
44
|
+
t.files = %w[lib/**/*.rb examples/**/*]
|
45
|
+
t.options = %w[--no-private]
|
46
|
+
t.stats_options = %w[--list-undoc]
|
47
|
+
end
|
48
|
+
|
49
|
+
CLEAN << '.yardoc'
|
50
|
+
CLEAN << 'doc'
|
51
|
+
|
52
|
+
# yard:audit
|
53
|
+
|
54
|
+
desc 'Run yardstick to show missing YARD doc elements'
|
55
|
+
task :'yard:audit' do
|
56
|
+
sh "yardstick 'lib/**/*.rb'"
|
57
|
+
end
|
58
|
+
|
59
|
+
# yard:coverage
|
60
|
+
|
61
|
+
require 'yardstick/rake/verify'
|
62
|
+
|
63
|
+
Yardstick::Rake::Verify.new(:'yard:coverage') do |verify|
|
64
|
+
verify.threshold = 100
|
65
|
+
end
|
66
|
+
|
67
|
+
# yard
|
68
|
+
|
69
|
+
desc 'Run all YARD tasks'
|
70
|
+
task yard: %i[yard:build yard:audit yard:coverage]
|
71
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module.exports = {
|
2
|
+
extends: ["@commitlint/config-conventional"],
|
3
|
+
rules: {
|
4
|
+
"body-leading-blank": [1, "always"],
|
5
|
+
"body-max-line-length": [2, "always", 100],
|
6
|
+
"footer-leading-blank": [1, "always"],
|
7
|
+
"header-max-length": [2, "always", 100],
|
8
|
+
"subject-empty": [2, "never"],
|
9
|
+
"subject-full-stop": [2, "never", "."],
|
10
|
+
"type-case": [2, "always", "lower-case"],
|
11
|
+
"type-empty": [2, "never"],
|
12
|
+
"type-enum": [
|
13
|
+
2,
|
14
|
+
"always",
|
15
|
+
[
|
16
|
+
"build",
|
17
|
+
"chore",
|
18
|
+
"ci",
|
19
|
+
"docs",
|
20
|
+
"feat",
|
21
|
+
"fix",
|
22
|
+
"perf",
|
23
|
+
"refactor",
|
24
|
+
"revert",
|
25
|
+
"style",
|
26
|
+
"test",
|
27
|
+
],
|
28
|
+
],
|
29
|
+
},
|
30
|
+
};
|
@@ -0,0 +1,249 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'track_open_instances/version'
|
4
|
+
|
5
|
+
# Mixin to track instances of a class that require explicit cleanup
|
6
|
+
#
|
7
|
+
# This module provides a mechanism to track instances of classes that need
|
8
|
+
# to be explicitly closed or cleaned up. It maintains a list of all instances
|
9
|
+
# created and allows checking for any unclosed instances, which can help in
|
10
|
+
# identifying resource leaks.
|
11
|
+
#
|
12
|
+
# @example Basic Usage
|
13
|
+
# class ManagedFile
|
14
|
+
# include TrackOpenInstances
|
15
|
+
#
|
16
|
+
# attr_reader :path
|
17
|
+
#
|
18
|
+
# def initialize(path)
|
19
|
+
# @path = path
|
20
|
+
# # Simulate opening the file
|
21
|
+
# puts "Opening file: #{path}"
|
22
|
+
# # Register the instance for tracking
|
23
|
+
# self.class.add_instance(self)
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# # Implement the close logic specific to the resource
|
27
|
+
# def close
|
28
|
+
# # Simulate closing the file
|
29
|
+
# puts "Closing file: #{path}"
|
30
|
+
# # Remove the instance from tracking
|
31
|
+
# self.class.remove_instance(self)
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# file1 = ManagedFile.new('/tmp/file1.txt')
|
36
|
+
# file2 = ManagedFile.new('/tmp/file2.txt')
|
37
|
+
#
|
38
|
+
# puts ManagedFile.unclosed_instances.count #=> 2
|
39
|
+
# puts ManagedFile.unclosed_instances.inspect #=> [#<ManagedFile:...>, #<ManagedFile:...>]
|
40
|
+
#
|
41
|
+
# file1.close
|
42
|
+
#
|
43
|
+
# puts ManagedFile.unclosed_instances.count #=> 1
|
44
|
+
# puts ManagedFile.unclosed_instances.inspect #=> [#<ManagedFile:...>]
|
45
|
+
#
|
46
|
+
# # In a test suite's teardown, you might use:
|
47
|
+
# # ManagedFile.assert_no_open_instances # This would raise if file2 wasn't closed
|
48
|
+
#
|
49
|
+
# file2.close
|
50
|
+
# ManagedFile.assert_no_open_instances # This will now pass
|
51
|
+
#
|
52
|
+
# @api public
|
53
|
+
module TrackOpenInstances
|
54
|
+
# Represents an open instance of a class that includes TrackOpenInstances
|
55
|
+
#
|
56
|
+
# @attr_reader [Object] instance The tracked instance
|
57
|
+
# @attr_reader [Array<String>] creation_stack The call stack at the time of instance creation
|
58
|
+
#
|
59
|
+
# This is useful for debugging and identifying where the instance was created.
|
60
|
+
#
|
61
|
+
# @api private
|
62
|
+
class OpenInstance
|
63
|
+
attr_reader :instance, :creation_stack
|
64
|
+
|
65
|
+
# Initializes a new OpenInstance
|
66
|
+
#
|
67
|
+
# @param instance [Object] The tracked instance
|
68
|
+
# @param creation_stack [Array<String>] The call stack at the time of instance creation
|
69
|
+
#
|
70
|
+
# @return [void]
|
71
|
+
#
|
72
|
+
# @api private
|
73
|
+
#
|
74
|
+
def initialize(instance, creation_stack)
|
75
|
+
@instance = instance
|
76
|
+
@creation_stack = creation_stack
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Ruby hook executed when this module is included in a base class
|
81
|
+
#
|
82
|
+
# Sets up the necessary class instance variables and extends the base
|
83
|
+
# class with ClassMethods.
|
84
|
+
#
|
85
|
+
# @param base [Class] The class including this module
|
86
|
+
#
|
87
|
+
# @return [void]
|
88
|
+
#
|
89
|
+
# @api private
|
90
|
+
def self.included(base)
|
91
|
+
base.extend(ClassMethods)
|
92
|
+
# @!attribute [rw] open_instances
|
93
|
+
# Internal storage for all tracked instances
|
94
|
+
# @return [Hash{Integer => OpenInstance}] The list of currently tracked instances
|
95
|
+
base.instance_variable_set(:@open_instances, {}.compare_by_identity)
|
96
|
+
# @!visibility private
|
97
|
+
# @!attribute [r] open_instances_mutex
|
98
|
+
# Mutex to ensure thread-safe access to the open_instances list
|
99
|
+
base.instance_variable_set(:@open_instances_mutex, Thread::Mutex.new)
|
100
|
+
end
|
101
|
+
|
102
|
+
# Contains class-level methods added to classes including TrackOpenInstances
|
103
|
+
module ClassMethods
|
104
|
+
# @!attribute [r] open_instances
|
105
|
+
#
|
106
|
+
# Direct access to the internal list of tracked instances
|
107
|
+
#
|
108
|
+
# Note: This returns all instances ever tracked unless explicitly removed.
|
109
|
+
# Use `unclosed_instances` for checking leaks. Direct use is uncommon.
|
110
|
+
#
|
111
|
+
# @example
|
112
|
+
# # Assuming MyResource includes TrackOpenInstances
|
113
|
+
# res1 = MyResource.new
|
114
|
+
# res2 = MyResource.new
|
115
|
+
# res1.close
|
116
|
+
# MyResource.open_instances #=> [#<MyResource... object_id=res2>] (after res1 removed)
|
117
|
+
#
|
118
|
+
# @return [Array<Object>] The raw list of currently tracked instances
|
119
|
+
#
|
120
|
+
# @api private
|
121
|
+
def open_instances
|
122
|
+
@open_instances_mutex.synchronize do
|
123
|
+
@open_instances.dup.freeze
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# Adds an instance to the tracking list (thread-safe)
|
128
|
+
#
|
129
|
+
# Typically called automatically by the instance's `initialize` method.
|
130
|
+
#
|
131
|
+
# @param instance [Object] The instance to add
|
132
|
+
#
|
133
|
+
# @return [void]
|
134
|
+
#
|
135
|
+
# @api private
|
136
|
+
def add_open_instance(instance)
|
137
|
+
@open_instances_mutex.synchronize do
|
138
|
+
@open_instances[instance] = OpenInstance.new(instance, caller(3..))
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# Removes an instance from the tracking list (thread-safe)
|
143
|
+
#
|
144
|
+
# Typically called automatically by the instance's `close` method.
|
145
|
+
#
|
146
|
+
# @param instance [Object] The instance to remove
|
147
|
+
#
|
148
|
+
# @return [void]
|
149
|
+
#
|
150
|
+
# @api private
|
151
|
+
def remove_open_instance(instance)
|
152
|
+
@open_instances_mutex.synchronize do
|
153
|
+
@open_instances.delete(instance)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
# The number of currently open instances
|
158
|
+
#
|
159
|
+
# @example
|
160
|
+
# res1 = MyResource.new
|
161
|
+
# res2 = MyResource.new
|
162
|
+
# MyResource.open_instance_count #=> 1
|
163
|
+
#
|
164
|
+
# @return [Integer]
|
165
|
+
#
|
166
|
+
# @api public
|
167
|
+
#
|
168
|
+
def open_instance_count
|
169
|
+
@open_instances_mutex.synchronize do
|
170
|
+
@open_instances.size
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
# Generates a report string listing unclosed instances and their creation stacks
|
175
|
+
#
|
176
|
+
# Useful for debugging resource leaks. Returns nil if no instances are unclosed.
|
177
|
+
#
|
178
|
+
# @example
|
179
|
+
# res = MyResource.new
|
180
|
+
# puts MyResource.open_instances_report
|
181
|
+
# There is 1 open MyResource instance(s):
|
182
|
+
# - object_id=701
|
183
|
+
# Created at:
|
184
|
+
# (caller stack line 1)
|
185
|
+
# (caller stack line 2)\n..."
|
186
|
+
#
|
187
|
+
# @return [String, nil] A formatted report string or nil if none are open
|
188
|
+
#
|
189
|
+
# @api public
|
190
|
+
def open_instances_report
|
191
|
+
@open_instances_mutex.synchronize do
|
192
|
+
return nil if @open_instances.count.zero?
|
193
|
+
|
194
|
+
String.new.tap do |report|
|
195
|
+
report << open_instances_report_header
|
196
|
+
report << open_instances_report_body
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
# The header string for the report
|
202
|
+
#
|
203
|
+
# @return [String]
|
204
|
+
#
|
205
|
+
# @api private
|
206
|
+
#
|
207
|
+
def open_instances_report_header
|
208
|
+
count = @open_instances.count
|
209
|
+
|
210
|
+
"There #{count == 1 ? 'is' : 'are'} #{count} " \
|
211
|
+
"open #{self.class} instance#{count == 1 ? '' : 's'}:\n"
|
212
|
+
end
|
213
|
+
|
214
|
+
# The body of the report detailing each open instance
|
215
|
+
#
|
216
|
+
# @return [String]
|
217
|
+
#
|
218
|
+
# @api private
|
219
|
+
#
|
220
|
+
def open_instances_report_body
|
221
|
+
String.new.tap do |body|
|
222
|
+
@open_instances.each do |instance, open_instance|
|
223
|
+
body << " - object_id=#{instance.object_id}\n"
|
224
|
+
body << " Call stack when created:\n"
|
225
|
+
open_instance.creation_stack.reverse.each { |line| body << " #{line}\n" }
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
# Asserts that no instances of the class remain unclosed
|
231
|
+
#
|
232
|
+
# Raises a ProcessExecuter::Error with a detailed report if any instances
|
233
|
+
# are found to be unclosed. Commonly used in test suite teardown blocks.
|
234
|
+
#
|
235
|
+
# @example
|
236
|
+
# # In RSpec teardown (e.g., after(:each))
|
237
|
+
# MyResource.assert_no_open_instances
|
238
|
+
#
|
239
|
+
# @raise [RuntimeError] If any instances are found unclosed
|
240
|
+
#
|
241
|
+
# @return [void]
|
242
|
+
#
|
243
|
+
# @api public
|
244
|
+
def assert_no_open_instances
|
245
|
+
report = open_instances_report
|
246
|
+
raise(report.to_s) if report
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
data/package.json
ADDED
data/pre-commit
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
##
|
4
|
+
# Run this before doing a commit. To ensure this happens, after cloning this
|
5
|
+
# repository, run bin/setup from the projects root directory
|
6
|
+
|
7
|
+
echo 'Performing pre-commit checks'
|
8
|
+
|
9
|
+
# Make sure we are testing with the latest version of gems
|
10
|
+
# since this is what will get installed in the CI build
|
11
|
+
#
|
12
|
+
echo "Running 'bundle update'..."
|
13
|
+
if ! bundle update > /dev/null; then
|
14
|
+
echo 'FAIL: bundle update failed'
|
15
|
+
exit 1
|
16
|
+
fi
|
17
|
+
|
18
|
+
# Run all the tests, code/doc analysis, gem build, etc.
|
19
|
+
#
|
20
|
+
echo "Running 'bundle exec rake default'..."
|
21
|
+
if ! bundle exec rake default > /dev/null 2>&1; then
|
22
|
+
echo 'FAIL: Rake default task failed'
|
23
|
+
exit 1
|
24
|
+
fi
|
25
|
+
|
26
|
+
echo 'SUCCESS'
|
metadata
ADDED
@@ -0,0 +1,243 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: track_open_instances
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- James Couball
|
8
|
+
bindir: exe
|
9
|
+
cert_chain: []
|
10
|
+
date: 2025-04-08 00:00:00.000000000 Z
|
11
|
+
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: bundler-audit
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - "~>"
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '0.9'
|
19
|
+
type: :development
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - "~>"
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '0.9'
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: create_github_release
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - "~>"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '2.1'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '2.1'
|
40
|
+
- !ruby/object:Gem::Dependency
|
41
|
+
name: main_branch_shared_rubocop_config
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0.1'
|
47
|
+
type: :development
|
48
|
+
prerelease: false
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0.1'
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: rake
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '13.2'
|
61
|
+
type: :development
|
62
|
+
prerelease: false
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '13.2'
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: rspec
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '3.13'
|
75
|
+
type: :development
|
76
|
+
prerelease: false
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '3.13'
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: rubocop
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '1.75'
|
89
|
+
type: :development
|
90
|
+
prerelease: false
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - "~>"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '1.75'
|
96
|
+
- !ruby/object:Gem::Dependency
|
97
|
+
name: simplecov
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - "~>"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0.22'
|
103
|
+
type: :development
|
104
|
+
prerelease: false
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0.22'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: simplecov-json
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - "~>"
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0.2'
|
117
|
+
type: :development
|
118
|
+
prerelease: false
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - "~>"
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0.2'
|
124
|
+
- !ruby/object:Gem::Dependency
|
125
|
+
name: simplecov-rspec
|
126
|
+
requirement: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - "~>"
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0.4'
|
131
|
+
type: :development
|
132
|
+
prerelease: false
|
133
|
+
version_requirements: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - "~>"
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0.4'
|
138
|
+
- !ruby/object:Gem::Dependency
|
139
|
+
name: redcarpet
|
140
|
+
requirement: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - "~>"
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '3.6'
|
145
|
+
type: :development
|
146
|
+
prerelease: false
|
147
|
+
version_requirements: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - "~>"
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '3.6'
|
152
|
+
- !ruby/object:Gem::Dependency
|
153
|
+
name: yard
|
154
|
+
requirement: !ruby/object:Gem::Requirement
|
155
|
+
requirements:
|
156
|
+
- - "~>"
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: '0.9'
|
159
|
+
- - ">="
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: 0.9.28
|
162
|
+
type: :development
|
163
|
+
prerelease: false
|
164
|
+
version_requirements: !ruby/object:Gem::Requirement
|
165
|
+
requirements:
|
166
|
+
- - "~>"
|
167
|
+
- !ruby/object:Gem::Version
|
168
|
+
version: '0.9'
|
169
|
+
- - ">="
|
170
|
+
- !ruby/object:Gem::Version
|
171
|
+
version: 0.9.28
|
172
|
+
- !ruby/object:Gem::Dependency
|
173
|
+
name: yardstick
|
174
|
+
requirement: !ruby/object:Gem::Requirement
|
175
|
+
requirements:
|
176
|
+
- - "~>"
|
177
|
+
- !ruby/object:Gem::Version
|
178
|
+
version: '0.9'
|
179
|
+
type: :development
|
180
|
+
prerelease: false
|
181
|
+
version_requirements: !ruby/object:Gem::Requirement
|
182
|
+
requirements:
|
183
|
+
- - "~>"
|
184
|
+
- !ruby/object:Gem::Version
|
185
|
+
version: '0.9'
|
186
|
+
description: |
|
187
|
+
A mixin to track instances of Ruby classes that require explicit cleanup,
|
188
|
+
helping to identify potential resource leaks. It maintains a list of
|
189
|
+
created instances and allows checking for any that remain unclosed.
|
190
|
+
email:
|
191
|
+
- jcouball@yahoo.com
|
192
|
+
executables: []
|
193
|
+
extensions: []
|
194
|
+
extra_rdoc_files: []
|
195
|
+
files:
|
196
|
+
- ".husky/commit-msg"
|
197
|
+
- ".markdownlint.yml"
|
198
|
+
- ".qlty/qlty.toml"
|
199
|
+
- ".rspec"
|
200
|
+
- ".rubocop.yml"
|
201
|
+
- ".yamllint.yml"
|
202
|
+
- ".yardopts"
|
203
|
+
- CHANGELOG.md
|
204
|
+
- CONTRIBUTING.md
|
205
|
+
- LICENSE.txt
|
206
|
+
- README.md
|
207
|
+
- RELEASING.md
|
208
|
+
- Rakefile
|
209
|
+
- commitlint.config.js
|
210
|
+
- lib/track_open_instances.rb
|
211
|
+
- lib/track_open_instances/version.rb
|
212
|
+
- package.json
|
213
|
+
- pre-commit
|
214
|
+
homepage: https://github.com/main-branch/track_open_instances
|
215
|
+
licenses:
|
216
|
+
- MIT
|
217
|
+
metadata:
|
218
|
+
allowed_push_host: https://rubygems.org
|
219
|
+
homepage_uri: https://github.com/main-branch/track_open_instances
|
220
|
+
source_code_uri: https://github.com/main-branch/track_open_instances
|
221
|
+
documentation_uri: https://rubydoc.info/gems/track_open_instances/0.1.0
|
222
|
+
changelog_uri: https://rubydoc.info/gems/track_open_instances/0.1.0/file/CHANGELOG.md
|
223
|
+
rubygems_mfa_required: 'true'
|
224
|
+
rdoc_options: []
|
225
|
+
require_paths:
|
226
|
+
- lib
|
227
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
228
|
+
requirements:
|
229
|
+
- - ">="
|
230
|
+
- !ruby/object:Gem::Version
|
231
|
+
version: 3.1.0
|
232
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
233
|
+
requirements:
|
234
|
+
- - ">="
|
235
|
+
- !ruby/object:Gem::Version
|
236
|
+
version: '0'
|
237
|
+
requirements:
|
238
|
+
- 'Platform: Mac, Linux, or Windows'
|
239
|
+
- 'Ruby: MRI 3.1 or later, TruffleRuby 24 or later, or JRuby 9.4 or later'
|
240
|
+
rubygems_version: 3.6.2
|
241
|
+
specification_version: 4
|
242
|
+
summary: A mixin to ensure that all instances of a class are closed
|
243
|
+
test_files: []
|