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 +4 -4
- data/CHANGELOG.md +8 -0
- data/lib/swhid/from_git.rb +91 -7
- data/lib/swhid/objects/release.rb +10 -0
- data/lib/swhid/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ab5130c9128fd1942d8a4a01eecb6d5f403f38fc2ce53d72323b08350e30bdf4
|
|
4
|
+
data.tar.gz: a7c5c116fcd54c08f7d51b4125d4871f25b98aacc4f7ab818ebae670fc0972c9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
data/lib/swhid/from_git.rb
CHANGED
|
@@ -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 (
|
|
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
|
|
131
|
-
|
|
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