v2.31.0-dev22 8d342c4

detector.go RawHistoryFolder

1package backup
2
3import (
4	"slices"
5	"strings"
6
7	"github.com/bnema/gordon/internal/domain"
8)
9
10// postgresAliases contains substrings that identify a PostgreSQL image or service.
11var postgresAliases = []string{"postgres", "postgresql", "pgsql", "postgis"}
12
13// detectDatabaseFromAttachment maps a container attachment to DB metadata.
14func detectDatabaseFromAttachment(domainName string, a domain.Attachment) (domain.DBInfo, bool) {
15	image := strings.ToLower(a.Image)
16	name := strings.ToLower(a.Name)
17
18	switch {
19	case looksLikePostgres(image) || looksLikePostgres(name):
20		return buildPostgresInfo(domainName, a), true
21	case hasPort(a.Ports, 5432):
22		// Port 5432 fallback: likely PostgreSQL even with non-standard naming.
23		return buildPostgresInfo(domainName, a), true
24	default:
25		return domain.DBInfo{}, false
26	}
27}
28
29// looksLikePostgres returns true if s contains any known PostgreSQL alias.
30func looksLikePostgres(s string) bool {
31	for _, alias := range postgresAliases {
32		if strings.Contains(s, alias) {
33			return true
34		}
35	}
36	return false
37}
38
39// hasPort returns true if the port list contains p.
40func hasPort(ports []int, p int) bool {
41	return slices.Contains(ports, p)
42}
43
44// buildPostgresInfo constructs a DBInfo for a PostgreSQL attachment.
45func buildPostgresInfo(domainName string, a domain.Attachment) domain.DBInfo {
46	port := 5432
47	for _, p := range a.Ports {
48		if p == 5432 {
49			port = 5432
50			break
51		}
52		if p > 0 && port == 5432 {
53			port = p
54		}
55	}
56
57	return domain.DBInfo{
58		Type:        domain.DBTypePostgreSQL,
59		Version:     postgresVersionFromImage(a.Image),
60		Domain:      domainName,
61		Name:        a.Name,
62		Host:        a.Name,
63		Port:        port,
64		ContainerID: a.ContainerID,
65		ImageName:   a.Image,
66	}
67}
68
69func postgresVersionFromImage(image string) string {
70	lastColon := strings.LastIndex(image, ":")
71	if lastColon == -1 {
72		return ""
73	}
74	tag := strings.TrimSpace(image[lastColon+1:])
75	if tag == "" {
76		return ""
77	}
78
79	for i := 0; i < len(tag); i++ {
80		if tag[i] < '0' || tag[i] > '9' {
81			if i == 0 {
82				return ""
83			}
84			return tag[:i]
85		}
86	}
87
88	return tag
89}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close