action_link 1.1.4 → 1.1.5

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: 18d3d5b1d7406bf12fdcafada8657bee46d7fa72a3d1996e8fbfed8d8d73cf6a
4
- data.tar.gz: 0d0213aa426a0d2186844b5fd74d945271014692a2deac49274fa3c845911f2e
3
+ metadata.gz: f6ca963716e05cd48088b03967fa4a540c4da07a969f5c02b0c5f74737f0b068
4
+ data.tar.gz: cd298d71d690639047a1e5f3a2729eb8b2c8525ca255d0ff74f3498d3918140e
5
5
  SHA512:
6
- metadata.gz: 4dbf16ddb95a21f5b119411198ee802e806f62bdc58475a7e95b2616087f9a294bf4b2798889fbf4ce689c66b7733894580c970b61ace3070d6176ba19af0cae
7
- data.tar.gz: 53f65ac7d41cb5d263455545838eb430a1f6a35e13d1cf1991169faa7e349267a1f0a8e65d650e2008cf66b3ef37bff93c03414f5c86f954e84f210e6e36cbca
6
+ metadata.gz: 8e7bcab9f6b35c35656933abfcef6e1ef1264a68b2de40fc5f3d215cfbb7b14616f5531693ab53b1f0db1ee17e5b4b645168a333b0464f96e90ef65e65893700
7
+ data.tar.gz: fb2a36f1df8d60d66c77c439d9b00f2ead2009c2c94bfa650aafba6a723104208348a4fbcb0895964685a9ff50a806660567bebb06ea7edeeb68b940fe3c3156
data/CHANGELOG.md CHANGED
@@ -1,4 +1,6 @@
1
- ## [Unreleased]
1
+ ## [1.1.5] - 2026-08-04
2
+
3
+ - Make VS Code snippet symlinking atomic so concurrent app boots no longer race into `Errno::EEXIST`
2
4
 
3
5
  ## [1.1.3] - 2026-05-26
4
6
 
@@ -20,8 +20,7 @@ module ActionLink
20
20
  target = vscode_dir.join('action_link.code-snippets')
21
21
  source = Engine.root.join('vscode/action_link.code-snippets')
22
22
 
23
- FileUtils.rm_f(target.to_s)
24
- FileUtils.ln_s(source, target, force: true)
23
+ VscodeSnippets.install(target, source)
25
24
  end
26
25
  end
27
26
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActionLink
4
- VERSION = '1.1.4'
4
+ VERSION = '1.1.5'
5
5
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'tmpdir'
4
+
5
+ module ActionLink
6
+ # Installs the gem's VS Code snippets as a symlink inside the host
7
+ # application's `.vscode` directory.
8
+ #
9
+ # This runs in every process that boots the host application (Spring
10
+ # preloader, Puma workers, rake tasks, ...), so those processes race each
11
+ # other. A non-atomic remove-then-create (`FileUtils.ln_s(force: true)`)
12
+ # lets two processes both pass the "does it exist?" check before either
13
+ # creates the link, so one of them dies with `Errno::EEXIST` on
14
+ # `symlink(2)`.
15
+ #
16
+ # To stay race-free the link is created under a temporary name in the
17
+ # system temp directory and then `rename(2)`-ed over the target, which
18
+ # atomically replaces whatever is already there.
19
+ module VscodeSnippets
20
+ class << self
21
+ def install(target, source)
22
+ target = target.to_s
23
+ source = source.to_s
24
+
25
+ return if already_linked?(target, source)
26
+
27
+ install_atomically(target, source)
28
+ end
29
+
30
+ private
31
+
32
+ def install_atomically(target, source)
33
+ tmp = File.join(Dir.tmpdir, "action_link-#{Process.pid}-#{Thread.current.object_id}.tmp")
34
+ FileUtils.rm_f(tmp)
35
+ File.symlink(source, tmp)
36
+ File.rename(tmp, target)
37
+ rescue Errno::EXDEV
38
+ replace(target, source)
39
+ ensure
40
+ FileUtils.rm_f(tmp) if tmp
41
+ end
42
+
43
+ def already_linked?(target, source)
44
+ File.symlink?(target) && File.readlink(target) == source
45
+ end
46
+
47
+ def replace(target, source)
48
+ FileUtils.rm_f(target)
49
+ File.symlink(source, target)
50
+ end
51
+ end
52
+ end
53
+ end
data/lib/action_link.rb CHANGED
@@ -6,6 +6,7 @@ require 'calls'
6
6
  require 'action_link/version'
7
7
  require 'action_link/model'
8
8
  require 'action_link/title_subject_name'
9
+ require 'action_link/vscode_snippets'
9
10
 
10
11
  require 'action_link/engine' if defined?(Rails::Engine)
11
12
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: action_link
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.4
4
+ version: 1.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - halo
@@ -104,6 +104,7 @@ files:
104
104
  - lib/action_link/model.rb
105
105
  - lib/action_link/title_subject_name.rb
106
106
  - lib/action_link/version.rb
107
+ - lib/action_link/vscode_snippets.rb
107
108
  - vscode/action_link.code-snippets
108
109
  homepage: https://github.com/halo/action_link
109
110
  licenses: