Initial commit
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
Torjus Håkestad 2022-01-15 19:07:33 +01:00
commit 2ff4b8dfbb
13 changed files with 315 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
dist/

50
.goreleaser.yaml Normal file
View File

@ -0,0 +1,50 @@
# This is an example .goreleaser.yml file with some sensible defaults.
# Make sure to check the documentation at https://goreleaser.com
before:
hooks:
# You may remove this if you don't use go modules.
- go mod tidy
# you may remove this if you don't need go generate
- go generate ./...
builds:
- id: "gpaste-client"
binary: "gpaste"
env:
- CGO_ENABLED=0
goos:
- linux
- windows
goarch:
- amd64
main: ./cmd/client/client.go
- id: "gpaste-server"
binary: "gpaste-server"
env:
- CGO_ENABLED=0
goos:
- linux
- windows
- darwin
goarch:
- amd64
main: ./cmd/server/server.go
archives:
- format_overrides:
- goos: windows
format: zip
checksum:
name_template: 'checksums.txt'
snapshot:
name_template: "{{ incpatch .Version }}-next"
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'
gitea_urls:
api: https://git.t-juice.club/api/v1/
download: https://git.t-juice.club
env_files:
gitea_token: gitea_token

49
.woodpecker.yml Normal file
View File

@ -0,0 +1,49 @@
pipeline:
test:
image: golang:latest
commands:
- go build ./cmd/client/client.go
- go build ./cmd/server/server.go
- go test -v ./...
- go vet ./...
when:
branch: master
event: [push, pull_request, tag, deployment]
image-latest:
image: plugins/docker
settings:
repo: registry.t-juice.club/gpaste
registry: registry.t-juice.club
username: woodpecker
password:
from_secret: registry_password
tags:
- latest
- "${CI_COMMIT_SHA:0:8}"
when:
branch: master
event: push
image-tagged:
image: plugins/docker
settings:
repo: registry.t-juice.club/gpaste
registry: registry.t-juice.club
username: woodpecker
password:
from_secret: registry_password
tags:
- "${CI_COMMIT_TAG}"
when:
event: [tag]
goreleaser-tagged:
image: goreleaser/goreleaser
commands:
- git fetch --tags
- echo "$GITEA_TOKEN" > gitea_token
- goreleaser release
when:
event: [tag]
secrets: [gitea_token]

13
Dockerfile Normal file
View File

@ -0,0 +1,13 @@
FROM golang:alpine AS builder
WORKDIR /src
COPY go.mod .
COPY go.sum .
RUN go mod download
COPY . .
RUN go build -o gpaste ./cmd/client/client.go
RUN go build -o gpaste-server ./cmd/server/server.go
FROM alpine:latest
COPY --from=builder /src/gpaste /bin/gpaste
COPY --from=builder /src/gpaste-server /bin/gpaste-server
CMD ["/bin/gpaste-server"]

7
cmd/client/client.go Normal file
View File

@ -0,0 +1,7 @@
package main
import "fmt"
func main() {
fmt.Println("Starting gpaste client")
}

7
cmd/server/server.go Normal file
View File

@ -0,0 +1,7 @@
package main
import "fmt"
func main() {
fmt.Println("Starting gpaste server")
}

21
file.go Normal file
View File

@ -0,0 +1,21 @@
package gpaste
import (
"io"
"time"
)
type File struct {
ID string
Body io.ReadCloser
MaxViews uint
ExpiresOn time.Time
}
type FileStore interface {
Store(f *File) error
Get(id string) (*File, error)
Delete(id string) error
List() ([]string, error)
}

82
filestore_memory.go Normal file
View File

@ -0,0 +1,82 @@
package gpaste
import (
"bytes"
"fmt"
"io"
"sync"
"time"
)
type fileData struct {
ID string
Body bytes.Buffer
MaxViews uint
ExpiresOn time.Time
}
type MemoryFileStore struct {
lock sync.RWMutex
data map[string]*fileData
}
func NewMemoryFileStore() *MemoryFileStore {
return &MemoryFileStore{
data: make(map[string]*fileData),
}
}
func (s *MemoryFileStore) Store(f *File) error {
data := &fileData{
ID: f.ID,
MaxViews: f.MaxViews,
ExpiresOn: f.ExpiresOn,
}
_, err := io.Copy(&data.Body, f.Body)
_ = f.Body.Close()
s.lock.Lock()
defer s.lock.Unlock()
s.data[f.ID] = data
return err
}
func (s *MemoryFileStore) Get(id string) (*File, error) {
s.lock.RLock()
defer s.lock.RUnlock()
fd, ok := s.data[id]
if !ok {
return nil, fmt.Errorf("no such item")
}
f := &File{
ID: fd.ID,
MaxViews: fd.MaxViews,
ExpiresOn: fd.ExpiresOn,
Body: io.NopCloser(&fd.Body),
}
return f, nil
}
func (s *MemoryFileStore) Delete(id string) error {
s.lock.Lock()
defer s.lock.RUnlock()
delete(s.data, id)
return nil
}
func (s *MemoryFileStore) List() ([]string, error) {
var ids []string
s.lock.RLock()
defer s.lock.RUnlock()
for id := range s.data {
ids = append(ids, id)
}
return ids, nil
}

13
filestore_memory_test.go Normal file
View File

@ -0,0 +1,13 @@
package gpaste_test
import (
"testing"
"git.t-juice.club/torjus/gpaste"
)
func TestMemoryFileStore(t *testing.T) {
s := gpaste.NewMemoryFileStore()
RunFilestoreTest(s, t)
}

63
filestore_test.go Normal file
View File

@ -0,0 +1,63 @@
package gpaste_test
import (
"bytes"
"io"
"testing"
"git.t-juice.club/torjus/gpaste"
"github.com/google/uuid"
)
func RunFilestoreTest(s gpaste.FileStore, t *testing.T) {
t.Run("Basic", func(t *testing.T) {
// Create
dataString := "TEST_LOL_OMG"
id := uuid.Must(uuid.NewRandom()).String()
bodyBuf := &bytes.Buffer{}
bodyBuf.Write([]byte(dataString))
body := io.NopCloser(bodyBuf)
f := &gpaste.File{
ID: id,
MaxViews: 0,
Body: body,
}
err := s.Store(f)
if err != nil {
t.Fatalf("Unable to store file: %s", err)
}
// Retrieve
retrieved, err := s.Get(id)
if err != nil {
t.Fatalf("Unable to retrieve file: %s", err)
}
retrievedBuf := &bytes.Buffer{}
_, err = retrievedBuf.ReadFrom(retrieved.Body)
if err != nil {
t.Fatalf("Unable to read retrieved body: %s", err)
}
_ = retrieved.Body.Close()
if err != nil {
t.Fatalf("Error reading from retrieved file: %s", err)
}
if retrievedBuf.String() != dataString {
t.Fatalf("Data from retrieved body mismatch. Got %s want %s", retrievedBuf.String(), dataString)
}
// List
ids, err := s.List()
if err != nil {
t.Fatalf("Error doing list: %s", err)
}
if len(ids) != 1 {
t.Fatalf("List has wrong length: %d", len(ids))
}
if ids[0] != id {
t.Fatalf("ID is wrong. Got %s want %s", ids[0], id)
}
})
}

5
go.mod Normal file
View File

@ -0,0 +1,5 @@
module git.t-juice.club/torjus/gpaste
go 1.17
require github.com/google/uuid v1.3.0

2
go.sum Normal file
View File

@ -0,0 +1,2 @@
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=

1
http.go Normal file
View File

@ -0,0 +1 @@
package gpaste