middleman-data_source 0.1.0

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 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