rails-diff 0.4.1 → 0.6.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: 453cfc382c12f3289040c2a737433d727ca411912da3302f772f55bf0b18ce11
4
- data.tar.gz: b93d35f857877e7b4d15cdb2f4387ec8d527708db106b0a9dbb9a370fb2ede73
3
+ metadata.gz: ebc8de5879d978edc4129cae7ec7bf8b71dc0b49ab8b5ff9bc6df8cb74baabf8
4
+ data.tar.gz: bf3f60595d842e247cf1219c8c48ad86d020a791f8d47475cce486fa63a85efc
5
5
  SHA512:
6
- metadata.gz: 0bc0bd3b39bb5b82b770f5b599d93a6c3cd7566561d587e69974b3fcfbf5ae53736ce49f49a79edf3c7db2fa5352f4586a94ad13e18300950414bbd9fa27ac57
7
- data.tar.gz: 7aac8160f88f3842a2d1074bcc0e98b88bfaa1cfdb87ead3b4f45d6e78a854cc27914a41b9b1057e8ffcb18ee2ae4012342020aaeffc3ed03816e7ffabe8559f
6
+ metadata.gz: 4022acb24a1b2ca674ed1e8c5d20797a641e8d20e571d138c99b98cb5a23212e4df06301a9362fa3bbcd0275d2ae384c93a836080ac3f1e4abbaef116f00871a
7
+ data.tar.gz: aff70125214849a5416b197d4060faba06a23262fc20f49c250dbb78c0d5df47d2d65f2f05e9f30a45f79d9bfb3dd622fed927b1791df3816e14de057f749266
data/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.6.0] - 2025-07-25
4
+
5
+ - Add `--only` option to only include specific files or directories in the diff.
6
+ - Add `rails-diff dotfiles` to compare dotfiles (configuration files) in the repository.
7
+ - [BUGFIX] --fail-on-diff wasn't aborting with errors on diff.
8
+
9
+ ## [0.5.0] - 2025-03-10
10
+
11
+ - Don't abort process on bundle check failure.
12
+ - Add optional debug logs.
13
+
14
+ ```sh
15
+ rails-diff file Gemfile --debug
16
+ ```
17
+
18
+ or
19
+
20
+ ```sh
21
+ DEBUG=1 rails-diff file Gemfile
22
+ ```
23
+
3
24
  ## [0.4.1] - 2025-03-05
4
25
 
5
26
  - Bump `rack` and `uri` minor versions.
@@ -49,6 +70,10 @@ M## [0.1.1] - 2025-02-21
49
70
 
50
71
  - Initial release
51
72
 
73
+ [0.6.0]: https://github.com/matheusrich/rails-diff/releases/tag/v0.6.0
74
+ [0.5.0]: https://github.com/matheusrich/rails-diff/releases/tag/v0.5.0
75
+ [0.4.1]: https://github.com/matheusrich/rails-diff/releases/tag/v0.4.1
76
+ [0.4.1]: https://github.com/matheusrich/rails-diff/releases/tag/v0.4.1
52
77
  [0.4.0]: https://github.com/matheusrich/rails-diff/releases/tag/v0.4.0
53
78
  [0.3.0]: https://github.com/matheusrich/rails-diff/releases/tag/v0.3.0
54
79
  [0.2.1]: https://github.com/matheusrich/rails-diff/releases/tag/v0.2.1
data/README.md CHANGED
@@ -67,7 +67,14 @@ rails-diff generated scaffold Post --fail-on-diff
67
67
  rails-diff generated authentication --commit 7df1b8
68
68
  ```
69
69
 
70
- ### Options
70
+ ### Compare dotfiles (configuration files)
71
+
72
+ ```bash
73
+ # Compare configuration files like .gitignore, .rspec, .rubocop.yml
74
+ rails-diff dotfiles
75
+ ```
76
+
77
+ ### Global Options
71
78
 
72
79
  #### --fail-on-diff
73
80
 
@@ -88,6 +95,44 @@ Example:
88
95
  rails-diff file Dockerfile --new-app-options="--database=postgresql"
89
96
  ```
90
97
 
98
+ #### --skip <files/directories>
99
+
100
+ Skip specific files or directories during the diff.
101
+
102
+ ```bash
103
+ rails-diff generated scaffold Post --skip app/views app/helpers
104
+ ```
105
+
106
+ #### --only <files/directories>
107
+
108
+ Only include specific files or directories in the diff.
109
+
110
+ ```bash
111
+ rails-diff generated scaffold Post --only app/models app/controllers
112
+ ```
113
+
114
+ #### --clear-cache/--no-cache
115
+
116
+ Clear the cache directory to force cloning Rails and regenerating the Rails template app.
117
+
118
+ ```bash
119
+ rails-diff file Dockerfile --clear-cache
120
+ ```
121
+
122
+ #### --debug
123
+
124
+ Print debug information.
125
+
126
+ ```sh
127
+ rails-diff file Gemfile --debug
128
+ ```
129
+
130
+ or with an environment variable:
131
+
132
+ ```sh
133
+ DEBUG=1 rails-diff file Gemfile
134
+ ```
135
+
91
136
  ## How it works
92
137
 
93
138
  When you run the diff, it will:
@@ -100,7 +145,10 @@ When you run the diff, it will:
100
145
 
101
146
  The gem caches the generated Rails application to avoid regenerating it on every run. The cache is automatically invalidated when:
102
147
  - Rails has new commits on main
103
- - The cache directory doesn't exist
148
+ - The cache directory doesn't exist (or is cleared with the `--clear-cache` option)
149
+ - You use `--new-app-options` with different options
150
+ - You change your `~/.railsrc` file
151
+ - You use `--commit` with a different commit
104
152
 
105
153
  You can also force clear the cache by using the `--no-cache` option (or its alias `--clear-cache`) with any command.
106
154
 
