nanoc-core 4.11.15 → 4.11.20

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: 1d36108ed7c1e713b65fe5119960115a3a8749efb49acb59dca207bdd82e5892
4
- data.tar.gz: d3799629cd606d9cb73aad14f798e2eac3e549149774e374e2a92832a4bc09e4
3
+ metadata.gz: ac94fc2464196846d4d6b38fb9a3ee02d0566aaa16f4f192e63f7989af937dc0
4
+ data.tar.gz: 0ba05d8ccb6d2cb10a8ec2909bb9bd99dee5203272c24cd02fdc6c6d4041dd17
5
5
  SHA512:
6
- metadata.gz: 6aea180789234158ce9d449d922e2bc88b4daf2ba877870eb865cfc0fbae52ac60995439294f2a70bc2c705a248d1dc512431a3df45beda5c4567a8046c06349
7
- data.tar.gz: edd1525adfe8ca4e64a227b6dc57c131a674d6bc56071d0befe29b1c765a97933b76102f5acfbf44c7f130c7b746e5494604183392331f7756170064dfec8cd1
6
+ metadata.gz: b76254a60ba5cc2d94f0dc6a01498b51fa22c068ba6ee93c6434cee1105a29922f664c08090b155b18a9016b065fb854f60dc38a57f2effa6b1a6a1c1d94aeee
7
+ data.tar.gz: 314da571f7e0b49544152e66dc1bc9b30ae49911b0f8aeaf863d23731294ffe33e7b21977a2238f619396119ab6b7a635453e80544ccaf0193e7a94495d34313
@@ -9,6 +9,8 @@ require 'tmpdir'
9
9
  require 'yaml'
10
10
 
11
11
  # External gems
12
+ require 'clonefile'
13
+ require 'concurrent-ruby'
12
14
  require 'json_schema'
13
15
  require 'ddmemoize'
14
16
  require 'ddmetrics'
@@ -50,8 +50,8 @@ module Nanoc
50
50
  end
51
51
 
52
52
  def calc_for_each_attribute_of(obj, digest_class = CompactDigest)
53
- obj.attributes.each_with_object({}) do |(key, value), memo|
54
- memo[key] = Nanoc::Core::Checksummer.calc(value, digest_class)
53
+ obj.attributes.transform_values do |value|
54
+ Nanoc::Core::Checksummer.calc(value, digest_class)
55
55
  end
56
56
  end
57
57
 
@@ -3,6 +3,12 @@
3
3
  module Nanoc
4
4
  module Core
5
5
  class CompilationItemRepView < ::Nanoc::Core::BasicItemRepView
6
+ # How long to wait before the requested file appears.
7
+ #
8
+ # This is a bit of a hack -- ideally, Nanoc would know that the file is
9
+ # being generated, and wait the appropriate amount of time.
10
+ FILE_APPEAR_TIMEOUT = 10.0
11
+
6
12
  # @abstract
7
13
  def item_view_class
8
14
  Nanoc::Core::CompilationItemView
@@ -27,7 +33,7 @@ module Nanoc
27
33
  # Wait for file to exist
28
34
  if res
29
35
  start = Time.now
30
- sleep 0.05 until File.file?(res) || Time.now - start > 1.0
36
+ sleep 0.05 until File.file?(res) || Time.now - start > FILE_APPEAR_TIMEOUT
31
37
  raise Nanoc::Core::Errors::InternalInconsistency, "File did not apear in time: #{res}" unless File.file?(res)
32
38
  end
33
39
 
@@ -32,7 +32,7 @@ module Nanoc
32
32
  end
33
33
 
34
34
  contract Nanoc::Core::ItemRep, C::KeywordArgs[is_outdated: C::Bool], C::Func[C::None => C::Any] => C::Any
35
- def run(_rep, is_outdated:) # rubocop:disable Lint/UnusedMethodArgument
35
+ def run(_rep, is_outdated:)
36
36
  raise NotImplementedError
37
37
  end
38
38
 
@@ -21,7 +21,7 @@ module Nanoc
21
21
  raise(res)
22
22
  when Proc
23
23
  fiber.resume(res.call)
24
- when DONE # rubocop:disable Lint/EmptyWhen
24
+ when DONE
25
25
  # ignore
26
26
  else
27
27
  raise Nanoc::Core::Errors::InternalInconsistency.new(
@@ -6,45 +6,6 @@ module Nanoc
6
6
  class Write < Abstract
7
7
  include Nanoc::Core::ContractsSupport
8
8
 
9
- class Worker
10
- def initialize(queue:, compiled_content_store:)
11
- @queue = queue
12
- @compiled_content_store = compiled_content_store
13
- end
14
-
15
- def start
16
- @thread = Thread.new do
17
- Thread.current.abort_on_exception = true
18
- Thread.current.priority = -1 # schedule I/O work ASAP
19
-
20
- writer = Nanoc::Core::ItemRepWriter.new
21
-
22
- while rep = @queue.pop # rubocop:disable Lint/AssignmentInCondition
23
- writer.write_all(rep, @compiled_content_store)
24
- end
25
- end
26
- end
27
-
28
- def join
29
- @thread.join
30
- end
31
- end
32
-
33
- class WorkerPool
34
- def initialize(queue:, size:, compiled_content_store:)
35
- @workers = Array.new(size) { Worker.new(queue: queue, compiled_content_store: compiled_content_store) }
36
- end
37
-
38
- def start
39
- @workers.each(&:start)
40
- end
41
-
42
- def join
43
- @workers.each(&:join)
44
- end
45
- end
46
-
47
- QUEUE_SIZE = 40
48
9
  WORKER_POOL_SIZE = 5
49
10
 
50
11
  def initialize(compiled_content_store:, wrapped:)
@@ -52,19 +13,16 @@ module Nanoc
52
13
 
53
14
  @compiled_content_store = compiled_content_store
54
15
 
55
- @queue = SizedQueue.new(QUEUE_SIZE)
56
- @worker_pool = WorkerPool.new(queue: @queue, size: WORKER_POOL_SIZE, compiled_content_store: @compiled_content_store)
57
- end
16
+ @pool = Concurrent::FixedThreadPool.new(WORKER_POOL_SIZE)
58
17
 
59
- def start
60
- super
61
- @worker_pool.start
18
+ @writer = Nanoc::Core::ItemRepWriter.new
62
19
  end
63
20
 
64
21
  def stop
22
+ @pool.shutdown
23
+ @pool.wait_for_termination
24
+
65
25
  super
66
- @queue.close
67
- @worker_pool.join
68
26
  end
69
27
 
70
28
  contract Nanoc::Core::ItemRep, C::KeywordArgs[is_outdated: C::Bool], C::Func[C::None => C::Any] => C::Any
@@ -76,7 +34,9 @@ module Nanoc
76
34
  # notification happens before the :rep_write_enqueued one.
77
35
  Nanoc::Core::NotificationCenter.post(:rep_write_enqueued, rep)
78
36
 
79
- @queue << rep
37
+ @pool.post do
38
+ @writer.write_all(rep, @compiled_content_store)
39
+ end
80
40
  end
81
41
  end
82
42
  end
@@ -46,8 +46,8 @@ module Nanoc
46
46
  @binary_cache[rep] = content.select { |_key, c| c.binary? }
47
47
  end
48
48
 
49
- def prune(*args)
50
- @wrapped_caches.each { |w| w.prune(*args) }
49
+ def prune(items:)
50
+ @wrapped_caches.each { |w| w.prune(items: items) }
51
51
  end
52
52
 
53
53
  # True if there is cached compiled content available for this item, and
@@ -32,7 +32,7 @@ module Nanoc
32
32
  outdatedness_store: outdatedness_store,
33
33
  }
34
34
 
35
- Nanoc::Core::Compiler.new(site, params)
35
+ Nanoc::Core::Compiler.new(site, **params)
36
36
  end
