cloudcannon-jekyll 0.2.1 → 0.3.4

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
  SHA256:
3
- metadata.gz: 9ae3c8abe082ec3f37215dec374610ec9afdbcfdf657088948285375e847410f
4
- data.tar.gz: 44974881ddba3a62062337da11a56d1fbdd406fa04cead477b216866d88bf5cc
3
+ metadata.gz: 29ba7626e36d9eda34cdc67fe54a1961c7fc8ea6af3b61d2bfe8e9f7074483c8
4
+ data.tar.gz: 82ea5cfc99366153d6464125652c200ccf0971fca780cf9d5cfbbe5bb70fd9c2
5
5
  SHA512:
6
- metadata.gz: 8d894aea066bba58238ac0a2dbcc277eee56c84d3aeddea107089db51717266f313001d187ac6f5bf077f3f46c044b5842e3e02afa96a0d38fcc8f967889a1c2
7
- data.tar.gz: f51833d3e91c35ca0e2fa0020b4844a0727c969bf026d01f83922c384ec5b4a0bc68afa11032434a8947281664daf0f5b89f44066d4fb0b76969e8a056486923
6
+ metadata.gz: 958d22f6c30642a9ef324aba1938768a8b7337b948f33780f2545a310c12e9535328a52367fa888d267a18b6572d07ef1d7387fdab9956211830c448946b52c2
7
+ data.tar.gz: 6c2dee57baf7d6fac11898094e3292c89559ac4d5077b898efdc65c1901df351101d37ef240de02eebd2db2dc2adfc9bd288ca232d7f9b3bd4f9ba8aeb36b177
@@ -0,0 +1,19 @@
1
+ name: Mark stale issues
2
+
3
+ on:
4
+ schedule:
5
+ - cron: "30 1 * * *"
6
+
7
+ jobs:
8
+ stale:
9
+
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - uses: actions/stale@v1
14
+ with:
15
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
16
+ stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days'
17
+ stale-issue-label: 'no-issue-activity'
18
+ days-before-stale: 30
19
+ days-before-close: 5
@@ -0,0 +1,6 @@
1
+ detectors:
2
+ LongParameterList:
3
+ max_params: 4 # Matches the Rubocop setting
4
+
5
+ exclude_paths:
6
+ - spec
@@ -28,15 +28,12 @@ Naming/MemoizedInstanceVariableName:
28
28
  Metrics/CyclomaticComplexity:
29
29
  Exclude:
30
30
  - lib/cloudcannon-jekyll/jsonify-filter.rb # TODO remove this and fix warnings
31
+ - lib/cloudcannon-jekyll/readers/old-data-reader.rb # TODO remove this and fix warnings
31
32
 
32
33
  Metrics/PerceivedComplexity:
33
34
  Exclude:
34
35
  - lib/cloudcannon-jekyll/jsonify-filter.rb # TODO remove this and fix warnings
35
36
 
36
- Metrics/MethodLength:
37
- Exclude:
38
- - lib/cloudcannon-jekyll/jsonify-filter.rb # TODO remove this and fix warnings
39
-
40
37
  Metrics/AbcSize:
41
38
  Exclude:
42
39
  - lib/cloudcannon-jekyll/jsonify-filter.rb # TODO remove this and fix warnings
data/HISTORY.md CHANGED
@@ -1,3 +1,41 @@
1
+ # 0.3.4
2
+
3
+ * Re-add id field for documents
4
+ * Fix for potential nil reference
5
+
6
+ # 0.3.3
7
+
8
+ * Rework fallback for older versions of Jekyll when reading data, posts and drafts again
9
+
10
+ # 0.3.2
11
+
12
+ * Rework fallback for older versions of Jekyll when reading data, posts and drafts
13
+ * Fix deprecation warning for `posts.map`
14
+
15
+ # 0.3.1
16
+
17
+ * Fix for empty collection configurations
18
+ * Added max depth parameter for jsonify filter and increase it for array structures in config output
19
+
20
+ # 0.3.0
21
+
22
+ * Add empty paths.pages
23
+ * Added drafts to collections in details
24
+ * Added drafts and data to collections in config
25
+ * Added category folder drafts and posts to collections in config
26
+ * Added `_path` field to each collection definition in config
27
+ * Removed some unused fields
28
+ * Renamed static to static-pages in details and removed `robots.txt` and `sitemap.xml` exceptions
29
+ * Add `url` to static-pages
30
+ * Normalise `_path` in static-pages
31
+
32
+ # 0.2.2
33
+
34
+ * Added JSON handling for integers in hash keys
35
+ * Fix typo for collections key in older Jekyll versions
36
+ * Change date format to ISO8601
37
+ * Validate against new version of config schema
38
+
1
39
  # 0.2.1
2
40
 
3
41
  * Add gem information and time to output config file
@@ -10,9 +10,9 @@ require_relative "cloudcannon-jekyll/version"
10
10
 
11
11
  Liquid::Template.register_filter(CloudCannonJekyll::JsonifyFilter)
12
12
 
