Skip to content

Commit

Permalink
Merge pull request #758 from nanoc/extract-rule-dsl
Browse files Browse the repository at this point in the history
Extract rule DSL
  • Loading branch information
denisdefreyne committed Dec 5, 2015
2 parents 2eb0769 + a9eaa61 commit 46e2b18
Show file tree
Hide file tree
Showing 31 changed files with 177 additions and 132 deletions.
1 change: 1 addition & 0 deletions lib/nanoc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,4 @@ def self.on_windows?
require 'nanoc/data_sources'
require 'nanoc/filters'
require 'nanoc/helpers'
require 'nanoc/rule_dsl'
3 changes: 0 additions & 3 deletions lib/nanoc/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,10 @@ module Nanoc::Int

# Load compilation classes
autoload 'Compiler', 'nanoc/base/compilation/compiler'
autoload 'CompilerDSL', 'nanoc/base/compilation/compiler_dsl'
autoload 'DependencyTracker', 'nanoc/base/compilation/dependency_tracker'
autoload 'ItemRepRepo', 'nanoc/base/compilation/item_rep_repo'
autoload 'OutdatednessChecker', 'nanoc/base/compilation/outdatedness_checker'
autoload 'OutdatednessReasons', 'nanoc/base/compilation/outdatedness_reasons'
autoload 'Rule', 'nanoc/base/compilation/rule'
autoload 'RuleContext', 'nanoc/base/compilation/rule_context'
end

require_relative 'base/core_ext'
Expand Down
3 changes: 2 additions & 1 deletion lib/nanoc/base/checksummer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ def update(obj, digest, visited = Set.new)
digest.update(obj.to_i.to_s)
when Nanoc::Identifier
update(obj.to_s, digest)
when Nanoc::Int::RulesCollection, Nanoc::Int::CodeSnippet
# TODO: Use RuleMemory rather than RulesCollection
when Nanoc::RuleDSL::RulesCollection, Nanoc::Int::CodeSnippet
update(obj.data, digest)
when Nanoc::Int::TextualContent
update(obj.string, digest)
Expand Down
14 changes: 7 additions & 7 deletions lib/nanoc/base/compilation/compiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class Compiler
attr_reader :rule_memory_store

# @api private
attr_reader :rule_memory_calculator
attr_reader :action_provider

# @api private
attr_reader :dependency_store
Expand All @@ -72,17 +72,17 @@ class Compiler
# @api private
attr_reader :reps

def initialize(site, rules_collection, compiled_content_cache:, checksum_store:, rule_memory_store:, rule_memory_calculator:, dependency_store:, outdatedness_checker:, reps:)
def initialize(site, rules_collection, compiled_content_cache:, checksum_store:, rule_memory_store:, action_provider:, dependency_store:, outdatedness_checker:, reps:)
@site = site
@rules_collection = rules_collection

@compiled_content_cache = compiled_content_cache
@checksum_store = checksum_store
@rule_memory_store = rule_memory_store
@rule_memory_calculator = rule_memory_calculator
@dependency_store = dependency_store
@outdatedness_checker = outdatedness_checker
@reps = reps
@action_provider = action_provider

@stack = []
end
Expand Down Expand Up @@ -139,7 +139,7 @@ def load_stores
def store
# Calculate rule memory
(@reps.to_a + @site.layouts.to_a).each do |obj|
rule_memory_store[obj] = rule_memory_calculator[obj].serialize
rule_memory_store[obj] = action_provider.memory_for(obj).serialize
end

# Calculate checksums
Expand All @@ -162,7 +162,7 @@ def objects

def build_reps
builder = Nanoc::Int::ItemRepBuilder.new(
site, rules_collection, rule_memory_calculator, @reps)
site, action_provider, @reps)
builder.run
end

Expand Down Expand Up @@ -207,7 +207,7 @@ def compile_reps

# Assign snapshots
@reps.each do |rep|
rep.snapshot_defs = rule_memory_calculator.snapshots_defs_for(rep)
rep.snapshot_defs = action_provider.snapshots_defs_for(rep)
end

# Find item reps to compile and compile them
Expand Down Expand Up @@ -264,7 +264,7 @@ def can_reuse_content_for_rep?(rep)
def recalculate_content_for_rep(rep)
executor = Nanoc::Int::Executor.new(self)