@@ -0,0 +1,63 @@
1
+ require "thor"
2
+
3
+ module Rails
4
+ module Diff
5
+ class CLI < Thor
6
+ class_option :no_cache, type: :boolean, desc: "Clear cache before running", aliases: ["--clear-cache"]
7
+ class_option :fail_on_diff, type: :boolean, desc: "Fail if there are differences"
8
+ class_option :commit, type: :string, desc: "Compare against a specific commit"
9
+ class_option :new_app_options, type: :string, desc: "Options to pass to the rails new command"
10
+ class_option :debug, type: :boolean, desc: "Print debug information", aliases: ["-d"]
11
+
12
+ def self.exit_on_failure? = true
13
+
14
+ desc "file FILE [FILE ...]", "Compare one or more files from your repository with Rails' generated version"
15
+ def file(*files)
16
+ abort "Please provide at least one file to compare" if files.empty?
17
+ ENV["DEBUG"] = "true" if options[:debug]
18
+
19
+ diff = Rails::Diff.file(
20
+ *files,
21
+ no_cache: options[:no_cache],
22
+ commit: options[:commit],
23
+ new_app_options: options[:new_app_options]
24
+ )
25
+ return if diff.empty?
26
+
27
+ options[:fail_on_diff] ? abort(diff) : puts(diff)
28
+ end
29
+
30
+ desc "dotfiles", "Compare dotfiles in your repository with the ones generated by Rails"
31
+ def dotfiles
32
+ dotfiles = `git ls-files --cached --others --exclude-standard -- '.*'`.split("\n")
33
+
34
+ file(*dotfiles)
35
+ end
36
+
37
+ desc "generated GENERATOR [args]", "Compare files that would be created by a Rails generator"
38
+ option :skip, type: :array, desc: "Skip specific files or directories", aliases: ["-s"], default: []
39
+ option :only, type: :array, desc: "Only include specific files or directories", aliases: ["-o"], default: []
40
+ def generated(generator_name, *args)
41
+ ENV["DEBUG"] = "true" if options[:debug]
42
+ diff = Rails::Diff.generated(
43
+ generator_name,
44
+ *args,
45
+ no_cache: options[:no_cache],
46
+ skip: options[:skip],
47
+ only: options[:only],
48
+ commit: options[:commit],
49
+ new_app_options: options[:new_app_options]
50
+ )
51
+ return if diff.empty?
52
+
53
+ options[:fail_on_diff] ? abort(diff) : puts(diff)
54
+ end
55
+
56
+ map %w[--version -v] => :__version
57
+ desc "--version, -v", "print the version"
58
+ def __version
59
+ puts VERSION
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rails
4
+ module Diff
5
+ class FileTracker
6
+ def initialize(base_dir, skip = [], only = [])
7
+ @base_dir = base_dir
8
+ @skip = skip
9
+ @only = only
10
+ end
11
+
12
+ def new_files
13
+ files_before = list_files(@base_dir)
14
+ yield
15
+ files_after = list_files(@base_dir, @skip, @only)
16
+ files_after - files_before
17
+ end
18
+
19
+ private
20
+
21
+ def list_files(dir, skip = [], only = [])
22
+ files = Dir.glob("#{dir}/**/*", File::FNM_DOTMATCH).reject do |it|
23
+ File.directory?(it) ||
24
+ it.start_with?("#{dir}/.git") ||
25
+ it.start_with?("#{dir}/tmp") ||
26
+ it.start_with?("#{dir}/log") ||
27
+ it.start_with?("#{dir}/test") ||
28
+ skip.any? { |s| it.start_with?("#{dir}/#{s}") }
29
+ end
30
+
31
+ if only.any?
32
+ files.select { |it| only.any? { |o| it.start_with?("#{dir}/#{o}") } }
33
+ else
34
+ files
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,21 @@
1
+ module Rails
2
+ module Diff
3
+ module Logger
4
+ extend self
5
+
6
+ def info(message)
7
+ puts "\e[1;34minfo:\e[0m\t#{message}"
8
+ end
9
+
10
+ def debug(message)
11
+ return unless ENV["DEBUG"]
12
+
13
+ puts "\e[1;33mdebug:\e[0m\t#{message}"
14
+ end
15
+
16
+ def error(label, message)
17
+ warn "\e[1;31m#{label}\e[0m #{message}"
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,95 @@
1
+ require "digest"
2
+
3
+ module Rails
4
+ module Diff
5
+ class RailsAppGenerator
6
+ RAILSRC_PATH = "#{ENV["HOME"]}/.railsrc"
7
+
8
+ def initialize(commit: nil, new_app_options: nil, no_cache: false, logger: Logger, cache_dir: Rails::Diff::CACHE_DIR)
9
+ @new_app_options = new_app_options.to_s.split
10
+ @rails_repo = RailsRepo.new(logger:, cache_dir:)
11
+ @commit = commit
12
+ @logger = logger
13
+ @cache_dir = cache_dir
14
+ clear_cache if no_cache
15
+ end
16
+
17
+ def clear_cache
18
+ logger.info "Clearing cache"
19
+ FileUtils.rm_rf(cache_dir, secure: true)
20
+ FileUtils.mkdir_p(cache_dir)
21
+ end
22
+
23
+ def create_template_app
24
+ return if cached_app?
25
+
26
+ create_new_rails_app
27
+ end
28
+
29
+ def template_app_path
30
+ @template_app_path ||= File.join(cache_dir, rails_cache_dir_key, rails_new_options_hash, app_name)
31
+ end
32
+
33
+ def install_app_dependencies
34
+ Dir.chdir(template_app_path) do
35
+ unless Rails::Diff.system!("bundle check", abort: false, logger: logger)
36
+ logger.info "Installing application dependencies"
37
+ Rails::Diff.system!("bundle install", logger: logger)
38
+ end
39
+ end
40
+ end
41
+
42
+ def run_generator(generator_name, *args, skip, only)
43
+ Dir.chdir(template_app_path) do
44
+ Rails::Diff.system!("bin/rails", "destroy", generator_name, *args, logger: logger)
45
+ logger.info "Running generator: rails generate #{generator_name} #{args.join(" ")}"
46
+
47
+ FileTracker.new(template_app_path, skip, only)
48
+ .new_files { Rails::Diff.system!("bin/rails", "generate", generator_name, *args, logger: logger) }
49
+ .map { |it| it.delete_prefix("#{template_app_path}/") }
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ attr_reader :new_app_options, :rails_repo, :logger, :cache_dir
56
+
57
+ def commit = @commit ||= rails_repo.latest_commit
58
+
59
+ def rails_cache_dir_key = "rails-#{commit.first(10)}"
60
+
61
+ def railsrc_options
62
+ @railsrc_options ||= File.exist?(RAILSRC_PATH) ? File.readlines(RAILSRC_PATH) : []
63
+ end
64
+
65
+ def app_name = @app_name ||= File.basename(Dir.pwd)
66
+
67
+ def cached_app?
68
+ File.exist?(template_app_path) && rails_repo.up_to_date?
69
+ end
70
+
71
+ def create_new_rails_app
72
+ checkout_rails_commit
73
+ generate_app
74
+ end
75
+
76
+ def generate_app
77
+ rails_repo.install_dependencies
78
+ if railsrc_options.any?
79
+ logger.info "Using default options from #{RAILSRC_PATH}:\n\t > #{railsrc_options.join(" ")}"
80
+ end
81
+ rails_repo.new_app(template_app_path, rails_new_options)
82
+ end
83
+
84
+ def checkout_rails_commit = rails_repo.checkout(commit)
85
+
86
+ def rails_new_options
87
+ @rails_new_options ||= (new_app_options + railsrc_options).compact
88
+ end
89
+
90
+ def rails_new_options_hash
91
+ Digest::MD5.hexdigest(rails_new_options.join(" "))
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,88 @@
1
+ module Rails
2
+ module Diff
3
+ class RailsRepo
4
+ RAILS_REPO = "https://github.com/rails/rails.git"
5
+
6
+ def initialize(logger:, cache_dir: Rails::Diff::CACHE_DIR, rails_repo: RAILS_REPO)
7
+ @logger = logger
8
+ @cache_dir = cache_dir
9
+ @rails_repo = rails_repo
10
+ end
11
+
12
+ def checkout(commit)
13
+ on_rails_dir do
14
+ logger.info "Checking out Rails (at commit #{commit[0..6]})"
15
+ Rails::Diff.system!("git", "checkout", commit, logger: logger)
16
+ end
17
+ end
18
+
19
+ def latest_commit
20
+ @latest_commit ||= on_rails_dir do
21
+ Rails::Diff.system!("git fetch origin main", logger: logger)
22
+ `git rev-parse origin/main`.strip
23
+ end
24
+ end
25
+
26
+ def up_to_date?
27
+ File.exist?(rails_path) && on_latest_commit?
28
+ end
29
+
30
+ def install_dependencies
31
+ within "railties" do
32
+ unless Rails::Diff.system!("bundle check", abort: false, logger: logger)
33
+ logger.info "Installing Rails dependencies"
34
+ Rails::Diff.system!("bundle install", logger: logger)
35
+ end
36
+ end
37
+ end
38
+
39
+ def new_app(name, options)
40
+ within "railties" do
41
+ command = rails_new_command(name, options)
42
+ logger.info "Generating new Rails application\n\t > #{command.join(" ")}"
43
+ Rails::Diff.system!(*command, logger: logger)
44
+ end
45
+ end
46
+
47
+ def within(dir, &block) = on_rails_dir { Dir.chdir(dir, &block) }
48
+
49
+ private
50
+
51
+ attr_reader :logger, :cache_dir, :rails_repo
52
+
53
+ def rails_path
54
+ File.join(cache_dir, "rails")
55
+ end
56
+
57
+ def on_latest_commit?
58
+ if current_commit == latest_commit
59
+ true
60
+ else
61
+ remove_repo
62
+ false
63
+ end
64
+ end
65
+
66
+ def on_rails_dir(&block)
67
+ clone_repo unless File.exist?(rails_path)
68
+ Dir.chdir(rails_path, &block)
69
+ end
70
+
71
+ def current_commit = on_rails_dir { `git rev-parse HEAD`.strip }
72
+
73
+ def remove_repo = FileUtils.rm_rf(rails_path, secure: true)
74
+
75
+ def clone_repo
76
+ logger.info "Cloning Rails repository"
77
+ Rails::Diff.system!("git", "clone", "--depth", "1", rails_repo, rails_path, logger: logger)
78
+ end
79
+
80
+ def rails_new_command(name, options)
81
+ [
82
+ "bundle", "exec", "rails", "new", name,
83
+ "--main", "--skip-bundle", "--force", "--quiet", *options
84
+ ]
85
+ end
86
+ end
87
+ end
88
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Rails
4
4
  module Diff