13
- # Hooks didn't exist in Jekyll 2 so we monkey patch to get an :after_reset hook
14
- if Jekyll::VERSION.start_with? "2"
13
+ if Jekyll::VERSION.start_with? "2."
15
14
  module Jekyll
15
+ # Hooks didn't exist in Jekyll 2 so we monkey patch to get an :after_reset hook
16
16
  class Site
17
17
  alias_method :jekyll_reset, :reset
18
18
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "time": {{ site.time | cc_jsonify }},
2
+ "time": {{ site.time | date_to_xmlschema | cc_jsonify }},
3
3
  "cloudcannon": {
4
4
  "name": "cloudcannon-jekyll",
5
5
  "version": {{ gem_version | cc_jsonify }}
@@ -8,7 +8,7 @@
8
8
  "include": {{ config.include | cc_jsonify }},
9
9
  "exclude": {{ config.exclude | cc_jsonify }},
10
10
  {% if config.baseurl %}"base-url": {{ config.baseurl | cc_jsonify }},{% endif %}
11
- {% if config.collections %}"comments": {{ config.collections | cc_jsonify: 'collections' }},{% endif %}
11
+ "collections": {{ collections | cc_jsonify: 'collections' }},
12
12
  {% if config._comments %}"comments": {{ config._comments | cc_jsonify }},{% endif %}
13
13
  {% if config._options %}"input-options": {{ config._options | cc_jsonify }},{% endif %}
14
14
  {% if config.defaults %}"defaults": {{ config.defaults | cc_jsonify }},{% endif %}
@@ -25,11 +25,12 @@
25
25
  "uploads": {{ config.uploads_dir | cc_jsonify }},
26
26
  "plugins": {{ config.plugins_dir | cc_jsonify }},
27
27
  "data": {{ config.data_dir | cc_jsonify }},
28
+ "pages": "",
28
29
  "collections": {{ config.collections_dir | cc_jsonify }},
29
30
  "includes": {{ config.includes_dir | cc_jsonify }},
30
31
  "layouts": {{ config.layouts_dir | cc_jsonify }}
31
32
  },
32
- {% if config._array_structures %}"array-structures": {{ config._array_structures | cc_jsonify }},{% endif %}
33
+ {% if config._array_structures %}"array-structures": {{ config._array_structures | cc_jsonify: nil, 20 }},{% endif %}
33
34
  {% assign select_data = config | cc_select_data_jsonify %}{% if select_data %}"select-data": {{ select_data }},{% endif %}
34
35
  "source": {{ config.source | replace: pwd, "" | cc_jsonify }}
35
36
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "time": {{ site.time | cc_jsonify }},
2
+ "time": {{ site.time | date_to_xmlschema | cc_jsonify }},
3
3
  "cloudcannon": {
4
4
  "name": "cloudcannon-jekyll",
5
5
  "version": {{ gem_version | cc_jsonify }}
@@ -8,7 +8,7 @@
8
8
  "include": {{ config.include | cc_jsonify }},
9
9
  "exclude": {{ config.exclude | cc_jsonify }},
10
10
  {% if config.baseurl %}"base-url": {{ config.baseurl | cc_jsonify }},{% endif %}
11
- {% if config.collections %}"comments": {{ config.collections | cc_jsonify: 'collections' }},{% endif %}
11
+ "collections": {{ collections | cc_jsonify: 'collections' }},
12
12
  {% if config._comments %}"comments": {{ config._comments | cc_jsonify }},{% endif %}
13
13
  {% if config._options %}"input-options": {{ config._options | cc_jsonify }},{% endif %}
14
14
  {% if config.defaults %}"defaults": {{ config.defaults | cc_jsonify }},{% endif %}
@@ -25,11 +25,12 @@
25
25
  "uploads": {{ config.uploads_dir | cc_jsonify }},
26
26
  "plugins": {{ config.plugins_dir | cc_jsonify }},
27
27
  "data": {{ config.data_dir | cc_jsonify }},
28
+ "pages": "",
28
29
  "collections": {{ config.collections_dir | cc_jsonify }},
29
30
  "includes": {{ config.includes_dir | cc_jsonify }},
30
31
  "layouts": {{ config.layouts_dir | cc_jsonify }}
31
32
  },
32
- {% if config._array_structures %}"array-structures": {{ config._array_structures | cc_jsonify }},{% endif %}
33
+ {% if config._array_structures %}"array-structures": {{ config._array_structures | cc_jsonify: nil, 20 }},{% endif %}
33
34
  {% assign select_data = config | cc_select_data_jsonify %}{% if select_data %}"select-data": {{ select_data }},{% endif %}
34
35
  "source": {{ config.source | replace: pwd, "" | cc_jsonify }}
