gem-digest 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 59ea827e8f6823c9eb9b56aad62ac5216b5153bd86c540c6639a95ac490572f8
4
+ data.tar.gz: c20cb62a7397459d636ef26306cb5261d9b7a9bdd6ddb2f564d2f1d73f6bcf39
5
+ SHA512:
6
+ metadata.gz: 55e07ba173fab062e7a3416db93caa2259baa1b3a51146d310266d94b92d1c9cdee9d74f8ae9f4c9306741a40f02ca00fd3d73374ea4fb6c18f6159075e62d56
7
+ data.tar.gz: 4d42813be1e897c0393756886a10352b35961e5ef7c94bf71201b51e538bf1c55708f5957e1f7c947bc77797ce8a40ce131be81b3d20587810719ebfbd4fae05
data/DEVELOPMENT.md ADDED
@@ -0,0 +1,241 @@
1
+ # ๐Ÿ› ๏ธ Development Guide
2
+
3
+ This document provides detailed information for developers working on gem-digest.
4
+
5
+ ## ๐Ÿ—๏ธ Project Structure
6
+
7
+ ```
8
+ gem-digest/
9
+ โ”œโ”€โ”€ .github/workflows/release.yml # CI/CD pipeline
10
+ โ”œโ”€โ”€ bin/console # Interactive console
11
+ โ”œโ”€โ”€ exe/gemd # Main executable
12
+ โ”œโ”€โ”€ lib/
13
+ โ”‚ โ”œโ”€โ”€ gem_digest.rb # Main module
14
+ โ”‚ โ””โ”€โ”€ gem_digest/
15
+ โ”‚ โ”œโ”€โ”€ analyzer.rb # Gemfile.lock parser
16
+ โ”‚ โ”œโ”€โ”€ categorizer.rb # Version categorization
17
+ โ”‚ โ”œโ”€โ”€ changelog_fetcher.rb # Changelog integration
18
+ โ”‚ โ”œโ”€โ”€ cli.rb # Command-line interface
19
+ โ”‚ โ”œโ”€โ”€ reporters/ # Output formatters
20
+ โ”‚ โ”‚ โ”œโ”€โ”€ base.rb
21
+ โ”‚ โ”‚ โ”œโ”€โ”€ console.rb
22
+ โ”‚ โ”‚ โ””โ”€โ”€ markdown.rb
23
+ โ”‚ โ””โ”€โ”€ version.rb # Version constant
24
+ โ”œโ”€โ”€ spec/ # Test suite
25
+ โ”œโ”€โ”€ output/ # Generated reports
26
+ โ””โ”€โ”€ config/ # Configuration files
27
+ ```
28
+
29
+ ## ๐Ÿงช Testing
30
+
31
+ ### Running Tests
32
+
33
+ ```bash
34
+ # Install dependencies
35
+ bundle install
36
+
37
+ # Run all tests
38
+ bundle exec rspec
39
+
40
+ # Run specific test files
41
+ bundle exec rspec spec/gem_digest/analyzer_spec.rb
42
+ bundle exec rspec spec/integration_spec.rb
43
+
44
+ # Run with coverage
45
+ bundle exec rspec --format documentation
46
+ ```
47
+
48
+ ### Test Structure
49
+
50
+ - **Unit Tests**: Test individual classes and methods
51
+ - **Integration Tests**: Test the complete workflow
52
+ - **Mock Network Calls**: Avoid hitting RubyGems API during tests
53
+
54
+ ### Adding New Tests
55
+
56
+ 1. Create test files in `spec/gem_digest/`
57
+ 2. Follow the naming convention: `*_spec.rb`
58
+ 3. Use RSpec best practices
59
+ 4. Mock external dependencies
60
+
61
+ ## ๐Ÿ”ง Development Workflow
62
+
63
+ ### Local Development
64
+
65
+ ```bash
66
+ # Clone the repository
67
+ git clone https://github.com/ND-Zyth/gem-digest.git
68
+ cd gem-digest
69
+
70
+ # Install dependencies
71
+ bundle install
72
+
73
+ # Run the tool locally
74
+ bundle exec ruby -Ilib exe/gemd analyze
75
+
76
+ # Or use the simple CLI for testing
77
+ ruby simple_cli.rb test_Gemfile.lock
78
+ ```
79
+
80
+ ### Code Quality
81
+
82
+ ```bash
83
+ # Run RuboCop for style checking
84
+ bundle exec rubocop
85
+
86
+ # Auto-fix issues
87
+ bundle exec rubocop -a
88
+
89
+ # Check specific files
90
+ bundle exec rubocop lib/gem_digest/analyzer.rb
91
+ ```
92
+
93
+ ### Building and Testing the Gem
94
+
95
+ ```bash
96
+ # Build the gem
97
+ gem build gem-digest.gemspec
98
+
99
+ # Install locally for testing
100
+ gem install gem-digest-*.gem
101
+
102
+ # Test the installed gem
103
+ gemd analyze
104
+ ```
105
+
106
+ ## ๐Ÿ“ฆ Release Process
107
+
108
+ ### Version Management
109
+
110
+ 1. Update version in `lib/gem_digest/version.rb`
111
+ 2. Update `CHANGELOG.md` with new features/fixes
112
+ 3. Commit changes: `git commit -m "Bump version to X.Y.Z"`
113
+ 4. Create and push tag: `git tag vX.Y.Z && git push origin vX.Y.Z`
114
+
115
+ ### Automated Release
116
+
117
+ The GitHub Actions workflow automatically:
118
+ 1. Runs tests on multiple Ruby versions and platforms
119
+ 2. Builds gems for each platform
120
+ 3. Creates a GitHub release with attached gem files
121
+ 4. Publishes to RubyGems (requires `RUBYGEMS_API_KEY` secret)
122
+
123
+ ## ๐Ÿ›๏ธ Architecture
124
+
125
+ ### Core Components
126
+
127
+ 1. **Analyzer**: Parses `Gemfile.lock` using Bundler and fetches latest versions from RubyGems API
128
+ 2. **Categorizer**: Compares versions using semantic versioning rules
129
+ 3. **Reporters**: Generate output in different formats (console, markdown)
130
+ 4. **CLI**: Provides user-friendly command-line interface
131
+
132
+ ### Data Flow
133
+
134
+ ```
135
+ Gemfile.lock โ†’ Analyzer โ†’ Categorizer โ†’ Reporter โ†’ Output
136
+ ```
137
+
138
+ ### API Design
139
+
140
+ The gem provides both CLI and programmatic interfaces:
141
+
142
+ ```ruby
143
+ # Programmatic usage
144
+ GemDigest.analyze("path/to/Gemfile.lock", format: "console")
145
+
146
+ # Individual components
147
+ analyzer = GemDigest::Analyzer.new("Gemfile.lock")
148
+ gems_data = analyzer.analyze
149
+
150
+ categorizer = GemDigest::Categorizer.new
151
+ categorized = categorizer.categorize(gems_data)
152
+
153
+ reporter = GemDigest::Reporters::Console.new
154
+ reporter.generate_report(categorized)
155
+ ```
156
+
157
+ ## ๐Ÿ”Œ Adding New Features
158
+
159
+ ### New Output Format
160
+
161
+ 1. Create new reporter class in `lib/gem_digest/reporters/`
162
+ 2. Inherit from `GemDigest::Reporters::Base`
163
+ 3. Implement `generate_report` method
164
+ 4. Add format option to CLI and main module
165
+
166
+ ### New Analysis Features
167
+
168
+ 1. Extend `Analyzer` class with new methods
169
+ 2. Update `Categorizer` if new categorization is needed
170
+ 3. Add corresponding tests
171
+ 4. Update documentation
172
+
173
+ ### Configuration Support
174
+
175
+ 1. Add configuration file parsing
176
+ 2. Extend CLI options
177
+ 3. Update reporters to use configuration
178
+ 4. Add configuration validation
179
+
180
+ ## ๐Ÿ› Debugging
181
+
182
+ ### Common Issues
183
+
184
+ 1. **Network Timeouts**: RubyGems API calls may timeout
185
+ - Solution: Add retry logic and better error handling
186
+
187
+ 2. **Version Parsing**: Complex version strings may not parse correctly
188
+ - Solution: Improve version parsing in `Categorizer`
189
+
190
+ 3. **Large Gemfiles**: Performance issues with many gems
191
+ - Solution: Add parallel processing or caching
192
+
193
+ ### Debug Mode
194
+
195
+ Enable verbose output for debugging:
196
+
197
+ ```bash
198
+ gemd analyze --verbose
199
+ ```
200
+
201
+ ### Logging
202
+
203
+ Add debug logging to track execution:
204
+
205
+ ```ruby
206
+ puts "Debug: Processing gem #{gem_name}" if options[:verbose]
207
+ ```
208
+
209
+ ## ๐Ÿ“š Dependencies
210
+
211
+ ### Runtime Dependencies
212
+
213
+ - `bundler ~> 2.0`: For parsing Gemfile.lock
214
+ - `commander ~> 4.5`: CLI framework
215
+ - `pastel ~> 0.8`: Colored output
216
+ - `tty-table ~> 0.12`: Formatted tables
217
+
218
+ ### Development Dependencies
219
+
220
+ - `rspec ~> 3.0`: Testing framework
221
+ - `rake ~> 13.0`: Build tasks
222
+ - `rubocop ~> 1.21`: Code style checking
223
+
224
+ ## ๐Ÿค Contributing
225
+
226
+ 1. Fork the repository
227
+ 2. Create a feature branch: `git checkout -b feature/new-feature`
228
+ 3. Make changes and add tests
229
+ 4. Run tests: `bundle exec rspec`
230
+ 5. Check code style: `bundle exec rubocop`
231
+ 6. Commit changes: `git commit -m "Add new feature"`
232
+ 7. Push branch: `git push origin feature/new-feature`
233
+ 8. Create pull request
234
+
235
+ ### Code Style
236
+
237
+ - Follow Ruby community standards
238
+ - Use RuboCop for style checking
239
+ - Write descriptive commit messages
240
+ - Add tests for new features
241
+ - Update documentation as needed
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024 ND-Zyth
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,131 @@
1
+ # ๐Ÿ’Ž Gem Digest
2
+
3
+ A powerful CLI tool that analyzes your `Gemfile.lock`, fetches the latest gem versions from RubyGems, and categorizes updates by semantic versioning (major, minor, patch).
4
+
5
+ ## ๐Ÿš€ Features
6
+
7
+ - **Smart Analysis**: Parses `Gemfile.lock` and compares with latest versions from RubyGems
8
+ - **Semantic Categorization**: Groups updates by major, minor, and patch versions
9
+ - **Multiple Output Formats**: Console output with colors and tables, or Markdown reports
10
+ - **Comprehensive Reporting**: Shows current vs latest versions with source information
11
+ - **Cross-Platform**: Works on Linux, macOS, and Windows
12
+
13
+ ## ๐Ÿ“ฆ Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ ```ruby
18
+ gem 'gem-digest'
19
+ ```
20
+
21
+ And then execute:
22
+
23
+ ```bash
24
+ $ bundle install
25
+ ```
26
+
27
+ Or install it yourself as:
28
+
29
+ ```bash
30
+ $ gem install gem-digest
31
+ ```
32
+
33
+ ## ๐Ÿ› ๏ธ Usage
34
+
35
+ ### Basic Analysis
36
+
37
+ Analyze your current directory's `Gemfile.lock`:
38
+
39
+ ```bash
40
+ $ gemd analyze
41
+ ```
42
+
43
+ ### Advanced Options
44
+
45
+ ```bash
46
+ # Specify a different Gemfile.lock path
47
+ $ gemd analyze --gemfile-lock /path/to/Gemfile.lock
48
+
49
+ # Generate a markdown report
50
+ $ gemd analyze --format markdown --output-dir reports
51
+
52
+ # Show gems that are already up to date
53
+ $ gemd analyze --show-up-to-date
54
+
55
+ # Verbose output
56
+ $ gemd analyze --verbose
57
+ ```
58
+
59
+ ### Example Output
60
+
61
+ ```
62
+ ๐Ÿ” Gem Digest Analysis Summary
63
+ ==================================================
64
+ ๐Ÿ“ฆ Total gems analyzed: 25
65
+ ๐Ÿ”ด Major updates available: 3
66
+ ๐ŸŸก Minor updates available: 8
67
+ ๐ŸŸข Patch updates available: 12
68
+ โœ… Up to date: 2
69
+
70
+ Major Updates (3)
71
+ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
72
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
73
+ โ”‚ Gem โ”‚ Current โ”‚ Latest โ”‚ Source โ”‚
74
+ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
75
+ โ”‚ rails โ”‚ 6.1.7 โ”‚ 7.0.4 โ”‚ rubygems โ”‚
76
+ โ”‚ rspec โ”‚ 3.11.0 โ”‚ 4.0.0 โ”‚ rubygems โ”‚
77
+ โ”‚ sidekiq โ”‚ 6.5.8 โ”‚ 7.0.2 โ”‚ rubygems โ”‚
78
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
79
+ ```
80
+
81
+ ## ๐Ÿ—๏ธ Development
82
+
83
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
84
+
85
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
86
+
87
+ ### Running Tests
88
+
89
+ ```bash
90
+ $ bundle exec rspec
91
+ ```
92
+
93
+ ### Code Quality
94
+
95
+ ```bash
96
+ $ bundle exec rubocop
97
+ ```
98
+
99
+ ## ๐Ÿค Contributing
100
+
101
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ND-Zyth/gem-digest.
102
+
103
+ ## ๐Ÿ“„ License
104
+
105
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
106
+
107
+ ## ๐Ÿ”ง API Reference
108
+
109
+ ### GemDigest Module
110
+
111
+ ```ruby
112
+ # Analyze gems programmatically
113
+ GemDigest.analyze("path/to/Gemfile.lock", format: "console")
114
+ GemDigest.analyze("path/to/Gemfile.lock", format: "markdown", output_dir: "reports")
115
+ ```
116
+
117
+ ### Classes
118
+
119
+ - `GemDigest::Analyzer` - Parses Gemfile.lock and fetches latest versions
120
+ - `GemDigest::Categorizer` - Categorizes gems by update type
121
+ - `GemDigest::Reporters::Console` - Generates colored console output
122
+ - `GemDigest::Reporters::Markdown` - Generates markdown reports
123
+ - `GemDigest::CLI` - Command-line interface
124
+
125
+ ## ๐ŸŽฏ Roadmap
126
+
127
+ - [ ] Support for private gem sources
128
+ - [ ] Changelog integration
129
+ - [ ] Security vulnerability detection
130
+ - [ ] Custom update policies
131
+ - [ ] Integration with CI/CD pipelines
data/REQUIREMENTS.md ADDED
@@ -0,0 +1,151 @@
1
+
2
+ ### ๐Ÿ“ Exact `gem-digest` Project Structure
3
+
4
+ ```
5
+ gem-digest/
6
+ โ”œโ”€โ”€ .github/
7
+ โ”‚ โ””โ”€โ”€ workflows/
8
+ โ”‚ โ””โ”€โ”€ release.yml
9
+ โ”œโ”€โ”€ bin/
10
+ โ”‚ โ”œโ”€โ”€ console
11
+ โ”‚ โ””โ”€โ”€ gemd
12
+ โ”œโ”€โ”€ config/
13
+ โ”œโ”€โ”€ exe/
14
+ โ”‚ โ””โ”€โ”€ gemd
15
+ โ”œโ”€โ”€ lib/
16
+ โ”‚ โ”œโ”€โ”€ gem_digest/
17
+ โ”‚ โ”‚ โ”œโ”€โ”€ analyzer.rb
18
+ โ”‚ โ”‚ โ”œโ”€โ”€ categorizer.rb
19
+ โ”‚ โ”‚ โ”œโ”€โ”€ changelog_fetcher.rb
20
+ โ”‚ โ”‚ โ”œโ”€โ”€ cli.rb
21
+ โ”‚ โ”‚ โ”œโ”€โ”€ reporters/
22
+ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ base.rb
23
+ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ console.rb
24
+ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ markdown.rb
25
+ โ”‚ โ”‚ โ””โ”€โ”€ version.rb
26
+ โ”‚ โ””โ”€โ”€ gem_digest.rb
27
+ โ”œโ”€โ”€ output/
28
+ โ”œโ”€โ”€ spec/
29
+ โ”‚ โ”œโ”€โ”€ gem_digest/
30
+ โ”‚ โ”‚ โ”œโ”€โ”€ analyzer_spec.rb
31
+ โ”‚ โ”‚ โ”œโ”€โ”€ categorizer_spec.rb
32
+ โ”‚ โ”‚ โ””โ”€โ”€ cli_spec.rb
33
+ โ”‚ โ”œโ”€โ”€ integration_spec.rb
34
+ โ”‚ โ””โ”€โ”€ spec_helper.rb
35
+ โ”œโ”€โ”€ .gitignore
36
+ โ”œโ”€โ”€ .rspec
37
+ โ”œโ”€โ”€ .rubocop.yml
38
+ โ”œโ”€โ”€ CHANGELOG.md
39
+ โ”œโ”€โ”€ Gemfile
40
+ โ”œโ”€โ”€ LICENSE.txt
41
+ โ”œโ”€โ”€ Rakefile
42
+ โ”œโ”€โ”€ README.md
43
+ โ””โ”€โ”€ gem-digest.gemspec
44
+ ```
45
+
46
+ ### ๐Ÿ“š Key Files and Directories Explained
47
+
48
+ | **File/Directory** | **Core Purpose** |
49
+ | :--- | :--- |
50
+ | **`exe/gemd`** | Main executable CLI entry point. Uses `#!/usr/bin/env ruby` shebang . |
51
+ | **`lib/gem_digest.rb`** | Primary require file that loads the module . |
52
+ | **`lib/gem_digest/cli.rb`** | Uses the `commander` gem to define commands, options, and help messages . |
53
+ | **`lib/gem_digest/analyzer.rb`** | Parses `Gemfile.lock` (using `Bundler` gem) and fetches latest versions from RubyGems. |
54
+ | **`lib/gem_digest/categorizer.rb`** | Compares versions and categorizes updates by semver (major, minor, patch). |
55
+ | **`lib/gem_digest/reporters/`** | Housedifferent output formats (console, markdown) . |
56
+ | **`gem-digest.gemspec`** | Defines gem metadata, version, and dependencies (e.g., `commander`, `bundler`) . |
57
+ | **`spec/`** | Contains unit and integration tests using RSpec . |
58
+ | **`.github/workflows/release.yml`** | CI/CD workflow to run tests on push and build/release cross-platform gems on tag. |
59
+
60
+ ### โš™๏ธ Core Components and Requirements
61
+
62
+ Your `gem-digest.gemspec` file should specify these core dependencies:
63
+
64
+ ```ruby
65
+ spec.add_dependency "bundler", "~> 2.0" # For parsing Gemfile.lock
66
+ spec.add_dependency "commander", "~> 4.5" # For building the CLI structure
67
+ spec.add_dependency "pastel", "~> 0.8" # For colored console output
68
+ spec.add_dependency "tty-table", "~> 0.12" # For formatted tables in the console
69
+
70
+ spec.add_development_dependency "rspec", "~> 3.0"
71
+ spec.add_development_dependency "rake", "~> 13.0"
72
+ ```
73
+
74
+ The main executable `exe/gemd` should start with:
75
+ ```ruby
76
+ #!/usr/bin/env ruby
77
+ require 'gem_digest'
78
+ require 'commander/import'
79
+
80
+ # ... CLI program definition using commander
81
+ ```
82
+
83
+ ### ๐Ÿ› ๏ธ Development Setup
84
+
85
+ 1. **Install dependencies locally**: Run `bundle install` to install all required gems.
86
+ 2. **Test during development**: Use `bundle exec ruby -Ilib exe/gemd` to run your tool with the correct load path without installing it . The `bin/console` script can provide an interactive environment for testing methods.
87
+ 3. **Run tests**: Execute `bundle exec rspec` to run your test suite.
88
+
89
+ ### ๐Ÿš€ Cross-Platform Build & Release via GitHub Actions
90
+
91
+ Create `.github/workflows/release.yml` to automatically build and release your gem for multiple platforms and Ruby versions. This workflow should:
92
+
93
+ - **Trigger on tag pushes** (e.g., `v1.0.0`)
94
+ - **Run tests** across multiple OS (Ubuntu, macOS, Windows) and Ruby versions
95
+ - **Build the gem** for each Ruby version
96
+ - **Create a GitHub Release** and attach all built `.gem` files
97
+
98
+ ```yaml
99
+ name: Build and Release Gem
100
+
101
+ on:
102
+ push:
103
+ tags:
104
+ - 'v*'
105
+
106
+ jobs:
107
+ build:
108
+ name: Build Gem on ${{ matrix.os }} (Ruby ${{ matrix.ruby }})
109
+ runs-on: ${{ matrix.os }}-latest
110
+ strategy:
111
+ matrix:
112
+ os: [ubuntu, macos, windows]
113
+ ruby: ['3.1', '3.2', '3.3']
114
+
115
+ steps:
116
+ - name: Checkout code
117
+ uses: actions/checkout@v4
118
+
119
+ - name: Set up Ruby
120
+ uses: ruby/setup-ruby@v1
121
+ with:
122
+ ruby-version: ${{ matrix.ruby }}
123
+ bundler-cache: true
124
+
125
+ - name: Run tests
126
+ run: bundle exec rspec
127
+
128
+ - name: Build Gem
129
+ run: gem build gem-digest.gemspec
130
+
131
+ - name: Upload Gem Artifact
132
+ uses: actions/upload-artifact@v4
133
+ with:
134
+ name: gem-digest-${{ matrix.os }}-ruby${{ matrix.ruby }}
135
+ path: "*.gem"
136
+
137
+ release:
138
+ name: Create Release
139
+ needs: build
140
+ runs-on: ubuntu-latest
141
+ steps:
142
+ - name: Download all built gems
143
+ uses: actions/download-artifact@v4
144
+ with:
145
+ path: artifacts
146
+
147
+ - name: Create GitHub Release
148
+ uses: softprops/action-gh-release@v1
149
+ with:
150
+ files: "artifacts/**/*.gem"
151
+ ```
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[spec rubocop]
data/exe/gemd ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative "../lib/gem_digest"
5
+ require_relative "../lib/gem_digest/cli"
6
+
7
+ GemDigest::CLI.start
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/gem_digest/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "gem-digest"
7
+ spec.version = GemDigest::VERSION
8
+ spec.authors = ["ND-Zyth"]
9
+ spec.email = ["NuclearDog@zohomail.com"]
10
+
11
+ spec.summary = "Analyze and categorize gem updates from Gemfile.lock"
12
+ spec.description = "A CLI tool that parses Gemfile.lock files, fetches latest gem versions from RubyGems, and categorizes updates by semantic versioning (major, minor, patch)."
13
+ spec.homepage = "https://github.com/ND-Zyth/gem-digest"
14
+ spec.license = "MIT"
15
+ spec.required_ruby_version = ">= 2.6.0"
16
+
17
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
18
+ spec.metadata["homepage_uri"] = spec.homepage
19
+ spec.metadata["source_code_uri"] = "https://github.com/ND-Zyth/gem-digest"
20
+ spec.metadata["changelog_uri"] = "https://github.com/ND-Zyth/gem-digest/blob/main/CHANGELOG.md"
21
+
22
+ # Specify which files should be added to the gem when it is released.
23
+ spec.files = Dir["lib/**/*", "exe/*", "*.md", "*.txt", "Rakefile", "*.gemspec"].select { |f| File.file?(f) }
24
+ spec.bindir = "exe"
25
+ spec.executables = ["gemd"]
26
+ spec.require_paths = ["lib"]
27
+
28
+ # Core dependencies
29
+ spec.add_dependency "bundler", "~> 2.0"
30
+ spec.add_dependency "commander", "~> 4.5"
31
+ spec.add_dependency "pastel", "~> 0.8"
32
+ spec.add_dependency "tty-table", "~> 0.12"
33
+
34
+ # Development dependencies
35
+ spec.add_development_dependency "rspec", "~> 3.0"
36
+ spec.add_development_dependency "rake", "~> 13.0"
37
+ spec.add_development_dependency "rubocop", "~> 1.21"
38
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler"
4
+ require "net/http"
5
+ require "json"
6
+ require "uri"
7
+
8
+ module GemDigest
9
+ class Analyzer
10
+ def initialize(gemfile_lock_path = "Gemfile.lock")
11
+ @gemfile_lock_path = gemfile_lock_path
12
+ raise Error, "Gemfile.lock not found at #{gemfile_lock_path}" unless File.exist?(gemfile_lock_path)
13
+ end
14
+
15
+ def analyze
16
+ lockfile = Bundler::LockfileParser.new(File.read(@gemfile_lock_path))
17
+ gems_data = []
18
+
19
+ lockfile.specs.each do |spec|
20
+ latest_version = fetch_latest_version(spec.name)
21
+ next unless latest_version
22
+
23
+ gems_data << {
24
+ name: spec.name,
25
+ current_version: spec.version.to_s,
26
+ latest_version: latest_version,
27
+ source: spec.source&.to_s || "rubygems"
28
+ }
29
+ end
30
+
31
+ gems_data
32
+ end
33
+
34
+ private
35
+
36
+ def fetch_latest_version(gem_name)
37
+ uri = URI("https://rubygems.org/api/v1/gems/#{gem_name}.json")
38
+
39
+ begin
40
+ response = Net::HTTP.get_response(uri)
41
+ return nil unless response.code == "200"
42
+
43
+ gem_info = JSON.parse(response.body)
44
+ gem_info["version"]
45
+ rescue StandardError => e
46
+ warn "Warning: Could not fetch latest version for #{gem_name}: #{e.message}"
47
+ nil
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GemDigest
4
+ class Categorizer
5
+ def categorize(gems_data)
6
+ categorized = {
7
+ major: [],
8
+ minor: [],
9
+ patch: [],
10
+ up_to_date: []
11
+ }
12
+
13
+ gems_data.each do |gem_data|
14
+ current = parse_version(gem_data[:current_version])
15
+ latest = parse_version(gem_data[:latest_version])
16
+
17
+ next unless current && latest
18
+
19
+ category = determine_update_category(current, latest)
20
+ categorized[category] << gem_data
21
+ end
22
+
23
+ categorized
24
+ end
25
+
26
+ private
27
+
28
+ def parse_version(version_string)
29
+ # Handle version strings like "1.2.3", "1.2.3.pre", etc.
30
+ parts = version_string.split(/[.-]/).map(&:to_i)
31
+ return nil if parts.empty?
32
+
33
+ # Ensure we have at least 3 parts (major, minor, patch)
34
+ while parts.length < 3
35
+ parts << 0
36
+ end
37
+
38
+ parts[0..2] # Return only major, minor, patch
39
+ end
40
+
41
+ def determine_update_category(current, latest)
42
+ return :up_to_date if current == latest
43
+
44
+ major_current, minor_current, patch_current = current
45
+ major_latest, minor_latest, patch_latest = latest
46
+
47
+ if major_latest > major_current
48
+ :major
49
+ elsif minor_latest > minor_current
50
+ :minor
51
+ elsif patch_latest > patch_current
52
+ :patch
53
+ else
54
+ :up_to_date
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "net/http"
4
+ require "json"
5
+ require "uri"
6
+
7
+ module GemDigest
8
+ class ChangelogFetcher
9
+ def initialize
10
+ @cache = {}
11
+ end
12
+
13
+ def fetch_changelog_url(gem_name)
14
+ return @cache[gem_name] if @cache.key?(gem_name)
15
+
16
+ uri = URI("https://rubygems.org/api/v1/gems/#{gem_name}.json")
17
+
18
+ begin
19
+ response = Net::HTTP.get_response(uri)
20
+ return nil unless response.code == "200"
21
+
22
+ gem_info = JSON.parse(response.body)
23
+ changelog_url = gem_info["changelog_uri"] ||
24
+ gem_info["homepage_uri"] ||
25
+ gem_info["source_code_uri"]
26
+
27
+ @cache[gem_name] = changelog_url
28
+ changelog_url
29
+ rescue StandardError => e
30
+ warn "Warning: Could not fetch changelog for #{gem_name}: #{e.message}"
31
+ @cache[gem_name] = nil
32
+ nil
33
+ end
34
+ end
35
+
36
+ def fetch_release_notes(gem_name, from_version, to_version)
37
+ # This is a placeholder for more advanced changelog parsing
38
+ # In a real implementation, you might parse GitHub releases, CHANGELOG files, etc.
39
+ changelog_url = fetch_changelog_url(gem_name)
40
+ return nil unless changelog_url
41
+
42
+ {
43
+ gem_name: gem_name,
44
+ from_version: from_version,
45
+ to_version: to_version,
46
+ changelog_url: changelog_url,
47
+ notes: "See changelog for details about changes from #{from_version} to #{to_version}"
48
+ }
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,85 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "commander/import"
5
+ require_relative "../gem_digest"
6
+
7
+ module GemDigest
8
+ class CLI
9
+ def self.start
10
+ program :name, "gemd"
11
+ program :version, GemDigest::VERSION
12
+ program :description, "Analyze and categorize gem updates from Gemfile.lock"
13
+
14
+ command :analyze do |c|
15
+ c.syntax = "gemd analyze [options]"
16
+ c.summary = "Analyze Gemfile.lock and show available gem updates"
17
+ c.description = "Parse Gemfile.lock, fetch latest versions from RubyGems, and categorize updates by semantic versioning"
18
+
19
+ c.option "--gemfile-lock PATH", String, "Path to Gemfile.lock (default: ./Gemfile.lock)"
20
+ c.option "--format FORMAT", String, "Output format: console or markdown (default: console)"
21
+ c.option "--output-dir DIR", String, "Output directory for reports (default: ./output)"
22
+ c.option "--show-up-to-date", "Show gems that are already up to date"
23
+ c.option "--verbose", "Show detailed output"
24
+
25
+ c.action do |args, options|
26
+ options.default(
27
+ gemfile_lock: "Gemfile.lock",
28
+ format: "console",
29
+ output_dir: "output",
30
+ show_up_to_date: false,
31
+ verbose: false
32
+ )
33
+
34
+ begin
35
+ puts "๐Ÿ” Analyzing gems..." if options.verbose
36
+
37
+ analyzer = GemDigest::Analyzer.new(options.gemfile_lock)
38
+ gems_data = analyzer.analyze
39
+
40
+ puts "๐Ÿ“Š Categorizing updates..." if options.verbose
41
+
42
+ categorizer = GemDigest::Categorizer.new
43
+ categorized_gems = categorizer.categorize(gems_data)
44
+
45
+ puts "๐Ÿ“ Generating report..." if options.verbose
46
+
47
+ reporter_class = case options.format
48
+ when "markdown"
49
+ GemDigest::Reporters::Markdown
50
+ else
51
+ GemDigest::Reporters::Console
52
+ end
53
+
54
+ reporter_options = {
55
+ output_dir: options.output_dir,
56
+ show_up_to_date: options.show_up_to_date,
57
+ verbose: options.verbose
58
+ }
59
+
60
+ reporter = reporter_class.new(reporter_options)
61
+ reporter.generate_report(categorized_gems)
62
+
63
+ rescue GemDigest::Error => e
64
+ puts "โŒ Error: #{e.message}"
65
+ exit 1
66
+ rescue StandardError => e
67
+ puts "โŒ Unexpected error: #{e.message}"
68
+ puts e.backtrace if options.verbose
69
+ exit 1
70
+ end
71
+ end
72
+ end
73
+
74
+ command :version do |c|
75
+ c.syntax = "gemd version"
76
+ c.summary = "Show gem-digest version"
77
+ c.action do
78
+ puts "gem-digest version #{GemDigest::VERSION}"
79
+ end
80
+ end
81
+
82
+ default_command :analyze
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GemDigest
4
+ module Reporters
5
+ class Base
6
+ def initialize(options = {})
7
+ @options = options
8
+ @output_dir = options[:output_dir] || "output"
9
+ ensure_output_directory
10
+ end
11
+
12
+ def generate_report(categorized_gems)
13
+ raise NotImplementedError, "Subclasses must implement generate_report"
14
+ end
15
+
16
+ protected
17
+
18
+ def ensure_output_directory
19
+ Dir.mkdir(@output_dir) unless Dir.exist?(@output_dir)
20
+ end
21
+
22
+ def count_updates(categorized_gems)
23
+ {
24
+ major: categorized_gems[:major].length,
25
+ minor: categorized_gems[:minor].length,
26
+ patch: categorized_gems[:patch].length,
27
+ up_to_date: categorized_gems[:up_to_date].length
28
+ }
29
+ end
30
+
31
+ def total_gems(categorized_gems)
32
+ categorized_gems.values.flatten.length
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pastel"
4
+ require "tty-table"
5
+
6
+ module GemDigest
7
+ module Reporters
8
+ class Console < Base
9
+ def initialize(options = {})
10
+ super
11
+ @pastel = Pastel.new
12
+ end
13
+
14
+ def generate_report(categorized_gems)
15
+ print_summary(categorized_gems)
16
+ print_category_tables(categorized_gems)
17
+ end
18
+
19
+ private
20
+
21
+ def print_summary(categorized_gems)
22
+ counts = count_updates(categorized_gems)
23
+ total = total_gems(categorized_gems)
24
+
25
+ puts @pastel.bold.cyan("\n๐Ÿ” Gem Digest Analysis Summary")
26
+ puts @pastel.dim("=" * 50)
27
+
28
+ puts "๐Ÿ“ฆ Total gems analyzed: #{@pastel.bold(total)}"
29
+ puts "๐Ÿ”ด Major updates available: #{@pastel.red.bold(counts[:major])}"
30
+ puts "๐ŸŸก Minor updates available: #{@pastel.yellow.bold(counts[:minor])}"
31
+ puts "๐ŸŸข Patch updates available: #{@pastel.green.bold(counts[:patch])}"
32
+ puts "โœ… Up to date: #{@pastel.dim(counts[:up_to_date])}"
33
+ puts
34
+ end
35
+
36
+ def print_category_tables(categorized_gems)
37
+ print_category("Major Updates", categorized_gems[:major], :red) if categorized_gems[:major].any?
38
+ print_category("Minor Updates", categorized_gems[:minor], :yellow) if categorized_gems[:minor].any?
39
+ print_category("Patch Updates", categorized_gems[:patch], :green) if categorized_gems[:patch].any?
40
+
41
+ if @options[:show_up_to_date] && categorized_gems[:up_to_date].any?
42
+ print_category("Up to Date", categorized_gems[:up_to_date], :dim)
43
+ end
44
+ end
45
+
46
+ def print_category(title, gems, color)
47
+ return if gems.empty?
48
+
49
+ puts @pastel.bold.send(color, "#{title} (#{gems.length})")
50
+ puts @pastel.dim("-" * (title.length + gems.length.to_s.length + 3))
51
+
52
+ table = TTY::Table.new(header: ["Gem", "Current", "Latest", "Source"])
53
+
54
+ gems.each do |gem_data|
55
+ table << [
56
+ gem_data[:name],
57
+ gem_data[:current_version],
58
+ gem_data[:latest_version],
59
+ format_source(gem_data[:source])
60
+ ]
61
+ end
62
+
63
+ puts table.render(:unicode, padding: [0, 1])
64
+ puts
65
+ end
66
+
67
+ def format_source(source)
68
+ return "rubygems" if source.nil? || source.empty? || source.include?("rubygems")
69
+
70
+ if source.include?("git")
71
+ "git"
72
+ elsif source.include?("path")
73
+ "local"
74
+ else
75
+ "other"
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GemDigest
4
+ module Reporters
5
+ class Markdown < Base
6
+ def generate_report(categorized_gems)
7
+ content = build_markdown_content(categorized_gems)
8
+ output_file = File.join(@output_dir, "gem-digest-report.md")
9
+
10
+ File.write(output_file, content)
11
+ puts "๐Ÿ“„ Markdown report generated: #{output_file}"
12
+ end
13
+
14
+ private
15
+
16
+ def build_markdown_content(categorized_gems)
17
+ content = []
18
+ content << "# ๐Ÿ’Ž Gem Digest Report"
19
+ content << ""
20
+ content << "Generated on: #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}"
21
+ content << ""
22
+
23
+ content << build_summary_section(categorized_gems)
24
+ content << build_details_section(categorized_gems)
25
+
26
+ content.join("\n")
27
+ end
28
+
29
+ def build_summary_section(categorized_gems)
30
+ counts = count_updates(categorized_gems)
31
+ total = total_gems(categorized_gems)
32
+
33
+ summary = []
34
+ summary << "## ๐Ÿ“Š Summary"
35
+ summary << ""
36
+ summary << "| Category | Count |"
37
+ summary << "|----------|-------|"
38
+ summary << "| ๐Ÿ“ฆ Total gems | #{total} |"
39
+ summary << "| ๐Ÿ”ด Major updates | #{counts[:major]} |"
40
+ summary << "| ๐ŸŸก Minor updates | #{counts[:minor]} |"
41
+ summary << "| ๐ŸŸข Patch updates | #{counts[:patch]} |"
42
+ summary << "| โœ… Up to date | #{counts[:up_to_date]} |"
43
+ summary << ""
44
+
45
+ summary.join("\n")
46
+ end
47
+
48
+ def build_details_section(categorized_gems)
49
+ details = []
50
+ details << "## ๐Ÿ“‹ Detailed Analysis"
51
+ details << ""
52
+
53
+ if categorized_gems[:major].any?
54
+ details << build_category_section("๐Ÿ”ด Major Updates", categorized_gems[:major])
55
+ end
56
+
57
+ if categorized_gems[:minor].any?
58
+ details << build_category_section("๐ŸŸก Minor Updates", categorized_gems[:minor])
59
+ end
60
+
61
+ if categorized_gems[:patch].any?
62
+ details << build_category_section("๐ŸŸข Patch Updates", categorized_gems[:patch])
63
+ end
64
+
65
+ if @options[:show_up_to_date] && categorized_gems[:up_to_date].any?
66
+ details << build_category_section("โœ… Up to Date", categorized_gems[:up_to_date])
67
+ end
68
+
69
+ details.join("\n")
70
+ end
71
+
72
+ def build_category_section(title, gems)
73
+ return "" if gems.empty?
74
+
75
+ section = []
76
+ section << "### #{title}"
77
+ section << ""
78
+ section << "| Gem | Current Version | Latest Version | Source |"
79
+ section << "|-----|-----------------|----------------|--------|"
80
+
81
+ gems.each do |gem_data|
82
+ section << "| #{gem_data[:name]} | #{gem_data[:current_version]} | #{gem_data[:latest_version]} | #{format_source(gem_data[:source])} |"
83
+ end
84
+
85
+ section << ""
86
+ section.join("\n")
87
+ end
88
+
89
+ def format_source(source)
90
+ return "RubyGems" if source.nil? || source.empty? || source.include?("rubygems")
91
+
92
+ if source.include?("git")
93
+ "Git"
94
+ elsif source.include?("path")
95
+ "Local"
96
+ else
97
+ "Other"
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GemDigest
4
+ VERSION = "0.1.0"
5
+ end
data/lib/gem_digest.rb ADDED
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "gem_digest/version"
4
+ require_relative "gem_digest/analyzer"
5
+ require_relative "gem_digest/categorizer"
6
+ require_relative "gem_digest/changelog_fetcher"
7
+ require_relative "gem_digest/cli"
8
+ require_relative "gem_digest/reporters/base"
9
+ require_relative "gem_digest/reporters/console"
10
+ require_relative "gem_digest/reporters/markdown"
11
+
12
+ module GemDigest
13
+ class Error < StandardError; end
14
+
15
+ def self.analyze(gemfile_lock_path = "Gemfile.lock", options = {})
16
+ analyzer = Analyzer.new(gemfile_lock_path)
17
+ gems_data = analyzer.analyze
18
+
19
+ categorizer = Categorizer.new
20
+ categorized_gems = categorizer.categorize(gems_data)
21
+
22
+ reporter_class = case options[:format]
23
+ when "markdown"
24
+ Reporters::Markdown
25
+ else
26
+ Reporters::Console
27
+ end
28
+
29
+ reporter = reporter_class.new(options)
30
+ reporter.generate_report(categorized_gems)
31
+ end
32
+ end
metadata ADDED
@@ -0,0 +1,163 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gem-digest
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - ND-Zyth
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2025-10-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: commander
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '4.5'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '4.5'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pastel
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.8'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.8'
55
+ - !ruby/object:Gem::Dependency
56
+ name: tty-table
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.12'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.12'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '13.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '13.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.21'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.21'
111
+ description: A CLI tool that parses Gemfile.lock files, fetches latest gem versions
112
+ from RubyGems, and categorizes updates by semantic versioning (major, minor, patch).
113
+ email:
114
+ - NuclearDog@zohomail.com
115
+ executables:
116
+ - gemd
117
+ extensions: []
118
+ extra_rdoc_files: []
119
+ files:
120
+ - DEVELOPMENT.md
121
+ - LICENSE.txt
122
+ - README.md
123
+ - REQUIREMENTS.md
124
+ - Rakefile
125
+ - exe/gemd
126
+ - gem-digest.gemspec
127
+ - lib/gem_digest.rb
128
+ - lib/gem_digest/analyzer.rb
129
+ - lib/gem_digest/categorizer.rb
130
+ - lib/gem_digest/changelog_fetcher.rb
131
+ - lib/gem_digest/cli.rb
132
+ - lib/gem_digest/reporters/base.rb
133
+ - lib/gem_digest/reporters/console.rb
134
+ - lib/gem_digest/reporters/markdown.rb
135
+ - lib/gem_digest/version.rb
136
+ homepage: https://github.com/ND-Zyth/gem-digest
137
+ licenses:
138
+ - MIT
139
+ metadata:
140
+ allowed_push_host: https://rubygems.org
141
+ homepage_uri: https://github.com/ND-Zyth/gem-digest
142
+ source_code_uri: https://github.com/ND-Zyth/gem-digest
143
+ changelog_uri: https://github.com/ND-Zyth/gem-digest/blob/main/CHANGELOG.md
144
+ post_install_message:
145
+ rdoc_options: []
146
+ require_paths:
147
+ - lib
148
+ required_ruby_version: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: 2.6.0
153
+ required_rubygems_version: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - ">="
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ requirements: []
159
+ rubygems_version: 3.0.3.1
160
+ signing_key:
161
+ specification_version: 4
162
+ summary: Analyze and categorize gem updates from Gemfile.lock
163
+ test_files: []