Skip to content

Commit

Permalink
Merge branch 'release-4.2.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
denisdefreyne committed Jun 19, 2016
2 parents bec3364 + d82741f commit 361d3e5
Show file tree
Hide file tree
Showing 20 changed files with 223 additions and 19 deletions.
1 change: 1 addition & 0 deletions Gemfile
Expand Up @@ -3,6 +3,7 @@ source 'https://rubygems.org'
gemspec

group :devel do
gem 'contracts', '~> 0.14'
gem 'coveralls', require: false
gem 'guard-rake'
gem 'fuubar'
Expand Down
7 changes: 7 additions & 0 deletions NEWS.md
@@ -1,5 +1,12 @@
# Nanoc news

## 4.2.1 (2016-06-19)

Fixes:

* Fixed an occasional `WeakRef::RefError` (#863, #865)
* Fixed `show-data` command not running preprocessor (#867, #870)

## 4.2 (2016-06-04)

Enhancements:
Expand Down
1 change: 1 addition & 0 deletions lib/nanoc/base.rb
Expand Up @@ -22,6 +22,7 @@ module Nanoc::Int
end

require_relative 'base/core_ext'
require_relative 'base/contracts_support'

require_relative 'base/entities'
require_relative 'base/repos'
Expand Down
60 changes: 60 additions & 0 deletions lib/nanoc/base/contracts_support.rb
@@ -0,0 +1,60 @@
require 'singleton'

module Nanoc::Int
# @api private
module ContractsSupport
class Ignorer
include Singleton

def method_missing(*_args)
self
end
end

module DisabledContracts
Any = Ignorer.instance
Bool = Ignorer.instance
Num = Ignorer.instance
KeywordArgs = Ignorer.instance
Optional = Ignorer.instance
Maybe = Ignorer.instance
None = Ignorer.instance
ArrayOf = Ignorer.instance
Or = Ignorer.instance
Func = Ignorer.instance
RespondTo = Ignorer.instance

def contract(*args)
end
end

module EnabledContracts
def contract(*args)
Contract(*args)
end
end

def self.included(base)
contracts_loadable =
begin
require 'contracts'
true
rescue LoadError
false
end

should_enable = contracts_loadable && !ENV.key?('DISABLE_CONTRACTS')

if should_enable
unless base.include?(::Contracts::Core)
base.include(::Contracts::Core)
base.extend(EnabledContracts)
base.const_set('C', ::Contracts)
end
else
base.extend(DisabledContracts)
base.const_set('C', DisabledContracts)
end
end
end
end
9 changes: 5 additions & 4 deletions lib/nanoc/base/entities.rb
@@ -1,16 +1,17 @@
require_relative 'entities/identifier'
require_relative 'entities/content'
require_relative 'entities/rule_memory_action'
require_relative 'entities/rule_memory_actions'

require_relative 'entities/code_snippet'
require_relative 'entities/configuration'
require_relative 'entities/lazy_value'
require_relative 'entities/content'
require_relative 'entities/document'
require_relative 'entities/identifier'
require_relative 'entities/identifiable_collection'
require_relative 'entities/item'
require_relative 'entities/item_rep'
require_relative 'entities/layout'
require_relative 'entities/pattern'
require_relative 'entities/rule_memory'
require_relative 'entities/rule_memory_action'
require_relative 'entities/rule_memory_actions'
require_relative 'entities/site'
require_relative 'entities/snapshot_def'
5 changes: 5 additions & 0 deletions lib/nanoc/base/entities/code_snippet.rb
Expand Up @@ -3,6 +3,8 @@ module Nanoc::Int
#
# @api private
class CodeSnippet
include Nanoc::Int::ContractsSupport

# A string containing the actual code in this code snippet.
#
# @return [String]
Expand All @@ -13,6 +15,7 @@ class CodeSnippet
# @return [String]
attr_reader :filename

contract String, String => C::Any
# Creates a new code snippet.
#
# @param [String] data The raw source code which will be executed before
Expand All @@ -24,11 +27,13 @@ def initialize(data, filename)
@filename = filename
end

contract C::None => nil
# Loads the code by executing it.
#
# @return [void]
def load
eval(@data, TOPLEVEL_BINDING, @filename)
nil
end

# Returns an object that can be used for uniquely identifying objects.
Expand Down
16 changes: 16 additions & 0 deletions lib/nanoc/base/entities/configuration.rb
Expand Up @@ -3,6 +3,8 @@ module Nanoc::Int
#
# @api private
class Configuration
include Nanoc::Int::ContractsSupport

NONE = Object.new.freeze

# The default configuration for a data source. A data source's
Expand Down Expand Up @@ -31,13 +33,15 @@ class Configuration
string_pattern_type: 'glob',
}.freeze

contract Hash => C::Any
# Creates a new configuration with the given hash.
#
# @param [Hash] hash The actual configuration hash
def initialize(hash = {})
@wrapped = hash.__nanoc_symbolize_keys_recursively
end

contract C::None => self
def with_defaults
new_wrapped = DEFAULT_CONFIG.merge(@wrapped)
new_wrapped[:data_sources] = new_wrapped[:data_sources].map do |ds|
Expand All @@ -47,18 +51,22 @@ def with_defaults
self.class.new(new_wrapped)
end

contract C::None => Hash
def to_h
@wrapped
end

contract C::Any => C::Bool
def key?(key)
@wrapped.key?(key)
end

contract C::Any => C::Any
def [](key)
@wrapped[key]
end

contract C::Any, C::Maybe[C::Any], C::Maybe[C::Func[C::None => C::Any]] => C::Any
def fetch(key, fallback = NONE, &_block)
@wrapped.fetch(key) do
if !fallback.equal?(NONE)
Expand All @@ -71,30 +79,38 @@ def fetch(key, fallback = NONE, &_block)
end
end

contract C::Any, C::Any => C::Any
def []=(key, value)
@wrapped[key] = value
end

contract C::Or[Hash, self] => self
def merge(hash)
self.class.new(@wrapped.merge(hash.to_h))
end

contract C::Any => self
def without(key)
self.class.new(@wrapped.reject { |k, _v| k == key })
end

contract C::Any => self
def update(hash)
@wrapped.update(hash)
self
end

contract C::Func[C::Any, C::Any => C::Any] => self
def each
@wrapped.each { |k, v| yield(k, v) }
self
end

contract C::None => self
def freeze
super
@wrapped.__nanoc_freeze_recursively
self
end

# Returns an object that can be used for uniquely identifying objects.
Expand Down
20 changes: 17 additions & 3 deletions lib/nanoc/base/entities/content.rb
Expand Up @@ -10,9 +10,12 @@ module Int
#
# @api private
class Content
include Nanoc::Int::ContractsSupport

# @return [String, nil]
attr_reader :filename

contract C::Maybe[String] => C::Any
# @param [String, nil] filename
def initialize(filename)
if filename && Pathname.new(filename).relative?
Expand All @@ -22,14 +25,17 @@ def initialize(filename)
@filename = filename
end

contract C::None => self
def freeze
super
@filename.freeze
self
end

# @param [String, Proc] content The uncompiled item content (if it is textual
# content) or the path to the filename containing the content (if this
# is binary content).
contract C::Or[Nanoc::Int::Content, String, Proc], C::KeywordArgs[binary: C::Optional[C::Bool], filename: C::Optional[C::Maybe[String]]] => self
# @param [Nanoc::Int::Content, String, Proc] content The uncompiled item
# content (if it is textual content) or the path to the filename
# containing the content (if this is binary content).
#
# @param [Boolean] binary Whether or not this item is binary
#
Expand Down Expand Up @@ -57,29 +63,36 @@ def binary?

# @api private
class TextualContent < Content
contract C::None => String
# @return [String]
def string
@string.value
end

contract C::Or[String, Proc], C::KeywordArgs[filename: C::Optional[C::Maybe[String]]] => C::Any
def initialize(string, filename: nil)
super(filename)
@string = Nanoc::Int::LazyValue.new(string)
end

contract C::None => self
def freeze
super
@string.freeze
self
end

contract C::None => C::Bool
def binary?
false
end

# TODO: Add contract
def marshal_dump
[filename, string]
end

# TODO: Add contract
def marshal_load(array)
@filename = array[0]
@string = Nanoc::Int::LazyValue.new(array[1])
Expand All @@ -88,6 +101,7 @@ def marshal_load(array)

# @api private
class BinaryContent < Content
contract C::None => C::Bool
def binary?
true
end
Expand Down
14 changes: 14 additions & 0 deletions lib/nanoc/base/entities/document.rb
Expand Up @@ -2,6 +2,8 @@ module Nanoc
module Int
# @api private
class Document
include Nanoc::Int::ContractsSupport

# @return [Nanoc::Int::Content]
attr_reader :content

Expand All @@ -16,6 +18,12 @@ def attributes
# @return [String, nil]
attr_accessor :checksum_data

c_content = C::Or[String, Nanoc::Int::Content]
c_attributes = C::Or[Hash, Proc]
c_identifier = C::Or[String, Nanoc::Identifier]
c_checksum_data = C::Optional[C::Maybe[String]]

contract c_content, c_attributes, c_identifier, C::KeywordArgs[checksum_data: c_checksum_data] => C::Any
# @param [String, Nanoc::Int::Content] content
#
# @param [Hash, Proc] attributes
Expand All @@ -30,28 +38,34 @@ def initialize(content, attributes, identifier, checksum_data: nil)
@checksum_data = checksum_data
end

contract C::None => self
# @return [void]
def freeze
super
@content.freeze
@attributes.freeze
self
end

contract C::None => String
# @abstract
#
# @return Unique reference to this object
def reference
raise NotImplementedError
end

contract C::None => String
def inspect
"<#{self.class} identifier=\"#{identifier}\">"
end

contract C::None => C::Num
def hash
self.class.hash ^ identifier.hash
end

contract C::Any => C::Bool
def ==(other)
other.respond_to?(:identifier) && identifier == other.identifier
end
Expand Down

0 comments on commit 361d3e5

Please sign in to comment.