rfix 1.0.15 → 1.1.0.pre.147

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 (79) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -0
  3. data/.rspec +0 -1
  4. data/.rubocop.yml +46 -31
  5. data/.travis.yml +5 -12
  6. data/Gemfile.base +10 -3
  7. data/Gemfile.base.lock +172 -0
  8. data/Gemfile.lock +28 -7
  9. data/Guardfile +1 -1
  10. data/Makefile +4 -13
  11. data/Rakefile +16 -95
  12. data/ci/Gemfile.rubocop-0.80.lock +16 -1
  13. data/ci/Gemfile.rubocop-0.81.lock +16 -1
  14. data/ci/Gemfile.rubocop-0.82.lock +16 -1
  15. data/ci/Gemfile.rubocop-0.83.lock +19 -4
  16. data/ci/Gemfile.rubocop-0.84.lock +19 -4
  17. data/ci/Gemfile.rubocop-0.85.1.lock +19 -4
  18. data/ci/Gemfile.rubocop-0.85.lock +16 -1
  19. data/exe/rfix +18 -144
  20. data/lib/rfix.rb +10 -3
  21. data/lib/rfix/box.rb +112 -0
  22. data/lib/rfix/branch.rb +30 -0
  23. data/lib/rfix/branches/base.rb +29 -0
  24. data/lib/rfix/branches/head.rb +11 -0
  25. data/lib/rfix/branches/main.rb +33 -0
  26. data/lib/rfix/branches/name.rb +21 -0
  27. data/lib/rfix/branches/reference.rb +19 -0
  28. data/lib/rfix/branches/upstream.rb +11 -0
  29. data/lib/rfix/cmd.rb +9 -14
  30. data/lib/rfix/commands/all.rb +26 -0
  31. data/lib/rfix/commands/branch.rb +15 -0
  32. data/lib/rfix/commands/extensions/options.rb +8 -0
  33. data/lib/rfix/commands/help.rb +7 -0
  34. data/lib/rfix/commands/helper/args.rb +137 -0
  35. data/lib/rfix/commands/helper/help.rb +6 -0
  36. data/lib/rfix/commands/helper/loader.rb +6 -0
  37. data/lib/rfix/commands/helper/option.rb +0 -0
  38. data/lib/rfix/commands/helper/params.rb +0 -0
  39. data/lib/rfix/commands/helper/rubocop.rb +17 -0
  40. data/lib/rfix/commands/info.rb +30 -0
  41. data/lib/rfix/commands/lint.rb +23 -0
  42. data/lib/rfix/commands/local.rb +12 -0
  43. data/lib/rfix/commands/origin.rb +19 -0
  44. data/lib/rfix/commands/setup.rb +29 -0
  45. data/lib/rfix/commands/welcome.rb +24 -0
  46. data/lib/rfix/deleted.rb +13 -0
  47. data/lib/rfix/error.rb +2 -0
  48. data/lib/rfix/extensions/extensions.rb +4 -26
  49. data/lib/rfix/extensions/offense.rb +2 -1
  50. data/lib/rfix/extensions/string.rb +8 -0
  51. data/lib/rfix/file.rb +46 -0
  52. data/lib/rfix/file_cache.rb +59 -0
  53. data/lib/rfix/formatter.rb +37 -10
  54. data/lib/rfix/git_helper.rb +13 -1
  55. data/lib/rfix/log.rb +104 -7
  56. data/lib/rfix/no_file.rb +13 -0
  57. data/lib/rfix/rake/paths.rb +50 -0
  58. data/lib/rfix/rake/support.rb +75 -0
  59. data/lib/rfix/repository.rb +201 -0
  60. data/lib/rfix/rfix.rb +7 -198
  61. data/lib/rfix/tracked.rb +76 -0
  62. data/lib/rfix/tracked_file.rb +1 -1
  63. data/lib/rfix/untracked.rb +13 -0
  64. data/lib/rfix/version.rb +1 -1
  65. data/path.rb +7 -0
  66. data/rfix.gemspec +6 -2
  67. data/rugged.rb +206 -0
  68. data/tasks/bump.rake +11 -0
  69. data/tasks/bundle.rake +17 -0
  70. data/tasks/complex.rake +54 -0
  71. data/tasks/simple.rake +58 -0
  72. data/tasks/travis.rake +74 -0
  73. data/tasks/vendor.rake +34 -0
  74. metadata +136 -13
  75. data/file.rb +0 -1
  76. data/lib/rfix/gem_helper.rb +0 -12
  77. data/lib/rfix/git_file.rb +0 -36
  78. data/lib/rfix/rake_helper.rb +0 -56
  79. data/lib/rfix/untracked_file.rb +0 -13
@@ -0,0 +1,23 @@
1
+ r_args = []
2
+
3
+ helper("help", binding)
4
+ helper("rubocop", binding)
5
+ helper("args", binding)
6
+
7
+ summary "Lints commits and untracked files not yet pushed to upstream"
8
+ usage "rfix lint [opts] [path ..]"
9
+ description "Lint (read-only) files"
10
+
11
+
12
+ run do |opts, args, _cmd|
13
+ opts[:dry] = true
14
+ opts[:untracked] = true
15
+
16
+ if main = opts[:"main-branch"]
17
+ branch = Rfix::Branch::Name.new(main)
18
+ else
19
+ branch = Rfix::Branch::MAIN
20
+ end
21
+
22
+ setup(r_args, opts, args, files: args.each.to_a, reference: branch)
23
+ end
@@ -0,0 +1,12 @@
1
+ r_args = []
2
+
3
+ helper("help", binding)
4
+ helper("rubocop", binding)
5
+ helper("args", binding)
6
+
7
+ summary "Auto-fixes commits not yet pushed to upstream"
8
+ usage "rfix local [opts] [path ..]"
9
+
10
+ run do |opts, args, _cmd|
11
+ setup(r_args, opts, args, files: args.each.to_a, reference: Rfix::Branch::UPSTREAM)
12
+ end
@@ -0,0 +1,19 @@
1
+ r_args = []
2
+
3
+ helper("help", binding)
4
+ helper("rubocop", binding)
5
+ helper("args", binding)
6
+
7
+ summary "Auto-fixes commits between HEAD and origin branch"
8
+ usage "rfix origin [opts] [path ..]"
9
+
10
+ run do |opts, args, _cmd|
11
+ if main = opts[:"main-branch"]
12
+ branch = Rfix::Branch::Name.new(main)
13
+ else
14
+ branch = Rfix::Branch::MAIN
15
+ end
16
+
17
+ # say "Using {{red:#{branch}}} as main branch"
18
+ setup(r_args, opts, args, files: args.each.to_a, reference: branch)
19
+ end
@@ -0,0 +1,29 @@
1
+ helper("help", binding)
2
+
3
+ option :r, :root, "{{*}} Project root path", default: Dir.pwd, argument: :required
4
+ option :b, :"main-branch", "{{*}} Branch to use", argument: :optional
5
+
6
+ summary "Sets the default branch for {{command:rfix local}}"
7
+
8
+ def set_branch(root_path, branch)
9
+ Rfix::Branch::Main.set(branch, at: root_path)
10
+ say "Main branch was set to {{italic:#{branch}}}"
11
+ end
12
+
13
+ run do |opts, _args|
14
+ if branch = Rfix::Branch::Main.get(at: opts[:root])
15
+ say "Current main branch set to {{info:#{branch}}}"
16
+ end
17
+
18
+ if branch = opts[:"main-branch"]
19
+ next set_branch(opts[:root], branch)
20
+ end
21
+
22
+ CLI::UI::Prompt.ask("Which one is your main branch?") do |handler|
23
+ Rfix::Branch.local(at: opts[:root]).each do |branch|
24
+ handler.option(branch) do |selection|
25
+ set_branch(opts[:root], selection)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,24 @@
1
+ r_args = []
2
+
3
+ helper("help", binding)
4
+
5
+ summary "This is how you get started with {{command:rfix}}"
6
+
7
+ run do |_opts, _args, _cmd|
8
+ indent = " " * 2
9
+ prt "{{v}} Thank you for installing {{green:rfix v#{Rfix::VERSION}}}!\n"
10
+ prt ""
11
+ prt "{{i}} Run {{command:rfix help}} for avalible commands or any of the following to get started:"
12
+ prt ""
13
+ prt "#{indent}{{command:$ rfix local}} {{italic:# Auto-fixes commits not yet pushed to upstream}}"
14
+ prt "#{indent}{{command:$ rfix origin}} {{italic:# Auto-fixes commits between HEAD and origin branch}}"
15
+ prt "#{indent}{{command:$ rfix lint}} {{italic:# Lints commits and untracked files not yet pushed to upstream}}"
16
+ prt ""
17
+ prt "{{*}} {{bold:ProTip:}} Append {{command:--dry}} to run {{command:rfix}} in {{warning:read-only}} mode"
18
+ prt ""
19
+ prt "{{i}} {{bold:Issues}} {{italic:https://github.com/oleander/rfix-rb/issues}}"
20
+ prt "{{i}} {{bold:Readme}} {{italic:https://github.com/oleander/rfix-rb/blob/master/README.md}}"
21
+ prt "{{i}} {{bold:Travis}} {{italic:https://travis-ci.org/github/oleander/rfix-rb}}"
22
+ prt ""
23
+ prt "{{italic:~ Linus}}\n"
24
+ end
@@ -0,0 +1,13 @@
1
+ class Rfix::Deleted < Rfix::File
2
+ def include?(_)
3
+ return false
4
+ end
5
+
6
+ def refresh!
7
+ # NOP
8
+ end
9
+
10
+ def inspect
11
+ "<Deleted({{info:#{path}}})>"
12
+ end
13
+ end
@@ -0,0 +1,2 @@
1
+ class Rfix::Error < StandardError
2
+ end
@@ -2,39 +2,17 @@
2
2
 
3
3
  require "rubocop"
4
4
  require "rainbow"
5
+ require "rfix/log"
5
6
 
6
7
  module Rfix::Ext
7
8
  module CommentConfig
9
+ include Rfix::Log # TODO: Remove
8
10
  # Called by RuboCop on every line to see
9
11
  # if its suppose to run against it or not
10
12
  def cop_enabled_at_line?(_cop, line)
11
13
  Rfix.enabled?(processed_source.file_path, line) && super
12
- end
13
- end
14
-
15
- module Runner
16
- # Called _after_ @source has been 'auto fixed' by Rubocop
17
- def check_for_infinite_loop(source, offences)
18
- # rubocop:disable Style/Semicolon
19
- Rfix.refresh!(source); super
20
- # rubocop:enable Style/Semicolon
21
- end
22
- end
23
-
24
- module Options
25
- # Appends custom --args to RuboCop CLI
26
- def define_options
27
- super.tap do |options|
28
- @ons.each do |args, block|
29
- option(options, *args, &block)
30
- end
31
- end
32
- end
33
-
34
- # Helper method used by rfix to append cli --args to Rubocop
35
- def on(*args, &block)
36
- @ons ||= []
37
- @ons += [[args, block]]
14
+ rescue StandardError
15
+ say_abort "[Rfix::Enabled] #{$ERROR_INFO}"
38
16
  end
39
17
  end
40
18
  end
@@ -33,7 +33,8 @@ module Rfix::Ext
33
33
  end
34
34
 
35
35
  def relative_path
36
- Rfix.to_relative(path: location.source_buffer.name)
36
+ # TODO: Fix this, do not use Dir.getwd, use git root
37
+ location.source_buffer.name.sub(File.join(Dir.getwd, "/"), "")
37
38
  end
38
39
 
39
40
  def clickable_path
@@ -0,0 +1,8 @@
1
+ require "rfix/log"
2
+
3
+ # TODO: Use refinements instead
4
+ class String
5
+ def fmt
6
+ Rfix::Log.fmt self
7
+ end
8
+ end
@@ -0,0 +1,46 @@
1
+ require "rugged"
2
+ require "shellwords"
3
+ require "digest"
4
+ require "listen"
5
+
6
+ class Rfix::File < Struct.new(:path, :repo, :ref)
7
+ include Rfix::Log
8
+
9
+ def initialize(path, repo, ref)
10
+ # check_absolute!(path)
11
+ super(path, repo, ref)
12
+ end
13
+
14
+ def check_absolute!(path)
15
+ if Pathname.new(path).absolute?
16
+ say_abort "Path must be relative #{path}"
17
+ end
18
+ end
19
+
20
+ def include?(_)
21
+ raise Rfix::Error.new("#include? not implemented")
22
+ end
23
+
24
+ def refresh!
25
+ raise Rfix::Error.new("#refresh! not implemented")
26
+ end
27
+
28
+ def inspect
29
+ raise Rfix::Error.new("#inspect not implemented")
30
+ end
31
+
32
+ def git_path
33
+ @git_path ||= Pathname.new(repo.workdir)
34
+ end
35
+
36
+ def absolute_path
37
+ path
38
+ # @absolute_path ||= to_abs(path)
39
+ end
40
+
41
+ def to_abs(path)
42
+ File.join(repo.workdir, path)
43
+ end
44
+
45
+ alias to_s path
46
+ end
@@ -0,0 +1,59 @@
1
+ class FileCache
2
+ attr_reader :root_path
3
+ include Rfix::Log
4
+
5
+ def initialize(path)
6
+ @files = Hash.new
7
+ @paths = Hash.new
8
+ @root_path = path
9
+ end
10
+
11
+ def add(file)
12
+ key = normalized_file_path(file)
13
+
14
+ if @files.key?(key)
15
+ return say_debug("File already exists with path {{error:#{file.path}}} using #{key}")
16
+ end
17
+
18
+ say_debug("Adding file with path {{green:#{file.path}}} using key {{info:#{key}}}")
19
+ @files[key] = file
20
+ end
21
+
22
+ def get(path)
23
+ key = normalize_path(path)
24
+
25
+ if file = @files[key]
26
+ say_debug("Found file #{file} with path #{path}")
27
+ return file
28
+ end
29
+
30
+ say_debug("Could {{error:NOT}} find path #{path}")
31
+ nil
32
+ end
33
+
34
+ def pluck(&block)
35
+ @files.values.map(&block)
36
+ end
37
+
38
+ private
39
+
40
+ def normalized_file_path(file)
41
+ normalize_path(file.absolute_path)
42
+ end
43
+
44
+ def to_abs(path)
45
+ File.join(root_path, path)
46
+ end
47
+
48
+ def normalize_path(path)
49
+ if cached = @paths[path]
50
+ return cached
51
+ end
52
+
53
+ if Pathname.new(path).absolute?
54
+ @paths[path] = File.realdirpath(path)
55
+ else
56
+ @paths[path] = File.realdirpath(to_abs(path))
57
+ end
58
+ end
59
+ end
@@ -7,26 +7,50 @@ require "shellwords"
7
7
 
8
8
  module Rfix
9
9
  class Formatter < RuboCop::Formatter::SimpleTextFormatter
10
+ include Rfix::Log
11
+
10
12
  def started(files)
11
- theme = Rouge::Themes::Gruvbox.new
13
+ theme = Rouge::Themes::Gruvbox.new
12
14
  @formatter = Rouge::Formatters::TerminalTruecolor.new(theme)
13
- @lexer = Rouge::Lexers::Ruby.new
14
- out "{{v}} Loading {{yellow:#{files.count}}} files"
15
- out("\n")
16
- @pg = CLI::UI::Progress.new
17
- @total = files.count
18
- @current = 0
19
- @files = {}
15
+ @current = 0
16
+ @total = files.count
17
+ @files = {}
18
+ @lexer = Rouge::Lexers::Ruby.new
19
+ @pg = CLI::UI::Progress.new
20
+ @all_files = files
21
+ end
22
+
23
+ def truncate(path)
24
+ path.sub(::File.join(Dir.getwd, "/"), "")
25
+ end
26
+
27
+ def render_files(files)
28
+ return unless Rfix.test?
29
+
30
+ files.each do |file|
31
+ offenses = @files.fetch(file)
32
+ corrected = offenses.select(&:corrected?)
33
+
34
+ if offenses.empty?
35
+ say truncate(file)
36
+ elsif offenses.count == corrected.count
37
+ say truncate(file)
38
+ else
39
+ say_error truncate(file)
40
+ end
41
+ end
20
42
  end
21
43
 
22
44
  def finished(files)
45
+ render_files(files)
46
+
23
47
  files.each do |file|
24
48
  render_file(file, @files.fetch(file))
25
49
  end
26
50
 
27
51
  offenses = @files.values.flatten
28
52
  corrected = offenses.select(&:corrected?)
29
- out("\n")
53
+ out("\n") unless @total.zero?
30
54
  report_summary(files.size, offenses.count, corrected.count)
31
55
  end
32
56
 
@@ -46,8 +70,11 @@ module Rfix
46
70
  end
47
71
 
48
72
  def file_finished(file, offenses)
73
+ out("\n") if @current == 0.0
49
74
  @current += 1.0
50
- @pg.tick(set_percent: (@current / @total))
75
+ unless Rfix.test?
76
+ @pg.tick(set_percent: (@current / @total))
77
+ end
51
78
  @files[file] = offenses
52
79
  end
53
80
 
@@ -4,17 +4,29 @@ require "open3"
4
4
  require "rfix"
5
5
  require "rfix/log"
6
6
  require "rfix/cmd"
7
+ require "shellwords"
7
8
 
8
9
  module Rfix::GitHelper
9
10
  include Rfix::Log
10
11
  include Rfix::Cmd
11
12
 
12
- def git(*args, root: Dir.pwd, quiet: false, &block)
13
+ def git(*params, root: Dir.pwd, quiet: false, &block)
14
+ args = split_args(params)
13
15
  args.unshift *["--git-dir", File.join(root, ".git")]
14
16
  args.unshift *["--work-tree", root]
15
17
  cmd("git", *args, quiet: quiet, &block)
16
18
  end
17
19
 
20
+ def split_args(params)
21
+ return if params.empty?
22
+ return split(params.first) if params.count == 1
23
+ return params
24
+ end
25
+
26
+ def split(str)
27
+ Shellwords.split(str)
28
+ end
29
+
18
30
  def has_branch?(branch)
19
31
  cmd_succeeded?("git", "cat-file", "-t", branch)
20
32
  end
@@ -4,31 +4,128 @@ require "rfix"
4
4
  require "cli/ui"
5
5
 
6
6
  module Rfix::Log
7
+ extend self
7
8
  def say(message)
8
- CLI::UI.puts("{{v}} #{message}")
9
+ prt("{{v}} #{message}")
9
10
  end
10
11
 
11
12
  def say_error(message)
12
- CLI::UI.puts("{{x}} #{message}")
13
+ prt("{{x}} #{message}")
13
14
  end
14
15
 
15
16
  def say_error_sub(message)
16
- CLI::UI.puts(message.to_s)
17
+ prt(message.to_s)
18
+ end
19
+
20
+ def error_box(title)
21
+ box(title, color: :red) { yield }
22
+ end
23
+
24
+ def abort_box(title)
25
+ error_box(title) { yield }
26
+ exit 1
27
+ end
28
+
29
+ def say_test(message)
30
+ prt("{{i}} #{strip(message)}")
17
31
  end
18
32
 
19
33
  def say_debug(message)
20
- if Rfix.debug?
21
- CLI::UI.puts("{{*}} [{{info:Debug}}] #{message}")
34
+ if debug? or test?
35
+ prt("{{i}} #{strip(message)}", to: $stderr)
22
36
  end
23
37
  end
24
38
 
25
39
  def say_abort(message)
26
- CLI::UI.puts("{{x}} #{message}")
40
+ prt("{{x}} #{message}")
27
41
  exit 1
28
42
  end
29
43
 
44
+ def debug?
45
+ return false unless defined?(RSpec)
46
+ return RSpec.configuration.debug?
47
+ end
48
+
49
+ def test?
50
+ Rfix.test?
51
+ end
52
+
30
53
  def say_exit(message)
31
- CLI::UI.puts("{{v}} #{message}")
54
+ prt("{{v}} #{message}")
32
55
  exit 0
33
56
  end
57
+
58
+ def say_plain(message)
59
+ prt(message)
60
+ end
61
+
62
+ def debug_box(title)
63
+ unless_debug do
64
+ box(title) { yield }
65
+ end
66
+ end
67
+
68
+ def prt(*args)
69
+ CLI::UI.puts(*args)
70
+ end
71
+
72
+ def fmt(*args)
73
+ CLI::UI.fmt(*args)
74
+ end
75
+
76
+ alias ftm fmt
77
+
78
+ def log_items(items, title:)
79
+ box("#{title} (#{items.count})") do
80
+ return margin(2) do
81
+ prt "{{warning:No items found}}"
82
+ end if items.empty?
83
+
84
+ items.each do |item|
85
+ if block_given?
86
+ say strip(yield item)
87
+ else
88
+ say strip(item.to_s)
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ def box(title, color: :reset)
95
+ margin do
96
+ CLI::UI::Frame.open(title, color: color) do
97
+ margin(2) do
98
+ yield
99
+ end
100
+ end
101
+ end
102
+ end
103
+
104
+ def strip(msg)
105
+ msg
106
+ # msg.gsub(current_path, "").gsub(Dir.pwd, ".").chomp
107
+ end
108
+
109
+ def current_path
110
+ File.join(Dir.pwd, "/")
111
+ end
112
+
113
+ def div(title, **args)
114
+ CLI::UI::Frame.divider(title, **args)
115
+ margin { yield }
116
+ end
117
+
118
+ def margin(n = 1)
119
+ new_line(n)
120
+ yield
121
+ new_line(n)
122
+ end
123
+
124
+ def new_line(n = 1)
125
+ say_plain("\n" * n)
126
+ end
127
+
128
+ def unless_debug
129
+ yield unless Rfix.debug?
130
+ end
34
131
  end