ace-support-items 0.15.5 → 0.15.7

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: ada51daf0c8206e7f3361c173324569468b5cd71c5a78b813fc50f9d570a212a
4
- data.tar.gz: 0ebe5ba5e4a96c1a8d10303dd05b341e1753dca986e099b4d9fc25646484ae03
3
+ metadata.gz: 77ee8986c0addbab15cae8ff084be6f6cd2cb8a106a4dbf730397df84c3f7eb5
4
+ data.tar.gz: bd78280f0691c97a66801600555c78c2de9d7620f82ca8791633444f04b03e9e
5
5
  SHA512:
6
- metadata.gz: e1380dae7a2ba521878f40dcdd5143149fe343ec33f1f20e97538f7a2768008f69b417093ab8b546f5fb795cbcf8f76e98f5f76b10532084d3cb4443fd5e850d
7
- data.tar.gz: a7a416f48468c984b33137255b7ec2a03ef8e8547efdf4d47ef34330d6a6407a645820c9f1cb1f7431cadec901750ba5285b3f526401402ae6c768fa29508685
6
+ metadata.gz: 9edcc8412ea604e65c9ba04c07c06845eb81c2e483bc05842ba0c0e92b82f3cc928df18736925d6a9f20fc39c01e5f9b32f2d876474c7d6da49fb66b279f0d0f
7
+ data.tar.gz: 7f09c644708a5ac6ea9e6bd0186cfa1261db1d742eb1f8df78280c594c0854e72fb2ca1c0a15c31c2161ce0083f4e482377c50b374d80b41d6f22681eb110826
data/CHANGELOG.md CHANGED
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.15.7] - 2026-03-29
11
+
12
+ ### Technical
13
+ - Normalized published gem metadata so RubyGems and Ruby Toolbox use current release information instead of the 1980 fallback date.
14
+
15
+ ## [0.15.6] - 2026-03-29
16
+
17
+ ### Fixed
18
+ - `FieldUpdater`: serialize same-file frontmatter mutations with an exclusive lock across the full read-modify-write cycle so concurrent updates do not silently lose one writer's changes.
19
+
20
+ ### Technical
21
+ - Added a cross-process regression that proves frontmatter updates wait on the file lock and preserve the latest locked-file edits before applying their own mutation.
10
22
 
11
23
  ## [0.15.5] - 2026-03-29
12
24
 
@@ -20,19 +20,24 @@ module Ace
20
20
  # @param remove [Hash] Fields to remove from arrays (key => value or array of values).
21
21
  # @return [Hash] Updated frontmatter hash
22
22
  def self.update(file_path, set: {}, add: {}, remove: {})
23
- content = File.read(file_path)
24
- frontmatter, body = Atoms::FrontmatterParser.parse(content)
25
- # Strip leading newline from body so rebuild doesn't double-space
26
- body = body.sub(/\A\n/, "")
23
+ File.open(file_path, File::RDWR) do |file|
24
+ file.flock(File::LOCK_EX)
27
25
 
28
- apply_set(frontmatter, set)
29
- apply_add(frontmatter, add)
30
- apply_remove(frontmatter, remove)
26
+ file.rewind
27
+ content = file.read
28
+ frontmatter, body = Atoms::FrontmatterParser.parse(content)
29
+ # Strip leading newline from body so rebuild doesn't double-space
30
+ body = body.sub(/\A\n/, "")
31
31
 
32
- new_content = Atoms::FrontmatterSerializer.rebuild(frontmatter, body)
33
- atomic_write(file_path, new_content)
32
+ apply_set(frontmatter, set)
33
+ apply_add(frontmatter, add)
34
+ apply_remove(frontmatter, remove)
34
35
 
35
- frontmatter
36
+ new_content = Atoms::FrontmatterSerializer.rebuild(frontmatter, body)
37
+ rewrite_locked_file(file, new_content)
38
+
39
+ frontmatter
40
+ end
36
41
  end
37
42
 
38
43
  # Apply --set operations (supports nested dot-key paths).
@@ -102,17 +107,18 @@ module Ace
102
107
  target[parts.last] = value
103
108
  end
104
109
 
105
- # Write content atomically using temp file + rename.
106
- def self.atomic_write(file_path, content)
107
- tmp_path = "#{file_path}.tmp.#{Process.pid}"
108
- File.write(tmp_path, content)
109
- File.rename(tmp_path, file_path)
110
- rescue
111
- File.unlink(tmp_path) if tmp_path && File.exist?(tmp_path)
112
- raise
110
+ # Rewrite content in-place on a locked file descriptor.
111
+ # This preserves the lock across the full read-modify-write cycle so
112
+ # concurrent updaters serialize instead of losing one writer's changes.
113
+ def self.rewrite_locked_file(file, content)
114
+ file.rewind
115
+ file.truncate(0)
116
+ file.write(content)
117
+ file.flush
118
+ file.fsync
113
119
  end
114
120
 
115
- private_class_method :apply_nested_set, :atomic_write
121
+ private_class_method :apply_nested_set, :rewrite_locked_file
116
122
  end
117
123
  end
118
124
  end
@@ -3,7 +3,7 @@
3
3
  module Ace
4
4
  module Support
5
5
  module Items
6
- VERSION = '0.15.5'
6
+ VERSION = '0.15.7'
7
7
  end
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ace-support-items
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.5
4
+ version: 0.15.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michal Czyz
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
10
+ date: 2026-03-29 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: ace-support-core