5
- VERSION = "0.4.1"
5
+ VERSION = "0.6.0"
6
6
  end
7
7
  end
data/lib/rails/diff.rb CHANGED
@@ -1,137 +1,64 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "diff/version"
4
3
  require "rails"
5
- require "thor"
6
4
  require "diffy"
7
5
  require "fileutils"
8
6
  require "open3"
7
+ require_relative "diff/cli"
8
+ require_relative "diff/file_tracker"
9
+ require_relative "diff/logger"
10
+ require_relative "diff/rails_app_generator"
11
+ require_relative "diff/rails_repo"
12
+ require_relative "diff/version"
9
13
 
10
14
  module Rails
11
15
  module Diff
12
- class Error < StandardError; end
13
-
14
- RAILS_REPO = "https://github.com/rails/rails.git"
15
16
  CACHE_DIR = File.expand_path("#{ENV["HOME"]}/.rails-diff/cache")
16
- RAILSRC_PATH = "#{ENV["HOME"]}/.railsrc"
17
17
 
18
18
  class << self
19
19
  def file(*files, no_cache: false, commit: nil, new_app_options: nil)
20
- clear_cache if no_cache
21
- ensure_template_app_exists(commit, new_app_options)
20
+ app_generator = RailsAppGenerator.new(commit:, new_app_options:, no_cache:)
21
+ app_generator.create_template_app
22
22
 
