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.
@@ -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
@@ -6,18 +6,21 @@ module TTY
6
6
  module File
7
7
  class CreateFile
8
8
 
9
- attr_reader :base, :relative_path, :content, :options, :prompt
9
+ attr_reader :base, :relative_path, :content, :prompt, :context
10
10
 
11
- def initialize(base, relative_path, content, options = {})
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
- @options = options
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 options[:force]
65
+ elsif @force
63
66
  notify(:force, :yellow)
64
- yield unless options[:noop]
65
- elsif options[:skip]
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 options[:noop]
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
- options.fetch(:verbose, true), options.fetch(:color, color))
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
@@ -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(string_a, string_b, options = {})
14
- @string_a = string_a
15
- @string_b = string_b
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
- diffs = Diff::LCS.diff(string_a_lines, string_b_lines)
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 = extract_hunks(diffs)
30
+ hunks = extract_hunks(diffs, string_a_lines, string_b_lines)
32
31
  format_hunks(hunks)
33
32
  end
34
33
 
35
- private
36
-
37
- def convert_to_lines(string)
38
- string.split(/\n/).map(&:chomp)
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
- def string_a_lines
42
- convert_to_lines(@string_a)
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
- def string_b_lines
46
- convert_to_lines(@string_b)
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 public
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 public
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, options = {})
17
+ def initialize(url, dest_path, limit: nil)
18
18
  @uri = URI.parse(url)
19
19
  @dest_path = dest_path
20
- @limit = options.fetch(:limit) { DEFAULT_REDIRECTS }
20
+ @limit = limit || DEFAULT_REDIRECTS
21
21
  end
22
22
 
23
23
  # Download a file
@@ -2,6 +2,6 @@
2
2
 
3
3
  module TTY
4
4
  module File
5
- VERSION = "0.9.0"
5
+ VERSION = "0.10.0"
6
6
  end # File
7
7
  end # TTY
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.9.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-04-28 00:00:00.000000000 Z
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.7.2
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.7.2
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.20'
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.20'
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://piotrmurach.github.io/tty
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://piotrmurach.github.io/tty
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: []