From 8a9ceca33d6d57581b5185878404ef1efdd04dd6 Mon Sep 17 00:00:00 2001 From: Seongmin Lee Date: Sun, 19 Oct 2025 22:38:47 +0900 Subject: [PATCH] appview: make default label defs configurable Change-Id: touzvprzqrrqkoolvsypxyrmossqmxxu hard-coded labels make hard to setup local sandboxed environment as the appview won't run until we fill all 5 definitions under TangledDid. so make them configurable with `TANGLED_LABEL_DEFAULTS` which is a list of aturis delimitted by , character we can have any number/kind of default labels but gfi is required for `/good-first-issue` page Signed-off-by: Seongmin Lee --- appview/config/config.go | 11 +++++++ appview/models/label.go | 68 +++++++++++++++------------------------- appview/repo/repo.go | 4 +-- appview/state/gfi.go | 4 +-- appview/state/state.go | 11 +++---- 5 files changed, 44 insertions(+), 54 deletions(-) diff --git a/appview/config/config.go b/appview/config/config.go index b2d21fb0..2e030b11 100644 --- a/appview/config/config.go +++ b/appview/config/config.go @@ -78,6 +78,11 @@ type Cloudflare struct { TurnstileSecretKey string `env:"TURNSTILE_SECRET_KEY"` } +type LabelConfig struct { + DefaultLabelDefs []string `env:"DEFAULTS"` // delimiter=, + GoodFirstIssue string `env:"GFI, default=at://did:plc:wshs7t2adsemcrrd4snkeqli/sh.tangled.label.definition/good-first-issue"` +} + func (cfg RedisConfig) ToURL() string { u := &url.URL{ Scheme: "redis", @@ -105,6 +110,7 @@ type Config struct { Redis RedisConfig `env:",prefix=TANGLED_REDIS_"` Pds PdsConfig `env:",prefix=TANGLED_PDS_"` Cloudflare Cloudflare `env:",prefix=TANGLED_CLOUDFLARE_"` + Label LabelConfig `env:",prefix=TANGLED_LABEL_"` } func LoadConfig(ctx context.Context) (*Config, error) { @@ -114,5 +120,10 @@ func LoadConfig(ctx context.Context) (*Config, error) { return nil, err } + fmt.Println("default labels:") + for _, l := range cfg.Label.DefaultLabelDefs { + fmt.Println(l) + } + return &cfg, nil } diff --git a/appview/models/label.go b/appview/models/label.go index a8d9e8f1..fb79b8ae 100644 --- a/appview/models/label.go +++ b/appview/models/label.go @@ -14,7 +14,6 @@ import ( "github.com/bluesky-social/indigo/atproto/syntax" "github.com/bluesky-social/indigo/xrpc" "tangled.org/core/api/tangled" - "tangled.org/core/consts" "tangled.org/core/idresolver" ) @@ -461,52 +460,35 @@ func ReduceLabelOps(ops []LabelOp) []LabelOp { return result } -var ( - LabelWontfix = fmt.Sprintf("at://%s/%s/%s", consts.TangledDid, tangled.LabelDefinitionNSID, "wontfix") - LabelDuplicate = fmt.Sprintf("at://%s/%s/%s", consts.TangledDid, tangled.LabelDefinitionNSID, "duplicate") - LabelAssignee = fmt.Sprintf("at://%s/%s/%s", consts.TangledDid, tangled.LabelDefinitionNSID, "assignee") - LabelGoodFirstIssue = fmt.Sprintf("at://%s/%s/%s", consts.TangledDid, tangled.LabelDefinitionNSID, "good-first-issue") - LabelDocumentation = fmt.Sprintf("at://%s/%s/%s", consts.TangledDid, tangled.LabelDefinitionNSID, "documentation") -) - -func DefaultLabelDefs() []string { - return []string{ - LabelWontfix, - LabelDuplicate, - LabelAssignee, - LabelGoodFirstIssue, - LabelDocumentation, - } -} - -func FetchDefaultDefs(r *idresolver.Resolver) ([]LabelDefinition, error) { - resolved, err := r.ResolveIdent(context.Background(), consts.TangledDid) - if err != nil { - return nil, fmt.Errorf("failed to resolve tangled.sh DID %s: %v", consts.TangledDid, err) - } - pdsEndpoint := resolved.PDSEndpoint() - if pdsEndpoint == "" { - return nil, fmt.Errorf("no PDS endpoint found for tangled.sh DID %s", consts.TangledDid) - } - client := &xrpc.Client{ - Host: pdsEndpoint, - } - +func FetchLabelDefs(r *idresolver.Resolver, aturis []string) ([]LabelDefinition, error) { var labelDefs []LabelDefinition + ctx := context.Background() - for _, dl := range DefaultLabelDefs() { - atUri := syntax.ATURI(dl) - parsedUri, err := syntax.ParseATURI(string(atUri)) + for _, dl := range aturis { + atUri, err := syntax.ParseATURI(dl) if err != nil { - return nil, fmt.Errorf("failed to parse AT-URI %s: %v", atUri, err) + return nil, fmt.Errorf("failed to parse AT-URI %s: %v", dl, err) + } + if atUri.Collection() != tangled.LabelDefinitionNSID { + return nil, fmt.Errorf("expected AT-URI pointing %s collection: %s", tangled.LabelDefinitionNSID, atUri) } + + owner, err := r.ResolveIdent(ctx, atUri.Authority().String()) + if err != nil { + return nil, fmt.Errorf("failed to resolve default label owner DID %s: %v", atUri.Authority(), err) + } + + xrpcc := xrpc.Client{ + Host: owner.PDSEndpoint(), + } + record, err := atproto.RepoGetRecord( - context.Background(), - client, + ctx, + &xrpcc, "", - parsedUri.Collection().String(), - parsedUri.Authority().String(), - parsedUri.RecordKey().String(), + atUri.Collection().String(), + atUri.Authority().String(), + atUri.RecordKey().String(), ) if err != nil { return nil, fmt.Errorf("failed to get record for %s: %v", atUri, err) @@ -526,8 +508,8 @@ func FetchDefaultDefs(r *idresolver.Resolver) ([]LabelDefinition, error) { } labelDef, err := LabelDefinitionFromRecord( - parsedUri.Authority().String(), - parsedUri.RecordKey().String(), + atUri.Authority().String(), + atUri.RecordKey().String(), labelRecord, ) if err != nil { diff --git a/appview/repo/repo.go b/appview/repo/repo.go index 14b38700..771e46da 100644 --- a/appview/repo/repo.go +++ b/appview/repo/repo.go @@ -1974,7 +1974,7 @@ func (rp *Repo) generalSettings(w http.ResponseWriter, r *http.Request) { return } - defaultLabels, err := db.GetLabelDefinitions(rp.db, db.FilterIn("at_uri", models.DefaultLabelDefs())) + defaultLabels, err := db.GetLabelDefinitions(rp.db, db.FilterIn("at_uri", rp.config.Label.DefaultLabelDefs)) if err != nil { l.Error("failed to fetch labels", "err", err) rp.pages.Error503(w) @@ -2253,7 +2253,7 @@ func (rp *Repo) ForkRepo(w http.ResponseWriter, r *http.Request) { Source: sourceAt, Description: f.Repo.Description, Created: time.Now(), - Labels: models.DefaultLabelDefs(), + Labels: rp.config.Label.DefaultLabelDefs, } record := repo.AsRecord() diff --git a/appview/state/gfi.go b/appview/state/gfi.go index 10de69cc..8b55df24 100644 --- a/appview/state/gfi.go +++ b/appview/state/gfi.go @@ -1,13 +1,11 @@ package state import ( - "fmt" "log" "net/http" "sort" "github.com/bluesky-social/indigo/atproto/syntax" - "tangled.org/core/api/tangled" "tangled.org/core/appview/db" "tangled.org/core/appview/models" "tangled.org/core/appview/pages" @@ -23,7 +21,7 @@ func (s *State) GoodFirstIssues(w http.ResponseWriter, r *http.Request) { page = pagination.FirstPage() } - goodFirstIssueLabel := fmt.Sprintf("at://%s/%s/%s", consts.TangledDid, tangled.LabelDefinitionNSID, "good-first-issue") + goodFirstIssueLabel := s.config.Label.GoodFirstIssue gfiLabelDef, err := db.GetLabelDefinition(s.db, db.FilterEq("at_uri", goodFirstIssueLabel)) if err != nil { diff --git a/appview/state/state.go b/appview/state/state.go index 78c4fbbd..d0c2834c 100644 --- a/appview/state/state.go +++ b/appview/state/state.go @@ -121,7 +121,7 @@ func Make(ctx context.Context, config *config.Config) (*State, error) { return nil, fmt.Errorf("failed to create jetstream client: %w", err) } - if err := BackfillDefaultDefs(d, res); err != nil { + if err := BackfillDefaultDefs(d, res, config.Label.DefaultLabelDefs); err != nil { return nil, fmt.Errorf("failed to backfill default label defs: %w", err) } @@ -284,7 +284,7 @@ func (s *State) Timeline(w http.ResponseWriter, r *http.Request) { return } - gfiLabel, err := db.GetLabelDefinition(s.db, db.FilterEq("at_uri", models.LabelGoodFirstIssue)) + gfiLabel, err := db.GetLabelDefinition(s.db, db.FilterEq("at_uri", s.config.Label.GoodFirstIssue)) if err != nil { // non-fatal } @@ -506,7 +506,7 @@ func (s *State) NewRepo(w http.ResponseWriter, r *http.Request) { Rkey: rkey, Description: description, Created: time.Now(), - Labels: models.DefaultLabelDefs(), + Labels: s.config.Label.DefaultLabelDefs, } record := repo.AsRecord() @@ -648,8 +648,7 @@ func rollbackRecord(ctx context.Context, aturi string, client *atpclient.APIClie return err } -func BackfillDefaultDefs(e db.Execer, r *idresolver.Resolver) error { - defaults := models.DefaultLabelDefs() +func BackfillDefaultDefs(e db.Execer, r *idresolver.Resolver, defaults []string) error { defaultLabels, err := db.GetLabelDefinitions(e, db.FilterIn("at_uri", defaults)) if err != nil { return err @@ -659,7 +658,7 @@ func BackfillDefaultDefs(e db.Execer, r *idresolver.Resolver) error { return nil } - labelDefs, err := models.FetchDefaultDefs(r) + labelDefs, err := models.FetchLabelDefs(r, defaults) if err != nil { return err } -- 2.43.0