35
36
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "time": {{ site.time | cc_jsonify }},
2
+ "time": {{ site.time | date_to_xmlschema | cc_jsonify }},
3
3
  "cloudcannon": {
4
4
  "name": "cloudcannon-jekyll",
5
5
  "version": {{ gem_version | cc_jsonify }}
@@ -12,9 +12,7 @@
12
12
  {% if config.baseurl -%}
13
13
  "base-url": {{ config.baseurl | cc_jsonify }},
14
14
  {%- endif %}
15
- {% if config.collections -%}
16
- "collections": {{ config.collections | cc_jsonify: 'collections' }},
17
- {%- endif %}
15
+ "collections": {{ collections | cc_jsonify: 'collections' }},
18
16
  {% if config._comments -%}
19
17
  "comments": {{ config._comments | cc_jsonify }},
20
18
  {%- endif %}
@@ -43,12 +41,13 @@
43
41
  "uploads": {{ config.uploads_dir | cc_jsonify }},
44
42
  "plugins": {{ config.plugins_dir | cc_jsonify }},
45
43
  "data": {{ config.data_dir | cc_jsonify }},
44
+ "pages": "",
46
45
  "collections": {{ config.collections_dir | cc_jsonify }},
47
46
  "includes": {{ config.includes_dir | cc_jsonify }},
48
47
  "layouts": {{ config.layouts_dir | cc_jsonify }}
49
48
  },
50
49
  {% if config._array_structures -%}
51
- "array-structures": {{ config._array_structures | cc_jsonify }},
50
+ "array-structures": {{ config._array_structures | cc_jsonify: nil, 20 }},
52
51
  {%- endif %}
53
52
  {% assign select_data = config | cc_select_data_jsonify -%}
54
53
  {% if select_data -%}
@@ -1,5 +1,5 @@
1
1
  {
2
- "time": {{ site.time | cc_jsonify }},
2
+ "time": {{ site.time | date_to_xmlschema | cc_jsonify }},
3
3
  "cloudcannon": {
4
4
  "name": "cloudcannon-jekyll",
5
5
  "version": {{ gem_version | cc_jsonify }}
@@ -18,10 +18,11 @@
18
18
  {% for data in site.data %}{% assign key = data[0] %}{% if site.cloudcannon.data[key] %}{% if data_seen %},{% endif %}{{ data[0] | cc_jsonify }}: {{ data[1] | cc_jsonify }}{% assign data_seen = true %}{% endif %}{% endfor %}},
19
19
  {% elsif site.cloudcannon.data %}"data": {{ site.data | cc_jsonify }},{% endif %}
20
20
  "collections": {
21
+ "drafts": {{ drafts | cc_jsonify }},
21
22
  "posts": {{ site.posts | reverse | cc_jsonify }}{% if site.collections.size > 0 %},{% endif %}
22
23
  {% for collection in site.collections %}"{{ collection[0] | xml_escape }}": {{ collection[1].docs | cc_jsonify }}{% unless forloop.last %},{% endunless %}
23
24
  {% endfor %}
24
25
  },
25
26
  "pages": {{ site.pages | cc_jsonify }},
26
- "static": {{ site.static_files | cc_static_files_jsonify }}
27
+ "static-pages": {{ site.static_files | cc_static_files_jsonify }}
27
28
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "time": {{ site.time | cc_jsonify }},
2
+ "time": {{ site.time | date_to_xmlschema | cc_jsonify }},
3
3
  "cloudcannon": {
4
4
  "name": "cloudcannon-jekyll",
5
5
  "version": {{ gem_version | cc_jsonify }}
@@ -18,9 +18,10 @@
18
18
  {% for data in site.data %}{% assign key = data[0] %}{% if site.cloudcannon.data[key] %}{% if data_seen %},{% endif %}{{ data[0] | cc_jsonify }}: {{ data[1] | cc_jsonify }}{% assign data_seen = true %}{% endif %}{% endfor %}},
19
19
  {% elsif site.cloudcannon.data %}"data": {{ site.data | cc_jsonify }},{% endif %}
20
20
  "collections": {
21
+ "drafts": {{ drafts | cc_jsonify }}{% if site.collections.size > 0 %},{% endif %}
21
22
  {% for collection in site.collections %}"{{ collection.label | xml_escape }}": {{ collection.docs | cc_jsonify }}{% unless forloop.last %},{% endunless %}
22
23
  {% endfor %}
23
24
  },
24
25
  "pages": {{ site.pages | cc_jsonify }},
25
- "static": {{ site.static_files | cc_static_files_jsonify }}
26
+ "static-pages": {{ site.static_files | cc_static_files_jsonify }}
26
27
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "time": {{ site.time | cc_jsonify }},
2
+ "time": {{ site.time | date_to_xmlschema | cc_jsonify }},
3
3
  "cloudcannon": {
4
4
  "name": "cloudcannon-jekyll",
5
5
  "version": {{ gem_version | cc_jsonify }}
@@ -30,11 +30,12 @@
30
30
  "data": {{ site.data | cc_jsonify }},
31
31
  {%- endif %}
32
32
  "collections": {
33
+ "drafts": {{ drafts | cc_jsonify }}{% if site.collections.size > 0 %},{% endif %}
33
34
  {%- for collection in site.collections -%}
34
35
  "{{ collection.label | xml_escape }}": {{ collection.docs | cc_jsonify }}
35
36
  {%- unless forloop.last %},{% endunless %}
36
37
  {%- endfor -%}
37
38
  },
38
39
  "pages": {{ site.pages | cc_jsonify }},
39
- "static": {{ site.static_files | cc_static_files_jsonify }}
40
+ "static-pages": {{ site.static_files | cc_static_files_jsonify }}
40
41
  }
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CloudCannonJekyll
4
+ # Processes Jekyll configuration to enable the plugin is run and fix common issues
4
5
  class Configuration
5
6
  def self.processed?(site)
6
7
  site.instance_variable_get(:@_cloudcannon_jekyll_processed) == true
@@ -16,7 +17,7 @@ module CloudCannonJekyll
16
17
  config = config.fix_common_issues if config.respond_to? :fix_common_issues
17
18
  config = config.add_default_excludes if config.respond_to? :add_default_excludes
18
19
 
19
- key = Jekyll::VERSION.start_with?("2") ? "gems" : "plugins"
20
+ key = Jekyll::VERSION.start_with?("2.") ? "gems" : "plugins"
20
21
 
21
22
  config[key] = Array(config[key])
22
23
  config[key].push("cloudcannon-jekyll") unless config[key].include? "cloudcannon-jekyll"
@@ -2,32 +2,128 @@
2
2
 
3
3
  require "jekyll"
4
4
  require "fileutils"
5
+ require_relative "reader"
5
6
 
6
7
  module CloudCannonJekyll
8
+ # Generates JSON files containing build config and build output details
7
9
  class Generator < Jekyll::Generator
8
10
  priority :lowest
9
11
 
10
12
  def generate(site)
11
13
  @site = site
14
+ @reader = Reader.new(@site)
15
+
16
+ collections_config = @site.config["collections"]&.dup || {}
17
+
18
+ # Workaround for empty collection configurations
19
+ collections_config.each_key do |key|
20
+ collections_config[key] ||= { "output" => false }
21
+ end
12
22
 
13
23
  payload = @site.site_payload.merge({
14
24
  "gem_version" => CloudCannonJekyll::VERSION,
25
+ })
26
+
27
+ drafts = add_blogging_config(collections_config)
28
+ add_collection_paths(collections_config)
29
+ add_data_config(collections_config)
30
+
31
+ generate_file("config", payload.merge({
15
32
  "pwd" => Dir.pwd,
16
33
  "config" => @site.config,
17
- })
34
+ "collections" => collections_config,
35
+ }))
18
36
 
19
- generate_file("details", payload)
20
- generate_file("config", payload)
37
+ generate_file("details", payload.merge({
38
+ "drafts" => drafts,
39
+ }))
40
+ end
21
41
 
22
- @site.keep_files ||= []
23
- @site.keep_files << path("details")
24
- @site.keep_files << path("config")
42
+ def collections_dir
43
+ return "" if Jekyll::VERSION.start_with? "2."
44
+
45
+ @site.config["collections_dir"] || ""
46
+ end
47
+
48
+ def data_dir
49
+ @site.config["data_dir"] || "_data"
50
+ end
51
+
52
+ # rubocop:disable Metrics/AbcSize
53
+ def add_category_folder_config(collections_config, posts_config = {})
54
+ posts = @site.posts || @site.collections["posts"]
55
+ docs = posts.class.method_defined?(:docs) ? posts.docs : posts
56
+ seen = {}
57
+
58
+ docs.map do |post|
59
+ parts = post.relative_path.split("/_posts/")
60
+ path = parts.first
61
+
62
+ # Ignore unless it's an unseen category folder post
63
+ next if parts.length < 2 || path.empty? || seen[path]
64
+
65
+ # Could check this to ensure raw files exist since posts can be generated without files
66
+ # next if @reader.read_posts(parts[0]).empty?
67
+
68
+ seen[path] = true
69
+ folder = path.sub(%r!^\/+!, "")
70
+ collections_path = "#{collections_dir}/#{folder}".gsub(%r!\/+!, "/").sub(%r!^\/+!, "")
71
+
72
+ collections_config["#{folder}/posts"] = posts_config.merge({
73
+ "_path" => "#{collections_path}/_posts",
74
+ })
75
+
76
+ # Adding the category draft config like this isn't ideal, since you could have drafts
77
+ # without posts, but it's a decent trade off vs looking for _drafts folders
78
+ collections_config["#{folder}/drafts"] = posts_config.merge({
79
+ "_path" => "#{collections_path}/_drafts",
80
+ })
81
+
82
+ path
83
+ end
84
+ end
85
+ # rubocop:enable Metrics/AbcSize
86
+
87
+ # Add data to collections config if raw data files exist
88
+ def add_data_config(collections_config)
89
+ data_files = @reader.read_data(data_dir)
90
+ collections_config["data"] = { "_path" => data_dir } if data_files&.keys&.any?
91
+ end
92
+
93
+ # Add posts/drafts to collections config
94
+ def add_blogging_config(collections_config)
95
+ collections_config["posts"] = { "output" => true } if Jekyll::VERSION.start_with? "2."
96
+ drafts = @reader.read_drafts(collections_dir)
97
+
98
+ if collections_config.key?("posts")
99
+ collections_config["drafts"] = collections_config["posts"]&.dup || {}
100
+ elsif drafts.any?
101
+ collections_config["drafts"] = {}
102
+ end
103
+
104
+ folders = add_category_folder_config(collections_config, collections_config["posts"])
105
+ folders.compact.each do |folder|
106
+ drafts += @reader.read_drafts(folder)
107
+ end
108
+
109
+ drafts
110
+ end
111
+
112
+ # Add _path to each collection config
113
+ def add_collection_paths(collections_config)
114
+ collections_config.each do |key, collection|
115
+ next if collection.key?("_path")
116
+
117
+ collection["_path"] = File.join(collections_dir, "_#{key}").sub(%r!^\/+!, "")
118
+ end
25
119
  end
