tty-file 0.9.0 → 0.10.0

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.
@@ -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: []