carson 4.0.1 → 4.0.2

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: b65ac7c43c1275299430d71f23f1da3a9896b112aa1f57e334222d06282a3a62
4
- data.tar.gz: ff4efcd085b8cb0deb4385bfdb40d98407d463547b6e065fbfc455f516cc4dbb
3
+ metadata.gz: 8bf071658d6db37302910554b54a528ac3efe7faa22a1cb88b42d13faf0b6b30
4
+ data.tar.gz: 0e30d7ca60c8d8f13438562b003009a64820ff7109ca1c525a127282a5c942c9
5
5
  SHA512:
6
- metadata.gz: b49a0b8760ad230996f6330b378fd7f9a202977c148683c4ae3eec066f2b820f6210e59a0e251ef275471d90db0d8154dee82cc5f97c3e46378cfad1fce074c2
7
- data.tar.gz: 64cc150e7bb257ebbd6d48a603ab7eaa3e3b9794f08fcc65625bb8264628cc99e14f5603fe526d7818253ac57169de995cdc71c413c75cc6a3e2b56dbbb41f2c
6
+ metadata.gz: 0d50b557c6e2a29b78d4f82dfedf2f89c4d6eacc68fb561d5684eb7c40582ba43de5ff84b6929c992fd98b5069e1ee15b17fb434f4512b3ea30f94c97a387ae6
7
+ data.tar.gz: 4cc5c13c062c226ffcfd8627882ecb6c3093169e61dc759d03e2b77110f93323b77bc90761107a8e2a7696b211fe42c603ad0823639c3eb062ff66753410f96b
data/RELEASE.md CHANGED
@@ -11,6 +11,14 @@ Release-note scope rule:
11
11
 
12
12
  - CLI grammar is now two-tier: portfolio commands (`list`, `onboard`, `offboard`, `refresh`, `version`) and repo-scoped commands (`carson <repo> <command>` or `carson <command>` from CWD)
13
13
 
