rails-diff 0.6.1 → 0.7.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 +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +31 -8
- data/lib/rails/diff/cli.rb +20 -3
- data/lib/rails/diff/file_tracker.rb +7 -16
- data/lib/rails/diff/rails_app_generator.rb +8 -8
- data/lib/rails/diff/rails_repo.rb +6 -3
- data/lib/rails/diff/version.rb +1 -1
- data/lib/rails/diff.rb +26 -12
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3b0a335992f7491133b576710e538fd0adc5d3bde79919e2fa60d145ae3e6055
|
|
4
|
+
data.tar.gz: f429b3d0d895f23bbda625a29172e3528bc86db2cb1e74fc6803aa7d2105c65e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: abe0d4f2ae2cf533aefa251726547b2eda321758edbf14882fc5948314d0e72eab78c054b238661f127df065fa6da0956b3469b07e2d219e35a199442443908e
|
|
7
|
+
data.tar.gz: 3bba7f7a5c9711601f7dcb11163947913103185f60a31dc3bd7f9e79c0b055fee8fad650a8abbb65c36b69deccec780f36b821c646216363f8a6286fcacb5318
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.7.0] - 2026-03-17
|
|
4
|
+
|
|
5
|
+
- Replace `diffy` with `difftastic` for better diff output with syntax highlighting.
|
|
6
|
+
- Add `--ref` option to compare against a specific tag, branch, or commit SHA (`--commit` is kept as an alias).
|
|
7
|
+
- [BUGFIX] `--commit` (now `--ref`) failed with shallow clones when the ref wasn't locally available.
|
|
8
|
+
|
|
3
9
|
## [0.6.0] - 2025-07-25
|
|
4
10
|
|
|
5
11
|
- Add `--only` option to only include specific files or directories in the diff.
|
|
@@ -70,6 +76,7 @@ M## [0.1.1] - 2025-02-21
|
|
|
70
76
|
|
|
71
77
|
- Initial release
|
|
72
78
|
|
|
79
|
+
[0.7.0]: https://github.com/matheusrich/rails-diff/releases/tag/v0.7.0
|
|
73
80
|
[0.6.0]: https://github.com/matheusrich/rails-diff/releases/tag/v0.6.0
|
|
74
81
|
[0.5.0]: https://github.com/matheusrich/rails-diff/releases/tag/v0.5.0
|
|
75
82
|
[0.4.1]: https://github.com/matheusrich/rails-diff/releases/tag/v0.4.1
|
data/README.md
CHANGED
|
@@ -41,8 +41,8 @@ rails-diff file Dockerfile --clear-cache
|
|
|
41
41
|
# Fail if there are differences (useful for CI)
|
|
42
42
|
rails-diff file Dockerfile --fail-on-diff
|
|
43
43
|
|
|
44
|
-
# Compare a specific commit
|
|
45
|
-
rails-diff file Dockerfile --
|
|
44
|
+
# Compare a specific ref (tag, branch, or commit SHA)
|
|
45
|
+
rails-diff file Dockerfile --ref v8.0.0
|
|
46
46
|
```
|
|
47
47
|
|
|
48
48
|
### Compare generator files
|
|
@@ -63,8 +63,8 @@ rails-diff generated scaffold Post --skip app/views app/helpers
|
|
|
63
63
|
# Fail if there are differences (useful for CI)
|
|
64
64
|
rails-diff generated scaffold Post --fail-on-diff
|
|
65
65
|
|
|
66
|
-
# Compare a specific commit
|
|
67
|
-
rails-diff generated authentication --
|
|
66
|
+
# Compare a specific ref (tag, branch, or commit SHA)
|
|
67
|
+
rails-diff generated authentication --ref v8.0.0
|
|
68
68
|
```
|
|
69
69
|
|
|
70
70
|
### Compare dotfiles (configuration files)
|
|
@@ -74,16 +74,39 @@ rails-diff generated authentication --commit 7df1b8
|
|
|
74
74
|
rails-diff dotfiles
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
+
### Compare infrastructure files
|
|
78
|
+
|
|
79
|
+
Compare all Rails-generated infrastructure files at once. This includes everything except `app/` and `lib/` (your application code): `bin/`, `config/`, `db/`, `public/`, `Dockerfile`, `Gemfile`, `Rakefile`, dotfiles, and more.
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# Compare all infrastructure files
|
|
83
|
+
rails-diff infra
|
|
84
|
+
|
|
85
|
+
# Compare only specific directories
|
|
86
|
+
rails-diff infra --only bin config
|
|
87
|
+
|
|
88
|
+
# Skip additional directories
|
|
89
|
+
rails-diff infra --skip db
|
|
90
|
+
|
|
91
|
+
# Fail if there are differences (useful for CI)
|
|
92
|
+
rails-diff infra --fail-on-diff
|
|
93
|
+
```
|
|
94
|
+
|
|
77
95
|
### Global Options
|
|
78
96
|
|
|
97
|
+
These options can be used with any of the commands above.
|
|
98
|
+
|
|
79
99
|
#### --fail-on-diff
|
|
80
100
|
|
|
81
101
|
If this option is specified, the command will exit with a non-zero status code if there are any differences between your files and the generated ones. This can be particularly useful when using the gem in Continuous Integration (CI) environments.
|
|
82
102
|
|
|
83
|
-
#### --
|
|
103
|
+
#### --ref <ref>
|
|
104
|
+
|
|
105
|
+
Specify a tag, branch, or commit SHA to compare against. If not provided, the
|
|
106
|
+
latest commit on main will be used by default. `--commit` is kept as an alias.
|
|
84
107
|
|
|
85
|
-
|
|
86
|
-
commit
|
|
108
|
+
> [!NOTE]
|
|
109
|
+
> When using a commit SHA, the full 40-character SHA is required (short SHAs are not supported).
|
|
87
110
|
|
|
88
111
|
#### --new-app-options <options>
|
|
89
112
|
|
|
@@ -148,7 +171,7 @@ The gem caches the generated Rails application to avoid regenerating it on every
|
|
|
148
171
|
- The cache directory doesn't exist (or is cleared with the `--clear-cache` option)
|
|
149
172
|
- You use `--new-app-options` with different options
|
|
150
173
|
- You change your `~/.railsrc` file
|
|
151
|
-
- You use `--
|
|
174
|
+
- You use `--ref` with a different ref
|
|
152
175
|
|
|
153
176
|
You can also force clear the cache by using the `--no-cache` option (or its alias `--clear-cache`) with any command.
|
|
154
177
|
|
data/lib/rails/diff/cli.rb
CHANGED
|
@@ -5,7 +5,7 @@ module Rails
|
|
|
5
5
|
class CLI < Thor
|
|
6
6
|
class_option :no_cache, type: :boolean, desc: "Clear cache before running", aliases: ["--clear-cache"]
|
|
7
7
|
class_option :fail_on_diff, type: :boolean, desc: "Fail if there are differences"
|
|
8
|
-
class_option :
|
|
8
|
+
class_option :ref, type: :string, desc: "Compare against a specific ref (tag, branch, or commit SHA)", aliases: ["--commit"]
|
|
9
9
|
class_option :new_app_options, type: :string, desc: "Options to pass to the rails new command"
|
|
10
10
|
class_option :debug, type: :boolean, desc: "Print debug information", aliases: ["-d"]
|
|
11
11
|
|
|
@@ -19,7 +19,7 @@ module Rails
|
|
|
19
19
|
diff = Rails::Diff.file(
|
|
20
20
|
*files,
|
|
21
21
|
no_cache: options[:no_cache],
|
|
22
|
-
|
|
22
|
+
ref: options[:ref],
|
|
23
23
|
new_app_options: options[:new_app_options]
|
|
24
24
|
)
|
|
25
25
|
return if diff.empty?
|
|
@@ -45,7 +45,24 @@ module Rails
|
|
|
45
45
|
no_cache: options[:no_cache],
|
|
46
46
|
skip: options[:skip],
|
|
47
47
|
only: options[:only],
|
|
48
|
-
|
|
48
|
+
ref: options[:ref],
|
|
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
|
+
desc "infra", "Compare non-application files in your repository (everything except app/ and lib/) with the ones generated by Rails"
|
|
57
|
+
option :skip, type: :array, desc: "Additional files or directories to skip", aliases: ["-s"], default: []
|
|
58
|
+
option :only, type: :array, desc: "Only include specific files or directories", aliases: ["-o"], default: []
|
|
59
|
+
def infra
|
|
60
|
+
ENV["DEBUG"] = "true" if options[:debug]
|
|
61
|
+
diff = Rails::Diff.infra(
|
|
62
|
+
no_cache: options[:no_cache],
|
|
63
|
+
skip: options[:skip],
|
|
64
|
+
only: options[:only],
|
|
65
|
+
ref: options[:ref],
|
|
49
66
|
new_app_options: options[:new_app_options]
|
|
50
67
|
)
|
|
51
68
|
return if diff.empty?
|
|
@@ -2,29 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
module Rails
|
|
4
4
|
module Diff
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
@base_dir = base_dir
|
|
8
|
-
@skip = skip
|
|
9
|
-
@only = only
|
|
10
|
-
end
|
|
5
|
+
module FileTracker
|
|
6
|
+
DEFAULT_EXCLUSIONS = %w[.git tmp log test].freeze
|
|
11
7
|
|
|
12
|
-
def new_files
|
|
13
|
-
files_before = list_files(
|
|
8
|
+
def self.new_files(base_dir, only:, skip: [])
|
|
9
|
+
files_before = list_files(base_dir)
|
|
14
10
|
yield
|
|
15
|
-
files_after = list_files(
|
|
11
|
+
files_after = list_files(base_dir, skip:, only:)
|
|
16
12
|
files_after - files_before
|
|
17
13
|
end
|
|
18
14
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def list_files(dir, skip = [], only = [])
|
|
15
|
+
def self.list_files(dir, skip: [], only: [], exclusions: DEFAULT_EXCLUSIONS)
|
|
22
16
|
files = Dir.glob("#{dir}/**/*", File::FNM_DOTMATCH).reject do |it|
|
|
23
17
|
File.directory?(it) ||
|
|
24
|
-
it.start_with?("#{dir}
|
|
25
|
-
it.start_with?("#{dir}/tmp") ||
|
|
26
|
-
it.start_with?("#{dir}/log") ||
|
|
27
|
-
it.start_with?("#{dir}/test") ||
|
|
18
|
+
exclusions.any? { |e| it.start_with?("#{dir}/#{e}") } ||
|
|
28
19
|
skip.any? { |s| it.start_with?("#{dir}/#{s}") }
|
|
29
20
|
end
|
|
30
21
|
|
|
@@ -5,10 +5,10 @@ module Rails
|
|
|
5
5
|
class RailsAppGenerator
|
|
6
6
|
RAILSRC_PATH = "#{ENV["HOME"]}/.railsrc"
|
|
7
7
|
|
|
8
|
-
def initialize(
|
|
8
|
+
def initialize(ref: nil, new_app_options: nil, no_cache: false, logger: Logger, cache_dir: Rails::Diff::CACHE_DIR)
|
|
9
9
|
@new_app_options = new_app_options.to_s.split
|
|
10
10
|
@rails_repo = RailsRepo.new(logger:, cache_dir:)
|
|
11
|
-
@
|
|
11
|
+
@ref = ref
|
|
12
12
|
@logger = logger
|
|
13
13
|
@cache_dir = cache_dir
|
|
14
14
|
clear_cache if no_cache
|
|
@@ -44,8 +44,8 @@ module Rails
|
|
|
44
44
|
Shell.run!("bin/rails", "destroy", generator_name, *args, logger:)
|
|
45
45
|
logger.info "Running generator: rails generate #{generator_name} #{args.join(" ")}"
|
|
46
46
|
|
|
47
|
-
FileTracker
|
|
48
|
-
.new_files { Shell.run!("bin/rails", "generate", generator_name, *args, logger:) }
|
|
47
|
+
FileTracker
|
|
48
|
+
.new_files(template_app_path, skip:, only:) { Shell.run!("bin/rails", "generate", generator_name, *args, logger:) }
|
|
49
49
|
.map { |it| it.delete_prefix("#{template_app_path}/") }
|
|
50
50
|
end
|
|
51
51
|
end
|
|
@@ -54,9 +54,9 @@ module Rails
|
|
|
54
54
|
|
|
55
55
|
attr_reader :new_app_options, :rails_repo, :logger, :cache_dir
|
|
56
56
|
|
|
57
|
-
def
|
|
57
|
+
def ref = @ref ||= rails_repo.latest_commit
|
|
58
58
|
|
|
59
|
-
def rails_cache_dir_key = "rails-#{
|
|
59
|
+
def rails_cache_dir_key = "rails-#{ref.first(10)}"
|
|
60
60
|
|
|
61
61
|
def railsrc_options
|
|
62
62
|
@railsrc_options ||= File.exist?(RAILSRC_PATH) ? File.readlines(RAILSRC_PATH) : []
|
|
@@ -69,7 +69,7 @@ module Rails
|
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
def create_new_rails_app
|
|
72
|
-
|
|
72
|
+
checkout_rails_ref
|
|
73
73
|
generate_app
|
|
74
74
|
end
|
|
75
75
|
|
|
@@ -81,7 +81,7 @@ module Rails
|
|
|
81
81
|
rails_repo.new_app(template_app_path, rails_new_options)
|
|
82
82
|
end
|
|
83
83
|
|
|
84
|
-
def
|
|
84
|
+
def checkout_rails_ref = rails_repo.checkout(ref)
|
|
85
85
|
|
|
86
86
|
def rails_new_options
|
|
87
87
|
@rails_new_options ||= (new_app_options + railsrc_options).compact
|
|
@@ -9,10 +9,13 @@ module Rails
|
|
|
9
9
|
@rails_repo = rails_repo
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
def checkout(
|
|
12
|
+
def checkout(ref)
|
|
13
13
|
on_rails_dir do
|
|
14
|
-
logger.info "Checking out Rails (at
|
|
15
|
-
Shell.run!("git", "checkout",
|
|
14
|
+
logger.info "Checking out Rails (at #{ref})"
|
|
15
|
+
unless Shell.run!("git", "checkout", ref, abort: false, logger:)
|
|
16
|
+
Shell.run!("git", "fetch", "--depth", "1", "origin", ref, logger:)
|
|
17
|
+
Shell.run!("git", "checkout", "FETCH_HEAD", logger:)
|
|
18
|
+
end
|
|
16
19
|
end
|
|
17
20
|
end
|
|
18
21
|
|
data/lib/rails/diff/version.rb
CHANGED
data/lib/rails/diff.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "rails"
|
|
4
|
-
require "
|
|
4
|
+
require "difftastic"
|
|
5
5
|
require "fileutils"
|
|
6
6
|
require_relative "diff/cli"
|
|
7
7
|
require_relative "diff/file_tracker"
|
|
@@ -16,8 +16,8 @@ module Rails
|
|
|
16
16
|
CACHE_DIR = File.expand_path("#{ENV["HOME"]}/.rails-diff/cache")
|
|
17
17
|
|
|
18
18
|
class << self
|
|
19
|
-
def file(*files, no_cache: false,
|
|
20
|
-
app_generator = RailsAppGenerator.new(
|
|
19
|
+
def file(*files, no_cache: false, ref: nil, new_app_options: nil)
|
|
20
|
+
app_generator = RailsAppGenerator.new(ref:, new_app_options:, no_cache:)
|
|
21
21
|
app_generator.create_template_app
|
|
22
22
|
|
|
23
23
|
files
|
|
@@ -25,13 +25,26 @@ module Rails
|
|
|
25
25
|
.join("\n")
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
def generated(generator_name, *args, no_cache: false, skip: [], only: [],
|
|
29
|
-
app_generator = RailsAppGenerator.new(
|
|
28
|
+
def generated(generator_name, *args, no_cache: false, skip: [], only: [], ref: nil, new_app_options: nil)
|
|
29
|
+
app_generator = RailsAppGenerator.new(ref:, new_app_options:, no_cache:)
|
|
30
30
|
app_generator.create_template_app
|
|
31
31
|
app_generator.install_app_dependencies
|
|
32
32
|
|
|
33
33
|
app_generator.run_generator(generator_name, *args, skip, only)
|
|
34
|
-
.
|
|
34
|
+
.filter_map { |it| diff_with_header(it, app_generator.template_app_path) }
|
|
35
|
+
.join("\n\n")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def infra(no_cache: false, skip: [], only: [], ref: nil, new_app_options: nil)
|
|
39
|
+
app_generator = RailsAppGenerator.new(ref:, new_app_options:, no_cache:)
|
|
40
|
+
app_generator.create_template_app
|
|
41
|
+
|
|
42
|
+
default_skip = %w[app lib]
|
|
43
|
+
effective_skip = (default_skip + skip).uniq
|
|
44
|
+
|
|
45
|
+
FileTracker.list_files(app_generator.template_app_path, skip: effective_skip, only:)
|
|
46
|
+
.map { |f| f.delete_prefix("#{app_generator.template_app_path}/") }
|
|
47
|
+
.filter_map { |it| diff_with_header(it, app_generator.template_app_path) }
|
|
35
48
|
.join("\n\n")
|
|
36
49
|
end
|
|
37
50
|
|
|
@@ -52,12 +65,13 @@ module Rails
|
|
|
52
65
|
return "File not found in the Rails template" unless File.exist?(rails_file)
|
|
53
66
|
return "File not found in your repository" unless File.exist?(repo_file)
|
|
54
67
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
68
|
+
differ = Difftastic::Differ.new(
|
|
69
|
+
color: :always,
|
|
70
|
+
left_label: "Rails File (#{file})",
|
|
71
|
+
right_label: "Repo File (#{file})"
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
differ.diff_files(rails_file, repo_file).chomp
|
|
61
75
|
end
|
|
62
76
|
end
|
|
63
77
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rails-diff
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Matheus Richard
|
|
@@ -24,19 +24,19 @@ dependencies:
|
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: '7.0'
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
|
-
name:
|
|
27
|
+
name: difftastic
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
29
29
|
requirements:
|
|
30
30
|
- - "~>"
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: '
|
|
32
|
+
version: '0.8'
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
37
|
- - "~>"
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: '
|
|
39
|
+
version: '0.8'
|
|
40
40
|
- !ruby/object:Gem::Dependency
|
|
41
41
|
name: thor
|
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|