rfix 1.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/main.yml +38 -0
- data/.gitignore +43 -0
- data/.rspec +2 -0
- data/.rubocop.yml +87 -0
- data/.travis.yml +37 -0
- data/Gemfile +2 -0
- data/Gemfile.base +14 -0
- data/Gemfile.base.lock +172 -0
- data/Gemfile.lock +181 -0
- data/Guardfile +16 -0
- data/LICENSE.txt +21 -0
- data/Makefile +4 -0
- data/README.md +92 -0
- data/Rakefile +27 -0
- data/bin/bundle +114 -0
- data/bin/console +29 -0
- data/bin/guard +29 -0
- data/bin/rake +29 -0
- data/bin/rfix +29 -0
- data/bin/rspec +29 -0
- data/bin/setup +29 -0
- data/ci/Gemfile.rubocop-0.80 +2 -0
- data/ci/Gemfile.rubocop-0.80.lock +170 -0
- data/ci/Gemfile.rubocop-0.81 +2 -0
- data/ci/Gemfile.rubocop-0.81.lock +170 -0
- data/ci/Gemfile.rubocop-0.82 +2 -0
- data/ci/Gemfile.rubocop-0.82.lock +170 -0
- data/ci/Gemfile.rubocop-0.83 +2 -0
- data/ci/Gemfile.rubocop-0.83.lock +168 -0
- data/ci/Gemfile.rubocop-0.84 +2 -0
- data/ci/Gemfile.rubocop-0.84.lock +171 -0
- data/ci/Gemfile.rubocop-0.85 +2 -0
- data/ci/Gemfile.rubocop-0.85.1 +2 -0
- data/ci/Gemfile.rubocop-0.85.1.lock +173 -0
- data/ci/Gemfile.rubocop-0.85.lock +173 -0
- data/exe/rfix +30 -0
- data/lib/rfix.rb +34 -0
- data/lib/rfix/box.rb +112 -0
- data/lib/rfix/branch.rb +31 -0
- data/lib/rfix/branches/base.rb +29 -0
- data/lib/rfix/branches/head.rb +13 -0
- data/lib/rfix/branches/main.rb +34 -0
- data/lib/rfix/branches/name.rb +23 -0
- data/lib/rfix/branches/reference.rb +21 -0
- data/lib/rfix/branches/upstream.rb +13 -0
- data/lib/rfix/cmd.rb +39 -0
- data/lib/rfix/commands/branch.rb +15 -0
- data/lib/rfix/commands/extensions/options.rb +8 -0
- data/lib/rfix/commands/help.rb +7 -0
- data/lib/rfix/commands/helper/args.rb +137 -0
- data/lib/rfix/commands/helper/help.rb +6 -0
- data/lib/rfix/commands/helper/loader.rb +6 -0
- data/lib/rfix/commands/helper/option.rb +0 -0
- data/lib/rfix/commands/helper/params.rb +0 -0
- data/lib/rfix/commands/helper/rubocop.rb +17 -0
- data/lib/rfix/commands/info.rb +30 -0
- data/lib/rfix/commands/lint.rb +23 -0
- data/lib/rfix/commands/local.rb +12 -0
- data/lib/rfix/commands/origin.rb +19 -0
- data/lib/rfix/commands/setup.rb +29 -0
- data/lib/rfix/commands/welcome.rb +24 -0
- data/lib/rfix/deleted.rb +13 -0
- data/lib/rfix/error.rb +2 -0
- data/lib/rfix/extensions/extensions.rb +18 -0
- data/lib/rfix/extensions/offense.rb +78 -0
- data/lib/rfix/extensions/string.rb +8 -0
- data/lib/rfix/file.rb +46 -0
- data/lib/rfix/file_cache.rb +59 -0
- data/lib/rfix/formatter.rb +126 -0
- data/lib/rfix/git_helper.rb +59 -0
- data/lib/rfix/log.rb +131 -0
- data/lib/rfix/no_file.rb +13 -0
- data/lib/rfix/rake/paths.rb +50 -0
- data/lib/rfix/rake/support.rb +75 -0
- data/lib/rfix/repository.rb +204 -0
- data/lib/rfix/rfix.rb +34 -0
- data/lib/rfix/tracked.rb +72 -0
- data/lib/rfix/tracked_file.rb +16 -0
- data/lib/rfix/untracked.rb +13 -0
- data/lib/rfix/version.rb +5 -0
- data/resources/ps.png +0 -0
- data/rfix.gemspec +68 -0
- data/tasks/bump.rake +11 -0
- data/tasks/bundle.rake +17 -0
- data/tasks/complex.rake +54 -0
- data/tasks/execute.rake +38 -0
- data/tasks/libgit2.rake +33 -0
- data/tasks/simple.rake +62 -0
- data/tasks/travis.rake +74 -0
- data/tasks/vendor.rake +34 -0
- metadata +350 -0
data/lib/rfix/deleted.rb
ADDED
data/lib/rfix/error.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rubocop"
|
4
|
+
require "rainbow"
|
5
|
+
require "rfix/log"
|
6
|
+
|
7
|
+
module Rfix::Ext
|
8
|
+
module CommentConfig
|
9
|
+
include Rfix::Log # TODO: Remove
|
10
|
+
# Called by RuboCop on every line to see
|
11
|
+
# if its suppose to run against it or not
|
12
|
+
def cop_enabled_at_line?(_cop, line)
|
13
|
+
Rfix.enabled?(processed_source.file_path, line) && super
|
14
|
+
rescue StandardError
|
15
|
+
say_abort "[Rfix::Enabled] #{$ERROR_INFO}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Rfix::Ext
|
2
|
+
module Offense
|
3
|
+
def where
|
4
|
+
line.to_s + ":" + real_column.to_s
|
5
|
+
end
|
6
|
+
|
7
|
+
def info
|
8
|
+
message.split(": ", 2).last.delete("\n")
|
9
|
+
end
|
10
|
+
|
11
|
+
def msg
|
12
|
+
CLI::UI.resolve_text("{{italic:#{info}}}", truncate_to: CLI::UI::Terminal.width - 10)
|
13
|
+
end
|
14
|
+
|
15
|
+
def code
|
16
|
+
message.split(": ", 2).first
|
17
|
+
end
|
18
|
+
|
19
|
+
def star
|
20
|
+
Rainbow("⭑")
|
21
|
+
end
|
22
|
+
|
23
|
+
def cross
|
24
|
+
Rainbow("✗").red
|
25
|
+
end
|
26
|
+
|
27
|
+
def check
|
28
|
+
Rainbow("✓").green
|
29
|
+
end
|
30
|
+
|
31
|
+
def circle
|
32
|
+
Rainbow("⍟")
|
33
|
+
end
|
34
|
+
|
35
|
+
def relative_path
|
36
|
+
# TODO: Fix this, do not use Dir.getwd, use git root
|
37
|
+
location.source_buffer.name.sub(File.join(Dir.getwd, "/"), "")
|
38
|
+
end
|
39
|
+
|
40
|
+
def clickable_path
|
41
|
+
"{{italic:#{relative_path}:#{where}}}"
|
42
|
+
end
|
43
|
+
|
44
|
+
def clickable_plain_severity
|
45
|
+
to_url("https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/#{code}", code)
|
46
|
+
end
|
47
|
+
|
48
|
+
def clickable_severity
|
49
|
+
"{{#{severity.code}}} {{italic:#{clickable_plain_severity}}}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def icon
|
53
|
+
return check.green if corrected?
|
54
|
+
return star.yellow if correctable?
|
55
|
+
|
56
|
+
cross.red
|
57
|
+
end
|
58
|
+
|
59
|
+
def to_clickable(url, title)
|
60
|
+
esc = CLI::UI::ANSI::ESC
|
61
|
+
cmd = esc + "]8;;"
|
62
|
+
slash = "\x07"
|
63
|
+
cmd + "#{escape(url)}#{slash}#{escape(title)}" + cmd + slash
|
64
|
+
end
|
65
|
+
|
66
|
+
def to_path(path, title)
|
67
|
+
to_clickable("file://#{path}", title)
|
68
|
+
end
|
69
|
+
|
70
|
+
def to_url(url, title)
|
71
|
+
to_clickable(url, title)
|
72
|
+
end
|
73
|
+
|
74
|
+
def escape(str)
|
75
|
+
Shellwords.escape(str)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/lib/rfix/file.rb
ADDED
@@ -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
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rubocop"
|
4
|
+
require "rouge"
|
5
|
+
require "rainbow"
|
6
|
+
require "shellwords"
|
7
|
+
|
8
|
+
module Rfix
|
9
|
+
class Formatter < RuboCop::Formatter::SimpleTextFormatter
|
10
|
+
include Rfix::Log
|
11
|
+
|
12
|
+
def started(files)
|
13
|
+
theme = Rouge::Themes::Gruvbox.new
|
14
|
+
@formatter = Rouge::Formatters::TerminalTruecolor.new(theme)
|
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
|
42
|
+
end
|
43
|
+
|
44
|
+
def finished(files)
|
45
|
+
render_files(files)
|
46
|
+
|
47
|
+
files.each do |file|
|
48
|
+
render_file(file, @files.fetch(file))
|
49
|
+
end
|
50
|
+
|
51
|
+
offenses = @files.values.flatten
|
52
|
+
corrected = offenses.select(&:corrected?)
|
53
|
+
out("\n") unless @total.zero?
|
54
|
+
report_summary(files.size, offenses.count, corrected.count)
|
55
|
+
end
|
56
|
+
|
57
|
+
def render_file(file, offenses)
|
58
|
+
return if offenses.empty?
|
59
|
+
|
60
|
+
offenses.each do |offense|
|
61
|
+
out("\n\n")
|
62
|
+
CLI::UI::Frame.open("#{offense.icon} #{offense.msg}", color: :reset)
|
63
|
+
report_line(file, offense, offense.location, offense.highlighted_area)
|
64
|
+
CLI::UI::Frame.close("#{offense.clickable_severity} » #{offense.clickable_path}", color: :reset)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def mark
|
69
|
+
CLI::UI::ANSI::ESC + "]1337;SetMark" + "\x07"
|
70
|
+
end
|
71
|
+
|
72
|
+
def file_finished(file, offenses)
|
73
|
+
out("\n") if @current == 0.0
|
74
|
+
@current += 1.0
|
75
|
+
unless Rfix.test?
|
76
|
+
@pg.tick(set_percent: (@current / @total))
|
77
|
+
end
|
78
|
+
@files[file] = offenses
|
79
|
+
end
|
80
|
+
|
81
|
+
def out(msg, format: true)
|
82
|
+
CLI::UI.puts(msg, to: output, format: format)
|
83
|
+
end
|
84
|
+
|
85
|
+
def fmt(msg)
|
86
|
+
CLI::UI.fmt(msg, enable_color: true)
|
87
|
+
end
|
88
|
+
|
89
|
+
def dim(value)
|
90
|
+
Rainbow(value).lightgray
|
91
|
+
end
|
92
|
+
|
93
|
+
def highlighted_source_line(offense)
|
94
|
+
source_before_highlight(offense) +
|
95
|
+
hightlight_source_tag(offense) +
|
96
|
+
source_after_highlight(offense)
|
97
|
+
end
|
98
|
+
|
99
|
+
def hightlight_source_tag(offense)
|
100
|
+
offense.highlighted_area.source
|
101
|
+
end
|
102
|
+
|
103
|
+
def source_before_highlight(offense)
|
104
|
+
source_line = offense.location.source_line
|
105
|
+
source_line[0...offense.highlighted_area.begin_pos]
|
106
|
+
end
|
107
|
+
|
108
|
+
def source_after_highlight(offense)
|
109
|
+
source_line = offense.location.source_line
|
110
|
+
source_line[offense.highlighted_area.end_pos..-1]
|
111
|
+
end
|
112
|
+
|
113
|
+
def report_line(_file, offense, _location, highlighted_area)
|
114
|
+
extra = " "
|
115
|
+
src = highlighted_source_line(offense).lines.map { |line| extra + line }.join("\n")
|
116
|
+
lines = @formatter.format(@lexer.lex(src)).gsub('\\e', CLI::UI::ANSI::ESC).lines.map(&:chomp)
|
117
|
+
out("\n\n")
|
118
|
+
out(lines.join("\n"), format: false)
|
119
|
+
b_pos = highlighted_area.begin_pos + extra.length
|
120
|
+
e_pos = highlighted_area.end_pos + extra.length
|
121
|
+
size = e_pos - b_pos
|
122
|
+
out((" " * b_pos) + Rainbow((" " * size)).underline.bold)
|
123
|
+
out("\n\n")
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "open3"
|
4
|
+
require "rfix"
|
5
|
+
require "rfix/log"
|
6
|
+
require "rfix/cmd"
|
7
|
+
require "shellwords"
|
8
|
+
|
9
|
+
module Rfix::GitHelper
|
10
|
+
include Rfix::Log
|
11
|
+
include Rfix::Cmd
|
12
|
+
|
13
|
+
def git(*params, root: Dir.pwd, quiet: false, &block)
|
14
|
+
args = split_args(params)
|
15
|
+
args.unshift *["--git-dir", File.join(root, ".git")]
|
16
|
+
args.unshift *["--work-tree", root]
|
17
|
+
cmd("git", *args, quiet: quiet, &block)
|
18
|
+
end
|
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
|
+
|
30
|
+
def has_branch?(branch)
|
31
|
+
cmd_succeeded?("git", "cat-file", "-t", branch)
|
32
|
+
end
|
33
|
+
|
34
|
+
def dirty?(path)
|
35
|
+
Dir.chdir(path) do
|
36
|
+
!cmd_succeeded?("git diff --quiet")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def params
|
41
|
+
[
|
42
|
+
"--word-diff-regex=[^[:space:]]",
|
43
|
+
"--no-renames",
|
44
|
+
"--no-merges",
|
45
|
+
"--first-parent",
|
46
|
+
"--find-renames",
|
47
|
+
"--find-copies",
|
48
|
+
"--diff-filter=AMCR",
|
49
|
+
"-U0",
|
50
|
+
"--no-color",
|
51
|
+
"-p"
|
52
|
+
]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# TODO: Rename above to just ::Git
|
57
|
+
module Rfix::Git
|
58
|
+
extend Rfix::GitHelper
|
59
|
+
end
|
data/lib/rfix/log.rb
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rfix"
|
4
|
+
require "cli/ui"
|
5
|
+
|
6
|
+
module Rfix::Log
|
7
|
+
extend self
|
8
|
+
def say(message)
|
9
|
+
prt("{{v}} #{message}")
|
10
|
+
end
|
11
|
+
|
12
|
+
def say_error(message)
|
13
|
+
prt("{{x}} #{message}")
|
14
|
+
end
|
15
|
+
|
16
|
+
def say_error_sub(message)
|
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)}")
|
31
|
+
end
|
32
|
+
|
33
|
+
def say_debug(message)
|
34
|
+
if debug? or test?
|
35
|
+
prt("{{i}} #{strip(message)}", to: $stderr)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def say_abort(message)
|
40
|
+
prt("{{x}} #{message}")
|
41
|
+
exit 1
|
42
|
+
end
|
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
|
+
|
53
|
+
def say_exit(message)
|
54
|
+
prt("{{v}} #{message}")
|
55
|
+
exit 0
|
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
|
131
|
+
end
|