rfix 1.1.0.pre.150

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