fog-external 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ examples/ernie.pid
data/.travis.yml ADDED
@@ -0,0 +1 @@
1
+ rvm: 1.9.2
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in fog-bertrpc.gemspec
4
+ gemspec
5
+
6
+ gem "bertrpc"
data/README.md ADDED
@@ -0,0 +1,32 @@
1
+ # Fog-External
2
+ With `fog-external`, you can use arbitrary Ruby objects as backend for `Fog::Storage`. This can mean a custom-written local-storage backend, or, without any more configuration, a BERT-RPC (or any other RPC implementation) remote call.
3
+
4
+ ## Installation
5
+ gem install fog-external
6
+
7
+ ## Usage
8
+ require 'fog/external/storage'
9
+
10
+ storage = Fog::Storage.new({
11
+ :provider => 'External',
12
+ :delegate => BERTRPC::Service.new('localhost', 9999).call.fog
13
+ })
14
+
15
+ You can then use `storage` just like any other Fog::Storage object, see [the Fog docs](http://fog.io/1.1.1/storage/) for what's possible.. The API is compatible to the one of `Fog::Local`.
16
+
17
+ The delegate must respond to a number of backend methods. The delegate in the above-example uses [BERT-RPC][1] to call a server on localhost:9999, using the `fog` module name.
18
+ See `examples/example.rb` for a complete example *including a Ernie-powered BERT-RPC backend*.
19
+
20
+ ## Copyright
21
+
22
+ (The MIT License)
23
+
24
+ Copyright © 2011 Jonas Schneider
25
+
26
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
27
+
28
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
29
+
30
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31
+
32
+ [1]: https://github.com/mojombo/bertrpc
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require 'rubygems'
2
+ require 'bundler/gem_tasks'
3
+
4
+ task :default => [:spec]
5
+
6
+ require 'rspec/core/rake_task'
7
+ desc "Run specs"
8
+ RSpec::Core::RakeTask.new do |t|
9
+ t.pattern = FileList['spec/**/*_spec.rb']
10
+ t.rspec_opts = %w(-fp --color)
11
+ end
data/Watchrfile ADDED
@@ -0,0 +1,37 @@
1
+ # vim:set filetype=ruby:
2
+ def run(cmd)
3
+ puts cmd
4
+ system cmd
5
+ end
6
+
7
+ def run_spec(args)
8
+ run("spin push #{args}")
9
+ #run("bundle exec rspec --fail-fast #{args}")
10
+ end
11
+
12
+ def spec(file)
13
+ if File.exists?(file)
14
+ run_spec(file)
15
+ else
16
+ puts("Spec: #{file} does not exist.")
17
+ end
18
+ end
19
+
20
+ watch("spec/.*/*_spec\.rb") do |match|
21
+ puts(match[0])
22
+ spec(match[0])
23
+ end
24
+
25
+ watch("lib/(.*/*)\.rb") do |match|
26
+ puts(match[0])
27
+ if File.exists?(p = "spec/"+match[1]+"_spec.rb")
28
+ spec(p)
29
+ else
30
+ spec("spec/fog/external/storage_spec.rb")
31
+ end
32
+ end
33
+
34
+ watch("spec/service_mock\.rb") do |match|
35
+ puts(match[0])
36
+ spec("spec/fog/external/storage_spec.rb")
37
+ end
@@ -0,0 +1,4 @@
1
+ [{module, fog},
2
+ {type, external},
3
+ {command, "ruby examples/fog.rb"},
4
+ {count, 1}].
@@ -0,0 +1,36 @@
1
+ require 'rubygems'
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'fog/external/storage'
4
+ require "bertrpc"
5
+
6
+ ROOT = '/tmp/fog-external-example-root'
7
+ Dir.chdir File.join(File.dirname(__FILE__), '..')
8
+
9
+ Dir.mkdir(ROOT) unless File.exists?(ROOT)
10
+
11
+ def run(cmd)
12
+ puts "=> #{cmd}"
13
+ system cmd
14
+ end
15
+
16
+ puts "Starting ernie on localhost:8000"
17
+ run "ernie -d -c examples/ernie.conf -P examples/ernie.pid -a /tmp/ernie.log"
18
+
19
+ puts "Ernie running."
20
+
21
+ storage = Fog::Storage.new({
22
+ :provider => 'External',
23
+ :delegate => BERTRPC::Service.new('localhost', 8000).call.fog
24
+ })
25
+
26
+ puts "Known directories: "
27
+ puts storage.directories.all.inspect
28
+
29
+ puts "Creating directory mydir/ ..."
30
+ puts storage.directories.create(key: 'mydir').save
31
+
32
+ puts "Known directories: "
33
+ puts storage.directories.all.inspect
34
+
35
+ puts "Stopping ernie on localhost:8000"
36
+ run "kill `cat examples/ernie.pid`"
data/examples/fog.rb ADDED
@@ -0,0 +1,102 @@
1
+ require 'ernie'
2
+ ROOT = '/tmp/fog-external-example-root'
3
+ # ported from Fog's Local storage
4
+
5
+ module Fog
6
+ def create_directory(key)
7
+ if ::File.directory?(path_to(key))
8
+ false
9
+ else
10
+ Dir.mkdir path_to(key)
11
+ end
12
+ end
13
+
14
+ def list_directories
15
+ data = Dir.entries(ROOT).select do |entry|
16
+ entry[0...1] != '.' && ::File.directory?(path_to(entry))
17
+ end.map do |entry|
18
+ {:key => entry}
19
+ end
20
+ end
21
+
22
+ def get_directory(key)
23
+ if ::File.directory?(path_to(key))
24
+ { key: key }
25
+ else
26
+ nil
27
+ end
28
+ end
29
+
30
+ def destroy_directory(key)
31
+ if ::File.directory?(path_to(key))
32
+ Dir.rmdir(path_to(key))
33
+ true
34
+ else
35
+ false
36
+ end
37
+ end
38
+
39
+
40
+ def list_files(dir_key)
41
+ Dir.chdir(path_to(dir_key)) do
42
+ data = Dir.glob('**/*').reject do |file|
43
+ ::File.directory?(file)
44
+ end.map do |key|
45
+ path = file_path(key)
46
+ {
47
+ :content_length => ::File.size(path),
48
+ :key => key,
49
+ :last_modified => ::File.mtime(path)
50
+ }
51
+ end
52
+ end
53
+ data
54
+ end
55
+
56
+ def get_file(key)
57
+ path = path_to(key)
58
+ if ::File.exists?(path)
59
+ {
60
+ :content_length => ::File.size(path),
61
+ :key => key,
62
+ :last_modified => ::File.mtime(path),
63
+ :body => ::File.read(path)
64
+ }
65
+ else
66
+ nil
67
+ end
68
+ end
69
+
70
+ def destroy_file(key)
71
+ path = path_to(key)
72
+
73
+ if ::File.exists?(path)
74
+ ::File.delete(path)
75
+ true
76
+ else
77
+ false
78
+ end
79
+ end
80
+
81
+ def save_file(key, body)
82
+ file = ::File.new(path, 'wb')
83
+ if body.is_a?(String)
84
+ file.write(body)
85
+ else
86
+ file.write(body.read)
87
+ end
88
+ file.close
89
+
90
+ ::File.mtime(path)
91
+ rescue
92
+ false
93
+ end
94
+
95
+ private
96
+
97
+ def path_to(entry)
98
+ ::File.join(ROOT, entry)
99
+ end
100
+ end
101
+
102
+ Ernie.expose(:fog, Fog)
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "fog-external"
6
+ s.version = "0.0.1"
7
+ s.authors = ["Jonas Schneider"]
8
+ s.email = ["mail@jonasschneider.com"]
9
+ s.homepage = ""
10
+ s.summary = %q{Fog::Storage with a consistent API}
11
+ s.description = %q{Use a custom backend (such as BERTRPC) with Fog:Storage.}
12
+
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.require_paths = ["lib"]
18
+
19
+ # specify any dependencies here; for example:
20
+ s.add_development_dependency('rake')
21
+ s.add_development_dependency "rspec"
22
+
23
+ s.add_runtime_dependency "fog"
24
+ end
@@ -0,0 +1,27 @@
1
+ require 'fog/core/collection'
2
+ require 'fog/external/models/storage/directory'
3
+
4
+ module Fog
5
+ module Storage
6
+ class External
7
+
8
+ class Directories < Fog::Collection
9
+ model Fog::Storage::External::Directory
10
+
11
+ def all
12
+ load(connection.remote.list_directories)
13
+ end
14
+
15
+ def get(id)
16
+ data = connection.remote.get_directory(id)
17
+ if data
18
+ new(data)
19
+ else
20
+ nil
21
+ end
22
+ end
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,44 @@
1
+ require 'fog/core/model'
2
+ require 'fog/external/models/storage/files'
3
+
4
+ module Fog
5
+ module Storage
6
+ class External
7
+
8
+ class Directory < Fog::Model
9
+ identity :key
10
+
11
+ def destroy
12
+ requires :key
13
+
14
+ connection.remote.destroy_directory(identity)
15
+ true
16
+ end
17
+
18
+ def files
19
+ @files ||= begin
20
+ Fog::Storage::External::Files.new(
21
+ :directory => self,
22
+ :connection => connection
23
+ )
24
+ end
25
+ end
26
+
27
+ def public=(new_public)
28
+ new_public
29
+ end
30
+
31
+ def public_url
32
+ nil
33
+ end
34
+
35
+ def save
36
+ requires :key
37
+
38
+ connection.remote.create_directory(identity)
39
+ end
40
+ end
41
+
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,79 @@
1
+ require 'fog/core/model'
2
+
3
+ module Fog
4
+ module Storage
5
+ class External
6
+
7
+ class File < Fog::Model
8
+ identity :key, :aliases => 'Key'
9
+
10
+ attribute :content_length, :aliases => 'Content-Length', :type => :integer
11
+ attribute :last_modified, :aliases => 'Last-Modified'
12
+
13
+ def directory
14
+ @directory
15
+ end
16
+
17
+ def directory=(new_directory)
18
+ @directory = new_directory
19
+ end
20
+
21
+ def content_type
22
+ @content_type ||= begin
23
+ unless (mime_types = ::MIME::Types.of(key)).empty?
24
+ mime_types.first.content_type
25
+ end
26
+ end
27
+ end
28
+
29
+ def body
30
+ attributes[:body] ||= if last_modified
31
+ directory.files.get(identity).body
32
+ else
33
+ ''
34
+ end
35
+ end
36
+
37
+ def body=(new_body)
38
+ attributes[:body] = new_body
39
+ end
40
+
41
+ def destroy
42
+ requires :key, :directory
43
+
44
+ connection.remote.destroy_file(full_key)
45
+ true
46
+ end
47
+
48
+ def public=(new_public)
49
+ new_public
50
+ end
51
+
52
+ def public_url
53
+ nil
54
+ end
55
+
56
+ def save
57
+ requires :body, :directory, :key
58
+
59
+ if res = connection.remote.save_file(full_key, body)
60
+ merge_attributes(
61
+ :content_length => Fog::Storage.get_body_size(body),
62
+ :last_modified => res
63
+ )
64
+ true
65
+ else
66
+ false
67
+ end
68
+ end
69
+
70
+ private
71
+
72
+ def full_key
73
+ ::File.join(directory.key, key)
74
+ end
75
+ end
76
+
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,54 @@
1
+ require 'fog/core/collection'
2
+ require 'fog/external/models/storage/file'
3
+
4
+ module Fog
5
+ module Storage
6
+ class External
7
+
8
+ class Files < Fog::Collection
9
+ attribute :directory
10
+ model Fog::Storage::External::File
11
+
12
+ def all
13
+ requires :directory
14
+
15
+ load(connection.remote.list_files(directory.key))
16
+ end
17
+
18
+ def get(id)
19
+ requires :directory
20
+
21
+ data = connection.remote.get_file(file_key(id))
22
+ if data
23
+ new(data)
24
+ else
25
+ nil
26
+ end
27
+ end
28
+
29
+ def head(id) # hackish!
30
+ requires :directory
31
+ real_key = file_key(id)
32
+ if data = connection.remote.list_files(directory.key).detect{|c|c[:key] == real_key}
33
+ new(data)
34
+ else
35
+ nil
36
+ end
37
+ end
38
+
39
+ def new(attributes = {})
40
+ requires :directory
41
+ super({ :directory => directory }.merge!(attributes))
42
+ end
43
+
44
+
45
+ private
46
+
47
+ def file_key(id)
48
+ ::File.join(directory.key, id)
49
+ end
50
+ end
51
+
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,31 @@
1
+ require 'fog'
2
+ require 'fog/storage'
3
+
4
+ require 'fog-external'
5
+
6
+ module Fog
7
+ module Storage
8
+ class External < Fog::Service
9
+
10
+ requires :delegate
11
+
12
+ model_path 'fog/external/models/storage'
13
+ collection :directories
14
+ model :directory
15
+ collection :files
16
+ model :file
17
+
18
+ class Real
19
+ def initialize(options={})
20
+ require 'mime/types'
21
+ @delegate = options[:delegate]
22
+ end
23
+
24
+ def remote
25
+ @delegate
26
+ end
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,29 @@
1
+ module Fog
2
+ module Storage
3
+ def self.new(attributes) # monkey patch to add :external
4
+ attributes = attributes.dup # prevent delete from having side effects
5
+ case provider = attributes.delete(:provider).to_s.downcase.to_sym
6
+ when :aws
7
+ require 'fog/aws/storage'
8
+ Fog::Storage::AWS.new(attributes)
9
+ when :google
10
+ require 'fog/google/storage'
11
+ Fog::Storage::Google.new(attributes)
12
+ when :local
13
+ require 'fog/local/storage'
14
+ Fog::Storage::Local.new(attributes)
15
+ when :ninefold
16
+ require 'fog/ninefold/storage'
17
+ Fog::Storage::Ninefold.new(attributes)
18
+ when :rackspace
19
+ require 'fog/rackspace/storage'
20
+ Fog::Storage::Rackspace.new(attributes)
21
+ when :external
22
+ require 'fog/external/storage'
23
+ Fog::Storage::External.new(attributes)
24
+ else
25
+ raise ArgumentError.new("#{provider} is not a recognized storage provider")
26
+ end
27
+ end
28
+ end
29
+ end
data/spec/boot.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'pp'
2
+ require 'rubygems'
3
+ require 'bundler'
4
+ Bundler.setup :default, :development
5
+
6
+ require "rspec"
7
+
8
+ project_root = File.expand_path(File.join(File.dirname(__FILE__), '..'))
9
+ $:.unshift File.join(project_root, 'lib')
@@ -0,0 +1,157 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
+
3
+ require 'fog/external/storage'
4
+
5
+ describe "fog-external" do
6
+ let(:storage) do
7
+ storage = Fog::Storage.new({
8
+ :provider => 'External',
9
+ :delegate => service_mock
10
+ })
11
+ end
12
+
13
+ let(:service_mock) do
14
+ ServiceMock.new
15
+ end
16
+
17
+ describe "#directories" do
18
+ it "#create creates a directory" do
19
+ service_mock.should_receive(:create_directory).with('mykey')
20
+ directory = storage.directories.create key: 'mykey'
21
+ end
22
+
23
+ it "#all lists directories" do
24
+ service_mock.should_receive(:list_directories) { [{:key => 'mykey'}] }
25
+ storage.directories.all.first.key.should == 'mykey'
26
+ end
27
+
28
+ describe "#get" do
29
+ it "gets a directory" do
30
+ service_mock.should_receive(:get_directory).with('mykey') { {:key => 'mykey'} }
31
+ x = storage.directories.get('mykey')
32
+ x.should be_kind_of(Fog::Storage::External::Directory)
33
+ x.key.should == 'mykey'
34
+ end
35
+
36
+ it "returns nil for unknown directory keys" do
37
+ service_mock.should_receive(:get_directory).with('something_strange') { nil }
38
+ x = storage.directories.get('something_strange')
39
+ x.should be_nil
40
+ end
41
+ end
42
+ end
43
+
44
+ describe "::Directory" do
45
+ let(:dir) { Fog::Storage::External::Directory.new connection: storage, key: 'mykey' }
46
+
47
+ it "#files" do
48
+ dir.files.should be_kind_of(Fog::Storage::External::Files)
49
+ dir.files.directory.should == dir
50
+ dir.files.connection.should == storage
51
+ end
52
+
53
+ it "#destroy" do
54
+ service_mock.should_receive(:destroy_directory).with('mykey')
55
+ dir.destroy
56
+ end
57
+
58
+ it "#public=" do
59
+ (dir.public = :a).should == :a
60
+ end
61
+
62
+ it "#public_url" do
63
+ dir.public_url.should be_nil
64
+ end
65
+
66
+ it "#save" do
67
+ service_mock.should_receive(:create_directory).with('mykey')
68
+ dir.save
69
+ end
70
+ end
71
+
72
+ describe "::Files" do
73
+ let(:dir) { Fog::Storage::External::Directory.new connection: storage, key: 'mykey' }
74
+ let(:files) { dir.files }
75
+
76
+ it "#all" do
77
+ service_mock.should_receive(:list_files).with("mykey") { [{:key => 'mykey/a'}] }
78
+ res = files.all
79
+ res.first.key.should == 'mykey/a'
80
+ end
81
+
82
+ it "#get" do
83
+ data = {:key => 'mykey/a', :content_length => 5, :last_modified => Time.now, :body => 'asdf' }
84
+ service_mock.should_receive(:get_file).with("mykey/a") { data }
85
+ res = files.get('a')
86
+
87
+ res.key.should == 'mykey/a'
88
+ res.content_length.should == 5
89
+ res.body.should == 'asdf'
90
+ end
91
+
92
+ it "#head" do
93
+ service_mock.should_receive(:list_files).twice.with("mykey") { [{:key => 'mykey/a'}] }
94
+
95
+ res = files.head('a')
96
+
97
+ res.key.should == 'mykey/a'
98
+ res.content_length.should be_nil
99
+
100
+ files.head('b').should be_nil
101
+ end
102
+
103
+ it "#new" do
104
+ files.new(:key => 'hai').directory.should == dir
105
+ files.new(:key => 'hai').key.should == 'hai'
106
+ end
107
+ end
108
+
109
+ describe "::Files" do
110
+ let(:dir) { Fog::Storage::External::Directory.new connection: storage, key: 'mykey' }
111
+ let(:file) { Fog::Storage::External::File.new connection: storage, last_modified: Time.now, key: 'a', directory: dir }
112
+
113
+ it "#body when the body is not set" do
114
+ data = {:key => 'mykey/a', :content_length => 5, :last_modified => Time.now, :body => 'asdf' }
115
+ service_mock.should_receive(:get_file).with("mykey/a") { data }
116
+ file.body.should == 'asdf'
117
+ end
118
+
119
+ it "#body when the body is set" do
120
+ file = Fog::Storage::External::File.new connection: storage, key: 'a', directory: dir, body: 'b'
121
+ file.body.should == 'b'
122
+ end
123
+
124
+ it "#body= sets the body" do
125
+ file.body = 'new'
126
+ file.body.should == 'new'
127
+ end
128
+
129
+ it "#directory" do
130
+ file.directory.should == dir
131
+ end
132
+
133
+ it "#content_type" do
134
+ file.key = 'a.txt'
135
+ file.content_type.should == 'text/plain'
136
+ end
137
+
138
+ it "#destroy" do
139
+ service_mock.should_receive(:destroy_file).with("mykey/a")
140
+ file.destroy
141
+ end
142
+
143
+ it "#public=" do
144
+ (file.public = :a).should == :a
145
+ end
146
+
147
+ it "#public_url" do
148
+ file.public_url.should be_nil
149
+ end
150
+
151
+ it "#save" do
152
+ service_mock.should_receive(:save_file).with("mykey/a", "test")
153
+ file.body = "test"
154
+ file.save
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,34 @@
1
+ class ServiceMock
2
+ def create_directory(key)
3
+ true
4
+ end
5
+
6
+ def list_directories
7
+ [{:key => 'mykey'}]
8
+ end
9
+
10
+ def get_directory(key)
11
+ {:key => 'mykey'} || nil
12
+ end
13
+
14
+ def destroy_directory(key)
15
+ true
16
+ end
17
+
18
+
19
+ def list_files(dir_key)
20
+ [{:key => 'mykey/a', :content_length => 5, :last_modified => Time.now}]
21
+ end
22
+
23
+ def get_file(key)
24
+ {:key => 'mykey/a', :content_length => 5, :last_modified => Time.now, :body => 'asdf'} || nil
25
+ end
26
+
27
+ def destroy_file(key)
28
+ true || false
29
+ end
30
+
31
+ def save_file(key, body)
32
+ mtime || false
33
+ end
34
+ end
@@ -0,0 +1,2 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'boot'))
2
+ require File.expand_path(File.join(File.dirname(__FILE__), 'service_mock'))
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fog-external
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jonas Schneider
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-12-03 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: &76776280 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *76776280
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ requirement: &76776070 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *76776070
36
+ - !ruby/object:Gem::Dependency
37
+ name: fog
38
+ requirement: &76775860 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *76775860
47
+ description: Use a custom backend (such as BERTRPC) with Fog:Storage.
48
+ email:
49
+ - mail@jonasschneider.com
50
+ executables: []
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - .gitignore
55
+ - .travis.yml
56
+ - Gemfile
57
+ - README.md
58
+ - Rakefile
59
+ - Watchrfile
60
+ - examples/ernie.conf
61
+ - examples/example.rb
62
+ - examples/fog.rb
63
+ - fog-external.gemspec
64
+ - lib/fog-external.rb
65
+ - lib/fog/external/models/storage/directories.rb
66
+ - lib/fog/external/models/storage/directory.rb
67
+ - lib/fog/external/models/storage/file.rb
68
+ - lib/fog/external/models/storage/files.rb
69
+ - lib/fog/external/storage.rb
70
+ - spec/boot.rb
71
+ - spec/fog/external/storage_spec.rb
72
+ - spec/service_mock.rb
73
+ - spec/spec_helper.rb
74
+ homepage: ''
75
+ licenses: []
76
+ post_install_message:
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ! '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ requirements: []
93
+ rubyforge_project:
94
+ rubygems_version: 1.8.10
95
+ signing_key:
96
+ specification_version: 3
97
+ summary: Fog::Storage with a consistent API
98
+ test_files:
99
+ - spec/boot.rb
100
+ - spec/fog/external/storage_spec.rb
101
+ - spec/service_mock.rb
102
+ - spec/spec_helper.rb