rails-diff 0.2.1 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 567e5e325109a4ed6c9daee6dd2c18a8c5bf20de492be9c4399c54347a2091fa
4
- data.tar.gz: 6ef46901ce7d1445e0c8651323fdad776e9225223c4f2e4c1d6e506c31d70130
3
+ metadata.gz: 65e5efcc214d48f2c3d2aac80dfb88c7506b3bd559a74e2c77f31fd1388736f0
4
+ data.tar.gz: cd3123a08c990c068401869e18e6a8c3ad0fb54867640b42a655357d73b23a01
5
5
  SHA512:
6
- metadata.gz: 1b5259244a5b576f651c75981c807854bb82d71cf3b7af72074a9ec05dacb30db477af39dc2a2ab1a11a2d328da23cbeb1b9deec62a0c190355785299f1622d5
7
- data.tar.gz: 6b037fd06f237a6a48d2b98e4dcd36609b8a2b3ece0a7bada82b38249b63ca20fdcbdb8ee707ecafefa0de40fd5db8d6c18a97be033f2771a620cfb1750d9c42
6
+ metadata.gz: 1177590a5fa948253de27d6169f567cd75a50dc9f840e4145b45ddc55e7e3f884c8595b0ed2a8a01911290be9eaeab34eaee670212cddd56f412b7ab1a4564ea
7
+ data.tar.gz: 67c3ff2090a3f81c1ff1d22e1dad2ca549b45e80588021eec5c128d0f8bede276cb8da2ffcd5719fc3a312e0be52fde112ccd37cf6a97398c6725e22dc3c2375
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.4.2
data/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.4.0] - 2025-03-05
4
+
5
+ - Respect `~/.railsrc` file when generating new rails apps (PR #4). Thanks [@marcoroth](https://github.com/marcoroth) 🎉
6
+ - Use array version of `system` to avoid command injection.
7
+ - Update cache keys to be shorter.
8
+ - Improve log messages.
9
+
10
+ ## [0.3.0] - 2025-02-23
11
+
12
+ - Allow passing options to generate the new application
13
+
14
+ ```sh
15
+ rails-diff file Gemfile --new-app-options="--database=postgresql"
16
+ ```
17
+
3
18
  ## [0.2.1] - 2025-02-22
4
19
 
5
20
  - Add missing version command
@@ -30,6 +45,8 @@ M## [0.1.1] - 2025-02-21
30
45
 
31
46
  - Initial release
32
47
 
48
+ [0.4.0]: https://github.com/matheusrich/rails-diff/releases/tag/v0.4.0
49
+ [0.3.0]: https://github.com/matheusrich/rails-diff/releases/tag/v0.3.0
33
50
  [0.2.1]: https://github.com/matheusrich/rails-diff/releases/tag/v0.2.1
34
51
  [0.2.0]: https://github.com/matheusrich/rails-diff/releases/tag/v0.2.0
35
52
  [0.1.1]: https://github.com/matheusrich/rails-diff/releases/tag/v0.1.1
data/README.md CHANGED
@@ -78,6 +78,16 @@ If this option is specified, the command will exit with a non-zero status code i
78
78
  Specify the commit hash you want to compare against. If not provided, the latest
79
79
  commit on main will be used by default.
80
80
 
81
+ #### --new-app-options <options>
82
+
83
+ Specify additional options to be used with the `rails new` command. This allows you to customize the generated Rails application, for example, by specifying a different database.
84
+
85
+ Example:
86
+
87
+ ```bash
88
+ rails-diff file Dockerfile --new-app-options="--database=postgresql"
89
+ ```
90
+
81
91
  ## How it works
82
92
 
83
93
  When you run the diff, it will:
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Rails
4
4
  module Diff
5
- VERSION = "0.2.1"
5
+ VERSION = "0.4.0"
6
6
  end
7
7
  end
data/lib/rails/diff.rb CHANGED
@@ -5,25 +5,27 @@ require "rails"
5
5
  require "thor"
6
6
  require "diffy"
7
7
  require "fileutils"
8
+ require "open3"
8
9
 
9
10
  module Rails
10
11
  module Diff
11
12
  class Error < StandardError; end
12
13
 
13
14
  RAILS_REPO = "https://github.com/rails/rails.git"
14
- CACHE_DIR = File.expand_path("~/.rails-diff/cache")
15
+ CACHE_DIR = File.expand_path("#{ENV["HOME"]}/.rails-diff/cache")
16
+ RAILSRC_PATH = "#{ENV["HOME"]}/.railsrc"
15
17
 
16
18
  class << self
17
- def file(*files, no_cache: false, commit: nil)
19
+ def file(*files, no_cache: false, commit: nil, new_app_options: nil)
18
20
  clear_cache if no_cache
19
- ensure_template_app_exists(commit)
21
+ ensure_template_app_exists(commit, new_app_options)
20
22
 
21
23
  files.filter_map { |it| diff_with_header(it) }.join("\n")
22
24
  end
23
25
 
24
- def generated(generator_name, *args, no_cache: false, skip: [], commit: nil)
26
+ def generated(generator_name, *args, no_cache: false, skip: [], commit: nil, new_app_options: nil)
25
27
  clear_cache if no_cache
26
- ensure_template_app_exists(commit)
28
+ ensure_template_app_exists(commit, new_app_options)
27
29
  install_app_dependencies
28
30
 
29
31
  generated_files(generator_name, *args, skip)
@@ -33,34 +35,56 @@ module Rails
33
35
 
34
36
  private
35
37
 
38
+ def system!(*cmd)
39
+ _, stderr, status = Open3.capture3(*cmd)
40
+
41
+ unless status.success?
42
+ puts "\e[1;31mCommand failed:\e[0m #{cmd.join(' ')}"
43
+ abort stderr
44
+ end
45
+
46
+ true
47
+ end
48
+
49
+ def info(message)
50
+ puts "\e[1;34minfo:\e[0m #{message}"
51
+ end
52
+
36
53
  def clear_cache
37
- puts "Clearing cache"
54
+ info "Clearing cache"
38
55
  FileUtils.rm_rf(CACHE_DIR)
39
56
  end
40
57
 
41
- def ensure_template_app_exists(commit)
58
+ def ensure_template_app_exists(commit, new_app_options)
42
59
  FileUtils.mkdir_p(CACHE_DIR)
60
+ @new_app_options = new_app_options
43
61
  @commit = commit || latest_commit
44
62
  return if cached_app?
45
63
 
46
- FileUtils.rm_rf(template_app_path)
47
64
  create_new_rails_app
48
65
  end
49
66
 
50
67
  def template_app_path
51
- @template_app_path ||= File.join(CACHE_DIR, commit, app_name)
68
+ @template_app_path ||= File.join(CACHE_DIR, "rails-#{commit.first(10)}", rails_new_options_hash, app_name)
52
69
  end
53
70
 
54
71
  def rails_path
55
72
  @rails_path ||= begin
56
73
  File.join(CACHE_DIR, "rails").tap do |path|
57
74
  unless File.exist?(path)
58
- system("git clone --depth 1 #{RAILS_REPO} #{path} >/dev/null 2>&1")
75
+ info "Cloning Rails repository"
76
+ system!("git", "clone", "--depth", "1", RAILS_REPO, path)
59
77
  end
60
78
  end
61
79
  end
62
80
  end
63
81
 
82
+ def railsrc_options
83
+ return @railsrc_options if defined?(@railsrc_options)
84
+
85
+ @railsrc_options = File.read(RAILSRC_PATH).lines if File.exist?(RAILSRC_PATH)
86
+ end
87
+
64
88
  def app_name = @app_name ||= File.basename(Dir.pwd)
65
89
 
66
90
  def list_files(dir, skip = [])
@@ -82,11 +106,10 @@ module Rails
82
106
  end
83
107
 
84
108
  def generated_files(generator_name, *args, skip)
85
- command = "#{generator_name} #{args.join(' ')}"
86
109
  Dir.chdir(template_app_path) do
87
- system("bin/rails destroy #{command} >/dev/null 2>&1")
88
- puts "Running generator: rails generate #{command}"
89
- track_new_files(skip) { system("bin/rails generate #{command} > /dev/null 2>&1") }
110
+ system!("bin/rails", "destroy", generator_name, *args)
111
+ info "Running generator: rails generate #{generator_name} #{args.join(' ')}"
112
+ track_new_files(skip) { system!("bin/rails", "generate", generator_name, *args) }
90
113
  .map { |it| it.delete_prefix("#{template_app_path}/") }
91
114
  end
92
115
  end
@@ -101,9 +124,9 @@ module Rails
101
124
 
102
125
  def install_app_dependencies
103
126
  Dir.chdir(template_app_path) do
104
- unless system("bundle check >/dev/null 2>&1")
105
- puts "Installing application dependencies"
106
- system("bundle install >/dev/null 2>&1")
127
+ unless system!("bundle check")
128
+ info "Installing application dependencies"
129
+ system!("bundle install")
107
130
  end
108
131
  end
109
132
  end
@@ -112,8 +135,8 @@ module Rails
112
135
  rails_file = File.join(template_app_path, file)
113
136
  repo_file = File.join(Dir.pwd, file)
114
137
 
115
- return "#{file} not found in the Rails template" unless File.exist?(rails_file)
116
- return "#{file} not found in your repository" unless File.exist?(repo_file)
138
+ return "File not found in the Rails template" unless File.exist?(rails_file)
139
+ return "File not found in your repository" unless File.exist?(repo_file)
117
140
 
118
141
  Diffy::Diff.new(
119
142
  rails_file,
@@ -124,14 +147,14 @@ module Rails
124
147
  end
125
148
 
126
149
  def cached_app?
127
- File.exist?(template_app_path) && !rails_updated?
150
+ File.exist?(template_app_path) && !out_of_date_rails?
128
151
  end
129
152
 
130
- def rails_updated?
131
- return true if !File.exist?(rails_path)
153
+ def out_of_date_rails?
154
+ return true unless File.exist?(rails_path)
132
155
 
133
156
  Dir.chdir(rails_path) do
134
- system("git fetch origin main >/dev/null 2>&1")
157
+ system!("git fetch origin main")
135
158
  current = `git rev-parse HEAD`.strip
136
159
  latest = `git rev-parse origin/main`.strip
137
160
 
@@ -153,34 +176,58 @@ module Rails
153
176
 
154
177
  def generate_app
155
178
  Dir.chdir("railties") do
156
- unless system("bundle check >/dev/null 2>&1")
157
- puts "Installing Rails dependencies"
158
- system("bundle install >/dev/null 2>&1")
179
+ unless system!("bundle check")
180
+ info "Installing Rails dependencies"
181
+ system!("bundle install")
159
182
  end
160
183
 
161
- puts "Generating new Rails application"
162
- system("bundle exec rails new #{template_app_path} --main --skip-bundle --force --skip-test --skip-system-test --quiet")
184
+ if railsrc_options
185
+ info "Using default options from #{RAILSRC_PATH}:\n > #{railsrc_options.join(' ')}"
186
+ end
187
+
188
+ info "Generating new Rails application\n > #{rails_new_command.join(' ')}"
189
+ system!(*rails_new_command)
163
190
  end
164
191
  end
165
192
 
166
193
  def checkout_rails
167
- puts "Checking out Rails (at commit #{commit[0..6]})"
168
- system("git checkout #{commit} >/dev/null 2>&1")
194
+ info "Checking out Rails (at commit #{commit[0..6]})"
195
+ system!("git", "checkout", commit)
169
196
  end
170
197
 
171
198
  def commit = @commit
172
199
 
200
+ def new_app_options = @new_app_options
201
+
173
202
  def latest_commit
174
203
  Dir.chdir(rails_path) do
175
204
  `git rev-parse origin/main`.strip
176
205
  end
177
206
  end
207
+
208
+ def rails_new_command = @rails_new_command ||= [
209
+ "bundle",
210
+ "exec",
211
+ "rails",
212
+ "new",
213
+ template_app_path,
214
+ "--main",
215
+ "--skip-bundle",
216
+ "--force",
217
+ "--quiet",
218
+ *rails_new_options
219
+ ]
220
+
221
+ def rails_new_options = @rails_new_options ||= [*new_app_options, *railsrc_options].compact
222
+
223
+ def rails_new_options_hash = Digest::MD5.hexdigest(rails_new_options.join(" "))
178
224
  end
179
225
 
180
226
  class CLI < Thor
181
227
  class_option :no_cache, type: :boolean, desc: "Clear cache before running", aliases: ["--clear-cache"]
182
228
  class_option :fail_on_diff, type: :boolean, desc: "Fail if there are differences"
183
229
  class_option :commit, type: :string, desc: "Compare against a specific commit"
230
+ class_option :new_app_options, type: :string, desc: "Options to pass to the rails new command"
184
231
 
185
232
  def self.exit_on_failure? = true
186
233
 
@@ -188,7 +235,7 @@ module Rails
188
235
  def file(*files)
189
236
  abort "Please provide at least one file to compare" if files.empty?
190
237
 
191
- diff = Rails::Diff.file(*files, no_cache: options[:no_cache], commit: options[:commit])
238
+ diff = Rails::Diff.file(*files, no_cache: options[:no_cache], commit: options[:commit], new_app_options: options[:new_app_options])
192
239
  return if diff.empty?
193
240
 
194
241
  options[:fail] ? abort(diff) : puts(diff)
@@ -197,7 +244,7 @@ module Rails
197
244
  desc "generated GENERATOR [args]", "Compare files that would be created by a Rails generator"
198
245
  option :skip, type: :array, desc: "Skip specific files or directories", aliases: ["-s"], default: []
199
246
  def generated(generator_name, *args)
200
- diff = Rails::Diff.generated(generator_name, *args, no_cache: options[:no_cache], skip: options[:skip], commit: options[:commit])
247
+ diff = Rails::Diff.generated(generator_name, *args, no_cache: options[:no_cache], skip: options[:skip], commit: options[:commit], new_app_options: options[:new_app_options])
201
248
  return if diff.empty?
202
249
 
203
250
  options[:fail] ? abort(diff) : puts(diff)
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-diff
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matheus Richard
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-02-22 00:00:00.000000000 Z
10
+ date: 2025-03-06 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rails
@@ -62,6 +62,7 @@ extensions: []
62
62
  extra_rdoc_files: []
63
63
  files:
64
64
  - ".rspec"
65
+ - ".ruby-version"
65
66
  - CHANGELOG.md
66
67
  - LICENSE.txt
67
68
  - README.md
@@ -91,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
91
92
  - !ruby/object:Gem::Version
92
93
  version: '0'
93
94
  requirements: []
94
- rubygems_version: 3.6.5
95
+ rubygems_version: 3.6.2
95
96
  specification_version: 4
96
97
  summary: Compare Rails-generated files with the ones in your repository
97
98
  test_files: []