14
+ ## 4.0.2
15
+
16
+ ### Fixed
17
+
18
+ - **Seal marker moved outside worktree** — `.carson-delivering` marker now lives at `~/.carson/seals/` instead of inside the worktree. The in-worktree marker polluted `git status`, showed as untracked in editors, and blocked `carson deliver` via the dirty-tree guard. Seal file includes the worktree path for debugging.
19
+ - **`receive_latest_standard!` works from worktrees** (#451) — `git fetch origin main:main` failed when `main` was checked out in the main worktree ("fatal: refusing to fetch into branch checked out"). Now uses `merge --ff-only` when main is checked out, fetch refspec otherwise.
20
+ - **Audit seal check delegates to Warehouse** — `carson audit` no longer hardcodes the marker path; it creates a Warehouse and asks `sealed?`. Single source of truth for seal location.
21
+
14
22
  ## 4.0.1
15
23
 
16
24
  ### What changed
data/VERSION CHANGED
@@ -1 +1 @@
1
- 4.0.1
1
+ 4.0.2
@@ -185,11 +185,12 @@ module Carson
185
185
 
186
186
  # Check if the workbench is sealed (parcel in flight).
187
187
  # Returns EXIT_BLOCK if sealed, nil otherwise.
188
+ # Delegates to Warehouse so the seal path is resolved in one place.
188
189
  def audit_sealed_workbench( json_output: )
189
- marker_path = File.join( work_dir, ".carson-delivering" )
190
- return nil unless File.exist?( marker_path )
190
+ warehouse = Warehouse.new( path: work_dir )
191
+ return nil unless warehouse.sealed?
191
192
 
192
- tracking_number = File.read( marker_path ).strip rescue "unknown"
193
+ tracking_number = warehouse.sealed_tracking_number || "unknown"
193
194
  if json_output
194
195
  require "json"
195
196
  output.puts JSON.pretty_generate( {
@@ -2,6 +2,8 @@
2
2
  # parcels (committed changes) are stored on shelves (worktrees) with
3
3
  # labels (branches). Git commands are hidden inside — callers never
4
4
  # see git terms.
5
+ require "digest"
6
+ require "fileutils"
5
7
  require "open3"
6
8
 
7
9
  module Carson
@@ -107,8 +109,12 @@ module Carson
107
109
 
108
110
  # Seal the shelf — no more packing until the delivery outcome is confirmed.
109
111
  # The courier seals the shelf after shipping and filing the waybill.
112
+ # The marker lives outside the worktree (~/.carson/seals/) so it does
113
+ # not pollute git status or block delivery with a dirty-tree guard.
110
114
  def seal_shelf!( tracking_number: )
111
- File.write( delivering_marker_path, tracking_number.to_s )
115
+ marker = delivering_marker_path
116
+ FileUtils.mkdir_p( File.dirname( marker ) )
117
+ File.write( marker, "#{tracking_number}\n#{@path}" )
112
118
  end
113
119
 
114
120
  # Unseal the shelf — the courier brought back the parcel.
@@ -125,18 +131,43 @@ module Carson
125
131
  # The tracking number of the in-flight delivery (nil if not sealed).
126
132
  def sealed_tracking_number
127
133
  return nil unless sealed?
128
- File.read( delivering_marker_path ).strip
134
+ File.read( delivering_marker_path ).lines.first.strip
129
135
  end
130
136
 
131
137
  # Receive the latest standard from the registry after a parcel is accepted.
132
138
  # Fast-forwards local main without switching branches.
133
139
  # Returns true on success, false on failure.
140
+ #
141
+ # Two paths depending on the main worktree's checkout state:
142
+ # - Main checked out → merge --ff-only (updates ref + working tree).
143
+ # - Main not checked out → fetch refspec (updates ref only, safe when
144
+ # no worktree has the branch).
134
145
  def receive_latest_standard!( remote: bureau_address )
135
- _, _, status = Open3.capture3(
136
- "git", "-C", main_worktree_root,
137
- "fetch", remote, "#{main_label}:#{main_label}"
146
+ root = main_worktree_root
147
+
148
+ # Fetch remote tracking refs — always safe, even when main is checked out.
149
+ _, _, fetch_status = Open3.capture3( "git", "-C", root, "fetch", remote )
150
+ return false unless fetch_status.success?
151
+
152
+ # Determine how to advance local main.
153
+ head_ref, _, head_status = Open3.capture3(
154
+ "git", "-C", root, "rev-parse", "--abbrev-ref", "HEAD"
138
155
  )
139
- status.success?
156
+ return false unless head_status.success?
157
+
158
+ if head_ref.strip == @main_label
159
+ # Main is checked out in the main worktree — fast-forward via merge.
160
+ _, _, merge_status = Open3.capture3(
161
+ "git", "-C", root, "merge", "--ff-only", "#{remote}/#{@main_label}"
162
+ )
163
+ merge_status.success?
164
+ else
165
+ # Main is not checked out — safe to update the ref via fetch refspec.
166
+ _, _, refspec_status = Open3.capture3(
167
+ "git", "-C", root, "fetch", remote, "#{@main_label}:#{@main_label}"
168
+ )
169
+ refspec_status.success?
170
+ end
140
171
  end
141
172
 
142
173
  # --- Inventory ---
@@ -173,8 +204,12 @@ module Carson
173
204
  private
174
205
 
175
206
  # Path to the delivery marker file — signals the shelf is sealed.
207
+ # Lives outside the worktree at ~/.carson/seals/<sha256-of-path>
208
+ # so it does not pollute git status.
176
209
  def delivering_marker_path
177
- File.join( path, ".carson-delivering" )
210
+ seals_dir = File.join( Dir.home, ".carson", "seals" )
211
+ key = Digest::SHA256.hexdigest( @path )
212
+ File.join( seals_dir, key )
178
213
  end
179
214
 
180
215
  # All git commands go through this single gateway.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: carson
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.1
4
+ version: 4.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hailei Wang