Refine proboctl catalog selection flags and listing

Require exactly one selection anchor (--id, --linked-banner,
--linked-org, or --common-third-party) for common-tracker-pattern
reenrich, dropping the catch-all --all; the tracker-type, keyword, and
state flags now narrow the anchor's result except when explicit --id
values are given. Add --linked-banner, --linked-org, and a tri-state
--with-common-third-party to the list command, replacing the separate
--linked/--unlinked booleans, and rename --third-party to
--common-third-party across both commands.

Support these by adding an ID restriction to CommonTrackerPatternFilter
so linked-banner/linked-org selections can be intersected with the
remaining filters in a single query.

Memoize the pg client on the proboctl Factory to avoid a duplicate
Prometheus collector registration panic when more than one command
path builds a client. Surface timestamps in both listing tables and
flag enriched-but-undescribed rows in the displayed enrichment state.

Signed-off-by: Émile Ré <emile@probo.com>
This commit is contained in:
Émile Ré
2026-06-08 17:01:56 +02:00
parent d5427a824b
commit 4eb352a61d
6 changed files with 194 additions and 94 deletions

View File

@@ -33,14 +33,30 @@ type Factory struct {
Version string
PgDSN string
CfgFile string
pgClient *pg.Client
}
// PgClient returns a shared pg client, building it on first use. The client
// is memoized because pg.NewClient registers Prometheus collectors, so
// constructing it more than once panics with a duplicate registration.
func (f *Factory) PgClient() (*pg.Client, error) {
if f.pgClient != nil {
return f.pgClient, nil
}
if f.PgDSN == "" {
return nil, fmt.Errorf("set --pg-dsn or DATABASE_URL")
}
return pgconn.NewPgClientFromDSN(f.PgDSN)
client, err := pgconn.NewPgClientFromDSN(f.PgDSN)
if err != nil {
return nil, err
}
f.pgClient = client
return f.pgClient, nil
}
// ProbodConfig loads the shared probod configuration file (--cfg-file).