This repository has no description
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}