rule_memory_calculator[rep].each do |action|
action_provider.memory_for(rep).each do |action|
case action
when Nanoc::Int::RuleMemoryActions::Filter
executor.filter(rep, action.filter_name, action.params)
Expand Down
4 changes: 2 additions & 2 deletions lib/nanoc/base/compilation/outdatedness_checker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ class OutdatednessChecker
# @param [Nanoc::Int::Site] site
# @param [Nanoc::Int::ChecksumStore] checksum_store
# @param [Nanoc::Int::DependencyStore] dependency_store
# @param [Nanoc::Int::RulesCollection] rules_collection
# @param [Nanoc::RuleDSL::RulesCollection] rules_collection
# @param [Nanoc::Int::RuleMemoryStore] rule_memory_store
# @param [Nanoc::Int::RuleMemoryCalculator] rule_memory_calculator
# @param [Nanoc::RuleDSL::RuleMemoryCalculator] rule_memory_calculator
# @param [Nanoc::Int::ItemRepRepo] reps
def initialize(site:, checksum_store:, dependency_store:, rules_collection:, rule_memory_store:, rule_memory_calculator:, reps:)
@site = site
Expand Down
1 change: 0 additions & 1 deletion lib/nanoc/base/entities.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,5 @@
require_relative 'entities/rule_memory'
require_relative 'entities/rule_memory_action'
require_relative 'entities/rule_memory_actions'
require_relative 'entities/rules_collection'
require_relative 'entities/site'
require_relative 'entities/snapshot_def'
4 changes: 1 addition & 3 deletions lib/nanoc/base/services.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require_relative 'services/action_provider'
require_relative 'services/compiler_loader'
require_relative 'services/executor'
require_relative 'services/item_rep_builder'
Expand All @@ -7,7 +8,4 @@
require_relative 'services/notification_center'
require_relative 'services/preprocessor'
require_relative 'services/postprocessor'
require_relative 'services/recording_executor'
require_relative 'services/rule_memory_calculator'
require_relative 'services/rules_loader'
require_relative 'services/temp_filename_factory'
16 changes: 16 additions & 0 deletions lib/nanoc/base/services/action_provider.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module Nanoc::Int
# @private
class ActionProvider
def rep_names_for(_item)
raise NotImplementedError
end

def memory_for(_rep)
raise NotImplementedError
end

def snapshots_defs_for(_rep)
raise NotImplementedError
end
end
end
11 changes: 7 additions & 4 deletions lib/nanoc/base/services/compiler_loader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ module Nanoc::Int
# @api private
class CompilerLoader
def load(site)
rules_collection = Nanoc::Int::RulesCollection.new
rules_collection = Nanoc::RuleDSL::RulesCollection.new

rule_memory_store = Nanoc::Int::RuleMemoryStore.new

rule_memory_calculator =
Nanoc::Int::RuleMemoryCalculator.new(
Nanoc::RuleDSL::RuleMemoryCalculator.new(
rules_collection: rules_collection, site: site)

dependency_store =
Expand All @@ -29,19 +29,22 @@ def load(site)
reps: item_rep_repo,
)

action_provider = Nanoc::RuleDSL::ActionProvider.new(
rules_collection, rule_memory_calculator)

params = {
compiled_content_cache: Nanoc::Int::CompiledContentCache.new,
checksum_store: checksum_store,
rule_memory_store: rule_memory_store,
rule_memory_calculator: rule_memory_calculator,
dependency_store: dependency_store,
outdatedness_checker: outdatedness_checker,
reps: item_rep_repo,
action_provider: action_provider,
}

compiler = Nanoc::Int::Compiler.new(site, rules_collection, params)

Nanoc::Int::RulesLoader.new(site.config, rules_collection).load
Nanoc::RuleDSL::RulesLoader.new(site.config, rules_collection).load

compiler
end
Expand Down
16 changes: 4 additions & 12 deletions lib/nanoc/base/services/item_rep_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,20 @@ module Nanoc::Int
class ItemRepBuilder
attr_reader :reps

def initialize(site, rules_collection, rule_memory_calculator, reps)
def initialize(site, action_provider, reps)
@site = site
@rules_collection = rules_collection
@rule_memory_calculator = rule_memory_calculator
@action_provider = action_provider
@reps = reps
end

def run
@site.items.each do |item|
rep_names_for(item).each do |rep_name|
@action_provider.rep_names_for(item).each do |rep_name|
@reps << Nanoc::Int::ItemRep.new(item, rep_name)
end
end