37
37
 
38
38
  def compiled_content_cache_class
@@ -113,7 +113,7 @@ module Nanoc
113
113
  src_ref = obj2ref(src)
114
114
  dst_ref = obj2ref(dst)
115
115
 
116
- existing_props = Nanoc::Core::DependencyProps.new(@graph.props_for(dst_ref, src_ref) || {})
116
+ existing_props = Nanoc::Core::DependencyProps.new(**(@graph.props_for(dst_ref, src_ref) || {}))
117
117
  new_props = Nanoc::Core::DependencyProps.new(raw_content: raw_content, attributes: attributes, compiled_content: compiled_content, path: path)
118
118
  props = existing_props.merge(new_props)
119
119
 
@@ -62,11 +62,7 @@ module Nanoc
62
62
 
63
63
  # Write
64
64
  if is_modified
65
- begin
66
- FileUtils.ln(temp_path, raw_path, force: true)
67
- rescue Errno::EXDEV, Errno::EACCES
68
- FileUtils.cp(temp_path, raw_path)
69
- end
65
+ smart_cp(temp_path, raw_path)
70
66
  end
71
67
 
72
68
  item_rep.modified = is_modified
@@ -80,6 +76,26 @@ module Nanoc
80
76
  def temp_filename
81
77
  Nanoc::Core::TempFilenameFactory.instance.create(TMP_TEXT_ITEMS_DIR)
82
78
  end
79
+
80
+ def smart_cp(from, to)
81
+ # Try clonefile
82
+ FileUtils.rm_f(to)
83
+ begin
84
+ res = Clonefile.always(from, to)
85
+ return if res
86
+ rescue Clonefile::UnsupportedPlatform, Errno::ENOTSUP, Errno::EXDEV, Errno::EINVAL
87
+ end
88
+
89
+ # Try with hardlink
90
+ begin
91
+ FileUtils.ln(from, to, force: true)
92
+ return
93
+ rescue Errno::EXDEV, Errno::EACCES
94
+ end
95
+
96
+ # Fall back to old-school copy
97
+ FileUtils.cp(from, to)
98
+ end
83
99
  end
84
100
  end
85
101
  end
@@ -14,6 +14,7 @@ module Nanoc
14
14
  def initialize
15
15
  @counts = {}
16
16
  @root_dir = Dir.mktmpdir('nanoc')
17
+ @mutex = Mutex.new
17
18
  end
18
19
 
19
20
  # @param [String] prefix A string prefix to include in the temporary
@@ -21,8 +22,11 @@ module Nanoc
21
22
  #
22
23
  # @return [String] A new unused filename
23
24
  def create(prefix)
24
- count = @counts.fetch(prefix, 0)
25
- @counts[prefix] = count + 1
25
+ count = nil
26
+ @mutex.synchronize do
27
+ count = @counts.fetch(prefix, 0)
28
+ @counts[prefix] = count + 1
29
+ end
26
30
 
27
31
  dirname = File.join(@root_dir, prefix)
28
32
  filename = File.join(@root_dir, prefix, count.to_s)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Nanoc
4
4
  module Core
5
- VERSION = '4.11.15'
5
+ VERSION = '4.11.20'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,15 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nanoc-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.11.15
4
+ version: 4.11.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - Denis Defreyne
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-07 00:00:00.000000000 Z
11
+ date: 2020-12-18 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: clonefile
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.5.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.5.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: concurrent-ruby
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.1'
13
41
  - !ruby/object:Gem::Dependency
14
42
  name: ddmemoize
15
43
  requirement: !ruby/object:Gem::Requirement
@@ -300,7 +328,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
300
328
  - !ruby/object:Gem::Version
301
329
  version: '0'
302
330
  requirements: []
303
- rubygems_version: 3.1.2
331
+ rubygems_version: 3.2.2
304
332
  signing_key:
305
333
  specification_version: 4
306
334
  summary: Core of Nanoc