vfs-momolog 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.
Files changed (51) hide show
  1. data/.gitignore +8 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +22 -0
  4. data/Rakefile +2 -0
  5. data/docs/basics.rb +116 -0
  6. data/docs/s3_backup.rb +29 -0
  7. data/docs/s3_backup/app/files/bos.png +0 -0
  8. data/docs/s3_basics.rb +19 -0
  9. data/docs/s3_sandbox.rb +24 -0
  10. data/docs/site/404.html +8 -0
  11. data/docs/site/basics.html +305 -0
  12. data/docs/site/index.html +8 -0
  13. data/docs/site/s3_backup.html +111 -0
  14. data/docs/site/s3_basics.html +84 -0
  15. data/docs/site/s3_sandbox.html +99 -0
  16. data/docs/site/ssh_basics.html +84 -0
  17. data/docs/site/ssh_deployment.html +125 -0
  18. data/docs/site/ssh_sandbox.html +103 -0
  19. data/docs/ssh_basics.rb +19 -0
  20. data/docs/ssh_deployment.rb +35 -0
  21. data/docs/ssh_deployment/app/app.rb +0 -0
  22. data/docs/ssh_sandbox.rb +28 -0
  23. data/lib/vfs.rb +18 -0
  24. data/lib/vfs/drivers/local.rb +180 -0
  25. data/lib/vfs/drivers/specification.rb +169 -0
  26. data/lib/vfs/entries/dir.rb +256 -0
  27. data/lib/vfs/entries/entry.rb +152 -0
  28. data/lib/vfs/entries/file.rb +155 -0
  29. data/lib/vfs/entries/universal_entry.rb +24 -0
  30. data/lib/vfs/entry_proxy.rb +42 -0
  31. data/lib/vfs/error.rb +4 -0
  32. data/lib/vfs/integration.rb +30 -0
  33. data/lib/vfs/path.rb +123 -0
  34. data/lib/vfs/version.rb +3 -0
  35. data/lib/vfs/vfs.rb +38 -0
  36. data/old/hash_fs.rb +216 -0
  37. data/old/hash_fs_spec.rb +10 -0
  38. data/readme.md +143 -0
  39. data/spec/container_spec.rb +31 -0
  40. data/spec/dir_spec.rb +253 -0
  41. data/spec/entry_spec.rb +42 -0
  42. data/spec/file_spec.rb +215 -0
  43. data/spec/misc_spec.rb +19 -0
  44. data/spec/path_spec.rb +127 -0
  45. data/spec/spec_helper.rb +50 -0
  46. data/spec/storages/local_spec.rb +24 -0
  47. data/spec/storages/local_spec/emptygit +0 -0
  48. data/spec/universal_entry_spec.rb +69 -0
  49. data/todo.md +19 -0
  50. data/vfs.gemspec +17 -0
  51. metadata +105 -0
