tty-file 0.6.0 → 0.7.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.
Files changed (46) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +18 -2
  3. data/README.md +58 -16
  4. data/Rakefile +1 -1
  5. data/lib/tty-file.rb +0 -2
  6. data/lib/tty/file.rb +35 -9
  7. data/lib/tty/file/create_file.rb +3 -1
  8. data/lib/tty/file/differ.rb +3 -2
  9. data/lib/tty/file/digest_file.rb +1 -1
  10. data/lib/tty/file/download_file.rb +3 -3
  11. data/lib/tty/file/read_backward_file.rb +0 -1
  12. data/lib/tty/file/version.rb +2 -2
  13. data/spec/fixtures/cli_app/%name%_cli.rb +2 -0
  14. data/spec/fixtures/cli_app/commands/subcommand.rb +2 -0
  15. data/spec/fixtures/cli_app/excluded/%name%_cli.rb +2 -0
  16. data/spec/fixtures/templates/%file_name%.rb +1 -0
  17. data/spec/fixtures/templates/unit_test.rb +1 -0
  18. data/spec/spec_helper.rb +90 -0
  19. data/spec/unit/append_to_file_spec.rb +85 -0
  20. data/spec/unit/binary_spec.rb +206 -0
  21. data/spec/unit/checksum_file_spec.rb +39 -0
  22. data/spec/unit/chmod_spec.rb +78 -0
  23. data/spec/unit/copy_directory_spec.rb +106 -0
  24. data/spec/unit/copy_file_spec.rb +157 -0
  25. data/spec/unit/create_directory_spec.rb +79 -0
  26. data/spec/unit/create_file_spec.rb +116 -0
  27. data/spec/unit/diff_spec.rb +93 -0
  28. data/spec/unit/differ/call_spec.rb +101 -0
  29. data/spec/unit/download_file_spec.rb +54 -0
  30. data/spec/unit/escape_glob_path_spec.rb +14 -0
  31. data/spec/unit/inject_into_file_spec.rb +162 -0
  32. data/spec/unit/prepend_to_file_spec.rb +98 -0
  33. data/spec/unit/remove_file_spec.rb +53 -0
  34. data/spec/unit/replace_in_file_spec.rb +126 -0
  35. data/spec/unit/tail_file_spec.rb +63 -0
  36. data/tasks/console.rake +1 -1
  37. data/tasks/coverage.rake +1 -1
  38. data/tasks/spec.rake +1 -1
  39. data/tty-file.gemspec +5 -4
  40. metadata +30 -13
  41. data/.gitignore +0 -10
  42. data/.rspec +0 -3
  43. data/.travis.yml +0 -26
  44. data/CODE_OF_CONDUCT.md +0 -49
  45. data/Gemfile +0 -9
  46. data/appveyor.yml +0 -26