23
- files.filter_map { |it| diff_with_header(it) }.join("\n")
23
+ files
24
+ .filter_map { |it| diff_with_header(it, app_generator.template_app_path) }
25
+ .join("\n")
24
26
  end
25
27
 
26
- def generated(generator_name, *args, no_cache: false, skip: [], commit: nil, new_app_options: nil)
27
- clear_cache if no_cache
28
- ensure_template_app_exists(commit, new_app_options)
29
- install_app_dependencies
28
+ def generated(generator_name, *args, no_cache: false, skip: [], only: [], commit: nil, new_app_options: nil)
29
+ app_generator = RailsAppGenerator.new(commit:, new_app_options:, no_cache:)
30
+ app_generator.create_template_app
31
+ app_generator.install_app_dependencies
30
32
 
31
- generated_files(generator_name, *args, skip)
32
- .map { |it| diff_with_header(it) }
33
+ app_generator.run_generator(generator_name, *args, skip, only)
34
+ .map { |it| diff_with_header(it, app_generator.template_app_path) }
33
35
  .join("\n\n")
34
36
  end
35
37
 
36
- private
37
-
38
- def system!(*cmd)
38
+ def system!(*cmd, logger:, abort: true)
39
39
  _, stderr, status = Open3.capture3(*cmd)
40
-
41
- unless status.success?
42
- puts "\e[1;31mCommand failed:\e[0m #{cmd.join(' ')}"
40
+ logger.debug(cmd.join(" "))
41
+ if status.success?
42
+ true
43
+ elsif abort
44
+ logger.error("Command failed:", cmd.join(" "))
43
45
  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
-
53
- def clear_cache
54
- info "Clearing cache"
55
- FileUtils.rm_rf(CACHE_DIR)
56
- end
57
-
58
- def ensure_template_app_exists(commit, new_app_options)
59
- FileUtils.mkdir_p(CACHE_DIR)
60
- @new_app_options = new_app_options
61
- @commit = commit || latest_commit
62
- return if cached_app?
63
-
64
- create_new_rails_app
65
- end
66
-
67
- def template_app_path
68
- @template_app_path ||= File.join(CACHE_DIR, "rails-#{commit.first(10)}", rails_new_options_hash, app_name)
69
- end
70
-
71
- def rails_path
72
- @rails_path ||= begin
73
- File.join(CACHE_DIR, "rails").tap do |path|
74
- unless File.exist?(path)
75
- info "Cloning Rails repository"
76
- system!("git", "clone", "--depth", "1", RAILS_REPO, path)
77
- end
78
- end
46
+ else
47
+ false
79
48
  end
80
49
  end
81
50
 
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
-
88
- def app_name = @app_name ||= File.basename(Dir.pwd)
89
-
90
- def list_files(dir, skip = [])
91
- Dir.glob("#{dir}/**/*", File::FNM_DOTMATCH).reject do |it|
92
- File.directory?(it) ||
93
- it.start_with?("#{dir}/.git") ||
94
- it.start_with?("#{dir}/tmp") ||
95
- it.start_with?("#{dir}/log") ||
96
- it.start_with?("#{dir}/test") ||
97
- skip.any? { |s| it.start_with?("#{dir}/#{s}") }
98
- end
99
- end
100
-
101
- def track_new_files(skip)
102
- files_before = list_files(template_app_path)
103
- yield
104
- files_after = list_files(template_app_path, skip)
105
- files_after - files_before
106
- end
107
-
108
- def generated_files(generator_name, *args, skip)
109
- Dir.chdir(template_app_path) do
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) }
113
- .map { |it| it.delete_prefix("#{template_app_path}/") }
114
- end
115
- end
51
+ private
116
52
 
