tty-file 0.7.0 → 0.7.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/lib/tty/file.rb +35 -21
- data/lib/tty/file/version.rb +1 -1
- data/spec/spec_helper.rb +4 -0
- data/spec/unit/append_to_file_spec.rb +96 -71
- data/spec/unit/binary_spec.rb +19 -1
- data/spec/unit/checksum_file_spec.rb +9 -0
- data/spec/unit/chmod_spec.rb +65 -51
- data/spec/unit/copy_directory_spec.rb +110 -96
- data/spec/unit/copy_file_spec.rb +117 -102
- data/spec/unit/create_directory_spec.rb +83 -69
- data/spec/unit/create_file_spec.rb +96 -82
- data/spec/unit/diff_spec.rb +97 -83
- data/spec/unit/download_file_spec.rb +49 -35
- data/spec/unit/inject_into_file_spec.rb +162 -148
- data/spec/unit/prepend_to_file_spec.rb +109 -83
- data/spec/unit/remove_file_spec.rb +45 -31
- data/spec/unit/replace_in_file_spec.rb +127 -113
- data/spec/unit/tail_file_spec.rb +61 -47
- data/tty-file.gemspec +4 -4
- metadata +12 -13
@@ -1,53 +1,67 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
RSpec.describe TTY::File, '#remove_file' do
|
4
|
-
|
5
|
-
|
4
|
+
shared_context "removing a file" do
|
5
|
+
it "removes a given file", unless: RSpec::Support::OS.windows? do
|
6
|
+
src_path = path_factory.call('Gemfile')
|
6
7
|
|
7
|
-
|
8
|
+
TTY::File.remove_file(src_path, verbose: false)
|
8
9
|
|
9
|
-
|
10
|
-
|
10
|
+
expect(::File.exist?(src_path)).to be(false)
|
11
|
+
end
|
11
12
|
|
12
|
-
|
13
|
-
|
13
|
+
it "removes a directory" do
|
14
|
+
src_path = path_factory.call('templates')
|
14
15
|
|
15
|
-
|
16
|
+
TTY::File.remove_file(src_path, verbose: false)
|
16
17
|
|
17
|
-
|
18
|
-
|
18
|
+
expect(::File.exist?(src_path)).to be(false)
|
19
|
+
end
|
19
20
|
|
20
|
-
|
21
|
-
|
21
|
+
it "pretends removing file" do
|
22
|
+
src_path = path_factory.call('Gemfile')
|
22
23
|
|
23
|
-
|
24
|
+
TTY::File.remove_file(src_path, noop: true, verbose: false)
|
24
25
|
|
25
|
-
|
26
|
-
|
26
|
+
expect(::File.exist?(src_path)).to be(true)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "removes files in secure mode" do
|
30
|
+
src_path = path_factory.call('Gemfile')
|
31
|
+
allow(::FileUtils).to receive(:rm_r)
|
32
|
+
|
33
|
+
TTY::File.remove_file(src_path, verbose: false, secure: false)
|
34
|
+
|
35
|
+
expect(::FileUtils).to have_received(:rm_r).
|
36
|
+
with(src_path.to_s, force: nil, secure: false)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "logs status" do
|
40
|
+
src_path = path_factory.call('Gemfile')
|
27
41
|
|
28
|
-
|
29
|
-
|
30
|
-
|
42
|
+
expect {
|
43
|
+
TTY::File.remove_file(src_path, noop: true)
|
44
|
+
}.to output(/\e\[31mremove\e\[0m(.*)Gemfile/).to_stdout_from_any_process
|
45
|
+
end
|
31
46
|
|
32
|
-
|
47
|
+
it "logs status without color" do
|
48
|
+
src_path = path_factory.call('Gemfile')
|
33
49
|
|
34
|
-
|
35
|
-
|
50
|
+
expect {
|
51
|
+
TTY::File.remove_file(src_path, noop: true, color: false)
|
52
|
+
}.to output(/\s+remove(.*)Gemfile/).to_stdout_from_any_process
|
53
|
+
end
|
36
54
|
end
|
37
55
|
|
38
|
-
|
39
|
-
|
56
|
+
context "when passed a String instance for the file argument" do
|
57
|
+
let(:path_factory) { method(:tmp_path) }
|
40
58
|
|
41
|
-
|
42
|
-
TTY::File.remove_file(src_path, noop: true)
|
43
|
-
}.to output(/\e\[31mremove\e\[0m(.*)Gemfile/).to_stdout_from_any_process
|
59
|
+
include_context "removing a file"
|
44
60
|
end
|
45
61
|
|
46
|
-
|
47
|
-
|
62
|
+
context "when passed a Pathname instance for the file argument" do
|
63
|
+
let(:path_factory) { method(:tmp_pathname) }
|
48
64
|
|
49
|
-
|
50
|
-
TTY::File.remove_file(src_path, noop: true, color: false)
|
51
|
-
}.to output(/\s+remove(.*)Gemfile/).to_stdout_from_any_process
|
65
|
+
include_context "removing a file"
|
52
66
|
end
|
53
67
|
end
|
@@ -1,126 +1,140 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
RSpec.describe TTY::File, '#replace_in_file' do
|
4
|
-
|
5
|
-
file
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
file
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
4
|
+
shared_context "replacing in a file" do
|
5
|
+
it "replaces file content with a matching string" do
|
6
|
+
file = path_factory.call('Gemfile')
|
7
|
+
status = nil
|
8
|
+
expect {
|
9
|
+
status = TTY::File.replace_in_file(file, /gem 'rails'/, "gem 'hanami'")
|
10
|
+
}.to output(/replace/).to_stdout_from_any_process
|
11
|
+
|
12
|
+
expect(status).to eq(true)
|
13
|
+
expect(File.read(file)).to eq([
|
14
|
+
"gem 'nokogiri'\n",
|
15
|
+
"gem 'hanami', '5.0.0'\n",
|
16
|
+
"gem 'rack', '>=1.0'\n"
|
17
|
+
].join)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "replaces file content with a matching block value" do
|
21
|
+
file = path_factory.call('Gemfile')
|
22
|
+
status = nil
|
23
|
+
expect {
|
24
|
+
status =TTY::File.replace_in_file(file, /gem 'rails'/, verbose: false) do |match|
|
25
|
+
match = "gem 'hanami'"
|
26
|
+
end
|
27
|
+
}.to_not output(/replace/).to_stdout_from_any_process
|
28
|
+
|
29
|
+
expect(status).to eq(true)
|
30
|
+
expect(File.read(file)).to eq([
|
31
|
+
"gem 'nokogiri'\n",
|
32
|
+
"gem 'hanami', '5.0.0'\n",
|
33
|
+
"gem 'rack', '>=1.0'\n"
|
34
|
+
].join)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "doesn't match file content" do
|
38
|
+
file = path_factory.call('Gemfile')
|
39
|
+
content = ::File.read(file)
|
40
|
+
status = TTY::File.replace_in_file(file, /unknown/, 'Hello', verbose: false)
|
41
|
+
|
42
|
+
expect(status).to eq(false)
|
43
|
+
expect(::File.read(file)).to eq(content)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "silences verbose output" do
|
47
|
+
content = "gem 'hanami'"
|
48
|
+
file = path_factory.call('Gemfile')
|
49
|
+
expect {
|
50
|
+
TTY::File.replace_in_file(file, /gem 'rails'/, content, verbose: false)
|
51
|
+
}.to_not output(/replace/).to_stdout_from_any_process
|
52
|
+
end
|
53
|
+
|
54
|
+
it "fails to replace content when missing correct file path" do
|
55
|
+
expect {
|
56
|
+
TTY::File.replace_in_file(path_factory.call('non-existent-path'),
|
57
|
+
/gem 'rails'/, "gem 'hanami'", verbose: false)
|
58
|
+
}.to raise_error(ArgumentError, /File path (.)* does not exist/)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "logs action" do
|
62
|
+
content = "gem 'hanami'"
|
63
|
+
file = path_factory.call('Gemfile')
|
64
|
+
|
65
|
+
expect {
|
66
|
+
TTY::File.replace_in_file(file, /gem 'rails'/, content, noop: true)
|
67
|
+
}.to output(/\e\[32mreplace\e\[0m(.*)Gemfile/).to_stdout_from_any_process
|
68
|
+
end
|
69
|
+
|
70
|
+
it "logs action without color" do
|
71
|
+
content = "gem 'hanami'"
|
72
|
+
file = path_factory.call('Gemfile')
|
73
|
+
|
74
|
+
expect {
|
75
|
+
TTY::File.replace_in_file(file, /gem 'rails'/, content,
|
76
|
+
noop: true, color: false)
|
77
|
+
}.to output(/\s+replace(.*)Gemfile/).to_stdout_from_any_process
|
78
|
+
end
|
79
|
+
|
80
|
+
it "allows for noop run" do
|
81
|
+
content = "gem 'hanami'"
|
82
|
+
file = path_factory.call('Gemfile')
|
35
83
|
|
36
|
-
it "doesn't match file content" do
|
37
|
-
file = tmp_path('Gemfile')
|
38
|
-
content = ::File.read(file)
|
39
|
-
status = TTY::File.replace_in_file(file, /unknown/, 'Hello', verbose: false)
|
40
|
-
|
41
|
-
expect(status).to eq(false)
|
42
|
-
expect(::File.read(file)).to eq(content)
|
43
|
-
end
|
44
|
-
|
45
|
-
it "silences verbose output" do
|
46
|
-
content = "gem 'hanami'"
|
47
|
-
file = tmp_path('Gemfile')
|
48
|
-
expect {
|
49
|
-
TTY::File.replace_in_file(file, /gem 'rails'/, content, verbose: false)
|
50
|
-
}.to_not output(/replace/).to_stdout_from_any_process
|
51
|
-
end
|
52
|
-
|
53
|
-
it "fails to replace content when missing correct file path" do
|
54
|
-
expect {
|
55
|
-
TTY::File.replace_in_file('/non-existent-path',
|
56
|
-
/gem 'rails'/, "gem 'hanami'", verbose: false)
|
57
|
-
}.to raise_error(ArgumentError, /File path (.)* does not exist/)
|
58
|
-
end
|
59
|
-
|
60
|
-
it "logs action" do
|
61
|
-
content = "gem 'hanami'"
|
62
|
-
file = tmp_path('Gemfile')
|
63
|
-
|
64
|
-
expect {
|
65
|
-
TTY::File.replace_in_file(file, /gem 'rails'/, content, noop: true)
|
66
|
-
}.to output(/\e\[32mreplace\e\[0m(.*)Gemfile/).to_stdout_from_any_process
|
67
|
-
end
|
68
|
-
|
69
|
-
it "logs action without color" do
|
70
|
-
content = "gem 'hanami'"
|
71
|
-
file = tmp_path('Gemfile')
|
72
|
-
|
73
|
-
expect {
|
74
84
|
TTY::File.replace_in_file(file, /gem 'rails'/, content,
|
75
|
-
noop: true,
|
76
|
-
|
85
|
+
noop: true, verbose: false)
|
86
|
+
|
87
|
+
expect(File.read(file)).to eq([
|
88
|
+
"gem 'nokogiri'\n",
|
89
|
+
"gem 'rails', '5.0.0'\n",
|
90
|
+
"gem 'rack', '>=1.0'\n"
|
91
|
+
].join)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "doesn't replace content when no match found" do
|
95
|
+
content = "gem 'hanami'"
|
96
|
+
file = path_factory.call('Gemfile')
|
97
|
+
|
98
|
+
status = TTY::File.gsub_file(file, /gem 'rails'/, content, verbose: false)
|
99
|
+
expect(status).to eq(true)
|
100
|
+
expect(File.read(file)).to eq([
|
101
|
+
"gem 'nokogiri'\n",
|
102
|
+
"gem 'hanami', '5.0.0'\n",
|
103
|
+
"gem 'rack', '>=1.0'\n"
|
104
|
+
].join)
|
105
|
+
|
106
|
+
status = TTY::File.gsub_file(file, /gem 'rails'/, content, verbose: false)
|
107
|
+
expect(status).to eq(false)
|
108
|
+
|
109
|
+
expect(File.read(file)).to eq([
|
110
|
+
"gem 'nokogiri'\n",
|
111
|
+
"gem 'hanami', '5.0.0'\n",
|
112
|
+
"gem 'rack', '>=1.0'\n"
|
113
|
+
].join)
|
114
|
+
end
|
115
|
+
|
116
|
+
it "replaces with multibyte content" do
|
117
|
+
content = "gem 'ようこそ'"
|
118
|
+
file = path_factory.call('Gemfile')
|
119
|
+
|
120
|
+
TTY::File.gsub_file(file, /gem 'rails'/, content, verbose: false)
|
121
|
+
expect(File.open(file, 'r:UTF-8', &:read)).to eq([
|
122
|
+
"gem 'nokogiri'\n",
|
123
|
+
"#{content}, '5.0.0'\n",
|
124
|
+
"gem 'rack', '>=1.0'\n"
|
125
|
+
].join)
|
126
|
+
end
|
77
127
|
end
|
78
128
|
|
79
|
-
|
80
|
-
|
81
|
-
file = tmp_path('Gemfile')
|
82
|
-
|
83
|
-
TTY::File.replace_in_file(file, /gem 'rails'/, content,
|
84
|
-
noop: true, verbose: false)
|
85
|
-
|
86
|
-
expect(File.read(file)).to eq([
|
87
|
-
"gem 'nokogiri'\n",
|
88
|
-
"gem 'rails', '5.0.0'\n",
|
89
|
-
"gem 'rack', '>=1.0'\n"
|
90
|
-
].join)
|
91
|
-
end
|
129
|
+
context "when passed a String instance for the file argument" do
|
130
|
+
let(:path_factory) { method(:tmp_path) }
|
92
131
|
|
93
|
-
|
94
|
-
content = "gem 'hanami'"
|
95
|
-
file = tmp_path('Gemfile')
|
96
|
-
|
97
|
-
status = TTY::File.gsub_file(file, /gem 'rails'/, content, verbose: false)
|
98
|
-
expect(status).to eq(true)
|
99
|
-
expect(File.read(file)).to eq([
|
100
|
-
"gem 'nokogiri'\n",
|
101
|
-
"gem 'hanami', '5.0.0'\n",
|
102
|
-
"gem 'rack', '>=1.0'\n"
|
103
|
-
].join)
|
104
|
-
|
105
|
-
status = TTY::File.gsub_file(file, /gem 'rails'/, content, verbose: false)
|
106
|
-
expect(status).to eq(false)
|
107
|
-
|
108
|
-
expect(File.read(file)).to eq([
|
109
|
-
"gem 'nokogiri'\n",
|
110
|
-
"gem 'hanami', '5.0.0'\n",
|
111
|
-
"gem 'rack', '>=1.0'\n"
|
112
|
-
].join)
|
132
|
+
include_context "replacing in a file"
|
113
133
|
end
|
114
134
|
|
115
|
-
|
116
|
-
|
117
|
-
file = tmp_path('Gemfile')
|
135
|
+
context "when passed a Pathname instance for the file argument" do
|
136
|
+
let(:path_factory) { method(:tmp_pathname) }
|
118
137
|
|
119
|
-
|
120
|
-
expect(File.open(file, 'r:UTF-8', &:read)).to eq([
|
121
|
-
"gem 'nokogiri'\n",
|
122
|
-
"#{content}, '5.0.0'\n",
|
123
|
-
"gem 'rack', '>=1.0'\n"
|
124
|
-
].join)
|
138
|
+
include_context "replacing in a file"
|
125
139
|
end
|
126
140
|
end
|
data/spec/unit/tail_file_spec.rb
CHANGED
@@ -1,63 +1,77 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
RSpec.describe TTY::File, '#tail_file' do
|
4
|
-
|
5
|
-
file
|
6
|
-
|
7
|
-
lines = TTY::File.tail_file(file, 5, chunk_size: 2**3)
|
8
|
-
|
9
|
-
expect(lines).to eq([
|
10
|
-
"line12",
|
11
|
-
"line13",
|
12
|
-
"line14",
|
13
|
-
"line15",
|
14
|
-
"line16"
|
15
|
-
])
|
16
|
-
end
|
4
|
+
shared_context "tailing a file" do
|
5
|
+
it "tails file for lines with chunks smaller than file size" do
|
6
|
+
file = path_factory.call('tail/lines')
|
17
7
|
|
18
|
-
|
19
|
-
file = tmp_path('tail/lines')
|
8
|
+
lines = TTY::File.tail_file(file, 5, chunk_size: 2**3)
|
20
9
|
|
21
|
-
|
10
|
+
expect(lines).to eq([
|
11
|
+
"line12",
|
12
|
+
"line13",
|
13
|
+
"line14",
|
14
|
+
"line15",
|
15
|
+
"line16"
|
16
|
+
])
|
17
|
+
end
|
22
18
|
|
23
|
-
|
24
|
-
|
25
|
-
"line13",
|
26
|
-
"line14",
|
27
|
-
"line15",
|
28
|
-
"line16"
|
29
|
-
])
|
19
|
+
it "tails file for lines with chunks equal file size" do
|
20
|
+
file = path_factory.call('tail/lines')
|
30
21
|
|
31
|
-
|
22
|
+
lines = TTY::File.tail_file(file, 5, chunk_size: file.size)
|
32
23
|
|
33
|
-
|
34
|
-
|
24
|
+
expect(lines).to eq([
|
25
|
+
"line12",
|
26
|
+
"line13",
|
27
|
+
"line14",
|
28
|
+
"line15",
|
29
|
+
"line16"
|
30
|
+
])
|
35
31
|
|
36
|
-
|
32
|
+
end
|
37
33
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
34
|
+
it "tails file for lines with chunks larger than file size" do
|
35
|
+
file = path_factory.call('tail/lines')
|
36
|
+
|
37
|
+
lines = TTY::File.tail_file(file, 5, chunk_size: 2**9)
|
38
|
+
|
39
|
+
expect(lines).to eq([
|
40
|
+
"line12",
|
41
|
+
"line13",
|
42
|
+
"line14",
|
43
|
+
"line15",
|
44
|
+
"line16"
|
45
|
+
])
|
46
|
+
end
|
47
|
+
|
48
|
+
it "tails file and yields lines" do
|
49
|
+
file = path_factory.call('tail/lines')
|
50
|
+
lines = []
|
46
51
|
|
47
|
-
|
48
|
-
|
49
|
-
|
52
|
+
TTY::File.tail_file(file, 5, chunk_size: 8) do |line|
|
53
|
+
lines << line
|
54
|
+
end
|
50
55
|
|
51
|
-
|
52
|
-
|
56
|
+
expect(lines).to eq([
|
57
|
+
"line12",
|
58
|
+
"line13",
|
59
|
+
"line14",
|
60
|
+
"line15",
|
61
|
+
"line16"
|
62
|
+
])
|
53
63
|
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "when passed a String instance for the file argument" do
|
67
|
+
let(:path_factory) { method(:tmp_path) }
|
68
|
+
|
69
|
+
include_context "tailing a file"
|
70
|
+
end
|
71
|
+
|
72
|
+
context "when passed a Pathname instance for the file argument" do
|
73
|
+
let(:path_factory) { method(:tmp_pathname) }
|
54
74
|
|
55
|
-
|
56
|
-
"line12",
|
57
|
-
"line13",
|
58
|
-
"line14",
|
59
|
-
"line15",
|
60
|
-
"line16"
|
61
|
-
])
|
75
|
+
include_context "tailing a file"
|
62
76
|
end
|
63
77
|
end
|