rfix 1.2.2

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.
Files changed (92) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/main.yml +38 -0
  3. data/.gitignore +43 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +87 -0
  6. data/.travis.yml +37 -0
  7. data/Gemfile +2 -0
  8. data/Gemfile.base +14 -0
  9. data/Gemfile.base.lock +172 -0
  10. data/Gemfile.lock +181 -0
  11. data/Guardfile +16 -0
  12. data/LICENSE.txt +21 -0
  13. data/Makefile +4 -0
  14. data/README.md +92 -0
  15. data/Rakefile +27 -0
  16. data/bin/bundle +114 -0
  17. data/bin/console +29 -0
  18. data/bin/guard +29 -0
  19. data/bin/rake +29 -0
  20. data/bin/rfix +29 -0
  21. data/bin/rspec +29 -0
  22. data/bin/setup +29 -0
  23. data/ci/Gemfile.rubocop-0.80 +2 -0
  24. data/ci/Gemfile.rubocop-0.80.lock +170 -0
  25. data/ci/Gemfile.rubocop-0.81 +2 -0
  26. data/ci/Gemfile.rubocop-0.81.lock +170 -0
  27. data/ci/Gemfile.rubocop-0.82 +2 -0
  28. data/ci/Gemfile.rubocop-0.82.lock +170 -0
  29. data/ci/Gemfile.rubocop-0.83 +2 -0
  30. data/ci/Gemfile.rubocop-0.83.lock +168 -0
  31. data/ci/Gemfile.rubocop-0.84 +2 -0
  32. data/ci/Gemfile.rubocop-0.84.lock +171 -0
  33. data/ci/Gemfile.rubocop-0.85 +2 -0
  34. data/ci/Gemfile.rubocop-0.85.1 +2 -0
  35. data/ci/Gemfile.rubocop-0.85.1.lock +173 -0
  36. data/ci/Gemfile.rubocop-0.85.lock +173 -0
  37. data/exe/rfix +30 -0
  38. data/lib/rfix.rb +34 -0
  39. data/lib/rfix/box.rb +112 -0
  40. data/lib/rfix/branch.rb +31 -0
  41. data/lib/rfix/branches/base.rb +29 -0
  42. data/lib/rfix/branches/head.rb +13 -0
  43. data/lib/rfix/branches/main.rb +34 -0
  44. data/lib/rfix/branches/name.rb +23 -0
  45. data/lib/rfix/branches/reference.rb +21 -0
  46. data/lib/rfix/branches/upstream.rb +13 -0
  47. data/lib/rfix/cmd.rb +39 -0
  48. data/lib/rfix/commands/branch.rb +15 -0
  49. data/lib/rfix/commands/extensions/options.rb +8 -0
  50. data/lib/rfix/commands/help.rb +7 -0
  51. data/lib/rfix/commands/helper/args.rb +137 -0
  52. data/lib/rfix/commands/helper/help.rb +6 -0
  53. data/lib/rfix/commands/helper/loader.rb +6 -0
  54. data/lib/rfix/commands/helper/option.rb +0 -0
  55. data/lib/rfix/commands/helper/params.rb +0 -0
  56. data/lib/rfix/commands/helper/rubocop.rb +17 -0
  57. data/lib/rfix/commands/info.rb +30 -0
  58. data/lib/rfix/commands/lint.rb +23 -0
  59. data/lib/rfix/commands/local.rb +12 -0
  60. data/lib/rfix/commands/origin.rb +19 -0
  61. data/lib/rfix/commands/setup.rb +29 -0
  62. data/lib/rfix/commands/welcome.rb +24 -0
  63. data/lib/rfix/deleted.rb +13 -0
  64. data/lib/rfix/error.rb +2 -0
  65. data/lib/rfix/extensions/extensions.rb +18 -0
  66. data/lib/rfix/extensions/offense.rb +78 -0
  67. data/lib/rfix/extensions/string.rb +8 -0
  68. data/lib/rfix/file.rb +46 -0
  69. data/lib/rfix/file_cache.rb +59 -0
  70. data/lib/rfix/formatter.rb +126 -0
  71. data/lib/rfix/git_helper.rb +59 -0
  72. data/lib/rfix/log.rb +131 -0
  73. data/lib/rfix/no_file.rb +13 -0
  74. data/lib/rfix/rake/paths.rb +50 -0
  75. data/lib/rfix/rake/support.rb +75 -0
  76. data/lib/rfix/repository.rb +204 -0
  77. data/lib/rfix/rfix.rb +34 -0
  78. data/lib/rfix/tracked.rb +72 -0
  79. data/lib/rfix/tracked_file.rb +16 -0
  80. data/lib/rfix/untracked.rb +13 -0
  81. data/lib/rfix/version.rb +5 -0
  82. data/resources/ps.png +0 -0
  83. data/rfix.gemspec +68 -0
  84. data/tasks/bump.rake +11 -0
  85. data/tasks/bundle.rake +17 -0
  86. data/tasks/complex.rake +54 -0
  87. data/tasks/execute.rake +38 -0
  88. data/tasks/libgit2.rake +33 -0
  89. data/tasks/simple.rake +62 -0
  90. data/tasks/travis.rake +74 -0
  91. data/tasks/vendor.rake +34 -0
  92. metadata +350 -0
