middleman-data_source 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 85df268b12b267b0188e48c25197f71e010d8fb1
4
+ data.tar.gz: ff9ba310306744a80915886e1e49ac64c0e24e9b
5
+ SHA512:
6
+ metadata.gz: 13f802e2a98a282a811b285d6c1333feb82a1cd49661e38d72210dbb0d79754e484d8c28a31d6bd9c8c979fd20d1265a328b5c3e04dfbfe9ac7d38126aaab8dc
7
+ data.tar.gz: 332500e03df8e1c0a1e9e28edbc29106554f5f8a3e493a91f35bbaa522b38890df0bb4217c6dd2368e33b7491697a5ecd85b5bd37362e6bd3e909d29d04aed5b
data/changelog.md ADDED
@@ -0,0 +1,2 @@
1
+ # 0.1.0
2
+ - initial release supporting rack or borrower discovered assets parsed with YAML or JSON.
@@ -0,0 +1,2 @@
1
+ require 'borrower'
2
+ require_relative 'middleman/data_source'
@@ -0,0 +1,7 @@
1
+ require_relative 'data_source/version' unless defined?(Middleman::DataSource::VERSION)
2
+ require_relative 'data_source/extension'
3
+
4
+ module Middleman
5
+ module DataSource
6
+ end
7
+ end
@@ -0,0 +1,78 @@
1
+ module Middleman
2
+ module DataSource
3
+
4
+ class Extension < ::Middleman::Extension
5
+ self.supports_multiple_instances = true
6
+
7
+ option :rack_app, nil, 'rack app to use'
8
+ option :root, nil, 'http(s) host to use'
9
+ option :files, [], 'routes to mount as remote data files'
10
+
11
+ def rack_app
12
+ @_rack_app ||= ::Rack::Test::Session.new( ::Rack::MockSession.new( options.rack_app ) )
13
+ end
14
+
15
+ def after_configuration
16
+ options.files.each do |remote_file|
17
+ extension = File.extname remote_file
18
+ basename = File.basename remote_file, extension
19
+ parts = remote_file.split(File::SEPARATOR)[0..-2]
20
+
21
+ if parts.empty?
22
+ original_callback = app.data.callbacks[basename]
23
+ app.data.callbacks[basename] = Proc.new do
24
+ attempt_merge_then_enhance decode_data(remote_file, extension), original_callback
25
+ end
26
+ else
27
+ original_callback = app.data.callbacks[parts.first]
28
+ app.data.callbacks[parts.first] = Proc.new do
29
+ built_data = { basename => decode_data(remote_file, extension) }
30
+ parts[1..-1].reverse.each do |part|
31
+ built_data = { part => built_data }
32
+ end
33
+
34
+ attempt_merge_then_enhance built_data, original_callback
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def attempt_merge_then_enhance new_data, original_callback
43
+ if original_callback
44
+ original_data = original_callback.call
45
+ if original_data.respond_to? :merge
46
+ return ::Middleman::Util.recursively_enhance original_data.deep_merge(new_data)
47
+ end
48
+ end
49
+
50
+ return ::Middleman::Util.recursively_enhance new_data
51
+ end
52
+
53
+ def decode_data file_path, extension
54
+ if ['.yaml', '.yml'].include? extension
55
+ YAML.load get_file_contents file_path
56
+ elsif extension == '.json'
57
+ ActiveSupport::JSON.decode get_file_contents file_path
58
+ else
59
+ raise UnsupportedDataExtension
60
+ end
61
+ end
62
+
63
+ def get_file_contents file_path
64
+ if options.rack_app
65
+ rack_app.get( URI.escape(file_path) ).body
66
+ else
67
+ Borrower::Content.get File.join( options.root, file_path )
68
+ end
69
+ end
70
+
71
+ class UnsupportedDataExtension < ArgumentError
72
+ end
73
+
74
+ end
75
+ ::Middleman::Extensions.register(:data_source, Middleman::DataSource::Extension)
76
+
77
+ end
78
+ end
@@ -0,0 +1,7 @@
1
+ module Middleman
2
+ module DataSource
3
+
4
+ VERSION = "0.1.0"
5
+
6
+ end
7
+ end
@@ -0,0 +1 @@
1
+ require 'middleman-data_source'
data/readme.md ADDED
@@ -0,0 +1,110 @@
1
+ Allows mounting of remote JSON & YAML to the [Middleman](http://middlemanapp.com) `data` object.
2
+
3
+ # Use
4
+
5
+ With Rubygems
6
+
7
+ ```bash
8
+ $ gem install middleman-data_source
9
+ ```
10
+
11
+ With Bundler
12
+
13
+ ```ruby
14
+ gem 'middleman-data_source'
15
+ ```
16
+
17
+ Then in your [Middleman](http://middlemanapp.com)'s `config.rb`
18
+
19
+ ```ruby
20
+ activate :data_source do |c|
21
+ c.root = "http://yourdatahost.com"
22
+ c.files = [
23
+ "some.yaml",
24
+ "paths/js.json"
25
+ ]
26
+ end
27
+ ```
28
+
29
+ And access them like any other data:
30
+
31
+ ```ruby
32
+ # source/index.html
33
+
34
+ = data.some.title
35
+ ```
36
+
37
+ You can fetch your data in two ways:
38
+ 1. from the file system or web with [Borrower](http://github.com/stevenosloan/borrower)
39
+ 2. with a rack app
40
+
41
+ Multiple instances of the extension are supported, so activate once for each data source you require.
42
+
43
+
44
+ ### With Borrower
45
+
46
+ Borrower provides a common interface for fetching files from the filesystem or through http, so it's configured the same either way. You'll specify your `root`, then the files you want loaded (with paths relative to root).
47
+
48
+ ```ruby
49
+ # config.rb
50
+
51
+ activate :data_source do |c|
52
+ c.root = '/var/data'
53
+ c.files = [
54
+ 'middleman.json' # will look for this file at /var/data/middleman.json
55
+ # and be accessible through data.middleman
56
+ ]
57
+ end
58
+
59
+ activate :data_source do |c|
60
+ c.root = "http://yourhost.com"
61
+ c.files = [
62
+ 'middleman.json' # will look for the file at http://yourhost.com/middleman.json
63
+ # and be accessible through data.middleman
64
+ ]
65
+ ```
66
+
67
+ ### With a Rack App
68
+
69
+ We can also fetch data through a local rack app, so if you want to manipulate a database and mount the data you can. A simple example that just uses Rack::Static would look like this:
70
+
71
+ ```ruby
72
+ # config.rb
73
+
74
+ activate :data_source do |c|
75
+
76
+ c.rack_app = Rack::Builder.new do
77
+ use Rack::Static, urls: ["/"],
78
+ root: "remote_data"
79
+ run lambda {|env| [404, {'Content-type' => 'text/plain'}, ['Not found']] }
80
+ end
81
+
82
+ c.files = [
83
+ 'rack.json' # passes /rack.json to your rack app
84
+ # and mounts the data to data.rack
85
+ ]
86
+ end
87
+ ```
88
+
89
+
90
+ # Testing
91
+
92
+ ```bash
93
+ $ rspec
94
+ ```
95
+
96
+
97
+ # Contributing
98
+
99
+ If there is any thing you'd like to contribute or fix, please:
100
+
101
+ - Fork the repo
102
+ - Add tests for any new functionality
103
+ - Make your changes
104
+ - Verify all existing tests work properly
105
+ - Make a pull request
106
+
107
+
108
+ # License
109
+
110
+ The `middleman-data_source` gem is distributed under the [MIT License](/LICENSE).
@@ -0,0 +1,20 @@
1
+ set :environment, :test
2
+ set :show_exceptions, false
3
+
4
+ activate :data_source do |c|
5
+
6
+ c.rack_app = Rack::Builder.new do
7
+ use Rack::Static, urls: ["/"],
8
+ root: "remote_data"
9
+ run lambda {|env| [404, {'Content-type' => 'text/plain'}, ['Not found']] }
10
+ end
11
+
12
+ c.files = [
13
+ 'remote.json',
14
+ 'deeply/nested.json',
15
+ 'deeply/nested/routes.json',
16
+ 'in_yaml.yml',
17
+ 'in_json.json'
18
+ ]
19
+
20
+ end
@@ -0,0 +1,16 @@
1
+ set :environment, :test
2
+ set :show_exceptions, false
3
+
4
+ activate :data_source do |c|
5
+
6
+ c.root = File.join( Dir.pwd, 'remote_data' )
7
+
8
+ c.files = [
9
+ 'remote.json',
10
+ 'deeply/nested.json',
11
+ 'deeply/nested/routes.json',
12
+ 'in_yaml.yml',
13
+ 'in_json.json'
14
+ ]
15
+
16
+ end
@@ -0,0 +1,22 @@
1
+ set :environment, :test
2
+ set :show_exceptions, false
3
+
4
+ activate :data_source do |c|
5
+
6
+ c.root = File.join( Dir.pwd, 'remote_data1' )
7
+
8
+ c.files = [
9
+ 'remote.json'
10
+ ]
11
+
12
+ end
13
+
14
+ activate :data_source do |c|
15
+
16
+ c.root = File.join( Dir.pwd, 'remote_data2' )
17
+
18
+ c.files = [
19
+ 'in_yaml.yml'
20
+ ]
21
+
22
+ end
@@ -0,0 +1,3 @@
1
+ activate :data_source do |c|
2
+ c.files = [ 'unsupported.jpg' ]
3
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe Middleman::DataSource do
4
+ end
@@ -0,0 +1,90 @@
1
+ require 'spec_helper'
2
+
3
+ describe Middleman::DataSource::Extension do
4
+
5
+ it "is registered as an extension" do
6
+ expect( Middleman::Extensions.registered[:data_source] ).to eq Middleman::DataSource::Extension
7
+ end
8
+
9
+ shared_examples "data import" do
10
+ it "adds data to application" do
11
+ expect( @mm.data.remote ).to eq [{"item" => "one"}, {"item" => "two"}]
12
+ end
13
+
14
+ it "supports nested routes" do
15
+ expect( @mm.data.deeply.nested.routes ).to eq [{"item" => "one"}, {"item" => "two"}]
16
+ end
17
+
18
+ it "attempts to not clobber data of overlapping nested routes (if it's hashes)" do
19
+ expect( @mm.data.deeply.nested.has_key? "nestable" ).to eq true
20
+ expect( @mm.data.deeply.nested["nestable"] ).to eq "data"
21
+ end
22
+
23
+ it "support yaml or json" do
24
+ expect( @mm.data.in_yaml ).to eq ["data","in","yaml"]
25
+ expect( @mm.data.in_json ).to eq ["data","in","json"]
26
+ end
27
+ end
28
+
29
+ context "with the base fixture app" do
30
+ before :each do
31
+ Given.fixture 'base'
32
+ @mm = Middleman::Fixture.app
33
+ @extension = @mm.extensions[:data_source]
34
+ end
35
+
36
+ after :each do
37
+ Given.cleanup!
38
+ end
39
+
40
+ it_behaves_like "data import"
41
+ end
42
+
43
+ context "with unsupported_extension" do
44
+ before :each do
45
+ Given.fixture 'unsupported_extension'
46
+ @app = Middleman::Fixture.app
47
+ end
48
+
49
+ after :each do
50
+ Given.cleanup!
51
+ end
52
+
53
+ it "raises UnsupportedDataExtension" do
54
+ expect{ @app.data.unsupported }.to raise_error Middleman::DataSource::Extension::UnsupportedDataExtension
55
+ end
56
+ end
57
+
58
+ context "with root set to http source" do
59
+ before :each do
60
+ Given.fixture 'borrower'
61
+ @mm = Middleman::Fixture.app
62
+ @extension = @mm.extensions[:data_source]
63
+ end
64
+
65
+ after :each do
66
+ Given.cleanup!
67
+ end
68
+
69
+ it_behaves_like "data import"
70
+ end
71
+
72
+
73
+ context "with multiple instances" do
74
+ before :each do
75
+ Given.fixture 'multiple_instances'
76
+ @mm = Middleman::Fixture.app
77
+ @extension = @mm.extensions[:data_source]
78
+ end
79
+
80
+ after :each do
81
+ Given.cleanup!
82
+ end
83
+
84
+ it "returns data from both instances" do
85
+ expect( @mm.data.remote ).to eq [{"item" => "one"}, {"item" => "two"}]
86
+ expect( @mm.data.in_yaml ).to eq ["data","in","yaml"]
87
+ end
88
+ end
89
+
90
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe Middleman::DataSource::VERSION do
4
+ it "has a version" do
5
+ expect( Middleman::DataSource::VERSION >= '0.0.0' ).to eq true
6
+ end
7
+ end
@@ -0,0 +1,26 @@
1
+ require 'rspec'
2
+ require 'rack/test'
3
+ require 'middleman'
4
+
5
+ require_relative 'support/given'
6
+ require_relative 'support/fixture'
7
+ require_relative 'support/browser'
8
+
9
+ if ENV['DEBUG']
10
+ require 'pry'
11
+ end
12
+
13
+ RSpec.configure do |c|
14
+
15
+ c.mock_with :rspec do |mocks|
16
+ mocks.verify_doubled_constant_names = true
17
+ mocks.verify_partial_doubles = true
18
+ end
19
+
20
+ end
21
+
22
+ def tracer msg
23
+ STDOUT.puts "\n\n==========================\n\n#{msg}\n\n==========================\n"
24
+ end
25
+
26
+ require 'middleman-data_source'
@@ -0,0 +1,20 @@
1
+ module Middleman
2
+ class Browser
3
+
4
+ attr_reader :browser
5
+
6
+ def initialize app
7
+ app_on_rack = app.class.to_rack_app
8
+ @browser = ::Rack::Test::Session.new( ::Rack::MockSession.new(app_on_rack) )
9
+ end
10
+
11
+ def get path
12
+ browser.get( URI.escape(path) ).body
13
+ end
14
+
15
+ def get_response path
16
+ browser.get( URI.escape(path) )
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,22 @@
1
+ module Middleman
2
+ module Fixture
3
+
4
+ class << self
5
+
6
+ def default env=:test
7
+ Middleman::Application.server.inst do
8
+ set :environment, env
9
+ end
10
+ end
11
+
12
+ def app &block
13
+ ENV['MM_ROOT'] = Given::TMP
14
+ Middleman::Application.server.inst do
15
+ instance_eval(&block) if block
16
+ end
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,28 @@
1
+ module Given
2
+ ROOT = File.expand_path( '../..', __dir__ )
3
+ TMP = File.join( ROOT, 'tmp' )
4
+
5
+ class << self
6
+
7
+ def fixture fixture
8
+ cleanup!
9
+
10
+ `rsync -av ./spec/fixtures/#{fixture}/ #{TMP}/`
11
+ Dir.chdir TMP
12
+ end
13
+
14
+ def file name, content
15
+ file_path = File.join( TMP, name )
16
+ FileUtils.mkdir_p( File.dirname(file_path) )
17
+ File.open( file_path, 'w' ) do |file|
18
+ file.write content
19
+ end
20
+ end
21
+
22
+ def cleanup!
23
+ Dir.chdir ROOT
24
+ `rm -rf #{TMP}`
25
+ end
26
+
27
+ end
28
+ end
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: middleman-data_source
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Steven Sloan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: middleman
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: borrower
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.9'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.9'
41
+ description: " Allow for loading data in middleman from remote sources "
42
+ email: stevenosloan@gmail.com
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - changelog.md
48
+ - lib/middleman-data_source.rb
49
+ - lib/middleman/data_source.rb
50
+ - lib/middleman/data_source/extension.rb
51
+ - lib/middleman/data_source/version.rb
52
+ - lib/middleman_extension.rb
53
+ - readme.md
54
+ - spec/fixtures/base/config.rb
55
+ - spec/fixtures/borrower/config.rb
56
+ - spec/fixtures/multiple_instances/config.rb
57
+ - spec/fixtures/unsupported_extension/config.rb
58
+ - spec/lib/middleman-data_source_spec.rb
59
+ - spec/lib/middleman/data_source/extension_spec.rb
60
+ - spec/lib/middleman/data_source/version_spec.rb
61
+ - spec/spec_helper.rb
62
+ - spec/support/browser.rb
63
+ - spec/support/fixture.rb
64
+ - spec/support/given.rb
65
+ homepage: http://github.com/stevenosloan/middleman-data_source
66
+ licenses:
67
+ - MIT
68
+ metadata: {}
69
+ post_install_message:
70
+ rdoc_options: []
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 2.4.3
86
+ signing_key:
87
+ specification_version: 4
88
+ summary: Allow for loading data in middleman from remote sources
89
+ test_files:
90
+ - spec/fixtures/base/config.rb
91
+ - spec/fixtures/borrower/config.rb
92
+ - spec/fixtures/multiple_instances/config.rb
93
+ - spec/fixtures/unsupported_extension/config.rb
94
+ - spec/lib/middleman/data_source/extension_spec.rb
95
+ - spec/lib/middleman/data_source/version_spec.rb
96
+ - spec/lib/middleman-data_source_spec.rb
97
+ - spec/spec_helper.rb
98
+ - spec/support/browser.rb
99
+ - spec/support/fixture.rb
100
+ - spec/support/given.rb