nested_file 0.0.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.
@@ -0,0 +1,87 @@
1
+ module NestedFile
2
+ class ConvertPath
3
+ include FromHash
4
+ attr_accessor :parent_dir, :mount_dir
5
+ # converts the directory relative to the mount point to an absolute parent path
6
+ def mount_to_parent(path)
7
+ File.join parent_dir, path
8
+ end
9
+ def parent_to_mount(path)
10
+ path.gsub("#{parent_dir}/","")
11
+ end
12
+ def mount_to_parent_if_relative(path)
13
+ if Pathname.new(path).absolute?
14
+ path
15
+ else
16
+ mount_to_parent(path)
17
+ end
18
+ end
19
+ end
20
+
21
+ class PutDir
22
+ include FromHash
23
+ attr_accessor :parent_dir, :mount_dir, :relative_dir
24
+
25
+ fattr(:convert_path) do
26
+ ConvertPath.new(parent_dir: parent_dir, mount_dir: mount_dir)
27
+ end
28
+ fattr(:relative_convert_path) do
29
+ ConvertPath.new(parent_dir: relative_dir||parent_dir, mount_dir: mount_dir)
30
+ end
31
+ extend Forwardable
32
+ def_delegators :convert_path, :mount_to_parent, :parent_to_mount
33
+
34
+ def contents(path)
35
+ log "contents for #{path}" do
36
+ parent_path = mount_to_parent(path)
37
+ res = Dir.entries(parent_path)
38
+ res.map { |x| File.basename(x) }
39
+ end
40
+ end
41
+ def file?(path)
42
+ FileTest.file? mount_to_parent(path)
43
+ end
44
+ def directory?(path)
45
+ FileTest.directory? mount_to_parent(path)
46
+ end
47
+ def read_file_inner(path)
48
+ body = File.read(mount_to_parent(path))
49
+ PutFile.new(raw_body: body, filename: mount_to_parent(path), convert_path: relative_convert_path).parsed_body
50
+ end
51
+ def read_file(path)
52
+ log "read file #{path}" do
53
+ read_file_inner path
54
+ end
55
+ end
56
+ def size(path)
57
+ log "size for #{path}" do
58
+ read_file_inner(path).size
59
+ end
60
+ end
61
+
62
+ module Raw
63
+ def raw_open(path,*args)
64
+ if args[0] == 'w'
65
+ File.new(mount_to_parent(path),'w')
66
+ else
67
+ nil
68
+ end
69
+ end
70
+ def raw_truncate(path,i,f)
71
+ f.truncate(i)
72
+ end
73
+ def raw_close(*args)
74
+ args.last.close
75
+ end
76
+ def raw_write(path,offset,sz,buf,file=nil)
77
+ PutFile.new(raw_body: buf, filename: mount_to_parent(path), convert_path: relative_convert_path).write_all! file
78
+ buf.length
79
+ end
80
+ end
81
+ include Raw
82
+
83
+ def can_write?(path)
84
+ true
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,43 @@
1
+ module NestedFile
2
+ class PutFile
3
+ include FromHash
4
+ attr_accessor :raw_body, :filename, :convert_path
5
+
6
+ fattr(:parsed_body) do
7
+ res = raw_body.gsub(/<file (.+?)>.*?<\/file>/m) do
8
+ f = $1
9
+ full = convert_path.mount_to_parent_if_relative(f)
10
+ FileSection::Read.new(file_to_insert: f, full_file_to_insert: full).to_s
11
+ end
12
+ res.gsub(/<files (.+?)>.*?<\/files>/m) do
13
+ f = $1
14
+ full = convert_path.mount_to_parent_if_relative(f)
15
+ FileGroup.new(file_glob: f, full_glob: full, convert_path: convert_path).to_s
16
+ end
17
+ end
18
+
19
+ def write_subs!
20
+ raw_body.scan(/<file (.+?)>(.*?)<\/file>/m) do |m|
21
+ sub_file, sub_body = *m
22
+ #ff = File.expand_path(sub_file,File.dirname(filename))
23
+ full = convert_path.mount_to_parent_if_relative(sub_file)
24
+ FileSection::Write.new(parent_body: sub_body, full_file_to_insert: full).write!
25
+ end
26
+ end
27
+ def write_self!(file=nil)
28
+ res = raw_body.gsub(/<file (.+?)>(.*?)<\/file>/m) do
29
+ "<file #{$1}>\n</file>"
30
+ end
31
+
32
+ if file
33
+ file.write res
34
+ else
35
+ File.create filename, res
36
+ end
37
+ end
38
+ def write_all!(file=nil)
39
+ write_subs!
40
+ write_self!(file)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,28 @@
1
+ module NestedFile
2
+ def self.root
3
+ res = File.expand_path(File.dirname(__FILE__))+"/../.."
4
+ File.expand_path(res)
5
+ end
6
+ end
7
+
8
+ def log(str)
9
+ res = nil
10
+ if block_given?
11
+ res = yield
12
+ str = "#{str} res: #{res}"
13
+ end
14
+ # puts str
15
+ File.append "/code/orig/nested_file/debug.log","#{str}\n"
16
+ res
17
+ end
18
+
19
+ File.create "/code/orig/nested_file/debug.log","Starting at #{Time.now}\n"
20
+
21
+ # class String
22
+ # def gsub_safe(reg,str,&b)
23
+ # res = gsub(reg,str,&b)
24
+ # c = caller.join("\n")
25
+ # raise "didn't change, gsub #{self} with #{reg}, replace with #{str}\n#{c}" if res == self
26
+ # res
27
+ # end
28
+ # end
@@ -0,0 +1,110 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+ # stub: nested_file 0.0.1 ruby lib
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = "nested_file"
9
+ s.version = "0.0.1"
10
+
11
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib"]
13
+ s.authors = ["Mike Harris"]
14
+ s.date = "2016-05-17"
15
+ s.description = "nested_file"
16
+ s.email = "mharris717@gmail.com"
17
+ s.executables = ["nested_file"]
18
+ s.extra_rdoc_files = [
19
+ "LICENSE.txt",
20
+ "README.rdoc"
21
+ ]
22
+ s.files = [
23
+ ".document",
24
+ ".rspec",
25
+ ".travis.yml",
26
+ "Gemfile",
27
+ "Gemfile.lock",
28
+ "Guardfile",
29
+ "LICENSE.txt",
30
+ "README.rdoc",
31
+ "Rakefile",
32
+ "VERSION",
33
+ "bin/nested_file",
34
+ "lib/nested_file.rb",
35
+ "lib/nested_file/file_group.rb",
36
+ "lib/nested_file/file_section.rb",
37
+ "lib/nested_file/file_tag.rb",
38
+ "lib/nested_file/put_dir.rb",
39
+ "lib/nested_file/put_file.rb",
40
+ "lib/nested_file/util.rb",
41
+ "nested_file.gemspec",
42
+ "spec/file_section_spec.rb",
43
+ "spec/nested_file_spec.rb",
44
+ "spec/parent_template/a.txt",
45
+ "spec/parent_template/include_others.txt",
46
+ "spec/parent_template/include_others_rel.txt",
47
+ "spec/parent_template/sub2/x.txt",
48
+ "spec/put_dir_spec.rb",
49
+ "spec/spec_helper.rb",
50
+ "tmp/.gitkeep",
51
+ "unmount_all_fuse.rb",
52
+ "util/green.gif",
53
+ "util/package.json",
54
+ "util/red.png",
55
+ "util/run_specs",
56
+ "util/watch.js",
57
+ "vol/spawn_mount.rb",
58
+ "vol/watch_cat.rb"
59
+ ]
60
+ s.homepage = "http://github.com/mharris717/nested_file"
61
+ s.licenses = ["MIT"]
62
+ s.rubygems_version = "2.5.1"
63
+ s.summary = "nested_file"
64
+
65
+ if s.respond_to? :specification_version then
66
+ s.specification_version = 4
67
+
68
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
69
+ s.add_runtime_dependency(%q<mharris_ext>, [">= 0"])
70
+ s.add_runtime_dependency(%q<rfusefs>, [">= 0"])
71
+ s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
72
+ s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
73
+ s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
74
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
75
+ s.add_development_dependency(%q<guard>, [">= 0"])
76
+ s.add_development_dependency(%q<guard-rspec>, [">= 0"])
77
+ s.add_development_dependency(%q<guard-spork>, [">= 0"])
78
+ s.add_development_dependency(%q<rb-fsevent>, ["~> 0.9"])
79
+ s.add_development_dependency(%q<lre>, [">= 0"])
80
+ s.add_development_dependency(%q<rr>, [">= 0"])
81
+ else
82
+ s.add_dependency(%q<mharris_ext>, [">= 0"])
83
+ s.add_dependency(%q<rfusefs>, [">= 0"])
84
+ s.add_dependency(%q<rspec>, ["~> 2.8.0"])
85
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
86
+ s.add_dependency(%q<bundler>, [">= 1.0.0"])
87
+ s.add_dependency(%q<jeweler>, [">= 0"])
88
+ s.add_dependency(%q<guard>, [">= 0"])
89
+ s.add_dependency(%q<guard-rspec>, [">= 0"])
90
+ s.add_dependency(%q<guard-spork>, [">= 0"])
91
+ s.add_dependency(%q<rb-fsevent>, ["~> 0.9"])
92
+ s.add_dependency(%q<lre>, [">= 0"])
93
+ s.add_dependency(%q<rr>, [">= 0"])
94
+ end
95
+ else
96
+ s.add_dependency(%q<mharris_ext>, [">= 0"])
97
+ s.add_dependency(%q<rfusefs>, [">= 0"])
98
+ s.add_dependency(%q<rspec>, ["~> 2.8.0"])
99
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
100
+ s.add_dependency(%q<bundler>, [">= 1.0.0"])
101
+ s.add_dependency(%q<jeweler>, [">= 0"])
102
+ s.add_dependency(%q<guard>, [">= 0"])
103
+ s.add_dependency(%q<guard-rspec>, [">= 0"])
104
+ s.add_dependency(%q<guard-spork>, [">= 0"])
105
+ s.add_dependency(%q<rb-fsevent>, ["~> 0.9"])
106
+ s.add_dependency(%q<lre>, [">= 0"])
107
+ s.add_dependency(%q<rr>, [">= 0"])
108
+ end
109
+ end
110
+
@@ -0,0 +1,32 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "FileSection" do
4
+ include_context "file stub"
5
+
6
+ it 'smoke' do
7
+ file = "/a/b/c"
8
+ body = 'abc'
9
+ file_stub.add file,body
10
+ section = NestedFile::FileSection.new(full_file_to_insert: file, file_to_insert: file)
11
+ section.insert_body.should == body
12
+ section.to_s.should == "<file /a/b/c>\nabc\n</file>"
13
+ end
14
+
15
+ it 'smoke' do
16
+ file = "c.txt"
17
+ file_stub.add "/a/c.txt",'abc'
18
+
19
+ section = NestedFile::FileSection.new(file_to_insert: file, full_file_to_insert: "/a/c.txt")
20
+ section.to_s.should == "<file c.txt>\nabc\n</file>"
21
+ end
22
+
23
+ it "reading file that doesn't exist" do
24
+ section = NestedFile::FileSection.new(full_file_to_insert: "a.txt", file_to_insert: nil)
25
+ section.insert_body.should == ''
26
+ end
27
+
28
+ it 'trimmed_body only trims 1 newline' do
29
+ section = NestedFile::FileSection::Write.new(parent_body: "\n\nabc\n")
30
+ section.trimmed_parent_body.should == "\nabc"
31
+ end
32
+ end
@@ -0,0 +1,249 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ def try_for_period(sec)
4
+ start = Time.now
5
+ while (Time.now-start) < sec
6
+ begin
7
+ return yield
8
+ rescue => exp
9
+ #puts "failed, elapsed #{Time.now-start}"
10
+ sleep(0.05)
11
+ end
12
+ end
13
+ raise 'reached end'
14
+ yield
15
+ end
16
+
17
+ def print_child_file_changes
18
+ puts "print_child_file_changes"
19
+ STDIN.gets
20
+ before_files = Dir["#{child_dir}/**/*.txt"]
21
+ yield
22
+ after_files = Dir["#{child_dir}/**/*.txt"]
23
+ both_files = (before_files+after_files).uniq
24
+
25
+ puts "#{both_files} total files"
26
+ both_files.each do |file|
27
+ if [before_files,after_files].any? { |fs| !fs.include?(file) }
28
+ puts "#{file} #{before_files.include?(file)}/#{after_files.include?(file)}"
29
+ end
30
+ end
31
+ end
32
+
33
+ describe "NestedFile" do
34
+ let(:parent_dir) { Dir.mktmpdir("parent") }
35
+ let(:child_dir) { Dir.mktmpdir("child") }
36
+
37
+ def fork_mount
38
+ File.create "#{parent_dir}/zzz.txt","hello"
39
+ child_dir
40
+
41
+ pid = fork do
42
+ cmd = "bundle exec ruby ./bin/nested_file #{parent_dir} #{child_dir}"
43
+ exec cmd
44
+ end
45
+
46
+ sleep 0.05
47
+ try_for_period(2) do
48
+ File.read("#{child_dir}/zzz.txt")
49
+ end
50
+
51
+ mount_name = ec("mount", silent: true).scan(/^(\S+)\s.*#{child_dir}/).first.first
52
+ {pid: pid, mount_name: mount_name}
53
+ end
54
+
55
+ def create_parent_file(path,str)
56
+ try_for_period(2) do
57
+ File.create "#{parent_dir}/#{path}",str
58
+ end
59
+ end
60
+
61
+ def create_child_file(path,str)
62
+ try_for_period(2) do
63
+ File.create "#{child_dir}/#{path}",str
64
+ end
65
+ end
66
+
67
+ before(:all) do
68
+ @fork_data = fork_mount
69
+ end
70
+ after(:all) do
71
+ if @fork_data
72
+ Process.kill "KILL",@fork_data[:pid]
73
+ ec "umount #{@fork_data[:mount_name]}", silent: true
74
+ end
75
+ end
76
+
77
+ before(:each) do
78
+ `rm -rf #{parent_dir}/*`
79
+ Dir["spec/parent_template/*"].each do |f|
80
+ `cp -r #{f} #{parent_dir}`
81
+ end
82
+
83
+ Dir["#{parent_dir}/**/*.txt"].each do |file|
84
+ body = File.read(file).gsub("{{NF_ROOT}}",NestedFile.root).gsub("{{NF_PARENT_DIR}}",parent_dir)
85
+ File.create file, body
86
+ end
87
+ end
88
+
89
+ describe "basic reads" do
90
+ it 'read from mounted fs' do
91
+ str = File.read "#{child_dir}/a.txt"
92
+ str.should == "hello"
93
+ end
94
+
95
+ it 'read subs in file contents - full path' do
96
+ str = File.read "#{child_dir}/include_others.txt"
97
+ str.should == "<file #{parent_dir}/a.txt>\nhello\n</file>"
98
+ end
99
+
100
+ it 'read subs in file contents - relative_path' do
101
+ str = File.read "#{child_dir}/include_others_rel.txt"
102
+ str.should == "<file a.txt>\nhello\n</file>"
103
+ end
104
+
105
+ it 'ls should work in subs' do
106
+ Dir["#{child_dir}/sub2/*"].should == ["#{child_dir}/sub2/x.txt"]
107
+ end
108
+ end
109
+
110
+ describe "can use glob in file desc" do
111
+ before do
112
+ create_parent_file "sub/a.txt","abc"
113
+ create_parent_file "sub/b.txt","xyz"
114
+ create_parent_file "sub_all.txt","<files sub/*.txt></files>"
115
+ end
116
+
117
+ it 'shows group' do
118
+ exp = ['<files sub/*.txt>']
119
+ exp += ['<file sub/a.txt>','abc','</file>']
120
+ exp += ['<file sub/b.txt>','xyz','</file>']
121
+ exp << "</files>"
122
+ File.read("#{child_dir}/sub_all.txt").should == exp.join("\n")
123
+ end
124
+ end
125
+
126
+ describe "nested body not saved to parent" do
127
+ before do
128
+ create_child_file "d.txt","<file e.txt>data</file>"
129
+ end
130
+ it 'e is data' do
131
+ File.read("#{parent_dir}/e.txt").should == "data"
132
+ end
133
+ it "d.txt doesn't have body" do
134
+ File.read("#{parent_dir}/d.txt").should == "<file e.txt>\n</file>"
135
+ end
136
+ end
137
+
138
+
139
+ describe 'saving file with sections writes to other files' do
140
+ before(:each) do
141
+ body = "<file c.txt>\nI was here\n</file>"
142
+ create_child_file "b.txt",body
143
+ end
144
+
145
+ it 'exists' do
146
+ FileTest.should be_exist("#{parent_dir}/b.txt")
147
+ FileTest.should be_exist("#{child_dir}/b.txt")
148
+ FileTest.should be_exist("#{parent_dir}/c.txt")
149
+ FileTest.should be_exist("#{child_dir}/c.txt")
150
+ end
151
+
152
+ it 'c.txt has written text' do
153
+ File.read("#{parent_dir}/c.txt").should == "I was here"
154
+ end
155
+ end
156
+
157
+ describe 'saving file with sections writes to other files - relative path' do
158
+ before(:each) do
159
+ body = "<file c.txt>\nI was here\n</file>"
160
+ create_child_file "b.txt", body
161
+ end
162
+
163
+ it 'exists' do
164
+ FileTest.should be_exist("#{parent_dir}/b.txt")
165
+ FileTest.should be_exist("#{child_dir}/b.txt")
166
+ FileTest.should be_exist("#{parent_dir}/c.txt")
167
+ FileTest.should be_exist("#{child_dir}/c.txt")
168
+ end
169
+
170
+ it 'c.txt has written text' do
171
+ File.read("#{parent_dir}/c.txt").should == "I was here"
172
+ end
173
+
174
+ end
175
+
176
+ describe 'saving file with sections writes to other files - save to sub' do
177
+ before(:each) do
178
+ body = "<file sub/z.txt>\nI was here\n</file>"
179
+ create_child_file "b.txt", body
180
+ end
181
+
182
+ it 'z.txt has written text' do
183
+ File.read("#{parent_dir}/sub/z.txt").should == "I was here"
184
+ end
185
+ end
186
+
187
+ # this test probably useless now
188
+ describe 'saving file with sections writes to other files - save to parent' do
189
+ before(:each) do
190
+ body = "<file p.txt>\nI was here\n</file>"
191
+ create_child_file "sub/b.txt", body
192
+ end
193
+
194
+ it 'z.txt has written text' do
195
+ File.read("#{parent_dir}/p.txt").should == "I was here"
196
+ end
197
+ end
198
+
199
+ describe 'modifying file referenced elsewhere updates other file' do
200
+ def exp_body(body=nil)
201
+ if body
202
+ "<file #{parent_dir}/a.txt>\n#{body}\n</file>"
203
+ else
204
+ "<file #{parent_dir}/a.txt>\n</file>"
205
+ end
206
+ end
207
+ def parent_body
208
+ File.read("#{parent_dir}/include_others.txt")
209
+ end
210
+ def child_body
211
+ File.read("#{child_dir}/include_others.txt")
212
+ end
213
+
214
+ it 'writing to parent - longer string - include_others.txt has written text' do
215
+ create_parent_file "a.txt", "Hello There"
216
+ parent_body.should == exp_body
217
+ child_body.should == exp_body('Hello There')
218
+ end
219
+
220
+ it 'writing to child - longer string - include_others.txt has written text' do
221
+ create_child_file "a.txt", "Hello There"
222
+ parent_body.should == exp_body
223
+ child_body.should == exp_body('Hello There')
224
+ end
225
+
226
+ it 'writing to parent - shorter string - include_others.txt has written text' do
227
+ create_parent_file "a.txt", "bb"
228
+ parent_body.should == exp_body
229
+ child_body.should == exp_body('bb')
230
+ end
231
+
232
+ it 'writing to child - shorter string - include_others.txt has written text' do
233
+ create_child_file "a.txt", "bb"
234
+ parent_body.should == exp_body
235
+ child_body.should == exp_body('bb')
236
+ end
237
+ end
238
+
239
+ describe "don't overwrite existing" do
240
+ before do
241
+ create_parent_file "exist.txt","Hello"
242
+ create_child_file "summary.txt","<file exist.txt></file>"
243
+ end
244
+
245
+ it 'leaves exist.txt alone' do
246
+ File.read("#{parent_dir}/exist.txt").should == 'Hello'
247
+ end
248
+ end
249
+ end