Nanoc::Int::ItemRepRouter.new(@reps, @rule_memory_calculator, @site).run
end

def rep_names_for(item)
matching_rules = @rules_collection.item_compilation_rules_for(item)
raise Nanoc::Int::Errors::NoMatchingCompilationRuleFound.new(item) if matching_rules.empty?

matching_rules.map(&:rep_name).uniq
Nanoc::Int::ItemRepRouter.new(@reps, @action_provider, @site).run
end
end
end
7 changes: 3 additions & 4 deletions lib/nanoc/base/services/item_rep_router.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,16 @@ def initialize(output_path, rep_a, rep_b)
end
end

# TODO: Replace rule_memory_calculator with { rep => rule_memory }
def initialize(reps, rule_memory_calculator, site)
def initialize(reps, action_provider, site)
@reps = reps
@rule_memory_calculator = rule_memory_calculator
@action_provider = action_provider
@site = site
end

def run
paths_to_reps = {}
@reps.each do |rep|
mem = @rule_memory_calculator[rep]
mem = @action_provider.memory_for(rep)
mem.snapshot_actions.each do |snapshot_action|
route_rep(rep, snapshot_action, paths_to_reps)
end
Expand Down
13 changes: 13 additions & 0 deletions lib/nanoc/rule_dsl.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module Nanoc
# @api private
module RuleDSL
autoload 'CompilerDSL', 'nanoc/rule_dsl/compiler_dsl'
autoload 'ActionProvider', 'nanoc/rule_dsl/provider'
autoload 'RecordingExecutor', 'nanoc/rule_dsl/recording_executor'
autoload 'RuleContext', 'nanoc/rule_dsl/rule_context'
autoload 'RuleMemoryCalculator', 'nanoc/rule_dsl/rule_memory_calculator'
autoload 'Rule', 'nanoc/rule_dsl/rule'
autoload 'RulesCollection', 'nanoc/rule_dsl/rules_collection'
autoload 'RulesLoader', 'nanoc/rule_dsl/rules_loader'
end
end
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module Nanoc::Int
module Nanoc::RuleDSL
# Contains methods that will be executed by the site’s `Rules` file.
#
# @api private
Expand All @@ -14,7 +14,7 @@ class CompilerDSL
#
# @api private
#
# @param [Nanoc::Int::RulesCollection] rules_collection The collection of
# @param [Nanoc::RuleDSL::RulesCollection] rules_collection The collection of
# rules to modify when loading this DSL
#
# @param [Hash] config The site configuration
Expand Down Expand Up @@ -71,7 +71,7 @@ def preprocess(&block)
def compile(identifier, rep: :default, &block)
raise ArgumentError.new('#compile requires a block') unless block_given?

rule = Nanoc::Int::Rule.new(create_pattern(identifier), rep, block)
rule = Nanoc::RuleDSL::Rule.new(create_pattern(identifier), rep, block)
@rules_collection.add_item_compilation_rule(rule)
end

Expand Down Expand Up @@ -109,7 +109,7 @@ def compile(identifier, rep: :default, &block)
def route(identifier, rep: :default, snapshot: :last, &block)
raise ArgumentError.new('#route requires a block') unless block_given?

rule = Nanoc::Int::Rule.new(create_pattern(identifier), rep, block, snapshot_name: snapshot)
rule = Nanoc::RuleDSL::Rule.new(create_pattern(identifier), rep, block, snapshot_name: snapshot)
@rules_collection.add_item_routing_rule(rule)
end

Expand Down Expand Up @@ -170,7 +170,7 @@ def passthrough(identifier, rep: :default)
raise ArgumentError.new('#passthrough does not require a block') if block_given?

compilation_block = proc {}
compilation_rule = Nanoc::Int::Rule.new(create_pattern(identifier), rep, compilation_block)
compilation_rule = Nanoc::RuleDSL::Rule.new(create_pattern(identifier), rep, compilation_block)
@rules_collection.add_item_compilation_rule(compilation_rule)