@@ -0,0 +1,103 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="content-type" content="text/html;charset=utf-8">
5
+ <title>ssh_sandbox.rb</title>
6
+ <link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
7
+ </head>
8
+ <body>
9
+ <div id='container'>
10
+ <div id="background"></div>
11
+ <div id="jump_to">
12
+ Jump To &hellip;
13
+ <div id="jump_wrapper">
14
+ <div id="jump_page">
15
+ <a class="source" href="basics.html">basics.rb</a>
16
+ <a class="source" href="s3_backup.html">s3_backup.rb</a>
17
+ <a class="source" href="s3_basics.html">s3_basics.rb</a>
18
+ <a class="source" href="s3_sandbox.html">s3_sandbox.rb</a>
19
+ <a class="source" href="ssh_basics.html">ssh_basics.rb</a>
20
+ <a class="source" href="ssh_deployment.html">ssh_deployment.rb</a>
21
+ <a class="source" href="ssh_sandbox.html">ssh_sandbox.rb</a>
22
+ </div>
23
+ </div>
24
+ </div>
25
+ <table cellspacing=0 cellpadding=0>
26
+ <thead>
27
+ <tr>
28
+ <th class=docs><h1>ssh_sandbox.rb</h1></th>
29
+ <th class=code></th>
30
+ </tr>
31
+ </thead>
32
+ <tbody>
33
+ <tr id='section-1'>
34
+ <td class=docs>
35
+ <div class="pilwrap">
36
+ <a class="pilcrow" href="#section-1">&#182;</a>
37
+ </div>
38
+ <p>Example of using SFTP as a storage for <a href="index.html">Virtual File System</a></p>
39
+ </td>
40
+ <td class=code>
41
+ <div class='highlight'><pre></pre></div>
42
+ </td>
43
+ </tr>
44
+ <tr id='section-2'>
45
+ <td class=docs>
46
+ <div class="pilwrap">
47
+ <a class="pilcrow" href="#section-2">&#182;</a>
48
+ </div>
49
+ <p>To use SSH/SFTP we need the SSH driver, You need &lsquo;vos&rsquo;, &lsquo;net-ssh&rsquo; and &lsquo;net-sftp&rsquo; gems installed.</p>
50
+
51
+ <pre><code>gem install vos net-ssh net-sftp
52
+ </code></pre>
53
+ </td>
54
+ <td class=code>
55
+ <div class='highlight'><pre><span class="nb">require</span> <span class="s1">&#39;vfs&#39;</span>
56
+ <span class="nb">require</span> <span class="s1">&#39;vos&#39;</span>
57
+ <span class="nb">require</span> <span class="s1">&#39;vos/drivers/ssh&#39;</span></pre></div>
58
+ </td>
59
+ </tr>
60
+ <tr id='section-3'>
61
+ <td class=docs>
62
+ <div class="pilwrap">
63
+ <a class="pilcrow" href="#section-3">&#182;</a>
64
+ </div>
65
+ <p>Initializing SSH driver, if You can connect to server using identity file provide host only.</p>
66
+
67
+ <p>If the connection requires login and password You need to provide it:</p>
68
+
69
+ <pre><code>driver = Vos::Drivers::Ssh.new \
70
+ host: &lsquo;xxx.com&rsquo;,
71
+ user: &lsquo;xxx&rsquo;,
72
+ password: &lsquo;xxx&rsquo;
73
+ </code></pre>
74
+ </td>
75
+ <td class=code>
76
+ <div class='highlight'><pre><span class="n">driver</span> <span class="o">=</span> <span class="no">Vos</span><span class="o">::</span><span class="no">Drivers</span><span class="o">::</span><span class="no">Ssh</span><span class="o">.</span><span class="n">new</span> <span class="n">host</span><span class="p">:</span> <span class="s1">&#39;xxx.com&#39;</span></pre></div>
77
+ </td>
78
+ </tr>
79
+ <tr id='section-4'>
80
+ <td class=docs>
81
+ <div class="pilwrap">
82
+ <a class="pilcrow" href="#section-4">&#182;</a>
83
+ </div>
84
+ <p>After creating driver we can create storage.</p>
85
+ </td>
86
+ <td class=code>
87
+ <div class='highlight'><pre><span class="n">box</span> <span class="o">=</span> <span class="no">Vos</span><span class="o">::</span><span class="no">Box</span><span class="o">.</span><span class="n">new</span> <span class="n">driver</span></pre></div>
88
+ </td>
89
+ </tr>
90
+ <tr id='section-5'>
91
+ <td class=docs>
92
+ <div class="pilwrap">
93
+ <a class="pilcrow" href="#section-5">&#182;</a>
94
+ </div>
95
+ <p>Preparing temporary dir for sample and cleaning it before starting.</p>
96
+ </td>
97
+ <td class=code>
98
+ <div class='highlight'><pre><span class="vg">$sandbox</span> <span class="o">=</span> <span class="n">box</span><span class="o">[</span><span class="s1">&#39;/tmp/vfs_sandbox&#39;</span><span class="o">].</span><span class="n">to_dir</span><span class="o">.</span><span class="n">destroy</span></pre></div>
99
+ </td>
100
+ </tr>
101
+ </table>
102
+ </div>
103
+ </body>
@@ -0,0 +1,19 @@
1
+ # Example of [Virtual File System][vfs] working with SFTP.
2
+ #
3
+ # This is exactly the same [basic example][basics] but this time
4
+ # we using SFTP as storage instead of local file system.
5
+
6
+ # Adding examples folder to load paths.
7
+ $LOAD_PATH << File.expand_path("#{__FILE__}/../..")
8
+
9
+ # Connecting to SFTP and preparing sandbox. You may take a look at
10
+ # the [docs/ssh_sandbox.rb][ssh_sandbox] to see the actual code.
11
+ require 'docs/ssh_sandbox'
12
+
13
+ # Now we just executig [basic example][basics]
14
+ # but with the `$storage` set to SFTP.
15
+ require 'docs/basics'
16
+
17
+ # [vfs]: index.html
18
+ # [basics]: basics.html
19
+ # [ssh_sandbox]: ssh_sandbox.html
@@ -0,0 +1,35 @@
1
+ # Example of Application Deployment using [Virtual File System][vfs].
2
+ #
3
+ # In this example we uploading sample app files to remote server,
4
+ # write database configuration file and restart the server on remote machine.
5
+
6
+ # Adding examples folder to load paths.
7
+ $LOAD_PATH << File.expand_path("#{__FILE__}/../..")
8
+
9
+ # Connecting to SFTP and preparing sandbox. You may take a look at
10
+ # the [docs/ssh_sandbox.rb][ssh_sandbox] to see the actual code.
11
+ require 'docs/ssh_sandbox'
12
+ sandbox = $sandbox
13
+
14
+ # Preparing sample files located in our local folder in
15
+ # current directory.
16
+ current_dir = __FILE__.to_entry.parent
17
+ sample_app = current_dir['ssh_deployment/app']
18
+
19
+ # Copying application files to remote machine.
20
+ app = sandbox['apps/app']
21
+ sample_app.copy_to app
22
+ p app['app.rb'].exist? # => true
23
+
24
+ # Writing database configuration file.
25
+ config = app['config.yml']
26
+ config.write "database: mysql"
27
+ config.append "name: app_production"
28
+ p app['config.yml'].exist? # => true
29
+
30
+ # Updating gems and restarting the server.
31
+ p app.bash("echo 'bundle install'") # => bundle install
32
+ p app.bash("echo 'server start'") # => server start
33
+
34
+ # [vfs]: index.html
35
+ # [ssh_sandbox]: ssh_sandbox.html
File without changes
@@ -0,0 +1,28 @@
1
+ # Example of using SFTP as a storage for [Virtual File System][vfs]
2
+
3
+ # To use SSH/SFTP we need the SSH driver, You need 'vos', 'net-ssh' and 'net-sftp' gems installed.
4
+ #
5
+ # gem install vos net-ssh net-sftp
6
+ #
7
+ require 'vfs'
8
+ require 'vos'
9
+ require 'vos/drivers/ssh'
10
+
11
+ # Initializing SSH driver, if You can connect to server using identity file provide host only.
12
+ #
13
+ # If the connection requires login and password You need to provide it:
14
+ #
15
+ # driver = Vos::Drivers::Ssh.new \
16
+ # host: 'xxx.com',
17
+ # user: 'xxx',
18
+ # password: 'xxx'
19
+ #
20
+ driver = Vos::Drivers::Ssh.new host: 'xxx.com'
21
+
22
+ # After creating driver we can create storage.
23
+ box = Vos::Box.new driver
24
+
25
+ # Preparing temporary dir for sample and cleaning it before starting.
26
+ $sandbox = box['/tmp/vfs_sandbox'].to_dir.destroy
27
+
28
+ # [vfs]: index.html
data/lib/vfs.rb ADDED
@@ -0,0 +1,18 @@
1
+ module Vfs
2
+ autoload :Path, 'vfs/path'
3
+ autoload :Error, 'vfs/error'
4
+
5
+ autoload :Entry, 'vfs/entries/entry'
6
+ autoload :File, 'vfs/entries/file'
7
+ autoload :Dir, 'vfs/entries/dir'
8
+ autoload :UniversalEntry, 'vfs/entries/universal_entry'
9
+
10
+ autoload :EntryProxy, 'vfs/entry_proxy'
11
+
12
+ module Drivers
13
+ autoload :Local, 'vfs/drivers/local'
14
+ end
15
+ end
16
+
17
+ require 'vfs/vfs'
18
+ require 'vfs/integration'
@@ -0,0 +1,180 @@
1
+ require 'fileutils'
2
+ require 'tempfile'
3
+
4
+ module Vfs
5
+ module Drivers
6
+ class Local
7
+ class Writer
8
+ def initialize out; @out = out end
9
+
10
+ def write data
11
+ @out.write data
12
+ end
13
+ end
14
+
15
+ DEFAULT_BUFFER = 1000 * 1024
16
+
17
+ def initialize options = {}
18
+ options = options.clone
19
+ @root = options.delete(:root) || ''
20
+ raise "invalid options #{options}" unless options.empty?
21
+ end
22
+
23
+ def open &block
24
+ block.call self if block
25
+ end
26
+ def close; end
27
+
28
+ attr_writer :buffer
29
+ def buffer
30
+ @buffer || DEFAULT_BUFFER
31
+ end
32
+
33
+ #
34
+ # Attributes
35
+ #
36
+ def attributes path
37
+ path = with_root path
38
+
39
+ stat = ::File.stat path
40
+ attrs = {}
41
+ attrs[:file] = !!stat.file?
42
+ attrs[:dir] = !!stat.directory?
43
+
44
+ # attributes special for file system
45
+ attrs[:created_at] = stat.ctime
46
+ attrs[:updated_at] = stat.mtime
47
+ attrs[:size] = stat.size if attrs[:file]
48
+ attrs
49
+ rescue Errno::ENOTDIR
50
+ nil
51
+ rescue Errno::ENOENT
52
+ nil
53
+ end
54
+
55
+ def set_attributes path, attrs
56
+ # TODO2 set attributes
57
+ not_implemented
58
+ end
59
+
60
+
61
+ #
62
+ # File
63
+ #
64
+ def read_file path, &block
65
+ path = with_root path
66
+ ::File.open path, 'r' do |is|
67
+ while buff = is.gets(self.buffer || DEFAULT_BUFFER)
68
+ block.call buff
69
+ end
70
+ end
71
+ end
72
+
73
+ def write_file original_path, append, &block
74
+ path = with_root original_path
75
+
76
+ option = append ? 'a' : 'w'
77
+ ::File.open path, "#{option}b" do |out|
78
+ block.call Writer.new(out)
79
+ end
80
+ end
81
+
82
+ def delete_file path
83
+ path = with_root path
84
+ ::File.delete path
85
+ end
86
+
87
+ # def move_file from, to
88
+ # FileUtils.mv from, to
89
+ # end
90
+
91
+
92
+ #
93
+ # Dir
94
+ #
95
+ def create_dir path
96
+ path = with_root path
97
+ ::Dir.mkdir path
98
+ end
99
+
100
+ def delete_dir original_path
101
+ path = with_root original_path
102
+ ::FileUtils.rm_r path
103
+ end
104
+
105
+ def each_entry path, query, &block
106
+ path = with_root path
107
+
108
+ if query
109
+ path_with_trailing_slash = path == '/' ? path : "#{path}/"
110
+ ::Dir["#{path_with_trailing_slash}#{query}"].each do |absolute_path|
111
+ name = absolute_path.sub path_with_trailing_slash, ''
112
+ block.call name, ->{::File.directory?(absolute_path) ? :dir : :file}
113
+ # if ::File.directory? absolute_path
114
+ # block.call relative_path, :dir
115
+ # else
116
+ # block.call relative_path, :file
117
+ # end
118
+ end
119
+ else
120
+ ::Dir.foreach path do |name|
121
+ next if name == '.' or name == '..'
122
+ block.call name, ->{::File.directory?("#{path}/#{name}") ? :dir : :file}
123
+ # if ::File.directory? "#{path}/#{relative_name}"
124
+ # block.call relative_name, :dir
125
+ # else
126
+ # block.call relative_name, :file
127
+ # end
128
+ end
129
+ end
130
+ end
131
+
132
+ # def efficient_dir_copy from, to, override
133
+ # return false if override # FileUtils.cp_r doesn't support this behaviour
134
+ #
135
+ # from.driver.open_fs do |from_fs|
136
+ # to.driver.open_fs do |to_fs|
137
+ # if from_fs.local? and to_fs.local?
138
+ # FileUtils.cp_r from.path, to.path
139
+ # true
140
+ # else
141
+ # false
142
+ # end
143
+ # end
144
+ # end
145
+ # end
146
+
147
+ #
148
+ # Other
149
+ #
150
+ def local?; true end
151
+
152
+ def tmp &block
153
+ path = "/tmp/#{rand(10**6)}"
154
+ # tmp_dir = "#{::Dir.tmpdir}/#{rand(10**6)}"
155
+ if block
156
+ begin
157
+ ::FileUtils.mkdir_p with_root(path)
158
+ block.call path
159
+ ensure
160
+ ::FileUtils.rm_r with_root(path) if ::File.exist? with_root(path)
161
+ end
162
+ else
163
+ ::FileUtils.mkdir_p with_root(path)
164
+ path
165
+ end
166
+ end
167
+
168
+ def to_s; '' end
169
+
170
+ protected
171
+ def root
172
+ @root || raise('root not defined!')
173
+ end
174
+
175
+ def with_root path
176
+ path == '/' ? root : root + path
177
+ end
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,169 @@
1
+ require 'rspec_ext'
2
+ require 'ruby_ext'
3
+
4
+ shared_examples_for 'vfs driver basic' do
5
+ it 'should respond to :local?' do
6
+ @driver.should respond_to(:local?)
7
+ end
8
+
9
+ it "should provide open method" do
10
+ @driver.open
11
+ @driver.open{'result'}.should == 'result'
12
+ end
13
+ end
14
+
15
+ shared_examples_for 'vfs driver attributes basic' do
16
+ it 'should have root dir' do
17
+ attrs = @driver.attributes('/')
18
+ attrs[:dir].should be_true
19
+ attrs[:file].should be_false
20
+ end
21
+
22
+ it "attributes should return nil if there's no entry" do
23
+ @driver.attributes('/non_existing_entry').should be_nil
24
+ end
25
+ end
26
+
27
+ shared_examples_for 'vfs driver files' do
28
+ it "file attributes" do
29
+ @driver.attributes('/file').should be_nil
30
+
31
+ @driver.write_file('/file', false){|w| w.write 'something'}
32
+ attrs = @driver.attributes('/file')
33
+ attrs[:file].should be_true
34
+ attrs[:dir].should be_false
35
+ end
36
+
37
+ it "read, write, append" do
38
+ # write
39
+ @driver.write_file('/file', false){|w| w.write 'something'}
40
+ @driver.attributes('/file')[:file].should == true
41
+
42
+ # read
43
+ data = ""
44
+ @driver.read_file('/file'){|buff| data << buff}
45
+ data.should == 'something'
46
+
47
+ # append
48
+ @driver.write_file('/file', true){|w| w.write ' another'}
49
+ data = ""
50
+ @driver.read_file('/file'){|buff| data << buff}
51
+ data.should == 'something another'
52
+ end
53
+
54
+ it "delete_file" do
55
+ @driver.write_file('/file', false){|w| w.write 'something'}
56
+ @driver.attributes('/file')[:file].should be_true
57
+ @driver.delete_file('/file')
58
+ @driver.attributes('/file').should be_nil
59
+ end
60
+ end
61
+
62
+ shared_examples_for 'vfs driver full attributes for files' do
63
+ it "attributes for files" do
64
+ @driver.write_file('/file', false){|w| w.write 'something'}
65
+ attrs = @driver.attributes('/file')
66
+ attrs[:file].should be_true
67
+ attrs[:dir].should be_false
68
+ attrs[:created_at].class.should == Time
69
+ attrs[:updated_at].class.should == Time
70
+ attrs[:size].should == 9
71
+ end
72
+ end
73
+
74
+ shared_examples_for 'vfs driver dirs' do
75
+ it "directory crud" do
76
+ @driver.attributes('/dir').should be_nil
77
+
78
+ @driver.create_dir('/dir')
79
+ attrs = @driver.attributes('/dir')
80
+ attrs[:file].should be_false
81
+ attrs[:dir].should be_true
82
+
83
+ @driver.delete_dir('/dir')
84
+ @driver.attributes('/dir').should be_nil
85
+ end
86
+
87
+ it 'should delete not-empty directories' do
88
+ @driver.create_dir('/dir')
89
+ @driver.create_dir('/dir/dir2')
90
+ @driver.write_file('/dir/dir2/file', false){|w| w.write 'something'}
91
+ @driver.attributes('/dir').should_not be_nil
92
+
93
+ @driver.delete_dir('/dir')
94
+ @driver.attributes('/dir').should be_nil
95
+ end
96
+
97
+ it 'each' do
98
+ -> {@driver.each_entry('/not_existing_dir', nil){|path, type| list[path] = type}}.should raise_error
99
+
100
+ @driver.create_dir '/dir'
101
+ @driver.create_dir('/dir/dir2')
102
+ @driver.write_file('/dir/file', false){|w| w.write 'something'}
103
+
104
+ list = {}
105
+ @driver.each_entry '/dir', nil do |path, type|
106
+ type = type.call if type.is_a? Proc
107
+ list[path] = type
108
+ end
109
+
110
+ list.should == {'dir2' => :dir, 'file' => :file}
111
+ end
112
+
113
+ # it "upload_directory & download_directory" do
114
+ # upload_path_check = "#{@remote_path}/dir2/file"
115
+ # check_attributes upload_path_check, nil
116
+ # @driver.upload_directory(@from_local, @remote_path)
117
+ # check_attributes upload_path_check, file: true, dir: false
118
+ #
119
+ # download_path_check = "#{@to_local}/dir2/file"
120
+ # File.exist?(download_path_check).should be_false
121
+ # @driver.download_directory(@remote_path, @to_local)
122
+ # File.exist?(download_path_check).should be_true
123
+ # end
124
+ end
125
+
126
+ shared_examples_for 'vfs driver query' do
127
+ it 'each with query' do
128
+ @driver.create_dir '/dir'
129
+ @driver.create_dir('/dir/dir_a')
130
+ @driver.create_dir('/dir/dir_b')
131
+ @driver.write_file('/dir/file_a', false){|w| w.write 'something'}
132
+
133
+ list = {}
134
+ @driver.each_entry '/dir', '*_a' do |path, type|
135
+ type = type.call if type.is_a? Proc
136
+ list[path] = type
137
+ end
138
+
139
+ list.should == {'dir_a' => :dir, 'file_a' => :file}
140
+ end
141
+ end
142
+
143
+ shared_examples_for 'vfs driver full attributes for dirs' do
144
+ it "attributes for dirs" do
145
+ @driver.create_dir('/dir')
146
+ attrs = @driver.attributes('/dir')
147
+ attrs[:file].should be_false
148
+ attrs[:dir].should be_true
149
+ attrs[:created_at].class.should == Time
150
+ attrs[:updated_at].class.should == Time
151
+ attrs.should_not include(:size)
152
+ end
153
+ end
154
+
155
+ shared_examples_for 'vfs driver tmp dir' do
156
+ it "tmp dir" do
157
+ dir = @driver.tmp
158
+ @driver.attributes(dir).should_not be_nil
159
+ @driver.delete_dir dir
160
+ @driver.attributes(dir).should be_nil
161
+
162
+ dir = nil
163
+ @driver.tmp do |tmp_dir|
164
+ dir = tmp_dir
165
+ @driver.attributes(dir).should_not be_nil
166
+ end
167
+ @driver.attributes(dir).should be_nil
168
+ end
169
+ end