ruby-reforge 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/.rspec +4 -0
- data/.ruby-version +2 -0
- data/CHANGELOG.md +27 -0
- data/Gemfile +14 -0
- data/LICENSE.txt +22 -0
- data/QUICKSTART.md +77 -0
- data/README.md +115 -0
- data/Rakefile +9 -0
- data/exe/ruby-reforge +7 -0
- data/lib/ruby/reforge/cli.rb +146 -0
- data/lib/ruby/reforge/git_integration.rb +52 -0
- data/lib/ruby/reforge/migration_rules.rb +79 -0
- data/lib/ruby/reforge/rails_rules.rb +47 -0
- data/lib/ruby/reforge/reporter.rb +83 -0
- data/lib/ruby/reforge/rewriter.rb +96 -0
- data/lib/ruby/reforge/scanner.rb +178 -0
- data/lib/ruby/reforge/version.rb +8 -0
- data/lib/ruby/reforge/version_updater.rb +112 -0
- data/lib/ruby/reforge.rb +18 -0
- data/ruby-reforge.gemspec +48 -0
- metadata +212 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: ab4619d1d1f5500df76531c2c3483b1ac972c2b513e5a2ac9017a271219ad605
|
|
4
|
+
data.tar.gz: a4c5435975e097dd6e3241ddc4122fb6e9830bd55e9101a987edbb6f3b392a37
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 106c1ed7177fc8010264651a160cf50434f5768762a6cd1ed1536c373464e1f8f32950f0e5d815fcf0b393070a48719ba3bca1e84ddf0b98c84f200676ea32a4
|
|
7
|
+
data.tar.gz: cf2e590eaa44a0d37aff8081d1dc32a338c817be793a88c6c355db628752288e9a2ede674d924270c1e683a6eaf0fd47f8d74be5a52646c4f974c94c439847d1
|
data/.rspec
ADDED
data/.ruby-version
ADDED
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] - 2024-01-XX
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Initial release
|
|
12
|
+
- CLI interface with `upgrade`, `report`, and `ai-fix` commands
|
|
13
|
+
- Automatic version file updates (`.ruby-version`, `Gemfile`, `gemspec`)
|
|
14
|
+
- Code scanner using Prism for AST parsing
|
|
15
|
+
- Migration rules for Ruby 3.0, 3.1, 3.2, and 3.3
|
|
16
|
+
- Rails-specific deprecation rules
|
|
17
|
+
- Interactive mode for reviewing changes
|
|
18
|
+
- Dry-run mode
|
|
19
|
+
- Git integration (branch creation and commits)
|
|
20
|
+
- Detailed reporting with colorized output
|
|
21
|
+
|
|
22
|
+
### Features
|
|
23
|
+
- Detects and fixes deprecated methods (`File.exists?`, `Dir.exists?`, etc.)
|
|
24
|
+
- Pattern-based code rewriting
|
|
25
|
+
- Rails filter to action migrations
|
|
26
|
+
- Comprehensive upgrade reports
|
|
27
|
+
|
data/Gemfile
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
# Specify your gem's dependencies in ruby-reforge.gemspec
|
|
6
|
+
gemspec
|
|
7
|
+
|
|
8
|
+
gem "rake", "~> 13.0"
|
|
9
|
+
|
|
10
|
+
group :development, :test do
|
|
11
|
+
gem "rspec", "~> 3.12"
|
|
12
|
+
gem "rubocop", "~> 1.50"
|
|
13
|
+
end
|
|
14
|
+
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Ruby Reforge Team
|
|
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 all
|
|
13
|
+
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 THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
data/QUICKSTART.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Quick Start Guide
|
|
2
|
+
|
|
3
|
+
## Building the Gem
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
cd ruby-reforge
|
|
7
|
+
gem build ruby-reforge.gemspec
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
This will create a `ruby-reforge-0.1.0.gem` file.
|
|
11
|
+
|
|
12
|
+
## Installing Locally
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
gem install ./ruby-reforge-0.1.0.gem
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Or install from the local directory:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
bundle install
|
|
22
|
+
bundle exec ruby-reforge --help
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Development Setup
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
bundle install
|
|
29
|
+
bundle exec rspec # Run tests
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Usage Examples
|
|
33
|
+
|
|
34
|
+
### Generate a report
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
ruby-reforge report
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Upgrade to Ruby 3.3
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
ruby-reforge upgrade 3.3
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Interactive mode
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
ruby-reforge upgrade 3.3 --interactive
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Dry run (see what would change)
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
ruby-reforge upgrade 3.3 --dry-run
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Project Structure
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
ruby-reforge/
|
|
62
|
+
├── lib/
|
|
63
|
+
│ └── ruby/
|
|
64
|
+
│ └── reforge/
|
|
65
|
+
│ ├── cli.rb # CLI interface
|
|
66
|
+
│ ├── scanner.rb # Code scanner
|
|
67
|
+
│ ├── rewriter.rb # Code rewriter
|
|
68
|
+
│ ├── version_updater.rb # Version file updates
|
|
69
|
+
│ ├── migration_rules.rb # Ruby version rules
|
|
70
|
+
│ ├── rails_rules.rb # Rails-specific rules
|
|
71
|
+
│ ├── reporter.rb # Report generator
|
|
72
|
+
│ └── git_integration.rb # Git operations
|
|
73
|
+
├── exe/
|
|
74
|
+
│ └── ruby-reforge # Executable
|
|
75
|
+
├── spec/ # Tests
|
|
76
|
+
└── ruby-reforge.gemspec # Gem specification
|
|
77
|
+
```
|
data/README.md
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Ruby Reforge
|
|
2
|
+
|
|
3
|
+
🚀 Automatically upgrade Ruby projects to newer versions and fix deprecated code.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
`ruby-reforge` is a gem that scans a Ruby or Rails project, detects incompatible code for a target Ruby version (e.g., upgrading from 3.1 → 3.3), and automatically rewrites or suggests fixes.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- ✅ Updates `.ruby-version`, `Gemfile`, and `gemspec` files
|
|
12
|
+
- ✅ Fixes deprecated Ruby syntax automatically
|
|
13
|
+
- ✅ Detects and fixes removed features
|
|
14
|
+
- ✅ Rewrites code for new Ruby syntax
|
|
15
|
+
- ✅ Generates detailed upgrade reports
|
|
16
|
+
- ✅ Interactive mode for reviewing changes
|
|
17
|
+
- ✅ Git integration (creates branches, commits changes)
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
gem install ruby-reforge
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Or add it to your Gemfile:
|
|
26
|
+
|
|
27
|
+
```ruby
|
|
28
|
+
gem 'ruby-reforge', group: :development
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
### Upgrade to a new Ruby version
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
ruby-reforge upgrade 3.3
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
This will:
|
|
40
|
+
1. Update version files (`.ruby-version`, `Gemfile`, `gemspec`)
|
|
41
|
+
2. Scan your codebase for deprecated patterns
|
|
42
|
+
3. Automatically fix issues
|
|
43
|
+
4. Create a git branch and commit changes
|
|
44
|
+
|
|
45
|
+
### Generate a report
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
ruby-reforge report
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Shows what needs to be fixed without making changes.
|
|
52
|
+
|
|
53
|
+
### Interactive mode
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
ruby-reforge upgrade 3.3 --interactive
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Prompts before making each change.
|
|
60
|
+
|
|
61
|
+
### Dry run
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
ruby-reforge upgrade 3.3 --dry-run
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Shows what would be changed without making any changes.
|
|
68
|
+
|
|
69
|
+
## What It Fixes
|
|
70
|
+
|
|
71
|
+
### Deprecated Methods
|
|
72
|
+
|
|
73
|
+
- `File.exists?` → `File.exist?`
|
|
74
|
+
- `Dir.exists?` → `Dir.exist?`
|
|
75
|
+
- `URI.escape` → `CGI.escape`
|
|
76
|
+
- And more...
|
|
77
|
+
|
|
78
|
+
### Version Files
|
|
79
|
+
|
|
80
|
+
- Updates `.ruby-version`
|
|
81
|
+
- Updates `Gemfile` ruby version
|
|
82
|
+
- Updates `gemspec` required_ruby_version
|
|
83
|
+
|
|
84
|
+
### Ruby 3.0+ Keyword Arguments
|
|
85
|
+
|
|
86
|
+
Detects and suggests fixes for keyword argument changes.
|
|
87
|
+
|
|
88
|
+
## Examples
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
# Upgrade to Ruby 3.3
|
|
92
|
+
ruby-reforge upgrade 3.3
|
|
93
|
+
|
|
94
|
+
# Generate report for Ruby 3.2
|
|
95
|
+
ruby-reforge report --target 3.2
|
|
96
|
+
|
|
97
|
+
# Interactive upgrade
|
|
98
|
+
ruby-reforge upgrade 3.3 --interactive
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Roadmap
|
|
102
|
+
|
|
103
|
+
- [ ] Rails-specific deprecations
|
|
104
|
+
- [ ] Gem dependency compatibility checker
|
|
105
|
+
- [ ] AI-assisted fixes for complex code
|
|
106
|
+
- [ ] Test framework updates
|
|
107
|
+
- [ ] Performance improvement suggestions
|
|
108
|
+
|
|
109
|
+
## Contributing
|
|
110
|
+
|
|
111
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
112
|
+
|
|
113
|
+
## License
|
|
114
|
+
|
|
115
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/exe/ruby-reforge
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "thor"
|
|
4
|
+
require "rainbow"
|
|
5
|
+
require "tty-prompt"
|
|
6
|
+
|
|
7
|
+
module Ruby
|
|
8
|
+
module Reforge
|
|
9
|
+
class CLI < Thor
|
|
10
|
+
include Thor::Actions
|
|
11
|
+
|
|
12
|
+
desc "upgrade VERSION", "Upgrade Ruby project to target version"
|
|
13
|
+
option :interactive, type: :boolean, aliases: "-i", desc: "Interactive mode - prompts before changes"
|
|
14
|
+
option :dry_run, type: :boolean, aliases: "-d", desc: "Show what would be changed without making changes"
|
|
15
|
+
option :branch, type: :string, desc: "Git branch name (default: upgrade/ruby-VERSION)"
|
|
16
|
+
def upgrade(version)
|
|
17
|
+
say "🚀 Ruby Reforge - Upgrading to Ruby #{version}", :green
|
|
18
|
+
say ""
|
|
19
|
+
|
|
20
|
+
target_version = normalize_version(version)
|
|
21
|
+
current_version = detect_current_ruby_version
|
|
22
|
+
|
|
23
|
+
if current_version == target_version
|
|
24
|
+
say "✓ Already on Ruby #{target_version}", :green
|
|
25
|
+
exit 0
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
say "Current Ruby version: #{current_version || 'unknown'}", :yellow
|
|
29
|
+
say "Target Ruby version: #{target_version}", :yellow
|
|
30
|
+
say ""
|
|
31
|
+
|
|
32
|
+
# Create git branch if in git repo
|
|
33
|
+
if git_integration.available?
|
|
34
|
+
branch_name = options[:branch] || "upgrade/ruby-#{target_version}"
|
|
35
|
+
git_integration.create_branch(branch_name) unless options[:dry_run]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Scan for issues
|
|
39
|
+
say "🔍 Scanning codebase...", :cyan
|
|
40
|
+
issues = scanner.scan(target_version)
|
|
41
|
+
|
|
42
|
+
# Generate report
|
|
43
|
+
reporter.report(issues, current_version, target_version)
|
|
44
|
+
|
|
45
|
+
if options[:dry_run]
|
|
46
|
+
say "\n🔍 DRY RUN - No changes made", :yellow
|
|
47
|
+
exit 0
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Interactive mode
|
|
51
|
+
if options[:interactive]
|
|
52
|
+
prompt = TTY::Prompt.new
|
|
53
|
+
unless prompt.yes?("Proceed with automatic fixes?")
|
|
54
|
+
say "Aborted.", :red
|
|
55
|
+
exit 0
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Update version files
|
|
60
|
+
say "\n📝 Updating version files...", :cyan
|
|
61
|
+
version_updater.update(target_version)
|
|
62
|
+
|
|
63
|
+
# Apply fixes
|
|
64
|
+
say "\n🔧 Applying fixes...", :cyan
|
|
65
|
+
rewriter.rewrite(issues, interactive: options[:interactive])
|
|
66
|
+
|
|
67
|
+
# Commit changes
|
|
68
|
+
if git_integration.available? && !options[:dry_run]
|
|
69
|
+
git_integration.commit_version_files
|
|
70
|
+
git_integration.commit_code_changes
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
say "\n✅ Upgrade complete!", :green
|
|
74
|
+
say "\nNext steps:"
|
|
75
|
+
say " 1. Review the changes"
|
|
76
|
+
say " 2. Run your test suite"
|
|
77
|
+
say " 3. Update dependencies: bundle update"
|
|
78
|
+
say " 4. Check for any manual fixes needed"
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
desc "report", "Generate a report of deprecated code and upgrade issues"
|
|
82
|
+
option :target, type: :string, desc: "Target Ruby version (default: latest stable)"
|
|
83
|
+
def report
|
|
84
|
+
say "📊 Ruby Reforge - Generating Report", :green
|
|
85
|
+
say ""
|
|
86
|
+
|
|
87
|
+
current_version = detect_current_ruby_version
|
|
88
|
+
target_version = options[:target] ? normalize_version(options[:target]) : "3.3.0"
|
|
89
|
+
|
|
90
|
+
say "Current Ruby version: #{current_version || 'unknown'}", :yellow
|
|
91
|
+
say "Target Ruby version: #{target_version}", :yellow
|
|
92
|
+
say ""
|
|
93
|
+
|
|
94
|
+
say "🔍 Scanning codebase...", :cyan
|
|
95
|
+
issues = scanner.scan(target_version)
|
|
96
|
+
|
|
97
|
+
reporter.report(issues, current_version, target_version)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
desc "ai-fix", "Use AI to fix complex deprecated code (experimental)"
|
|
101
|
+
option :model, type: :string, default: "local", desc: "AI model to use (local, openai, anthropic)"
|
|
102
|
+
def ai_fix
|
|
103
|
+
say "🤖 AI-Assisted Fix Mode (Experimental)", :green
|
|
104
|
+
say "This feature is coming soon!", :yellow
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
private
|
|
108
|
+
|
|
109
|
+
def normalize_version(version)
|
|
110
|
+
# Normalize version string (e.g., "3.3" -> "3.3.0")
|
|
111
|
+
parts = version.split(".").map(&:to_i)
|
|
112
|
+
parts << 0 while parts.size < 3
|
|
113
|
+
parts[0..2].join(".")
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def detect_current_ruby_version
|
|
117
|
+
version_updater.detect_current_version
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def scanner
|
|
121
|
+
@scanner ||= Scanner.new(source_root)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def rewriter
|
|
125
|
+
@rewriter ||= Rewriter.new(source_root)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def version_updater
|
|
129
|
+
@version_updater ||= VersionUpdater.new(source_root)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def reporter
|
|
133
|
+
@reporter ||= Reporter.new
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def git_integration
|
|
137
|
+
@git_integration ||= GitIntegration.new(source_root)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def source_root
|
|
141
|
+
@source_root ||= Dir.pwd
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "fileutils"
|
|
4
|
+
|
|
5
|
+
module Ruby
|
|
6
|
+
module Reforge
|
|
7
|
+
class GitIntegration
|
|
8
|
+
def initialize(root_path)
|
|
9
|
+
@root_path = root_path
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def available?
|
|
13
|
+
git_dir = File.join(@root_path, ".git")
|
|
14
|
+
File.directory?(git_dir) && system("git --version > /dev/null 2>&1")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def create_branch(branch_name)
|
|
18
|
+
return unless available?
|
|
19
|
+
|
|
20
|
+
system("cd #{@root_path} && git checkout -b #{branch_name} 2>/dev/null") ||
|
|
21
|
+
system("cd #{@root_path} && git checkout #{branch_name} 2>/dev/null")
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def commit_version_files
|
|
25
|
+
return unless available?
|
|
26
|
+
|
|
27
|
+
files = [".ruby-version", "Gemfile"]
|
|
28
|
+
files += Dir.glob(File.join(@root_path, "**/*.gemspec"))
|
|
29
|
+
|
|
30
|
+
staged_files = files.select { |f| File.exist?(File.join(@root_path, f)) }
|
|
31
|
+
return if staged_files.empty?
|
|
32
|
+
|
|
33
|
+
system("cd #{@root_path} && git add #{staged_files.join(' ')}")
|
|
34
|
+
system("cd #{@root_path} && git commit -m 'chore: update Ruby version files'")
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def commit_code_changes
|
|
38
|
+
return unless available?
|
|
39
|
+
|
|
40
|
+
# Get list of modified Ruby files
|
|
41
|
+
modified = `cd #{@root_path} && git diff --name-only --diff-filter=M`.split("\n")
|
|
42
|
+
ruby_files = modified.select { |f| f.end_with?(".rb") }
|
|
43
|
+
|
|
44
|
+
return if ruby_files.empty?
|
|
45
|
+
|
|
46
|
+
system("cd #{@root_path} && git add #{ruby_files.join(' ')}")
|
|
47
|
+
system("cd #{@root_path} && git commit -m 'fix: update deprecated Ruby syntax'")
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ruby
|
|
4
|
+
module Reforge
|
|
5
|
+
class MigrationRules
|
|
6
|
+
RULES = {
|
|
7
|
+
"3.0.0" => {
|
|
8
|
+
deprecated_methods: {
|
|
9
|
+
"File.exists?" => "File.exist?",
|
|
10
|
+
"Dir.exists?" => "Dir.exist?",
|
|
11
|
+
"URI.escape" => "CGI.escape",
|
|
12
|
+
"URI.unescape" => "CGI.unescape"
|
|
13
|
+
},
|
|
14
|
+
deprecated_patterns: {
|
|
15
|
+
/File\.exists\?/ => "File.exist?",
|
|
16
|
+
/Dir\.exists\?/ => "Dir.exist?",
|
|
17
|
+
/URI\.escape/ => "CGI.escape",
|
|
18
|
+
/URI\.unescape/ => "CGI.unescape"
|
|
19
|
+
},
|
|
20
|
+
breaking_changes: [
|
|
21
|
+
"Keyword arguments are now separated from positional arguments"
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
"3.1.0" => {
|
|
25
|
+
deprecated_methods: {
|
|
26
|
+
"File.exists?" => "File.exist?",
|
|
27
|
+
"Dir.exists?" => "Dir.exist?"
|
|
28
|
+
},
|
|
29
|
+
deprecated_patterns: {
|
|
30
|
+
/File\.exists\?/ => "File.exist?",
|
|
31
|
+
/Dir\.exists\?/ => "Dir.exist?"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"3.2.0" => {
|
|
35
|
+
deprecated_methods: {
|
|
36
|
+
"File.exists?" => "File.exist?",
|
|
37
|
+
"Dir.exists?" => "Dir.exist?"
|
|
38
|
+
},
|
|
39
|
+
deprecated_patterns: {
|
|
40
|
+
/File\.exists\?/ => "File.exist?",
|
|
41
|
+
/Dir\.exists\?/ => "Dir.exist?"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"3.3.0" => {
|
|
45
|
+
deprecated_methods: {
|
|
46
|
+
"File.exists?" => "File.exist?",
|
|
47
|
+
"Dir.exists?" => "Dir.exist?"
|
|
48
|
+
},
|
|
49
|
+
deprecated_patterns: {
|
|
50
|
+
/File\.exists\?/ => "File.exist?",
|
|
51
|
+
/Dir\.exists\?/ => "Dir.exist?"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}.freeze
|
|
55
|
+
|
|
56
|
+
def self.for_version(version)
|
|
57
|
+
# Find the most appropriate rule set
|
|
58
|
+
target = normalize_version(version)
|
|
59
|
+
rule_key = RULES.keys.select { |k| normalize_version(k) <= target }.max || RULES.keys.first
|
|
60
|
+
new(RULES[rule_key] || {})
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def self.normalize_version(version)
|
|
64
|
+
parts = version.to_s.split(".").map(&:to_i)
|
|
65
|
+
parts << 0 while parts.size < 3
|
|
66
|
+
parts[0..2].join(".")
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
attr_reader :deprecated_methods, :deprecated_patterns, :breaking_changes
|
|
70
|
+
|
|
71
|
+
def initialize(rules = {})
|
|
72
|
+
@deprecated_methods = rules[:deprecated_methods] || {}
|
|
73
|
+
@deprecated_patterns = rules[:deprecated_patterns] || {}
|
|
74
|
+
@breaking_changes = rules[:breaking_changes] || []
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ruby
|
|
4
|
+
module Reforge
|
|
5
|
+
class RailsRules
|
|
6
|
+
RAILS_DEPRECATIONS = {
|
|
7
|
+
"before_filter" => "before_action",
|
|
8
|
+
"after_filter" => "after_action",
|
|
9
|
+
"around_filter" => "around_action",
|
|
10
|
+
"skip_before_filter" => "skip_before_action",
|
|
11
|
+
"skip_after_filter" => "skip_after_action",
|
|
12
|
+
"skip_around_filter" => "skip_around_action",
|
|
13
|
+
"update_attributes" => "update",
|
|
14
|
+
"update_attributes!" => "update!",
|
|
15
|
+
"render :text" => "render plain:",
|
|
16
|
+
"render :nothing" => "head :ok"
|
|
17
|
+
}.freeze
|
|
18
|
+
|
|
19
|
+
RAILS_PATTERNS = {
|
|
20
|
+
/before_filter/ => "before_action",
|
|
21
|
+
/after_filter/ => "after_action",
|
|
22
|
+
/around_filter/ => "around_action",
|
|
23
|
+
/skip_before_filter/ => "skip_before_action",
|
|
24
|
+
/skip_after_filter/ => "skip_after_action",
|
|
25
|
+
/skip_around_filter/ => "skip_around_action",
|
|
26
|
+
/\.update_attributes\(/ => ".update(",
|
|
27
|
+
/\.update_attributes!/ => ".update!",
|
|
28
|
+
/render\s+:text\s*=>/ => "render plain:",
|
|
29
|
+
/render\s+:nothing/ => "head :ok"
|
|
30
|
+
}.freeze
|
|
31
|
+
|
|
32
|
+
def self.deprecated_methods
|
|
33
|
+
RAILS_DEPRECATIONS
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.deprecated_patterns
|
|
37
|
+
RAILS_PATTERNS
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def self.detect_rails_project?(root_path)
|
|
41
|
+
File.exist?(File.join(root_path, "config", "application.rb")) ||
|
|
42
|
+
File.exist?(File.join(root_path, "Gemfile")) && File.read(File.join(root_path, "Gemfile")).include?("rails")
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|