# Create routing rule
Expand All @@ -185,7 +185,7 @@ def passthrough(identifier, rep: :default)
item[:extension].nil? || (item[:content_filename].nil? && item.identifier =~ %r{#{item[:extension]}/$}) ? item.identifier.chop : item.identifier.chop + '.' + item[:extension]
end
end
routing_rule = Nanoc::Int::Rule.new(create_pattern(identifier), rep, routing_block, snapshot_name: :last)
routing_rule = Nanoc::RuleDSL::Rule.new(create_pattern(identifier), rep, routing_block, snapshot_name: :last)
@rules_collection.add_item_routing_rule(routing_rule)
end

Expand All @@ -210,10 +210,10 @@ def passthrough(identifier, rep: :default)
def ignore(identifier, rep: :default)
raise ArgumentError.new('#ignore does not require a block') if block_given?

compilation_rule = Nanoc::Int::Rule.new(create_pattern(identifier), rep, proc {})
compilation_rule = Nanoc::RuleDSL::Rule.new(create_pattern(identifier), rep, proc {})
@rules_collection.add_item_compilation_rule(compilation_rule)

routing_rule = Nanoc::Int::Rule.new(create_pattern(identifier), rep, proc {}, snapshot_name: :last)
routing_rule = Nanoc::RuleDSL::Rule.new(create_pattern(identifier), rep, proc {}, snapshot_name: :last)
@rules_collection.add_item_routing_rule(routing_rule)
end

Expand All @@ -233,7 +233,7 @@ def include_rules(name)
filename = ["#{name}", "#{name}.rb", "./#{name}", "./#{name}.rb"].find { |f| File.file?(f) }
raise Nanoc::Int::Errors::NoRulesFileFound.new if filename.nil?

Nanoc::Int::RulesLoader.new(@config, @rules_collection).parse(filename)
Nanoc::RuleDSL::RulesLoader.new(@config, @rules_collection).parse(filename)
end

# Creates a postprocessor block that will be executed after all data is
Expand Down
23 changes: 23 additions & 0 deletions lib/nanoc/rule_dsl/provider.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module Nanoc::RuleDSL
class ActionProvider < Nanoc::Int::ActionProvider
def initialize(rules_collection, rule_memory_calculator)
@rules_collection = rules_collection
@rule_memory_calculator = rule_memory_calculator
end

def rep_names_for(item)
matching_rules = @rules_collection.item_compilation_rules_for(item)
raise Nanoc::Int::Errors::NoMatchingCompilationRuleFound.new(item) if matching_rules.empty?

matching_rules.map(&:rep_name).uniq
end

def memory_for(rep)
@rule_memory_calculator[rep]
end

def snapshots_defs_for(rep)
@rule_memory_calculator.snapshots_defs_for(rep)
end
end
end
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module Nanoc
module Int
module RuleDSL
class RecordingExecutor
class NonFinalSnapshotWithPathError < ::Nanoc::Error
def initialize
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module Nanoc::Int
module Nanoc::RuleDSL
# Contains the processing information for a item.
#
# @api private
Expand Down Expand Up @@ -48,12 +48,12 @@ def applicable_to?(item)
#
# @param [Nanoc::Int::ItemRep] rep
# @param [Nanoc::Int::Site] site
# @param [Nanoc::Int::Executor, Nanoc::Int::RecordingExecutor] executor
# @param [Nanoc::Int::Executor, Nanoc::RuleDSL::RecordingExecutor] executor
# @param [Nanoc::ViewContext] view_context
#
# @return [void]
def apply_to(rep, site:, executor:, view_context:)
context = Nanoc::Int::RuleContext.new(
context = Nanoc::RuleDSL::RuleContext.new(
rep: rep, executor: executor, site: site, view_context: view_context)
context.instance_exec(matches(rep.item.identifier), &@block)
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module Nanoc::Int
module Nanoc::RuleDSL
# Provides a context in which compilation and routing rules can be executed.
# It provides access to the item representation that is being compiled or
# routed.
Expand All @@ -7,7 +7,7 @@ module Nanoc::Int
class RuleContext < Nanoc::Int::Context
# @param [Nanoc::Int::ItemRep] rep
# @param [Nanoc::Int::Site] site
# @param [Nanoc::Int::Executor, Nanoc::Int::RecordingExecutor] executor
# @param [Nanoc::Int::Executor, Nanoc::RuleDSL::RecordingExecutor] executor
# @param [Nanoc::ViewContext] view_context
def initialize(rep:, site:, executor:, view_context:)
@_executor = executor
Expand Down

0 comments on commit 46e2b18

Please sign in to comment.