26
120
 
27
121
  def generate_file(filename, data)
28
122
  dest = destination_path(filename)
29
123
  FileUtils.mkdir_p(File.dirname(dest))
30
- File.open(dest, "w") { |f| f.write(file_content(filename, data)) }
124
+ File.open(dest, "w") { |file| file.write(file_content(filename, data)) }
125
+ @site.keep_files ||= []
126
+ @site.keep_files << path(filename)
31
127
  end
32
128
 
33
129
  def version_path_suffix
@@ -50,13 +146,13 @@ module CloudCannonJekyll
50
146
  end
51
147
 
52
148
  def file_content(filename, data)
53
- json = PageWithoutAFile.new(@site, File.dirname(__FILE__), "", path(filename))
54
- json.content = File.read(source_path(filename))
55
- json.data["layout"] = nil
56
- json.data["sitemap"] = false
57
- json.data["permalink"] = "/#{path(filename)}"
58
- json.render({}, data)
59
- json.output
149
+ page = PageWithoutAFile.new(@site, File.dirname(__FILE__), "", path(filename))
150
+ page.content = File.read(source_path(filename))
151
+ page.data["layout"] = nil
152
+ page.data["sitemap"] = false
153
+ page.data["permalink"] = "/#{path(filename)}"
154
+ page.render({}, data)
155
+ page.output
60
156
  end
61
157
  end
62
158
  end
@@ -3,7 +3,10 @@
3
3
  require "jekyll"
4
4
 
5
5
  module CloudCannonJekyll
6
+ # Filter for converting Jekyll objects into JSON
6
7
  module JsonifyFilter