@@ -0,0 +1,13 @@
1
+ class NoFile < Struct.new(:path)
2
+ def include?(_line)
3
+ return true
4
+ end
5
+
6
+ def divide
7
+ Set.new
8
+ end
9
+
10
+ def empty?
11
+ false
12
+ end
13
+ end
@@ -0,0 +1,50 @@
1
+ module Travis
2
+ SETUP = "travis:setup".freeze
3
+ INSTALL = "travis:install".freeze
4
+ TASKS = "travis:tasks:all".freeze
5
+ GIT = "travis:git:config".freeze
6
+ end
7
+
8
+ module Bundle
9
+ INSTALL = "bundle:install".freeze
10
+ ADD = "bundle:git:add".freeze
11
+ TAG = "rally-point".freeze
12
+ REBUILD = "bundle:rebuild".freeze
13
+ BUILD = "bundle:build".freeze
14
+ ROOT = Dir.getwd
15
+ CONFIG = File.join(ROOT, ".rubocop.yml")
16
+ DIR = File.join(ROOT, "spec/fixtures")
17
+ TMP = File.join(ROOT, "tmp")
18
+
19
+ module Simple
20
+ FILE = File.join(DIR, "simple.bundle")
21
+ REPO = File.join(TMP, "simple")
22
+ REBUILD = "bundle:simple:rebuild".freeze
23
+ BUILD = "bundle:simple:build".freeze
24
+ FLUSH = "bundle:simple:flush".freeze
25
+ TEST = "bundle:simple:test".freeze
26
+ TAG = Bundle::TAG
27
+ end
28
+
29
+ module Complex
30
+ FILE = File.join(DIR, "complex.bundle")
31
+ REPO = File.join(TMP, "complex")
32
+ GITHUB = "https://github.com/oleander/git-fame-rb".freeze
33
+ REBUILD = "bundle:complex:rebuild".freeze
34
+ BUILD = "bundle:complex:build".freeze
35
+ FLUSH = "bundle:complex:flush".freeze
36
+ TEST = "bundle:complex:test".freeze
37
+ TAG = Bundle::TAG
38
+ end
39
+ end
40
+
41
+ module Vendor
42
+ ROOT = File.expand_path(File.join(__dir__, "../../.."))
43
+ DIR = File.join(ROOT, "vendor/shopify")
44
+ REPO = File.join(DIR, "cli-ui")
45
+ GITHUB = "https://github.com/shopify/cli-ui".freeze
46
+ START = "ef976d".freeze
47
+ BUILD = "vendor:shopify:build".freeze
48
+ REBUILD = "vendor:shopify:rebuild".freeze
49
+ TEST = "vendor:shopify:test".freeze
50
+ end
@@ -0,0 +1,75 @@
1
+ require "colorize"
2
+ require "fileutils"
3
+ require "shellwords"
4
+
5
+ module Rfix::Support
6
+ include FileUtils
7
+
8
+ alias _sh sh
9
+ alias _cd cd
10
+ alias _rm_rf rm_rf
11
+ alias _rm_f rm_f
12
+ alias _mkdir_p mkdir_p
13
+ alias _chdir chdir
14
+
15
+ def gemfiles
16
+ Dir["Gemfile*", "ci/Gemfile*"]
17
+ end
18
+
19
+ def say(msg)
20
+ $stderr.puts "#{'==>'.blue} #{to_relative(msg).italic}"
21
+ end
22
+
23
+ def sh(*args)
24
+ args = args.map(&:shellsplit).flatten
25
+ colorize args
26
+ _sh(*args)
27
+ end
28
+
29
+ def chdir(*args, &block)
30
+ colorize :cd, args
31
+ _chdir(*args, &block)
32
+ end
33
+
34
+ def rm_rf(*args)
35
+ colorize :rm, args
36
+ _rm_rf(*args)
37
+ end
38
+
39
+ def rm_f(*args)
40
+ colorize :rm, args
41
+ _rm_f(*args)
42
+ end
43
+
44
+ def cd(*args, &block)
45
+ colorize :cd, args
46
+ _cd(*args, &block)
47
+ end
48
+
49
+ def mkdir_p(*args)
50
+ colorize :mkdir, args
51
+ _mkdir_p(*args)
52
+ end
53
+
54
+ def clone_and_run(&block)
55
+ Dir.mktmpdir do |repo|
56
+ sh "git clone", Bundle::Complex::FILE, repo, "--branch", "master"
57
+ Dir.chdir(repo) { block.call(repo) }
58
+ end
59
+ end
60
+
61
+ private
62
+
63
+ def current_path
64
+ File.join(Dir.getwd, "/")
65
+ end
66
+
67
+ def to_relative(path)
68
+ path.to_s.gsub(current_path, "")
69
+ end
70
+
71
+ def colorize(*args)
72
+ head, *tail = args.flatten.map(&method(:to_relative))
73
+ say [head.yellow, tail.join(" ").italic].join(" ")
74
+ end
75
+ end
@@ -0,0 +1,204 @@
1
+ require "rugged"
2
+ require "rfix/file"
3
+ require "rfix/file_cache"
4
+ require "rfix/untracked"
5
+ require "rfix/tracked"
6
+
7
+ class Rfix::Repository
8
+ include Rfix::Log
9
+ attr_reader :files, :repo
10
+
11
+ def initialize(root_path:, load_untracked: false, reference: Rfix::Branch::HEAD, paths: [])
12
+ unless File.exist?(root_path)
13
+ raise Rfix::Error, "#{root_path} does not exist"
14
+ end
15
+
16
+ unless Pathname.new(root_path).absolute?
17
+ raise Rfix::Error, "#{root_path} is not absolute"
18
+ end
19
+
20
+ unless reference.is_a?(Rfix::Branch::Base)
21
+ raise Rfix::Error.new("Need Branch::Base, got {{error:#{reference.class}}}")
22
+ end
23
+
24
+ @files = FileCache.new(root_path)
25
+ @repo = Rugged::Repository.new(root_path)
26
+ @paths = paths
27
+ @reference = reference
28
+ @load_untracked = load_untracked
29
+
30
+ load!
31
+ end
32
+
33
+ def load_untracked?
34
+ @load_untracked
35
+ end
36
+
37
+ def load_tracked?
38
+ !! @reference
39
+ end
40
+
41
+ def reference
42
+ @reference
43
+ end
44
+
45
+ def refresh!(path)
46
+ @files.get(path).refresh!
47
+ end
48
+
49
+ def include?(path, line)
50
+ say_debug "Checking #{path}:#{line}"
51
+
52
+ if file = @files.get(path)
53
+ return file.include?(line)
54
+ end
55
+
56
+ say_debug "\tSkip file (return false)"
57
+ return false
58
+ end
59
+
60
+ def set_root(_path_path)
61
+ using_path(root_path)
62
+ end
63
+
64
+ def paths
65
+ files.pluck(&:absolute_path)
66
+ end
67
+
68
+ def current_branch
69
+ repo.head.name
70
+ end
71
+
72
+ def has_reference?(reference)
73
+ repo.rev_parse(reference)
74
+ rescue Rugged::ReferenceError
75
+ return false
76
+ end
77
+
78
+ def local_branches
79
+ repo.branches.each_name(:local).to_a
80
+ end
81
+
82
+ def git_path
83
+ repo.workdir
84
+ end
85
+
86
+ def head
87
+ @head ||= repo.rev_parse("HEAD")
88
+ end
89
+
90
+ def upstream
91
+ @upstream ||= reference.resolve(with: repo)
92
+ end
93
+
94
+ private
95
+
96
+ def load_tracked!
97
+ params = {
98
+ # ignore_whitespace_change: true,
99
+ include_untracked_content: true,
100
+ recurse_untracked_dirs: true,
101
+ # ignore_whitespace_eol: true,
102
+ include_unmodified: false,
103
+ include_untracked: true,
104
+ ignore_submodules: true,
105
+ # ignore_whitespace: true,
106
+ include_ignored: false,
107
+ context_lines: 0
108
+ }
109
+
110
+ unless @paths.empty?
111
+ say_debug("Use @paths #{@paths.join(", ")}")
112
+ params[:disable_pathspec_match] = false
113
+ params[:paths] = @paths
114
+ end
115
+
116
+ say_debug("Run diff on #{reference}")
117
+ upstream.diff(head, **params).tap do |diff|
118
+ diff.find_similar!(
119
+ renames_from_rewrites: true,
120
+ renames: true,
121
+ copies: true
122
+ )
123
+ end.each_delta do |delta|
124
+ path = delta.new_file.fetch(:path)
125
+ say_debug("Found #{path} while diff")
126
+ try_store(path, [delta.status])
127
+ end
128
+ rescue Rugged::ReferenceError
129
+ abort_box($ERROR_INFO.to_s) do
130
+ prt "Reference {{error:#{reference}}} cannot be found in repository"
131
+ end
132
+ rescue Rugged::ConfigError
133
+ abort_box($ERROR_INFO.to_s) do
134
+ prt "No upstream branch set for {{error:#{current_branch}}}"
135
+ end
136
+ rescue TypeError
137
+ abort_box($ERROR_INFO.to_s) do
138
+ prt "Reference {{error:#{reference}}} is not pointing to a tree or commit"
139
+ end
140
+ end
141
+
142
+ def load!
143
+ load_tracked!
144
+ load_untracked!
145
+ end
146
+
147
+ # https://github.com/libgit2/rugged/blob/35102c0ca10ab87c4c4ffe2e25221d26993c069c/test/status_test.rb
148
+ # - +:index_new+: the file is new in the index
149
+ # - +:index_modified+: the file has been modified in the index
150
+ # - +:index_deleted+: the file has been deleted from the index
151
+ # - +:worktree_new+: the file is new in the working directory
152
+ # - +:worktree_modified+: the file has been modified in the working directory
153
+ # - +:worktree_deleted+: the file has been deleted from the working directory
154
+
155
+ MODIFIED = [:modified, :worktree_modified, :index_modified].freeze
156
+ IGNORED = [:ignored].freeze
157
+ STAGED = [:added, :index_new].freeze
158
+ UNTRACKED = [:worktree_new, :untracked].freeze
159
+ COPIED = [:copied].freeze
160
+ DELETED = [:deleted, :worktree_deleted, :index_deleted].freeze
161
+ RENAMED = [:renamed].freeze
162
+
163
+ SKIP = [*DELETED, *RENAMED, *COPIED, *IGNORED].freeze
164
+ ACCEPT = [*MODIFIED].freeze
165
+
166
+ def load_untracked!
167
+ repo.status do |path, status|
168
+ try_store(path, status)
169
+ end
170
+ end
171
+
172
+ def store(file)
173
+ say_debug("Trying to add #{file.absolute_path}")
174
+ if File.exist?(file.absolute_path)
175
+ @files.add(file)
176
+ else
177
+ say_debug "#{file} does not exist"
178
+ end
179
+ end
180
+
181
+ def try_store(path, status)
182
+ if SKIP.any?(&status.method(:include?))
183
+ return say_debug("Ignored {{warning:#{status.join(', ')}}} #{path}")
184
+ end
185
+
186
+ if STAGED.any?(&status.method(:include?))
187
+ return store(Rfix::Untracked.new(path, repo, nil))
188
+ end
189
+
190
+ if UNTRACKED.any?(&status.method(:include?))
191
+ unless load_untracked?
192
+ return say_debug("Ignore #{path} as untracked files are ignored: #{status}")
193
+ end
194
+
195
+ return store(Rfix::Untracked.new(path, repo, nil))
196
+ end
197
+
198
+ if ACCEPT.any?(&status.method(:include?))
199
+ return store(Rfix::Tracked.new(path, repo, reference))
200
+ end
201
+
202
+ say_debug "Status not found {{error:#{status.join(', ')}}} for {{italic:#{path}}}"
203
+ end
204
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubocop"
4
+ require "rfix/log"
5
+
6
+ module Rfix
7
+ include Log
8
+ attr_accessor :repo
9
+ attr_accessor :test
10
+
11
+ alias test? test
12
+
13
+ def global_enable!
14
+ @global_enable = true
15
+ end
16
+
17
+ def global_enable?
18
+ @global_enable
19
+ end
20
+
21
+ def refresh!(source)
22
+ return true if global_enable?
23
+
24
+ repo.refresh!(source.file_path)
25
+ end
26
+
27
+ def enabled?(path, line)
28
+ return true if global_enable?
29
+
30
+ repo.include?(path, line)
31
+ end
32
+ end
33
+
34
+ # rubocop:enable Layout/LineLength
@@ -0,0 +1,72 @@
1
+ require "rfix/no_file"
2
+
3
+ class Rfix::Tracked < Rfix::File
4
+ include Rfix::Log
5
+
6
+ def include?(line)
7
+ set = diff.each_line.to_a.map{ |l| l.new_lineno }.reject { |l| l == -1 }.to_set
8
+ say_debug "Does {{yellow:#{set}}} contain {{red:#{line}}}"
9
+ set.include?(line)
10
+ end
11
+
12
+ private
13
+
14
+ # def set
15
+ # return NoFile.new(path) if @set.empty?
16
+ # return @set
17
+ # end
18
+
19
+ # def refresh!
20
+ # @changes = diff.each_line.to_a.map{ |l| l.new_lineno }.to_set
21
+ #
22
+ # if @changes.empty?
23
+ # @changes = NoFile.new(path)
24
+ # end
25
+ # rescue Rugged::TreeError
26
+ # @changed = NoFile.new(path)
27
+ # end
28
+
29
+ # def changes
30
+ # @changes or raise(Rfix::Error, "No changes found: #{self}")
31
+ # end
32
+
33
+ # def needs_update?
34
+ # current_changed_at = changed_at
35
+ # if @changed_at != current_changed_at
36
+ # @changed_at = current_changed_at
37
+ # return true
38
+ # end
39
+ #
40
+ # return false
41
+ # end
42
+
43
+ # def changed_at
44
+ # File.new(absolute_path).ctime
45
+ # end
46
+
47
+ def upstream
48
+ @upstream ||= ref.resolve(with: repo)
49
+ end
50
+
51
+ def head
52
+ @head ||= repo.rev_parse("HEAD")
53
+ end
54
+
55
+ def diff
56
+ upstream.diff_workdir({
57
+ include_untracked_content: true,
58
+ recurse_untracked_dirs: true,
59
+ include_untracked: true,
60
+ ignore_submodules: true,
61
+ include_ignored: false,
62
+ context_lines: 0,
63
+ paths: [path]
64
+ }).tap do |diff|
65
+ diff.find_similar!(
66
+ renames_from_rewrites: true,
67
+ renames: true,
68
+ copies: true
69
+ )
70
+ end
71
+ end
72
+ end