117
- def diff_with_header(file)
118
- diff = diff_file(file)
53
+ def diff_with_header(file, template_app_path)
54
+ diff = diff_file(file, template_app_path)
119
55
  return if diff.empty?
120
56
 
121
57
  header = "#{file} diff:"
122
58
  [header, "=" * header.size, diff].join("\n")
123
59
  end
124
60
 
125
- def install_app_dependencies
126
- Dir.chdir(template_app_path) do
127
- unless system!("bundle check")
128
- info "Installing application dependencies"
129
- system!("bundle install")
130
- end
131
- end
132
- end
133
-
134
- def diff_file(file)
61
+ def diff_file(file, template_app_path)
135
62
  rails_file = File.join(template_app_path, file)
136
63
  repo_file = File.join(Dir.pwd, file)
137
64
 
@@ -142,119 +69,9 @@ module Rails
142
69
  rails_file,
143
70
  repo_file,
144
71
  context: 2,
145
- source: 'files'
72
+ source: "files"
146
73
  ).to_s(:color).chomp
147
74
  end
148
-
149
- def cached_app?
150
- File.exist?(template_app_path) && !out_of_date_rails?
151
- end
152
-
153
- def out_of_date_rails?
154
- return true unless File.exist?(rails_path)
155
-
156
- Dir.chdir(rails_path) do
157
- system!("git fetch origin main")
158
- current = `git rev-parse HEAD`.strip
159
- latest = `git rev-parse origin/main`.strip
160
-
161
- if current != latest
162
- FileUtils.rm_rf(rails_path)
163
- return true
164
- end
165
- end
166
-
167
- false
168
- end
169
-
170
- def create_new_rails_app
171
- Dir.chdir(rails_path) do
172
- checkout_rails
173
- generate_app
174
- end
175
- end
176
-
177
- def generate_app
178
- Dir.chdir("railties") do
179
- unless system!("bundle check")
180
- info "Installing Rails dependencies"
181
- system!("bundle install")
182
- end
183
-
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)
190
- end
191
- end
192
-
193
- def checkout_rails
194
- info "Checking out Rails (at commit #{commit[0..6]})"
195
- system!("git", "checkout", commit)
196
- end
197
-
198
- def commit = @commit
199
-
200
- def new_app_options = @new_app_options
201
-
202
- def latest_commit
203
- Dir.chdir(rails_path) do
204
- `git rev-parse origin/main`.strip
205
- end
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(" "))
224
- end
225
-
226
- class CLI < Thor
227
- class_option :no_cache, type: :boolean, desc: "Clear cache before running", aliases: ["--clear-cache"]
228
- class_option :fail_on_diff, type: :boolean, desc: "Fail if there are differences"
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"
231
-
232
- def self.exit_on_failure? = true
233
-
234
- desc "file FILE [FILE ...]", "Compare one or more files from your repository with Rails' generated version"
235
- def file(*files)
236
- abort "Please provide at least one file to compare" if files.empty?
237
-
238
- diff = Rails::Diff.file(*files, no_cache: options[:no_cache], commit: options[:commit], new_app_options: options[:new_app_options])
239
- return if diff.empty?
240
-
241
- options[:fail] ? abort(diff) : puts(diff)
242
- end
243
-
244
- desc "generated GENERATOR [args]", "Compare files that would be created by a Rails generator"
245
- option :skip, type: :array, desc: "Skip specific files or directories", aliases: ["-s"], default: []
246
- def generated(generator_name, *args)
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])
248
- return if diff.empty?
249
-
250
- options[:fail] ? abort(diff) : puts(diff)
251
- end
252
-
253
- map %w[--version -v] => :__version
254
- desc "--version, -v", "print the version"
255
- def __version
256
- puts VERSION
257
- end
258
75
  end
259
76
  end
260
77
  end
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.4.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matheus Richard
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-03-06 00:00:00.000000000 Z
10
+ date: 2025-07-25 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rails
@@ -69,6 +69,11 @@ files:
69
69
  - Rakefile
70
70
  - exe/rails-diff
71
71
  - lib/rails/diff.rb
72
+ - lib/rails/diff/cli.rb
73
+ - lib/rails/diff/file_tracker.rb
74
+ - lib/rails/diff/logger.rb
75
+ - lib/rails/diff/rails_app_generator.rb
76
+ - lib/rails/diff/rails_repo.rb
72
77
  - lib/rails/diff/version.rb
73
78
  homepage: https://github.com/matheusrich/rails-diff
74
79
  licenses: