tty-file 0.9.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -0
- data/README.md +144 -75
- data/lib/tty-file.rb +1 -1
- data/lib/tty/file.rb +237 -155
- data/lib/tty/file/compare_files.rb +70 -0
- data/lib/tty/file/create_file.rb +28 -14
- data/lib/tty/file/differ.rb +40 -20
- data/lib/tty/file/download_file.rb +2 -2
- data/lib/tty/file/version.rb +1 -1
- metadata +10 -8
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "differ"
|
4
|
+
|
5
|
+
module TTY
|
6
|
+
module File
|
7
|
+
class CompareFiles
|
8
|
+
extend Forwardable
|
9
|
+
|
10
|
+
def initialize(format: :unified, header: true, context_lines: 5,
|
11
|
+
verbose: true, color: :green, noop: false, diff_colors: nil)
|
12
|
+
@format = format
|
13
|
+
@header = header
|
14
|
+
@context_lines = context_lines
|
15
|
+
@verbose = verbose
|
16
|
+
@color = color
|
17
|
+
@noop = noop
|
18
|
+
@diff_colors = diff_colors
|
19
|
+
end
|
20
|
+
|
21
|
+
# Compare files
|
22
|
+
#
|
23
|
+
# @api public
|
24
|
+
def call(file_a, file_b, file_a_path, file_b_path)
|
25
|
+
differ = Differ.new(format: @format, context_lines: @context_lines)
|
26
|
+
block_size = file_a.lstat.blksize
|
27
|
+
file_a_chunk = file_a.read(block_size)
|
28
|
+
file_b_chunk = file_b.read(block_size)
|
29
|
+
hunks = differ.(file_a_chunk, file_b_chunk)
|
30
|
+
|
31
|
+
return "" if file_a_chunk.empty? && file_b_chunk.empty?
|
32
|
+
return "No differences found\n" if hunks.empty?
|
33
|
+
|
34
|
+
output = []
|
35
|
+
|
36
|
+
if %i[unified context old].include?(@format) && @header
|
37
|
+
output << "#{differ.delete_char * 3} #{file_a_path}\n"
|
38
|
+
output << "#{differ.add_char * 3} #{file_b_path}"
|
39
|
+
end
|
40
|
+
|
41
|
+
output << "\n" unless hunks =~ /\A\n+@@/
|
42
|
+
output << hunks
|
43
|
+
while !file_a.eof? && !file_b.eof?
|
44
|
+
output << differ.(file_a.read(block_size), file_b.read(block_size))
|
45
|
+
end
|
46
|
+
color_diff_lines(output.join)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
# @api private
|
52
|
+
def color_diff_lines(hunks)
|
53
|
+
return hunks unless @color && @format == :unified
|
54
|
+
|
55
|
+
newline = "\n"
|
56
|
+
hunks.lines.map do |line|
|
57
|
+
if matched = line.to_s.match(/^(\+[^+]*?)\n/)
|
58
|
+
@diff_colors[:green].(matched[1]) + newline
|
59
|
+
elsif matched = line.to_s.match(/^(\-[^-].*?)\n/)
|
60
|
+
@diff_colors[:red].(matched[1]) + newline
|
61
|
+
elsif matched = line.to_s.match(/^(@@.+?@@)\n/)
|
62
|
+
@diff_colors[:cyan].(matched[1]) + newline
|
63
|
+
else
|
64
|
+
line
|
65
|
+
end
|
66
|
+
end.join
|
67
|
+
end
|
68
|
+
end # CompareFiles
|
69
|
+
end # File
|
70
|
+
end # TTY
|
data/lib/tty/file/create_file.rb
CHANGED
@@ -6,18 +6,21 @@ module TTY
|
|
6
6
|
module File
|
7
7
|
class CreateFile
|
8
8
|
|
9
|
-
attr_reader :base, :relative_path, :content, :
|
9
|
+
attr_reader :base, :relative_path, :content, :prompt, :context
|
10
10
|
|
11
|
-
def initialize(base, relative_path, content,
|
11
|
+
def initialize(base, relative_path, content, context: nil, force: false,
|
12
|
+
skip: false, verbose: true, noop: false, color: :green,
|
13
|
+
quiet: true)
|
12
14
|
@base = base
|
13
15
|
@content = content
|
14
|
-
@
|
16
|
+
@context = context || @base
|
17
|
+
@force = force
|
18
|
+
@skip = skip
|
19
|
+
@noop = noop
|
20
|
+
@verbose = verbose
|
21
|
+
@color = color
|
15
22
|
@relative_path = convert_encoded_path(relative_path)
|
16
|
-
@prompt = TTY::Prompt.new
|
17
|
-
end
|
18
|
-
|
19
|
-
def context
|
20
|
-
options[:context] || @base
|
23
|
+
@prompt = TTY::Prompt.new(quiet: quiet)
|
21
24
|
end
|
22
25
|
|
23
26
|
def exist?
|
@@ -59,10 +62,10 @@ module TTY
|
|
59
62
|
if exist?
|
60
63
|
if identical?
|
61
64
|
notify(:identical, :cyan)
|
62
|
-
elsif
|
65
|
+
elsif @force
|
63
66
|
notify(:force, :yellow)
|
64
|
-
yield unless
|
65
|
-
elsif
|
67
|
+
yield unless @noop
|
68
|
+
elsif @skip
|
66
69
|
notify(:skip, :yellow)
|
67
70
|
else
|
68
71
|
notify(:collision, :red)
|
@@ -70,15 +73,16 @@ module TTY
|
|
70
73
|
end
|
71
74
|
else
|
72
75
|
notify(:create, :green)
|
73
|
-
yield unless
|
76
|
+
yield unless @noop
|
74
77
|
end
|
75
78
|
end
|
76
79
|
|
77
80
|
# Notify console about performed action
|
81
|
+
#
|
78
82
|
# @api private
|
79
83
|
def notify(name, color)
|
80
84
|
base.__send__(:log_status, name, relative_path,
|
81
|
-
|
85
|
+
verbose: @verbose, color: @color ? color : false)
|
82
86
|
end
|
83
87
|
|
84
88
|
# Display conflict resolution menu and gather answer
|
@@ -87,13 +91,23 @@ module TTY
|
|
87
91
|
def file_collision(relative_path, content)
|
88
92
|
choices = [
|
89
93
|
{ key: "y", name: "yes, overwrite", value: :yes },
|
94
|
+
{ key: "d", name: "diff, compare files", value: :diff },
|
90
95
|
{ key: "n", name: "no, do not overwrite", value: :no },
|
91
96
|
{ key: "q", name: "quit, abort", value: :quit }
|
92
97
|
]
|
93
|
-
answer = prompt.expand("Overwrite #{relative_path}?", choices)
|
98
|
+
while (answer = prompt.expand("Overwrite #{relative_path}?", choices)) == :diff do
|
99
|
+
show_diff
|
100
|
+
end
|
94
101
|
interpret_answer(answer)
|
95
102
|
end
|
96
103
|
|
104
|
+
# Display difference between old and new file
|
105
|
+
#
|
106
|
+
# @api private
|
107
|
+
def show_diff
|
108
|
+
print base.__send__(:diff_files, relative_path, content, verbose: @verbose)
|
109
|
+
end
|
110
|
+
|
97
111
|
# @api private
|
98
112
|
def interpret_answer(answer)
|
99
113
|
case answer
|
data/lib/tty/file/differ.rb
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
require "diff/lcs"
|
4
4
|
require "diff/lcs/hunk"
|
5
|
-
require "enumerator"
|
6
5
|
|
7
6
|
module TTY
|
8
7
|
module File
|
@@ -10,11 +9,9 @@ module TTY
|
|
10
9
|
# Create a Differ
|
11
10
|
#
|
12
11
|
# @api public
|
13
|
-
def initialize(
|
14
|
-
@
|
15
|
-
@
|
16
|
-
@format = options.fetch(:format, :unified)
|
17
|
-
@context_lines = options.fetch(:context_lines, 3)
|
12
|
+
def initialize(format: :unified, context_lines: 3)
|
13
|
+
@format = format
|
14
|
+
@context_lines = context_lines
|
18
15
|
end
|
19
16
|
|
20
17
|
# Find character difference between two strings
|
@@ -24,30 +21,53 @@ module TTY
|
|
24
21
|
# difference found
|
25
22
|
#
|
26
23
|
# @api public
|
27
|
-
def call
|
28
|
-
|
24
|
+
def call(string_a, string_b)
|
25
|
+
string_a_lines = convert_to_lines(string_a)
|
26
|
+
string_b_lines = convert_to_lines(string_b)
|
27
|
+
diffs = Diff::LCS.diff(string_a_lines, string_b_lines)
|
29
28
|
return "" if diffs.empty?
|
30
29
|
|
31
|
-
hunks
|
30
|
+
hunks = extract_hunks(diffs, string_a_lines, string_b_lines)
|
32
31
|
format_hunks(hunks)
|
33
32
|
end
|
34
33
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
34
|
+
# Diff add char
|
35
|
+
#
|
36
|
+
# @api public
|
37
|
+
def add_char
|
38
|
+
case @format
|
39
|
+
when :old
|
40
|
+
">"
|
41
|
+
when :unified
|
42
|
+
"+"
|
43
|
+
else
|
44
|
+
"*"
|
45
|
+
end
|
39
46
|
end
|
40
47
|
|
41
|
-
|
42
|
-
|
48
|
+
# Diff delete char
|
49
|
+
#
|
50
|
+
# @api public
|
51
|
+
def delete_char
|
52
|
+
case @format
|
53
|
+
when :old
|
54
|
+
"<"
|
55
|
+
when :unified
|
56
|
+
"-"
|
57
|
+
else
|
58
|
+
"*"
|
59
|
+
end
|
43
60
|
end
|
44
61
|
|
45
|
-
|
46
|
-
|
62
|
+
private
|
63
|
+
|
64
|
+
# @api private
|
65
|
+
def convert_to_lines(string)
|
66
|
+
string.split(/\n/).map(&:chomp)
|
47
67
|
end
|
48
68
|
|
49
|
-
# @api
|
50
|
-
def extract_hunks(diffs)
|
69
|
+
# @api private
|
70
|
+
def extract_hunks(diffs, string_a_lines, string_b_lines)
|
51
71
|
file_length_difference = 0
|
52
72
|
|
53
73
|
diffs.map do |piece|
|
@@ -58,7 +78,7 @@ module TTY
|
|
58
78
|
end
|
59
79
|
end
|
60
80
|
|
61
|
-
# @api
|
81
|
+
# @api private
|
62
82
|
def format_hunks(hunks)
|
63
83
|
output = []
|
64
84
|
hunks.each_cons(2) do |prev_hunk, current_hunk|
|
@@ -14,10 +14,10 @@ module TTY
|
|
14
14
|
|
15
15
|
# @options
|
16
16
|
#
|
17
|
-
def initialize(url, dest_path,
|
17
|
+
def initialize(url, dest_path, limit: nil)
|
18
18
|
@uri = URI.parse(url)
|
19
19
|
@dest_path = dest_path
|
20
|
-
@limit =
|
20
|
+
@limit = limit || DEFAULT_REDIRECTS
|
21
21
|
end
|
22
22
|
|
23
23
|
# Download a file
|
data/lib/tty/file/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tty-file
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Murach
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-07-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pastel
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: '0.8'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
26
|
+
version: '0.8'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: tty-prompt
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0.
|
33
|
+
version: '0.22'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0.
|
40
|
+
version: '0.22'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: diff-lcs
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -109,20 +109,22 @@ files:
|
|
109
109
|
- README.md
|
110
110
|
- lib/tty-file.rb
|
111
111
|
- lib/tty/file.rb
|
112
|
+
- lib/tty/file/compare_files.rb
|
112
113
|
- lib/tty/file/create_file.rb
|
113
114
|
- lib/tty/file/differ.rb
|
114
115
|
- lib/tty/file/digest_file.rb
|
115
116
|
- lib/tty/file/download_file.rb
|
116
117
|
- lib/tty/file/read_backward_file.rb
|
117
118
|
- lib/tty/file/version.rb
|
118
|
-
homepage: https://
|
119
|
+
homepage: https://ttytoolkit.org
|
119
120
|
licenses:
|
120
121
|
- MIT
|
121
122
|
metadata:
|
122
123
|
allowed_push_host: https://rubygems.org
|
124
|
+
bug_tracker_uri: https://github.com/piotrmurach/tty-file/issues
|
123
125
|
changelog_uri: https://github.com/piotrmurach/tty-file/blob/master/CHANGELOG.md
|
124
126
|
documentation_uri: https://www.rubydoc.info/gems/tty-file
|
125
|
-
homepage_uri: https://
|
127
|
+
homepage_uri: https://ttytoolkit.org
|
126
128
|
source_code_uri: https://github.com/piotrmurach/tty-file
|
127
129
|
post_install_message:
|
128
130
|
rdoc_options: []
|