bridgetown-builder 0.14.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d55403ba9988ba7ef4f805e8f46f9bb1f3b6f5bf5571ba442372938fe11c3b7e
4
+ data.tar.gz: faf5ad6c2a5767522c00bf4618a8e3ff330f3b393cff018059e6fbf8bada5022
5
+ SHA512:
6
+ metadata.gz: 286318aa0554d4e905bbea42ba651f0293378dfc3c0c0ae978b54428d62dcae1aa1fc3e07e58221e5b2a91609c0c0b4b58845d0428ecabdc1e60733f3f504278
7
+ data.tar.gz: cdb633657736552e5a7a1691019dca4788895fa8b148c4ab52ba45b7d93d621e72b8a82950a8cad75ee86d7eb70f42876788576dfd473ee91232fd36745c59bc
@@ -0,0 +1,17 @@
1
+ ---
2
+ inherit_from: ../.rubocop.yml
3
+
4
+ AllCops:
5
+ Include:
6
+ - lib/**/*.rb
7
+ - spec/**/*.rb
8
+
9
+ Metrics/AbcSize:
10
+ Exclude:
11
+ - lib/bridgetown-builder/dsl/*
12
+ Metrics/MethodLength:
13
+ Exclude:
14
+ - lib/bridgetown-builder/dsl/*
15
+ Metrics/ParameterLists:
16
+ Exclude:
17
+ - lib/bridgetown-builder/dsl/hooks.rb
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+
5
+ task spec: :test
6
+ require "rake/testtask"
7
+ Rake::TestTask.new(:test) do |test|
8
+ test.libs << "lib" << "test"
9
+ test.pattern = "test/**/test_*.rb"
10
+ test.verbose = true
11
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../bridgetown-core/lib/bridgetown-core/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "bridgetown-builder"
7
+ spec.version = Bridgetown::VERSION
8
+ spec.author = "Bridgetown Team"
9
+ spec.email = "maintainers@bridgetownrb.com"
10
+ spec.summary = "A Bridgetown plugin to provide a sophisticated DSL for writing plugins at a higher level of abstraction."
11
+ spec.homepage = "https://github.com/bridgetownrb/bridgetown/tree/master/bridgetown-builder"
12
+ spec.license = "MIT"
13
+
14
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r!^(test|script|spec|features)/!) }
15
+ spec.require_paths = ["lib"]
16
+
17
+ spec.add_dependency("bridgetown-core", Bridgetown::VERSION)
18
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bridgetown-core"
4
+ require "bridgetown-core/version"
5
+
6
+ module Bridgetown
7
+ module Builders
8
+ autoload :PluginBuilder, "bridgetown-builder/plugin"
9
+ autoload :DocumentBuilder, "bridgetown-builder/document"
10
+ autoload :DocumentsGenerator, "bridgetown-builder/documents_generator"
11
+ end
12
+
13
+ autoload :Builder, "bridgetown-builder/builder"
14
+ end
15
+
16
+ Bridgetown::Hooks.register_one :site, :pre_read, priority: :low, reloadable: false do |site|
17
+ # SiteBuilder is the superclass sites can subclass to create any number of
18
+ # builders, but if the site hasn't defined it explicitly, this is a no-op
19
+ if defined?(SiteBuilder)
20
+ SiteBuilder.descendants.map do |c|
21
+ c.new(c.name, site)
22
+ end
23
+ end
24
+
25
+ # If the documents generator is in use, we need to add it at the top of the
26
+ # list so the site runs the generator before any others
27
+ if Bridgetown::Builders.autoload?(:DocumentsGenerator).nil? &&
28
+ !site.generators.first.is_a?(Bridgetown::Builders::DocumentsGenerator)
29
+ site.generators.unshift Bridgetown::Builders::DocumentsGenerator.new(site.config)
30
+ end
31
+ end
32
+
33
+ Bridgetown::Hooks.register_one :site, :pre_reload, reloadable: false do |site|
34
+ # Remove all anonymous generator classes so they can later get reloaded
35
+ site.converters.delete_if { |generator| generator.class.name.nil? }
36
+ site.generators.delete_if { |generator| generator.class.name.nil? }
37
+
38
+ unless Bridgetown::Builders.autoload? :DocumentsGenerator
39
+ Bridgetown::Builders::DocumentsGenerator.clear_documents_to_generate
40
+ end
41
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ # Superclass for a website's SiteBuilder abstract class
5
+ class Builder < Bridgetown::Builders::PluginBuilder
6
+ class << self
7
+ def register
8
+ Bridgetown::Hooks.register_one :site, :pre_read, reloadable: false do |site|
9
+ new(name, site)
10
+ end
11
+ end
12
+ end
13
+
14
+ # Subclass is expected to implement #build
15
+ def initialize(name, current_site = nil)
16
+ super(name, current_site)
17
+ build
18
+ end
19
+
20
+ def inspect
21
+ name
22
+ end
23
+
24
+ def self.inherited(const)
25
+ (@children ||= Set.new).add const
26
+ catch_inheritance(const) do |const_|
27
+ catch_inheritance(const_)
28
+ end
29
+ end
30
+
31
+ def self.catch_inheritance(const)
32
+ const.define_singleton_method :inherited do |const_|
33
+ (@children ||= Set.new).add const_
34
+ yield const_ if block_given?
35
+ end
36
+ end
37
+
38
+ def self.descendants
39
+ @children ||= Set.new
40
+ out = @children.map(&:descendants)
41
+ out << self unless ["SiteBuilder", "Bridgetown::Builder"].include?(name)
42
+ Set.new(out).flatten
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ module Builders
5
+ class DocumentBuilder
6
+ attr_reader :site
7
+
8
+ def initialize(site, path)
9
+ @site = site
10
+ @path = path
11
+ @data = ActiveSupport::HashWithIndifferentAccess.new
12
+ end
13
+
14
+ def front_matter(data)
15
+ @data.merge!(data)
16
+ end
17
+
18
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
19
+ def _add_document_to_site
20
+ @collection = (@data[:collection] || :posts).to_s
21
+ collection = @site.collections[@collection]
22
+ unless collection
23
+ collection = Collection.new(@site, @collection)
24
+ collection.metadata["output"] = true
25
+ @site.collections[@collection] = collection
26
+ end
27
+
28
+ doc = Document.new(
29
+ File.join(collection.directory, @path),
30
+ site: @site,
31
+ collection: collection
32
+ )
33
+ doc.send(:merge_defaults)
34
+ doc.content = @data[:content]
35
+ @data.delete(:content)
36
+
37
+ if @path.start_with?("/")
38
+ pathname = Pathname.new(@path)
39
+ @data[:permalink] = File.join(
40
+ pathname.dirname,
41
+ pathname.basename.sub(pathname.extname, "")
42
+ ) + "/"
43
+ end
44
+
45
+ doc.merge_data!(@data)
46
+ doc.send(:read_post_data)
47
+
48
+ collection.docs << doc
49
+ end
50
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
51
+
52
+ # rubocop:disable Style/MissingRespondToMissing
53
+ def method_missing(key, value = nil)
54
+ if respond_to?(key)
55
+ super
56
+ else
57
+ @data[key] = value
58
+ end
59
+ end
60
+ # rubocop:enable Style/MissingRespondToMissing
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ module Builders
5
+ class DocumentsGenerator < Bridgetown::Generator
6
+ priority :high
7
+
8
+ def self.add(path, block)
9
+ @documents_to_generate ||= []
10
+ @documents_to_generate << [path, block]
11
+ end
12
+
13
+ class << self
14
+ attr_reader :documents_to_generate
15
+ end
16
+
17
+ def self.clear_documents_to_generate
18
+ @documents_to_generate = []
19
+ end
20
+
21
+ def generate(site)
22
+ self.class.documents_to_generate&.each do |doc_block|
23
+ path, block = doc_block
24
+ doc_builder = DocumentBuilder.new(site, path)
25
+ doc_builder.instance_exec(&block)
26
+ doc_builder._add_document_to_site
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ module Builders
5
+ module DSL
6
+ module Generators
7
+ def generator(method_name = nil, &block)
8
+ block = method(method_name) if method_name.is_a?(Symbol)
9
+ local_name = name # pull the name method into a local variable
10
+
11
+ new_gen = Class.new(Bridgetown::Generator) do
12
+ define_method(:_builder_block) { block }
13
+ define_singleton_method(:custom_name) { local_name }
14
+
15
+ attr_reader :site
16
+
17
+ def inspect
18
+ "#{self.class.custom_name} (Generator)"
19
+ end
20
+
21
+ def generate(_site)
22
+ _builder_block.call
23
+ end
24
+ end
25
+
26
+ first_low_priority_index = site.generators.find_index { |gen| gen.class.priority == :low }
27
+ site.generators.insert(first_low_priority_index || 0, new_gen.new(site.config))
28
+
29
+ functions << { name: name, generator: new_gen }
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ module Builders
5
+ module DSL
6
+ module Hooks
7
+ def hook(
8
+ owner,
9
+ event,
10
+ method_name = nil,
11
+ priority: Bridgetown::Hooks::DEFAULT_PRIORITY,
12
+ &block
13
+ )
14
+ block = method(method_name) if method_name.is_a?(Symbol)
15
+
16
+ hook_block = Bridgetown::Hooks.register_one(owner, event, priority: priority, &block)
17
+ functions << { name: name, hook: [owner, event, priority, hook_block] }
18
+ end
19
+
20
+ def add_data(data_key)
21
+ hook(:site, :post_read) do
22
+ site.data[data_key] = yield
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "faraday_middleware/redirect_limit_reached"
4
+ require "faraday_middleware/response/follow_redirects"
5
+ require "faraday_middleware/response/parse_json"
6
+
7
+ module Bridgetown
8
+ module Builders
9
+ module DSL
10
+ module HTTP
11
+ def get(url, headers: {}, parse_json: true)
12
+ body = begin
13
+ connection(parse_json: parse_json).get(url, headers: headers).body
14
+ rescue Faraday::ParsingError
15
+ Bridgetown.logger.error(
16
+ "Faraday::ParsingError",
17
+ "The response from #{url} did not contain valid JSON"
18
+ )
19
+ nil
20
+ end
21
+ yield body
22
+ end
23
+
24
+ def connection(headers: {}, parse_json: true)
25
+ headers["Content-Type"] = "application/json" if parse_json
26
+
27
+ Faraday.new(headers: headers) do |faraday|
28
+ faraday.use FaradayMiddleware::FollowRedirects
29
+ faraday.use FaradayMiddleware::ParseJson if parse_json
30
+ yield faraday if block_given?
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ module Builders
5
+ module DSL
6
+ module Liquid
7
+ def liquid_filter(filter_name, method_name = nil, &block)
8
+ block = method(method_name) if method_name.is_a?(Symbol)
9
+
10
+ m = Module.new
11
+ m.send(:define_method, filter_name, &block)
12
+ ::Liquid::Template.register_filter(m)
13
+
14
+ functions << { name: name, filter: m }
15
+ end
16
+
17
+ def liquid_tag(tag_name, method_name = nil, as_block: false, &block)
18
+ block = method(method_name) if method_name.is_a?(Symbol)
19
+ local_name = name # pull the name method into a local variable
20
+
21
+ tag_class = as_block ? ::Liquid::Block : ::Liquid::Tag
22
+ tag = Class.new(tag_class) do
23
+ define_method(:_builder_block) { block }
24
+ define_singleton_method(:custom_name) { local_name }
25
+
26
+ def inspect
27
+ "#{self.class.custom_name} (Liquid Tag)"
28
+ end
29
+
30
+ attr_reader :content, :context
31
+
32
+ def render(context)
33
+ @context = context
34
+ @content = super if is_a?(::Liquid::Block)
35
+ _builder_block.call(@markup.strip, self)
36
+ end
37
+ end
38
+
39
+ ::Liquid::Template.register_tag tag_name, tag
40
+ functions << { name: name, tag: [tag_name, tag] }
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bridgetown-builder/dsl/generators"
4
+ require "bridgetown-builder/dsl/hooks"
5
+ require "bridgetown-builder/dsl/http"
6
+ require "bridgetown-builder/dsl/liquid"
7
+ module Bridgetown
8
+ module Builders
9
+ class PluginBuilder
10
+ include DSL::Generators
11
+ include DSL::Hooks
12
+ include DSL::HTTP
13
+ include DSL::Liquid
14
+
15
+ attr_accessor :functions, :name, :site, :config
16
+
17
+ def initialize(name, current_site = nil)
18
+ self.functions = Set.new
19
+ self.name = name
20
+ self.site = current_site || Bridgetown.sites.first
21
+
22
+ self.config = if defined?(self.class::CONFIG_DEFAULTS)
23
+ Bridgetown::Utils.deep_merge_hashes(
24
+ self.class::CONFIG_DEFAULTS.with_indifferent_access, site.config
25
+ )
26
+ else
27
+ site.config
28
+ end
29
+ end
30
+
31
+ def inspect
32
+ "#{name} (Hook)"
33
+ end
34
+
35
+ def doc(path, &block)
36
+ DocumentsGenerator.add(path, block)
37
+ end
38
+ end
39
+ end
40
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bridgetown-builder
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.14.0
5
+ platform: ruby
6
+ authors:
7
+ - Bridgetown Team
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-05-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bridgetown-core
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.14.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.14.0
27
+ description:
28
+ email: maintainers@bridgetownrb.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - ".rubocop.yml"
34
+ - Rakefile
35
+ - bridgetown-builder.gemspec
36
+ - lib/bridgetown-builder.rb
37
+ - lib/bridgetown-builder/builder.rb
38
+ - lib/bridgetown-builder/document.rb
39
+ - lib/bridgetown-builder/documents_generator.rb
40
+ - lib/bridgetown-builder/dsl/generators.rb
41
+ - lib/bridgetown-builder/dsl/hooks.rb
42
+ - lib/bridgetown-builder/dsl/http.rb
43
+ - lib/bridgetown-builder/dsl/liquid.rb
44
+ - lib/bridgetown-builder/plugin.rb
45
+ homepage: https://github.com/bridgetownrb/bridgetown/tree/master/bridgetown-builder
46
+ licenses:
47
+ - MIT
48
+ metadata: {}
49
+ post_install_message:
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ requirements: []
64
+ rubygems_version: 3.0.6
65
+ signing_key:
66
+ specification_version: 4
67
+ summary: A Bridgetown plugin to provide a sophisticated DSL for writing plugins at
68
+ a higher level of abstraction.
69
+ test_files: []