@@ -0,0 +1 @@
1
+ class <%= class_name %>Test; end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ if ENV['COVERAGE'] || ENV['TRAVIS']
4
+ require 'simplecov'
5
+ require 'coveralls'
6
+
7
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
8
+ SimpleCov::Formatter::HTMLFormatter,
9
+ Coveralls::SimpleCov::Formatter
10
+ ]
11
+
12
+ SimpleCov.start do
13
+ command_name 'spec'
14
+ add_filter 'spec'
15
+ end
16
+ end
17
+
18
+ require 'tty/file'
19
+ require 'find'
20
+ require "webmock/rspec"
21
+
22
+ module Helpers
23
+ def gem_root
24
+ ::File.join(File.dirname(__FILE__), "..")
25
+ end
26
+
27
+ def dir_path(*args)
28
+ path = ::File.join(gem_root, *args)
29
+ ::FileUtils.mkdir_p(path) unless ::File.exist?(path)
30
+ ::File.realpath(path)
31
+ end
32
+
33
+ def fixtures_path(filename = nil)
34
+ ::File.join(dir_path('spec', 'fixtures'), filename.to_s)
35
+ end
36
+
37
+ def tmp_path(filename = nil)
38
+ ::File.join(dir_path('tmp'), filename.to_s)
39
+ end
40
+
41
+ def exists_and_identical?(source, dest)
42
+ dest_path = tmp_path(dest)
43
+ expect(::File.exist?(dest_path)).to be(true)
44
+
45
+ source_path = fixtures_path(source)
46
+ expect(::FileUtils).to be_identical(source_path, dest_path)
47
+ end
48
+
49
+ def strip_heredoc(content)
50
+ indent = content.scan(/^[ \t]*(?=\S)/).min.size || 0
51
+ content.gsub(/^[ \t]{#{indent}}/, '')
52
+ end
53
+ end
54
+
55
+ RSpec.configure do |config|
56
+ config.include(Helpers)
57
+
58
+ config.before(:each) do
59
+ FileUtils.cp_r(fixtures_path('/.'), tmp_path)
60
+ end
61
+
62
+ config.after(:each) do
63
+ FileUtils.rm_rf(tmp_path)
64
+ end
65
+
66
+ config.expect_with :rspec do |expectations|
67
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
68
+ end
69
+
70
+ config.mock_with :rspec do |mocks|
71
+ mocks.verify_partial_doubles = true
72
+ end
73
+
74
+ # Limits the available syntax to the non-monkey patched syntax that is recommended.
75
+ config.disable_monkey_patching!
76
+
77
+ # This setting enables warnings. It's recommended, but in some cases may
78
+ # be too noisy due to issues in dependencies.
79
+ config.warnings = true
80
+
81
+ if config.files_to_run.one?
82
+ config.default_formatter = 'doc'
83
+ end
84
+
85
+ config.profile_examples = 2
86
+
87
+ config.order = :random
88
+
89
+ Kernel.srand config.seed
90
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe TTY::File, '#append_to_file' do
4
+ it "appends to file" do
5
+ file = tmp_path('Gemfile')
6
+ TTY::File.append_to_file(file, "gem 'tty'", verbose: false)
7
+ expect(File.read(file)).to eq([
8
+ "gem 'nokogiri'\n",
9
+ "gem 'rails', '5.0.0'\n",
10
+ "gem 'rack', '>=1.0'\n",
11
+ "gem 'tty'"
12
+ ].join)
13
+ end
14
+
15
+ it "appends multiple lines to file" do
16
+ file = tmp_path('Gemfile')
17
+ TTY::File.append_to_file(file, "gem 'tty'\n", "gem 'rake'", verbose: false)
18
+ expect(File.read(file)).to eq([
19
+ "gem 'nokogiri'\n",
20
+ "gem 'rails', '5.0.0'\n",
21
+ "gem 'rack', '>=1.0'\n",
22
+ "gem 'tty'\n",
23
+ "gem 'rake'"
24
+ ].join)
25
+ end
26
+
27
+ it "appends content in a block" do
28
+ file = tmp_path('Gemfile')
29
+ TTY::File.append_to_file(file, verbose: false) { "gem 'tty'"}
30
+ expect(File.read(file)).to eq([
31
+ "gem 'nokogiri'\n",
32
+ "gem 'rails', '5.0.0'\n",
33
+ "gem 'rack', '>=1.0'\n",
34
+ "gem 'tty'"
35
+ ].join)
36
+ end
37
+
38
+ it "doesn't append if already present" do
39
+ file = tmp_path('Gemfile')
40
+ TTY::File.append_to_file(file, "gem 'rack', '>=1.0'\n", force: false, verbose: false)
41
+ expect(::File.read(file)).to eq([
42
+ "gem 'nokogiri'\n",
43
+ "gem 'rails', '5.0.0'\n",
44
+ "gem 'rack', '>=1.0'\n",
45
+ ].join)
46
+ end
47
+
48
+ it "appends safely checking if content already present" do
49
+ file = tmp_path('Gemfile')
50
+ TTY::File.safe_append_to_file(file, "gem 'rack', '>=1.0'\n", verbose: false)
51
+
52
+ expect(::File.read(file)).to eq([
53
+ "gem 'nokogiri'\n",
54
+ "gem 'rails', '5.0.0'\n",
55
+ "gem 'rack', '>=1.0'\n",
56
+ ].join)
57
+ end
58
+
59
+ it "appends multiple times by default" do
60
+ file = tmp_path('Gemfile')
61
+ TTY::File.append_to_file(file, "gem 'tty'\n", verbose: false)
62
+ TTY::File.append_to_file(file, "gem 'tty'\n", verbose: false)
63
+ expect(::File.read(file)).to eq([
64
+ "gem 'nokogiri'\n",
65
+ "gem 'rails', '5.0.0'\n",
66
+ "gem 'rack', '>=1.0'\n",
67
+ "gem 'tty'\n",
68
+ "gem 'tty'\n"
69
+ ].join)
70
+ end
71
+
72
+ it "logs action" do
73
+ file = tmp_path('Gemfile')
74
+ expect {
75
+ TTY::File.add_to_file(file, "gem 'tty'")
76
+ }.to output(/\e\[32mappend\e\[0m.*Gemfile/).to_stdout_from_any_process
77
+ end
78
+
79
+ it "logs action without color" do
80
+ file = tmp_path('Gemfile')
81
+ expect {
82
+ TTY::File.add_to_file(file, "gem 'tty'", color: false)
83
+ }.to output(/\s+append.*Gemfile/).to_stdout_from_any_process
84
+ end
85
+ end
@@ -0,0 +1,206 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe TTY::File, '#binary?' do
4
+ let(:ascii) { "This is a text file.\nWith more than one line.\nAnd a \tTab.\nAnd other printable chars too: ~!@\#$%^&*()`:\"<>?{}|_+,./;'[]\\-=\n" }
5
+
6
+ let(:utf_8) { "Testing utf-8 unicode...\n\n\non a new line: \xE2\x80\x93\n" }
7
+
8
+ let(:latin_1) { "Testing latin chars...\nsuch as #{0xFD.chr}mlaut.\n" }
9
+
10
+ let(:shift_jis) { "And some kanjis:\n #{0x83.chr}#{0x80.chr}.\n" }
11
+
12
+ it "identifies zero-length file as non-binary" do
13
+ Tempfile.open('tty-file-binary-spec') do |file|
14
+ expect(TTY::File.binary?(file)).to eq(false)
15
+ end
16
+ end
17
+
18
+ it "indentifies text with hex as binary" do
19
+ Tempfile.open('tty-file-binary-spec') do |file|
20
+ file << "hi \xAD"
21
+ file.close
22
+
23
+ expect(TTY::File.binary?(file)).to eq(true)
24
+ end
25
+ end
26
+
27
+ it "identifies image as binary" do
28
+ file = tmp_path('blackhole.png')
29
+
30
+ expect(TTY::File.binary?(file)).to eq(true)
31
+ end
32
+
33
+ it "indetifies text file as non-binary" do
34
+ file = tmp_path('Gemfile')
35
+
36
+ expect(TTY::File.binary?(file)).to eq(false)
37
+ end
38
+
39
+ it "indetifies a null-terminated string file as binary" do
40
+ Tempfile.open('tty-file-binary-spec') do |file|
41
+ file.write("Binary content.\0")
42
+ file.close
43
+
44
+ expect(TTY::File.binary?(file)).to eq(true)
45
+ end
46
+ end
47
+
48
+ it "indetifies a null-terminated multi-line string file as binary" do
49
+ Tempfile.open('tty-file-binary-spec') do |file|
50
+ file.write("Binary content.\non manylnes\nreally\0")
51
+ file.close
52
+
53
+ expect(TTY::File.binary?(file)).to eq(true)
54
+ end
55
+ end
56
+
57
+ context "when the default external encoding is UTF-8" do
58
+ before do
59
+ @saved_verbosity = $VERBOSE
60
+ @saved_encoding = Encoding.default_external
61
+ $VERBOSE = nil
62
+ Encoding.default_external = Encoding::UTF_8
63
+ end
64
+
65
+ after do
66
+ Encoding.default_external = @saved_encoding
67
+ $VERBOSE = @saved_verbosity
68
+ end
69
+
70
+ it "identifies ASCII as non-binary" do
71
+ Tempfile.open('tty-file-binary-spec') do |file|
72
+ file << ascii
73
+ file.close
74
+
75
+ expect(TTY::File.binary?(file)).to eq(false)
76
+ end
77
+ end
78
+
79
+ it "identifies UTF-8 as non-binary" do
80
+ Tempfile.open('tty-file-binary-spec') do |file|
81
+ file << utf_8
82
+ file.close
83
+
84
+ expect(TTY::File.binary?(file)).to eq(false)
85
+ end
86
+ end
87
+
88
+ it "indentifies Latin-1 as invalid UTF-8 and hence as binary" do
89
+ Tempfile.open('tty-file-binary-spec') do |file|
90
+ file << latin_1
91
+ file.close
92
+
93
+ expect(TTY::File.binary?(file)).to eq(true)
94
+ end
95
+ end
96
+
97
+ it "identifies Shift-JIS as invalid UTF-8 and hence as binary" do
98
+ Tempfile.open('tty-file-binary-spec') do |file|
99
+ file << shift_jis
100
+ file.close
101
+
102
+ expect(TTY::File.binary?(file)).to eq(true)
103
+ end
104
+ end
105
+ end
106
+
107
+ context "when the default external encoding is Latin-1" do
108
+ before do
109
+ @saved_verbosity = $VERBOSE
110
+ @saved_encoding = Encoding.default_external
111
+ $VERBOSE = nil
112
+ Encoding.default_external = Encoding::ISO_8859_1
113
+ end
114
+
115
+ after do
116
+ Encoding.default_external = @saved_encoding
117
+ $VERBOSE = @saved_verbosity
118
+ end
119
+
120
+ it "identifies ASCII as non-binary" do
121
+ Tempfile.open('tty-file-binary-spec') do |file|
122
+ file << ascii
123
+ file.close
124
+
125
+ expect(TTY::File.binary?(file)).to eq(false)
126
+ end
127
+ end
128
+
129
+ it "identifies UTF-8 as invalid Latin-1 and hence binary" do
130
+ Tempfile.open('tty-file-binary-spec') do |file|
131
+ file << utf_8
132
+ file.close
133
+
134
+ expect(TTY::File.binary?(file)).to eq(true)
135
+ end
136
+ end
137
+
138
+ it "indentifies Latin-1 as non-binary" do
139
+ Tempfile.open('tty-file-binary-spec') do |file|
140
+ file << latin_1
141
+ file.close
142
+
143
+ expect(TTY::File.binary?(file)).to eq(false)
144
+ end
145
+ end
146
+
147
+ it "identifies Shift-JIS as invalid Latin-1 and hence as binary" do
148
+ Tempfile.open('tty-file-binary-spec') do |file|
149
+ file << shift_jis
150
+ file.close
151
+
152
+ expect(TTY::File.binary?(file)).to eq(true)
153
+ end
154
+ end
155
+ end
156
+
157
+ context "when the default external encoding is Shift-JIS" do
158
+ before do
159
+ @saved_verbosity = $VERBOSE
160
+ @saved_encoding = Encoding.default_external
161
+ $VERBOSE = nil
162
+ Encoding.default_external = Encoding::SHIFT_JIS
163
+ end
164
+
165
+ after do
166
+ Encoding.default_external = @saved_encoding
167
+ $VERBOSE = @saved_verbosity
168
+ end
169
+
170
+ it "identifies ASCII as non-binary" do
171
+ Tempfile.open('tty-file-binary-spec') do |file|
172
+ file << ascii
173
+ file.close
174
+
175
+ expect(TTY::File.binary?(file)).to eq(false)
176
+ end
177
+ end
178
+
179
+ it "identifies UTF-8 as invalid Shift-JIS and hence as binary" do
180
+ Tempfile.open('tty-file-binary-spec') do |file|
181
+ file << utf_8
182
+ file.close
183
+
184
+ expect(TTY::File.binary?(file)).to eq(true)
185
+ end
186
+ end
187
+
188
+ it "indentifies Latin-1 as invalid Shift-JIS and hence as binary" do
189
+ Tempfile.open('tty-file-binary-spec') do |file|
190
+ file << latin_1
191
+ file.close
192
+
193
+ expect(TTY::File.binary?(file)).to eq(true)
194
+ end
195
+ end
196
+
197
+ it "identifies Shift-JIS as non-binary" do
198
+ Tempfile.open('tty-file-binary-spec') do |file|
199
+ file << shift_jis
200
+ file.close
201
+
202
+ expect(TTY::File.binary?(file)).to eq(false)
203
+ end
204
+ end
205
+ end
206
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe TTY::File, '#checksum_file' do
4
+ it "generates checksum for a file" do
5
+ file = tmp_path('checksum/README.md')
6
+
7
+ checksum = TTY::File.checksum_file(file)
8
+ expected = '76ba1beb6c611fa32624ed253444138cdf23eb938a3812137f8a399c5b375bfe'
9
+
10
+ expect(checksum).to eq(expected)
11
+ end
12
+
13
+ it "generates checksum for IO object" do
14
+ io = StringIO.new("Some content\nThe end")
15
+
16
+ checksum = TTY::File.checksum_file(io, 'md5')
17
+ expected = "ad0962e2374b1899fcfb818896703e50"
18
+
19
+ expect(checksum).to eq(expected)
20
+ end
21
+
22
+ it "generates checksum for String" do
23
+ string = "Some content\nThe end"
24
+
25
+ checksum = TTY::File.checksum_file(string, 'sha1')
26
+ expected = "289388f187404135e6c15b21460442cf867180dd"
27
+
28
+ expect(checksum).to eq(expected)
29
+ end
30
+
31
+ it "doesn't digest when :noop option" do
32
+ digester = double(:digester)
33
+ allow(TTY::File::DigestFile).to receive(:new).and_return(digester)
34
+
35
+ TTY::File.checksum_file('string', noop: true)
36
+
37
+ expect(digester).to_not receive(:call)
38
+ end
39
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe TTY::File, '#chmod' do
4
+ context 'when octal permisssions' do
5
+ it "adds permissions to file - user executable",
6
+ unless: RSpec::Support::OS.windows? do
7
+
8
+ file = tmp_path('script.sh')
9
+ mode = File.lstat(file).mode
10
+ expect(File.executable?(file)).to eq(false)
11
+
12
+ TTY::File.chmod(file, mode | TTY::File::U_X, verbose: false)
13
+
14
+ expect(File.lstat(file).mode).to eq(mode | TTY::File::U_X)
15
+ end
16
+
17
+ it "logs status when :verbose flag is true",
18
+ unless: RSpec::Support::OS.windows? do
19
+
20
+ file = tmp_path('script.sh')
21
+ mode = File.lstat(file).mode
22
+ expect(File.executable?(file)).to eq(false)
23
+
24
+ expect {
25
+ TTY::File.chmod(file, mode | TTY::File::U_X)
26
+ }.to output(/chmod/).to_stdout_from_any_process
27
+
28
+ expect(File.lstat(file).mode).to eq(mode | TTY::File::U_X)
29
+ end
30
+
31
+ it "doesn't change permission when :noop flag is true" do
32
+ file = tmp_path('script.sh')
33
+ mode = File.lstat(file).mode
34
+ expect(File.executable?(file)).to eq(false)
35
+
36
+ TTY::File.chmod(file, mode | TTY::File::U_X, verbose: false, noop: true)
37
+
38
+ expect(File.lstat(file).mode).to eq(mode)
39
+ end
40
+ end
41
+
42
+ context 'when human readable permissions' do
43
+ it "adds permisions to file - user executable",
44
+ unless: RSpec::Support::OS.windows? do
45
+
46
+ file = tmp_path('script.sh')
47
+ mode = File.lstat(file).mode
48
+ expect(File.executable?(file)).to eq(false)
49
+
50
+ TTY::File.chmod(file, 'u+x', verbose: false)
51
+
52
+ expect(File.lstat(file).mode).to eq(mode | TTY::File::U_X)
53
+ end
54
+
55
+ it "removes permission for user executable" do
56
+ file = tmp_path('script.sh')
57
+ mode = File.lstat(file).mode
58
+ expect(File.writable?(file)).to eq(true)
59
+
60
+ TTY::File.chmod(file, 'u-w', verbose: false)
61
+
62
+ expect(File.lstat(file).mode).to eq(mode ^ TTY::File::U_W)
63
+ expect(File.writable?(file)).to eq(false)
64
+ end
65
+
66
+ it "adds multiple permissions separated by comma",
67
+ unless: RSpec::Support::OS.windows? do
68
+
69
+ file = tmp_path('script.sh')
70
+ mode = File.lstat(file).mode
71
+ expect(File.executable?(file)).to eq(false)
72
+
73
+ TTY::File.chmod(file, 'u+x,g+x', verbose: false)
74
+
75
+ expect(File.lstat(file).mode).to eq(mode | TTY::File::U_X | TTY::File::G_X)
76
+ end
77
+ end
78
+ end