Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions internal/difc/format_functions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,3 +177,58 @@ func TestFormatSecrecyLevel(t *testing.T) {
})
}
}

// TestSplitTagScope tests the shared tag/scope splitting helper.
func TestSplitTagScope(t *testing.T) {
tests := []struct {
name string
tag Tag
wantBase string
wantScope string
}{
{
name: "tag without scope",
tag: "public",
wantBase: "public",
wantScope: "",
},
{
name: "tag with scope",
tag: "approved:all",
wantBase: "approved",
wantScope: "all",
},
{
name: "scope containing colons is preserved",
tag: "private:org/repo:extra",
wantBase: "private",
wantScope: "org/repo:extra",
},
{
name: "empty scope suffix",
tag: "private:",
wantBase: "private",
wantScope: "",
},
{
name: "leading colon is not split",
tag: ":all",
wantBase: ":all",
wantScope: "",
},
{
name: "empty tag",
tag: "",
wantBase: "",
wantScope: "",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
base, scope := splitTagScope(tt.tag)
assert.Equal(t, tt.wantBase, base)
assert.Equal(t, tt.wantScope, scope)
})
}
}
30 changes: 20 additions & 10 deletions internal/difc/violations.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,17 @@ func FormatViolationError(result *EvaluationResult, agentSecrecy *SecrecyLabel,
return errors.New(msg.String())
}

// splitTagScope splits a tag into its base level and optional scope suffix
// (e.g., "approved:all" → ("approved", "all"), "public" → ("public", "")).
// A tag whose only colon is at the start (e.g., ":all") is returned unsplit.
func splitTagScope(tag Tag) (base, scope string) {
s := string(tag)
if idx := strings.Index(s, ":"); idx > 0 {
return s[:idx], s[idx+1:]
}
return s, ""
}

// formatIntegrityLevel converts a list of integrity tags into a human-readable
// integrity level description (e.g., `"approved"` instead of "[unapproved:all approved:all]").
func formatIntegrityLevel(tags []Tag) string {
Expand All @@ -129,11 +140,7 @@ func formatIntegrityLevel(tags []Tag) string {
// Find the highest integrity level mentioned in the tags
highest := ""
for _, tag := range tags {
s := string(tag)
// Strip scope suffix (e.g., "approved:all" → "approved")
if idx := strings.Index(s, ":"); idx > 0 {
s = s[:idx]
}
s, _ := splitTagScope(tag)
switch s {
case "merged":
logViolations.Printf("formatIntegrityLevel: resolved to \"merged\" from tags=%v", tags)
Expand Down Expand Up @@ -164,15 +171,18 @@ func formatSecrecyLevel(tags []Tag) string {
hasPrivate := false

for _, tag := range tags {
s := string(tag)
if strings.HasPrefix(s, "private:") {
scope := strings.TrimPrefix(s, "private:")
if scope != "" && len(scope) > len(bestScope) {
base, scope := splitTagScope(tag)
if base != "private" {
continue
}
if scope != "" {
if len(scope) > len(bestScope) {
bestScope = scope
}
continue
}
if s == "private" {
// No scope suffix at all (as opposed to an empty "private:" scope)
if string(tag) == "private" {
hasPrivate = true
}
}
Expand Down
Loading