swhid 0.3.0 → 0.3.1

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: 17e5d6a13e7f6d44bed90224e6ff6b1418bd9501b7bd14c1ef00d5d7adbbeb3c
4
- data.tar.gz: 712d0c4136e0ac2c5d11b38b73cbf77d75bbf87b188fc998a3f716e4f9e8ff98
3
+ metadata.gz: ab5130c9128fd1942d8a4a01eecb6d5f403f38fc2ce53d72323b08350e30bdf4
4
+ data.tar.gz: a7c5c116fcd54c08f7d51b4125d4871f25b98aacc4f7ab818ebae670fc0972c9
5
5
  SHA512:
6
- metadata.gz: 7fa9985d872d26ade840cdb509319fe27795dbd7bbac18b9a4141eb291dcee55cdeb5be31ad94a2fd557b2d676124016c955303bee9a7b4dac1ff698fc22ddc9
7
- data.tar.gz: e99b1253233fd0862a7b57da14ca6367036e5cb50b4d153ffe154165be2635bf8f7579a5a8d3ae10757972dfc511d591c9485bf66cca001db8336b5dc08d4349
6
+ metadata.gz: ad64d5ffad60fde8ec7399abcd63af7c34ae203c54f469df9866283864f1850c0f9b1c112ab89300c7ea52f56d5809189bbe6ec0bd2c9fc2ed85510daa3b2d37
7
+ data.tar.gz: a44ef79ecd7a5d64f4d29c56f470b749ab61eac0d3f3ddd29c8b4798f334fa3f43222b8b463819f221e5687ca1355f7c23b7754be43a739009aafa4adba3e3cd
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.3.1] - 2025-11-23
4
+
5
+ ### Fixed
6
+ - Snapshot implementation now includes HEAD symbolic reference
7
+ - Extra headers extraction for signed commits (gpgsig, mergetag, etc.)
8
+ - Tag-of-tag support (tags pointing to other tag objects)
9
+ - Extra headers extraction for signed tags
10
+
3
11
  ## [0.3.0] - 2025-11-23
4
12
 
5
13
  - `directory` CLI command - Generate SWHID for directory from filesystem
@@ -22,8 +22,8 @@ module Swhid
22
22
  message: commit.message
23
23
  }
24
24
 
25
- # Extract extra headers if present
26
- extra_headers = extract_extra_headers(commit)
25
+ # Extract extra headers if present (like gpgsig, svn headers, etc)
26
+ extra_headers = extract_extra_headers(repo, commit)
27
27
  metadata[:extra_headers] = extra_headers unless extra_headers.empty?
28
28
 
29
29
  Swhid.from_revision(metadata)
@@ -42,6 +42,7 @@ module Swhid
42
42
  if tag_obj.is_a?(Rugged::Tag::Annotation)
43
43
  target_type = case tag_obj.target
44
44
  when Rugged::Commit then "rev"
45
+ when Rugged::Tag::Annotation then "rel"
45
46
  when Rugged::Tree then "dir"
46
47
  when Rugged::Blob then "cnt"
47
48
  else "rev"
@@ -59,6 +60,10 @@ module Swhid
59
60
  metadata[:author_timezone] = format_timezone(tag_obj.tagger[:time])
60
61
  end
61
62
 
63
+ # Extract extra headers if present (like gpgsig for signed tags)
64
+ extra_headers = extract_tag_extra_headers(repo, tag_obj)
65
+ metadata[:extra_headers] = extra_headers unless extra_headers.empty?
66
+
62
67
  Swhid.from_release(metadata)
63
68
  else
64
69
  # Lightweight tag - points directly to commit
@@ -70,12 +75,27 @@ module Swhid
70
75
  repo = Rugged::Repository.new(repo_path)
71
76
  branches = []
72
77
 
78
+ # Check for HEAD first
79
+ head_path = File.join(repo.path, "HEAD")
80
+ if File.exist?(head_path)
81
+ head_content = File.read(head_path).strip
82
+ if head_content.start_with?("ref:")
83
+ # HEAD is a symbolic ref
84
+ target_ref = head_content.sub("ref: ", "")
85
+ branches << {
86
+ name: "HEAD",
87
+ target_type: "alias",
88
+ target: target_ref
89
+ }
90
+ end
91
+ end
92
+
73
93
  # Get all references (branches and tags)
