middleman-data_source 0.5.0 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f007a9a894f8c5fc6d56b47a8e238939b96fbf12
4
- data.tar.gz: 03abe96ea5700bb92236b4f00fc0681b279d33f9
3
+ metadata.gz: 8149a40f5de297992c3027d32d35a35592781065
4
+ data.tar.gz: 14b91bba9a92160b4c2d696df4698eefc48266ec
5
5
  SHA512:
6
- metadata.gz: 0f38a7aade0e3d9f051c37fe2095aacf13a8bc070d66072e9ed95051b09087ff01a1900052baf8aa9aefcc47f201fd93441bcd8477c71e924c145c539a6958b5
7
- data.tar.gz: a01f2c2bc6beacfb1a8e606241ff3a2fb5a4b66c159706f32145be7e57d820fe6f707ed584bea12c1449d3d14b91e1ae84c7dd52deb7f7635fb23f78c697c586
6
+ metadata.gz: 218bd22fd6a2875f9015641d9f87ccaaa865a24e4022304a1ed2a89b0094276e3197b0bf651b4a1cfff6300d097918e726e764087671dc1149ee7ee230ea52ea
7
+ data.tar.gz: 6589a1e6dd03534bf4121ff797058f91776ca6b90ce34b141b1bdb3171c4203a3e51b144a5184b75147b66f133f3e68d77f7b9f9563b475719bd5832b4bd54ce
data/changelog.md CHANGED
@@ -1,3 +1,7 @@
1
+ # 0.6.0
2
+ - add definable decoders & allow override of default json & yaml decoders
3
+ - allow for defining sources with arbitrary data types
4
+
1
5
  # 0.5.0
2
6
  - include support for resources that include query params after their file extension [@jordanandree]
3
7
 
@@ -7,6 +7,10 @@ module Middleman
7
7
  option :rack_app, nil, 'rack app to use'
8
8
  option :root, nil, 'http(s) host to use'
9
9
  option :files, [], 'routes to mount as remote data files'
10
+ option :sources, [], 'array of sources to mount as data'
11
+ option :decoders, {}, 'callable functions to decode data sources'
12
+
13
+ attr_reader :decoders, :sources
10
14
 
11
15
  def rack_app
12
16
  @_rack_app ||= ::Rack::Test::Session.new( ::Rack::MockSession.new( options.rack_app ) )
@@ -15,30 +19,32 @@ module Middleman
15
19
  def initialize app, options_hash={}, &block
16
20
  super app, options_hash, &block
17
21
 
18
- app_inst = app.respond_to?(:inst) ? app.inst : app
19
- remote_datas = if options.files.respond_to? :keys
20
- options.files
21
- else
22
- Hash[options.files.map do |remote_file|
23
- [remote_file, remote_file]
24
- end]
22
+ app_inst = app.respond_to?(:inst) ? app.inst : app
23
+ @sources = options.sources.dup
24
+ @decoders = default_decoders.merge(options.decoders)
25
+
26
+ options.files.flat_map do |remote_path, local|
27
+ @sources.push({
28
+ :alias => (local || remote_path),
29
+ :path => remote_path
30
+ })
25
31
  end
26
32
 
27
- remote_datas.each do |remote_file, local_representation|
28
- raw_extension = File.extname(remote_file)
33
+ @sources.each do |source|
34
+ raw_extension = File.extname(source[:path])
29
35
  extension = raw_extension.split('?').first
30
- parts = local_representation.split(File::SEPARATOR)
36
+ parts = source[:alias].split(File::SEPARATOR)
31
37
  basename = File.basename(parts.pop, raw_extension)
32
38
 
33
39
  if parts.empty?
34
40
  original_callback = app_inst.data.callbacks[basename]
35
41
  app_inst.data.callbacks[basename] = Proc.new do
36
- attempt_merge_then_enhance decode_data(remote_file, extension), original_callback
42
+ attempt_merge_then_enhance decode_data(source, extension), original_callback
37
43
  end
38
44
  else
39
45
  original_callback = app_inst.data.callbacks[parts.first]
40
46
  app_inst.data.callbacks[parts.first] = Proc.new do
41
- built_data = { basename => decode_data(remote_file, extension) }
47
+ built_data = { basename => decode_data(source, extension) }
42
48
  parts[1..-1].reverse.each do |part|
43
49
  built_data = { part => built_data }
44
50
  end
@@ -51,6 +57,19 @@ module Middleman
51
57
 
52
58
  private
53
59
 
60
+ def default_decoders
61
+ {
62
+ json: {
63
+ extensions: ['.json'],
64
+ decoder: ->(source) { ActiveSupport::JSON.decode(source) },
65
+ },
66
+ yaml: {
67
+ extensions: ['.yaml', '.yml'],
68
+ decoder: ->(source) { YAML.load(source) }
69
+ }
70
+ }
71
+ end
72
+
54
73
  def attempt_merge_then_enhance new_data, original_callback
55
74
  if original_callback
56
75
  original_data = original_callback.call
@@ -62,21 +81,27 @@ module Middleman
62
81
  return ::Middleman::Util.recursively_enhance new_data
63
82
  end
64
83
 
65
- def decode_data file_path, extension
66
- if ['.yaml', '.yml'].include? extension
67
- YAML.load get_file_contents file_path
68
- elsif extension == '.json'
69
- ActiveSupport::JSON.decode get_file_contents file_path
84
+ def decode_data source, extension
85
+ if source.has_key? :type
86
+ decoder = decoders[source[:type]]
70
87
  else
71
- raise UnsupportedDataExtension
88
+ decoder = decoders.find do |candidate|
89
+ candidate[1][:extensions].include? extension
90
+ end
91
+ decoder = decoder.last if decoder
72
92
  end
93
+
94
+ raise UnsupportedDataExtension unless decoder
95
+
96
+ decoder[:decoder].call get_file_contents source[:path]
73
97
  end
74
98
 
75
99
  def get_file_contents file_path
76
100
  if options.rack_app
77
101
  rack_app.get( URI.escape(file_path) ).body
78
102
  else
79
- Borrower::Content.get File.join( options.root, file_path )
103
+ file_path = File.join( options.root, file_path ) if options.root
104
+ Borrower::Content.get file_path
80
105
  end
81
106
  end
82
107
 
@@ -1,7 +1,7 @@
1
1
  module Middleman
2
2
  module DataSource
3
3
 
4
- VERSION = "0.5.0"
4
+ VERSION = "0.6.0"
5
5
 
6
6
  end
7
7
  end
data/readme.md CHANGED
@@ -98,6 +98,35 @@ activate :data_source do |c|
98
98
  end
99
99
  ```
100
100
 
101
+ ### Custom data types
102
+
103
+ By default we just look at the extension of a file to determine which decoder to use. By setting a source directly you can give it any data type you need. Each source is a hash with an `alias`, `path`, and `type` key. The `alias` and `path` would be the same as if you defined the source using files as `{ path => alias }`, while type corresponds to the decoder you'd like to use.
104
+
105
+ There are default decoders for `:yaml` and `:json`, however you are free to override them or create your own types.
106
+
107
+ ```ruby
108
+ # config.rb
109
+ activate :data_source do |c|
110
+
111
+ c.files = ['by_extension.ctype']
112
+
113
+ c.sources = [
114
+ {
115
+ alias: "foo_bar",
116
+ path: "/foo/bar.ctype",
117
+ type: :my_type
118
+ }
119
+ ]
120
+
121
+ c.decoders = {
122
+ my_type: {
123
+ extensions: ['.ctype'],
124
+ decoder: ->(src) { CustomType.parse(src) }
125
+ }
126
+ }
127
+ ```
128
+
129
+ In the above example, I can access `app.data.by_extension` w/ the file contents decoded by `CustomType`, because it's extension `.ctype` matches the one defined by the `:my_type` decoder. Similarly, `app.data.foo_bar` is also run through `CustomType` because it's `:type` attribute is set to `:my_type`.
101
130
 
102
131
  # Testing
103
132
 
@@ -9,13 +9,34 @@ activate :data_source do |c|
9
9
  run lambda {|env| [404, {'Content-type' => 'text/plain'}, ['Not found']] }
10
10
  end
11
11
 
12
+ c.sources = [
13
+ {
14
+ alias: "foo",
15
+ path: "foo.bar",
16
+ type: :yaml
17
+ },
18
+ {
19
+ alias: "my_decoder",
20
+ path: "w/e",
21
+ type: :my_decoder
22
+ }
23
+ ]
24
+
25
+ c.decoders = {
26
+ my_decoder: {
27
+ extensions: ['.ctype'],
28
+ decoder: ->(data) { ["grass","is","greener"] }
29
+ }
30
+ }
31
+
12
32
  c.files = [
13
33
  'remote.json',
14
34
  'deeply/nested.json',
15
35
  'deeply/nested/routes.json',
16
36
  'in_yaml.yml',
17
37
  'in_json.json',
18
- 'query_param.json?token=foo'
38
+ 'query_param.json?token=foo',
39
+ 'run_through_my_decoder.ctype'
19
40
  ]
20
41
 
21
42
  end
@@ -42,6 +42,18 @@ describe Middleman::DataSource::Extension do
42
42
  end
43
43
 
44
44
  it_behaves_like "data import"
45
+
46
+ it "allows assignment of sources w/ given type" do
47
+ expect( @mm.data.foo ).to eq ["one","two","three"]
48
+ end
49
+
50
+ it "allows assignment of custom data decoders" do
51
+ expect( @mm.data.my_decoder ).to eq ["grass","is","greener"]
52
+ end
53
+
54
+ it "sets custom decoders based on file extensions" do
55
+ expect( @mm.data.run_through_my_decoder ).to eq ["grass","is","greener"]
56
+ end
45
57
  end
46
58
 
47
59
  context "with unsupported_extension" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: middleman-data_source
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Sloan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-29 00:00:00.000000000 Z
11
+ date: 2015-07-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: middleman