8
+ STATIC_EXTENSIONS = [".html", ".htm"].freeze
9
+
7
10
  CC_JSONIFY_KEY_SWAPS = {
8
11
  "collections" => {
9
12
  "_sort_key" => "_sort-key",
@@ -42,102 +45,105 @@ module CloudCannonJekyll
42
45
  @simple_types.include?(input.class) || [true, false].include?(input)
43
46
  end
44
47
 
45
- def self.static_file_to_json(input, depth)
48
+ def self.static_file_to_json(input, depth, max_depth)
49
+ path = input.relative_path.sub(%r!^\/+!, "")
50
+ url = Jekyll::VERSION.start_with?("2.") ? "/#{path}" : input.url
51
+
46
52
  out = [
47
- "\"extname\": #{JsonifyFilter.to_json(input.extname, depth + 1)}",
48
- "\"path\": #{JsonifyFilter.to_json(input.relative_path, depth + 1)}",
53
+ "\"path\": #{JsonifyFilter.to_json(path, depth, max_depth)}",
54
+ "\"url\": #{JsonifyFilter.to_json(url, depth, max_depth)}",
49
55
  ]
50
56
 
51
- # modified_time isn't defined in Jekyll 2.4.0
52
- if input.respond_to? :modified_time
53
- out.push("\"modified_time\": #{JsonifyFilter.to_json(input.modified_time, depth + 1)}")
54
- end
55
-
56
57
  "{#{out.join(",")}}"
57
58
  end
58
59
 
59
- def self.document_data_to_json(data, out, prevent, depth)
60
+ def self.document_data_to_a(data, prevent, depth, max_depth)
60
61
  prevent += %w(content output next previous excerpt)
61
62
 
62
- data.each do |key, value|
63
+ out = data.map do |key, value|
63
64
  next if prevent.include? key
64
65
 
65
66
  prevent.push key
66
- out.push("#{key.to_json}: #{JsonifyFilter.to_json(value, depth + 1)}")
67
+ "#{key.to_json}: #{JsonifyFilter.to_json(value, depth, max_depth)}"
67
68
  end
68
69
 
69
- "{#{out.join(",")}}"
70
+ out.compact
70
71
  end
71
72
 
72
- def self.legacy_post_to_json(input, depth)
73
+ def self.legacy_post_to_json(input, depth, max_depth)
73
74
  prevent = %w(dir name path url date id categories tags)
74
75
 
75
76
  out = [
76
- "\"dir\": #{JsonifyFilter.to_json(input.dir, depth + 1)}",
77
- "\"name\": #{JsonifyFilter.to_json(input.name, depth + 1)}",
78
- "\"path\": #{JsonifyFilter.to_json(input.path, depth + 1)}",
79
- "\"url\": #{JsonifyFilter.to_json(input.url, depth + 1)}",
80
- "\"date\": #{JsonifyFilter.to_json(input.date, depth + 1)}",
81
- "\"id\": #{JsonifyFilter.to_json(input.id, depth + 1)}",
82
- "\"categories\": #{JsonifyFilter.to_json(input.categories, depth + 1)}",
83
- "\"tags\": #{JsonifyFilter.to_json(input.tags, depth + 1)}",
77
+ "\"name\": #{JsonifyFilter.to_json(input.name, depth, max_depth)}",
78
+ "\"path\": #{JsonifyFilter.to_json(input.path, depth, max_depth)}",
79
+ "\"url\": #{JsonifyFilter.to_json(input.url, depth, max_depth)}",
80
+ "\"date\": #{JsonifyFilter.to_json(input.date, depth, max_depth)}",
81
+ "\"id\": #{JsonifyFilter.to_json(input.id, depth, max_depth)}",
82
+ "\"categories\": #{JsonifyFilter.to_json(input.categories, depth, max_depth)}",
83
+ "\"tags\": #{JsonifyFilter.to_json(input.tags, depth, max_depth)}",
84
84
  ]
85
85
 
86
- JsonifyFilter.document_data_to_json(input.data, out, prevent, depth)
86
+ out += JsonifyFilter.document_data_to_a(input.data, prevent, depth, max_depth)
87
+ "{#{out.join(",")}}"
87
88
  end
88
89
 
89
- def self.page_to_json(input, depth)
90
+ def self.page_to_json(input, depth, max_depth)
90
91
  prevent = %w(dir name path url)
91
92
 
92
93
  out = [
93
- "\"dir\": #{JsonifyFilter.to_json(input.dir, depth + 1)}",
94
- "\"name\": #{JsonifyFilter.to_json(input.name, depth + 1)}",
95
- "\"path\": #{JsonifyFilter.to_json(input.path, depth + 1)}",
96
- "\"url\": #{JsonifyFilter.to_json(input.url, depth + 1)}",
94
+ "\"name\": #{JsonifyFilter.to_json(input.name, depth, max_depth)}",
95
+ "\"path\": #{JsonifyFilter.to_json(input.path, depth, max_depth)}",
96
+ "\"url\": #{JsonifyFilter.to_json(input.url, depth, max_depth)}",
97
97
  ]
98
98
 
99
99
  # Merge Jekyll Defaults into data for pages (missing at v3.8.5)
100
- defaults = input.site.frontmatter_defaults.all(input.relative_path, :pages).tap do |h|
101
- h.delete("date")
100
+ defaults = input.site.frontmatter_defaults.all(input.relative_path, :pages).tap do |default|
101
+ default.delete("date")
102
102
  end
103
103
 
104
104
  data = Jekyll::Utils.deep_merge_hashes(defaults, input.data)
105
- JsonifyFilter.document_data_to_json(data, out, prevent, depth)
105
+
106
+ out += JsonifyFilter.document_data_to_a(data, prevent, depth, max_depth)
107
+ "{#{out.join(",")}}"
106
108
  end
107
109
 
108
- def self.document_to_json(input, depth)
109
- prevent = %w(dir id relative_path url collection)
110
+ def self.document_to_json(input, depth, max_depth)
111
+ prevent = %w(dir relative_path url collection)
110
112
 
111
113
  out = [
112
- "\"path\": #{JsonifyFilter.to_json(input.relative_path, depth + 1)}",
113
- "\"relative_path\": #{JsonifyFilter.to_json(input.relative_path, depth + 1)}",
114
- "\"url\": #{JsonifyFilter.to_json(input.url, depth + 1)}",
114
+ "\"path\": #{JsonifyFilter.to_json(input.relative_path, depth, max_depth)}",
115
+ "\"url\": #{JsonifyFilter.to_json(input.url, depth, max_depth)}",
115
116
  ]
116
117
 
117
- unless input.collection.nil?
118
- out.push("\"collection\": #{JsonifyFilter.to_json(input.collection.label, depth + 1)}")
118
+ collection = input.collection
119
+ unless collection.nil?
120
+ collection_json = JsonifyFilter.to_json(collection.label, depth, max_depth)
121
+ out.push("\"collection\": #{collection_json}")
119
122
  end
120
123
 
121
- # id isn't defined in Jekyll 2.4.0
122
- out.push("\"id\": #{JsonifyFilter.to_json(input.id, depth + 1)}") if input.respond_to? :id
124
+ if input.respond_to? :id
125
+ out.push("\"id\": #{JsonifyFilter.to_json(input.id, depth, max_depth)}")
126
+ end
123
127
 
124
- JsonifyFilter.document_data_to_json(input.data, out, prevent, depth)
128
+ out += JsonifyFilter.document_data_to_a(input.data, prevent, depth, max_depth)
129
+ "{#{out.join(",")}}"
125
130
  end
126
131
 
127
- def self.array_to_json(input, depth, key_swaps = {})
132
+ def self.array_to_json(input, depth, max_depth, key_swaps = {})
128
133
  array = input.map do |value|
129
- JsonifyFilter.to_json(value, depth + 1, key_swaps)
134
+ JsonifyFilter.to_json(value, depth, max_depth, key_swaps)
130
135
  end
131
136
 
132
137
  "[#{array.join(",")}]"
133
138
  end
134
139
 
135
- def self.hash_to_json(input, depth, key_swaps = {})
136
- hash = input.map do |key, value|
137
- "#{(key_swaps[key] || key).to_json}: #{JsonifyFilter.to_json(value, depth + 1, key_swaps)}"
140
+ def self.hash_to_json(input, depth, max_depth, key_swaps = {})
141
+ out = input.map do |key, value|
142
+ string_key = (key_swaps[key] || key).to_s.to_json
143
+ "#{string_key}: #{JsonifyFilter.to_json(value, depth, max_depth, key_swaps)}"
138
144
  end
139
145
 
140
- "{#{hash.join(",")}}"
146
+ "{#{out.join(",")}}"
141
147
  end
142
148
 
143
149
  def self.config_to_select_data_json(input, depth)
@@ -155,7 +161,7 @@ module CloudCannonJekyll
155
161
  next if prevent.include? key
156
162
 
157
163
  prevent.push key
158
- "#{key.to_json}: #{JsonifyFilter.to_json(value, depth + 1)}"
164
+ "#{key.to_s.to_json}: #{JsonifyFilter.to_json(value, depth)}"
159
165
  end
160
166
 
161
167
  out.compact!
@@ -163,39 +169,37 @@ module CloudCannonJekyll
163
169
  "{#{out.join(",")}}" if out.any?
164
170
  end
165
171
 
166
- def self.to_json(input, depth, key_swaps = {})
167
- if depth > 8 || (depth > 2 && JsonifyFilter.document_type?(input))
172
+ def self.to_json(input, depth, max_depth = 9, key_swaps = {})
173
+ depth += 1
174
+
175
+ if depth > max_depth || (depth > 3 && JsonifyFilter.document_type?(input))
168
176
  '"MAXIMUM_DEPTH"'
169
177
  elsif JsonifyFilter.simple_type?(input)
170
178
  input.to_json
171
179
  elsif input.is_a?(Jekyll::StaticFile)
172
- JsonifyFilter.static_file_to_json(input, depth)
180
+ JsonifyFilter.static_file_to_json(input, depth, max_depth)
173
181
  elsif input.is_a?(Jekyll::Page)
174
- JsonifyFilter.page_to_json(input, depth)
182
+ JsonifyFilter.page_to_json(input, depth, max_depth)
175
183
  elsif Jekyll::VERSION.start_with?("2.") && input.is_a?(Jekyll::Post)
176
- JsonifyFilter.legacy_post_to_json(input, depth)
184
+ JsonifyFilter.legacy_post_to_json(input, depth, max_depth)
177
185
  elsif input.is_a?(Jekyll::Document)
178
- JsonifyFilter.document_to_json(input, depth)
186
+ JsonifyFilter.document_to_json(input, depth, max_depth)
179
187
  elsif input.is_a?(Array)
180
- JsonifyFilter.array_to_json(input, depth, key_swaps)
188
+ JsonifyFilter.array_to_json(input, depth, max_depth, key_swaps)
181
189
  elsif input.is_a?(Hash)
182
- JsonifyFilter.hash_to_json(input, depth, key_swaps)
190
+ JsonifyFilter.hash_to_json(input, depth, max_depth, key_swaps)
183
191
  else
184
192
  input.class.to_s.prepend("UNSUPPORTED:").to_json
185
193
  end
186
194
  end
187
195
 
188
196
  def cc_static_files_jsonify(input)
189
- out = []
190
- input.each do |page|
191
- next if page.extname != ".html" &&
192
- page.extname != ".htm" &&
193
- page.path != "/robots.txt" &&
194
- page.path != "/sitemap.xml"
195
-
196
- out.push(JsonifyFilter.to_json(page, 1))
197
+ out = input.map do |page|
198
+ JsonifyFilter.to_json(page, 1) if STATIC_EXTENSIONS.include?(page.extname)
197
199
  end
198
200
 
201
+ out.compact!
202
+
199
203
  "[#{out.join(",")}]"
200
204
  end
201
205
 
@@ -207,11 +211,11 @@ module CloudCannonJekyll
207
211
  end
208
212
  end
209
213
 
210
- def cc_jsonify(input, key_swaps_key = nil)
214
+ def cc_jsonify(input, key_swaps_key = nil, max_depth = 8)
211
215
  if CC_JSONIFY_KEY_SWAPS.key? key_swaps_key
212
- JsonifyFilter.to_json(input, 0, CC_JSONIFY_KEY_SWAPS[key_swaps_key])
216
+ JsonifyFilter.to_json(input, 0, max_depth, CC_JSONIFY_KEY_SWAPS[key_swaps_key])
213
217
  else
214
- JsonifyFilter.to_json(input, 0)
218
+ JsonifyFilter.to_json(input, 0, max_depth)
215
219
  end
216
220
  end
217
221
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CloudCannonJekyll
4
+ # Utility class to help generate files with no source file
4
5
  class PageWithoutAFile < Jekyll::Page
5
6
  def read_yaml(*)
6
7
  @data ||= {}
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "jekyll"
4
+ require_relative "readers/old-data-reader"
5
+ require_relative "readers/data-reader"
6
+
7
+ module CloudCannonJekyll
8
+ # Wraps read functions into one class
9
+ class Reader
10
+ attr_reader :site
11
+
12
+ def initialize(site)
13
+ @site = site
14
+ end
15
+
16
+ def read_data(dir = "_data")
17
+ # DataReader doesn't exist in old versions of Jekyll
18
+ if Jekyll::VERSION.start_with? "2."
19
+ CloudCannonJekyll::OldDataReader.new(@site).read(dir)
20
+ else
21
+ CloudCannonJekyll::DataReader.new(@site).read(dir)
22
+ end
23
+ end
24
+
25
+ def read_drafts(dir = "")
26
+ # PostReader doesn't exist in old versions of Jekyll
27
+ if Jekyll::VERSION.start_with? "2."
28
+ @site.read_content(dir, "_drafts", Jekyll::Draft)
29
+ else
30
+ Jekyll::PostReader.new(@site).read_drafts(dir)
31
+ end
32
+ end
33
+
34
+ def read_posts(dir = "")
35
+ # PostReader doesn't exist in old versions of Jekyll
36
+ if Jekyll::VERSION.start_with? "2."
37
+ @site.read_content(dir, "_posts", Jekyll::Post)
38
+ else
39
+ Jekyll::PostReader.new(@site).read_posts(dir)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ unless Jekyll::VERSION.start_with? "2."
4
+ require "jekyll"
5
+
6
+ module CloudCannonJekyll
7
+ # Reads data files and creates a collections-style hash representation
8
+ class DataReader < Jekyll::DataReader
9
+ # Determines how to read a data file.
10
+ # This is overridden return a hash instead of reading the file.
11
+ #
12
+ # Returns a hash with the path to the data file.
13
+ def read_data_file(path)
14
+ {
15
+ "path" => path,
16
+ }
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ if Jekyll::VERSION.start_with? "2."
4
+ require "jekyll"
5
+
6
+ module CloudCannonJekyll
7
+ # Reads data files and creates a collections-style hash representation
8
+ # Aims to replicate the data reading logic in Jekyll 2.5
9
+ class OldDataReader
10
+ attr_reader :site
11
+
12
+ def initialize(site)
13
+ @site = site
14
+ @safe = site.safe
15
+ @content = {}
16
+ end
17
+
18
+ def read(dir)
19
+ base = Jekyll.sanitized_path(@site.source, dir)
20
+ read_data_to(base, @content)
21
+ @content
22
+ end
23
+
24
+ def read_data_to(dir, data)
25
+ return unless File.directory?(dir) && (!@safe || !File.symlink?(dir))
26
+
27
+ entries = Dir.chdir(dir) do
28
+ Dir["*.{yaml,yml,json,csv}"] + Dir["*"].select { |fn| File.directory?(fn) }
29
+ end
30
+
31
+ entries.each do |entry|
32
+ path = Jekyll.sanitized_path(dir, entry)
33
+ next if File.symlink?(path) && @safe
34
+
35
+ key = sanitize_filename(File.basename(entry, ".*"))
36
+ if File.directory?(path)
37
+ read_data_to(path, data[key] = {})
38
+ else
39
+ data[key] = read_data_file(path)
40
+ end
41
+ end
42
+ end
43
+
44
+ def read_data_file(path)
45
+ {
46
+ "path" => path,
47
+ }
48
+ end
49
+
50
+ def sanitize_filename(name)
51
+ name.gsub!(%r![^\w\s_-]+!, "")
52
+ name.gsub!(%r!(^|\b\s)\s+($|\s?\b)!, '\\1\\2')
53
+ name.gsub(%r!\s+!, "_")
54
+ end
55
+ end
56
+ end
57
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CloudCannonJekyll
4
- VERSION = "0.2.1"
4
+ VERSION = "0.3.4"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cloudcannon-jekyll
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - CloudCannon
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-14 00:00:00.000000000 Z
11
+ date: 2020-12-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jekyll
@@ -107,7 +107,9 @@ executables: []
107
107
  extensions: []
108
108
  extra_rdoc_files: []
109
109
  files:
110
+ - ".github/workflows/stale.yml"
110
111
  - ".gitignore"
112
+ - ".reek.yml"
111
113
  - ".rspec"
112
114
  - ".rubocop.yml"
113
115
  - ".travis.yml"
@@ -128,6 +130,9 @@ files:
128
130
  - lib/cloudcannon-jekyll/generator.rb
129
131
  - lib/cloudcannon-jekyll/jsonify-filter.rb
130
132
  - lib/cloudcannon-jekyll/page-without-a-file.rb
133
+ - lib/cloudcannon-jekyll/reader.rb
134
+ - lib/cloudcannon-jekyll/readers/data-reader.rb
135
+ - lib/cloudcannon-jekyll/readers/old-data-reader.rb
131
136
  - lib/cloudcannon-jekyll/version.rb
132
137
  - script/ci-smoke-test
133
138
  - script/cibuild