74
94
  repo.references.each do |ref|
75
95
  ref_name = ref.name
76
96
 
77
97
  if ref.type == :symbolic
78
- # This is an alias (like HEAD pointing to refs/heads/main)
98
+ # This is an alias (symbolic ref)
79
99
  target_ref_name = ref.target
80
100
  branches << {
81
101
  name: ref_name,
@@ -125,11 +145,75 @@ module Swhid
125
145
  format("%s%02d%02d", sign, hours, minutes)
126
146
  end
127
147
 
128
- def self.extract_extra_headers(commit)
148
+ def self.extract_extra_headers(repo, commit)
129
149
  # Rugged doesn't expose extra headers directly
130
- # We would need to parse the raw commit object for this
131
- # For now, return empty array
132
- []
150
+ # We need to parse the raw commit object
151
+ raw_data = repo.read(commit.oid).data
152
+ lines = raw_data.split("\n")
153
+
154
+ extra_headers = []
155
+ in_headers = true
156
+
157
+ lines.each do |line|
158
+ # Stop when we hit the blank line before the message
159
+ if line.empty?
160
+ in_headers = false
161
+ next
162
+ end
163
+
164
+ next unless in_headers
165
+
166
+ # Skip standard headers
167
+ next if line.start_with?("tree ", "parent ", "author ", "committer ")
168
+
169
+ # Extract extra headers (like gpgsig, mergetag, svn-repo-uuid, etc)
170
+ if line.start_with?(" ")
171
+ # Continuation of previous header
172
+ if extra_headers.any?
173
+ extra_headers.last[1] += "\n#{line[1..]}"
174
+ end
175
+ elsif line.include?(" ")
176
+ key, value = line.split(" ", 2)
177
+ extra_headers << [key, value]
178
+ end
179
+ end
180
+
181
+ extra_headers
182
+ end
183
+
184
+ def self.extract_tag_extra_headers(repo, tag)
185
+ # Parse raw tag object for extra headers
186
+ raw_data = repo.read(tag.oid).data
187
+ lines = raw_data.split("\n")
188
+
189
+ extra_headers = []
190
+ in_headers = true
191
+
192
+ lines.each do |line|
193
+ # Stop when we hit the blank line before the message
194
+ if line.empty?
195
+ in_headers = false
196
+ next
197
+ end
198
+
199
+ next unless in_headers
200
+
201
+ # Skip standard tag headers
202
+ next if line.start_with?("object ", "type ", "tag ", "tagger ")
203
+
204
+ # Extract extra headers (like gpgsig for signed tags)
205
+ if line.start_with?(" ")
206
+ # Continuation of previous header
207
+ if extra_headers.any?
208
+ extra_headers.last[1] += "\n#{line[1..]}"
209
+ end
210
+ elsif line.include?(" ")
211
+ key, value = line.split(" ", 2)
212
+ extra_headers << [key, value]
213
+ end
214
+ end
215
+
216
+ extra_headers
133
217
  end
134
218
  end
135
219
  end
@@ -39,6 +39,11 @@ module Swhid
39
39
  lines << author_line
40
40
  end
41
41
 
42
+ extra_headers = metadata[:extra_headers] || []
43
+ extra_headers.each do |key, value|
44
+ lines << format_header_line(key, value)
45
+ end
46
+
42
47
  result = lines.join("\n") + "\n"
43
48
 
44
49
  if metadata[:message]
@@ -54,6 +59,11 @@ module Swhid
54
59
  "#{prefix} #{person_escaped} #{timestamp} #{tz}"
55
60
  end
56
61
 
62
+ def self.format_header_line(key, value)
63
+ value_escaped = value.gsub("\n", "\n ")
64
+ "#{key} #{value_escaped}"
65
+ end
66
+
57
67
  def self.extract_target(target)
58
68
  case target
59
69
  when Hash
data/lib/swhid/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Swhid
4
- VERSION = "0.3.0"
4
+ VERSION = "0.3.1"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: swhid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Nesbitt