this repo has no description
1package repoinfo 2 3import ( 4 "encoding/json" 5 "fmt" 6 "path" 7 "slices" 8 9 "github.com/bluesky-social/indigo/atproto/syntax" 10 "tangled.org/core/api/tangled" 11 "tangled.org/core/appview/models" 12 "tangled.org/core/appview/state/userutil" 13) 14 15func (r RepoInfo) owner() string { 16 if r.OwnerHandle != "" { 17 return r.OwnerHandle 18 } else { 19 return r.OwnerDid 20 } 21} 22 23func (r RepoInfo) FullName() string { 24 return path.Join(r.owner(), r.Name) 25} 26 27func (r RepoInfo) ownerWithoutAt() string { 28 if r.OwnerHandle != "" { 29 return r.OwnerHandle 30 } else { 31 return userutil.FlattenDid(r.OwnerDid) 32 } 33} 34 35func (r RepoInfo) FullNameWithoutAt() string { 36 return path.Join(r.ownerWithoutAt(), r.Name) 37} 38 39func (r RepoInfo) GetTabs() [][]string { 40 tabs := [][]string{ 41 {"overview", "/", "square-chart-gantt"}, 42 {"issues", "/issues", "circle-dot"}, 43 {"pulls", "/pulls", "git-pull-request"}, 44 {"pipelines", "/pipelines", "layers-2"}, 45 } 46 47 if r.Roles.SettingsAllowed() { 48 tabs = append(tabs, []string{"settings", "/settings", "cog"}) 49 } 50 51 return tabs 52} 53 54func (r RepoInfo) RepoAt() syntax.ATURI { 55 return syntax.ATURI(fmt.Sprintf("at://%s/%s/%s", r.OwnerDid, tangled.RepoNSID, r.Rkey)) 56} 57 58type RepoInfo struct { 59 Name string 60 Rkey string 61 OwnerDid string 62 OwnerHandle string 63 Description string 64 Website string 65 Topics []string 66 Knot string 67 Spindle string 68 IsStarred bool 69 Stats models.RepoStats 70 Roles RolesInRepo 71 Source *models.Repo 72 Ref string 73 CurrentDir string 74} 75 76// each tab on a repo could have some metadata: 77// 78// issues -> number of open issues etc. 79// settings -> a warning icon to setup branch protection? idk 80// 81// we gather these bits of info here, because go templates 82// are difficult to program in 83func (r RepoInfo) TabMetadata() map[string]any { 84 meta := make(map[string]any) 85 86 meta["pulls"] = r.Stats.PullCount.Open 87 meta["issues"] = r.Stats.IssueCount.Open 88 89 // more stuff? 90 91 return meta 92} 93 94type RolesInRepo struct { 95 Roles []string 96} 97 98func (r RolesInRepo) SettingsAllowed() bool { 99 return slices.Contains(r.Roles, "repo:settings") 100} 101 102func (r RolesInRepo) CollaboratorInviteAllowed() bool { 103 return slices.Contains(r.Roles, "repo:invite") 104} 105 106func (r RolesInRepo) RepoDeleteAllowed() bool { 107 return slices.Contains(r.Roles, "repo:delete") 108} 109 110func (r RolesInRepo) IsOwner() bool { 111 return slices.Contains(r.Roles, "repo:owner") 112} 113 114func (r RolesInRepo) IsCollaborator() bool { 115 return slices.Contains(r.Roles, "repo:collaborator") 116} 117 118func (r RolesInRepo) IsPushAllowed() bool { 119 return slices.Contains(r.Roles, "repo:push") 120} 121 122// PrimaryLanguage returns the first (most used) language from a list, or empty string if none 123func PrimaryLanguage(languages []interface{}) string { 124 if len(languages) == 0 { 125 return "" 126 } 127 128 // Languages are already sorted by percentage in descending order 129 // Just get the first one 130 if firstLang, ok := languages[0].(map[string]interface{}); ok { 131 if name, ok := firstLang["Name"].(string); ok { 132 return name 133 } 134 } 135 136 return "" 137} 138 139// StructuredData generates Schema.org JSON-LD structured data for the repository 140func (r RepoInfo) StructuredData(primaryLanguage string) string { 141 data := map[string]interface{}{ 142 "@context": "https://schema.org", 143 "@type": "SoftwareSourceCode", 144 "name": r.Name, 145 "description": r.Description, 146 "codeRepository": "https://tangled.org/" + r.FullName(), 147 "url": "https://tangled.org/" + r.FullName(), 148 "author": map[string]interface{}{ 149 "@type": "Person", 150 "name": r.owner(), 151 "url": "https://tangled.org/" + r.owner(), 152 }, 153 } 154 155 // Add programming language if available 156 if primaryLanguage != "" { 157 data["programmingLanguage"] = primaryLanguage 158 } 159 160 jsonBytes, err := json.Marshal(data) 161 if err != nil { 162 return "{}" 163 } 164 return string(jsonBytes) 165}