v0.32.0 53e25a3

blob.go RawHistoryFolder

1// SPDX-License-Identifier: AGPL-3.0-or-later
2
3package ports
4
5import (
6	"context"
7	"io"
8	"strings"
9	"time"
10)
11
12// BlobStore keeps the contents of release assets and CI artifacts, never
13// their metadata. Keys are built by the use cases from ids only ("a/b/c",
14// ASCII, no empty segment, no ".", no ".." segment, no leading "/", ≤ 512
15// bytes); an adapter rejects any other key with domain.ErrInvalid.
16// *blobdisk.Store and *blobs3.Store implement it.
17type BlobStore interface {
18	Put(ctx context.Context, key string, r io.Reader, size int64) (BlobInfo, error)              // size ≥ 0 required; replaces; a failure leaves no object
19	Open(ctx context.Context, key string, offset, length int64) (io.ReadCloser, BlobInfo, error) // length < 0: to the end; offset ≥ size → domain.ErrOutOfRange
20	Stat(ctx context.Context, key string) (BlobInfo, error)
21	Delete(ctx context.Context, key string) error                           // absent: nil
22	List(ctx context.Context, prefix string, fn func(BlobInfo) error) error // lexicographic; fn error stops and is returned
23	NewMultipart(ctx context.Context, key string) (MultipartUpload, error)
24	ListMultipart(ctx context.Context, prefix string, fn func(MultipartInfo) error) error
25	AbortMultipart(ctx context.Context, key, id string) error // for GC of uploads listed by ListMultipart
26	Check(ctx context.Context) error                          // startup probe; never creates anything
27}
28type BlobInfo struct {
29	Key     string
30	Size    int64
31	Digest  string
32	ModTime time.Time
33} // Digest "sha256:<hex>" from Put, "" from Stat/List/Open on S3
34type MultipartInfo struct {
35	Key, ID string
36	Started time.Time
37}
38
39// MultipartUpload uploads one object in parts of BlobMinPartSize or more
40// (the last may be smaller), at most BlobMaxParts, numbered from 1 in the
41// order given to Complete. Abort discards everything; Complete or Abort
42// must be called exactly once.
43type MultipartUpload interface {
44	ID() string
45	UploadPart(ctx context.Context, n int, r io.Reader, size int64) error
46	Complete(ctx context.Context) (BlobInfo, error) // parts in number order; Digest "" (the caller hashes)
47	Abort(ctx context.Context) error
48}
49
50const (
51	BlobMinPartSize = 5 << 20
52	BlobPartSize    = 8 << 20
53	BlobMaxParts    = 10_000
54)
55
56// ValidBlobKey reports whether key follows the rule above.
57func ValidBlobKey(key string) bool {
58	if len(key) == 0 || len(key) > 512 {
59		return false
60	}
61	for _, c := range []byte(key) {
62		if c > 127 {
63			return false
64		}
65	}
66	for _, segment := range strings.Split(key, "/") {
67		if segment == "" || segment == "." || segment == ".." {
68			return false
69		}
70	}
71	return true
72}

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 3

Tags 43

↑↓ moveenter openesc close