This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / appview / pulls / pulls.go
3.3 kB 122 lines
1package pulls 2 3import ( 4 "bytes" 5 "compress/gzip" 6 "fmt" 7 "io" 8 "log/slog" 9 "strings" 10 "time" 11 12 "tangled.org/core/api/tangled" 13 "tangled.org/core/appview/config" 14 "tangled.org/core/appview/db" 15 pulls_indexer "tangled.org/core/appview/indexer/pulls" 16 "tangled.org/core/appview/knotacl" 17 "tangled.org/core/appview/mentions" 18 "tangled.org/core/appview/models" 19 "tangled.org/core/appview/notify" 20 "tangled.org/core/appview/oauth" 21 "tangled.org/core/appview/pages" 22 "tangled.org/core/appview/reporesolver" 23 "tangled.org/core/idresolver" 24 "tangled.org/core/ogre" 25 "tangled.org/core/patchutil" 26 "tangled.org/core/types" 27 28 indigoxrpc "github.com/bluesky-social/indigo/xrpc" 29 "github.com/hashicorp/golang-lru/v2/expirable" 30) 31 32const ApplicationGzip = "application/gzip" 33 34const ( 35 diffCacheSize = 128 36 diffCacheTTL = 15 * time.Minute 37) 38 39type Pulls struct { 40 oauth *oauth.OAuth 41 repoResolver *reporesolver.RepoResolver 42 pages *pages.Pages 43 idResolver *idresolver.Resolver 44 mentionsResolver *mentions.Resolver 45 db *db.DB 46 config *config.Config 47 notifier notify.Notifier 48 acl *knotacl.Service 49 logger *slog.Logger 50 indexer *pulls_indexer.Indexer 51 ogreClient *ogre.Client 52 diffCache *expirable.LRU[string, types.DiffRenderer] 53 workflowDescCache *expirable.LRU[string, *tangled.CiDescribeWorkflowDefinition_Output] 54 mergeBaseCache *expirable.LRU[string, string] 55} 56 57func New( 58 oauth *oauth.OAuth, 59 repoResolver *reporesolver.RepoResolver, 60 pages *pages.Pages, 61 resolver *idresolver.Resolver, 62 mentionsResolver *mentions.Resolver, 63 db *db.DB, 64 config *config.Config, 65 notifier notify.Notifier, 66 acl *knotacl.Service, 67 indexer *pulls_indexer.Indexer, 68 logger *slog.Logger, 69) *Pulls { 70 return &Pulls{ 71 oauth: oauth, 72 repoResolver: repoResolver, 73 pages: pages, 74 idResolver: resolver, 75 mentionsResolver: mentionsResolver, 76 db: db, 77 config: config, 78 notifier: notifier, 79 acl: acl, 80 logger: logger, 81 indexer: indexer, 82 ogreClient: ogre.NewClient(config.Ogre.Host), 83 diffCache: expirable.NewLRU[string, types.DiffRenderer](diffCacheSize, nil, diffCacheTTL), 84 workflowDescCache: expirable.NewLRU[string, *tangled.CiDescribeWorkflowDefinition_Output](workflowCacheSize, nil, workflowCacheTTL), 85 mergeBaseCache: expirable.NewLRU[string, string](workflowCacheSize, nil, workflowCacheTTL), 86 } 87} 88 89func (s *Pulls) knotClient(host string) *indigoxrpc.Client { 90 scheme := "https" 91 if s.config.Core.Dev { 92 scheme = "http" 93 } 94 return &indigoxrpc.Client{Host: fmt.Sprintf("%s://%s", scheme, host)} 95} 96 97func gz(s string) io.Reader { 98 var b bytes.Buffer 99 w := gzip.NewWriter(&b) 100 w.Write([]byte(s)) 101 w.Close() 102 return &b 103} 104 105func ptrPullState(s models.PullState) *models.PullState { return &s } 106 107func validatePatch(patch *string) error { 108 if patch == nil || *patch == "" { 109 return fmt.Errorf("patch is empty") 110 } 111 112 // add newline if not present to diff style patches 113 if !patchutil.IsFormatPatch(*patch) && !strings.HasSuffix(*patch, "\n") { 114 *patch = *patch + "\n" 115 } 116 117 if err := patchutil.IsPatchValid(*patch); err != nil { 118 return err 119 } 120 121 return nil 122}