diff --git a/cmd/lure-api-server/Dockerfile b/cmd/lure-api-server/Dockerfile
deleted file mode 100644
index bd2bdf3..0000000
--- a/cmd/lure-api-server/Dockerfile
+++ /dev/null
@@ -1,3 +0,0 @@
-FROM alpine:latest
-COPY lure-api-server /usr/bin/lure-api-server
-ENTRYPOINT lure-api-server
diff --git a/cmd/lure-api-server/README.md b/cmd/lure-api-server/README.md
deleted file mode 100644
index 2b3fa16..0000000
--- a/cmd/lure-api-server/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# lure-api-server
-
-`lure-api-server` is the backend API server for lure-web, the web interface for LURE.
\ No newline at end of file
diff --git a/cmd/lure-api-server/api.go b/cmd/lure-api-server/api.go
deleted file mode 100644
index c00671f..0000000
--- a/cmd/lure-api-server/api.go
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * LURE - Linux User REpository
- * Copyright (C) 2023 Elara Musayelyan
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package main
-
-import (
- "context"
- "io"
-
- "github.com/twitchtv/twirp"
- "go.elara.ws/lure/cmd/lure-api-server/internal/api"
- "go.elara.ws/lure/internal/log"
- "go.elara.ws/lure/pkg/search"
- "golang.org/x/text/language"
-)
-
-type lureWebAPI struct{}
-
-func (l lureWebAPI) Search(ctx context.Context, req *api.SearchRequest) (*api.SearchResponse, error) {
- pkgs, err := search.Search(search.Options{
- Filter: search.Filter(req.FilterType),
- SortBy: search.SortBy(req.SortBy),
- Limit: req.Limit,
- Query: req.Query,
- })
- return &api.SearchResponse{Packages: searchPkgsToAPI(ctx, pkgs)}, err
-}
-
-func (l lureWebAPI) GetPkg(ctx context.Context, req *api.GetPackageRequest) (*api.Package, error) {
- pkg, err := search.GetPkg(req.Repository, req.Name)
- if err != nil {
- return nil, err
- }
- return searchPkgToAPI(ctx, pkg), nil
-}
-
-func (l lureWebAPI) GetBuildScript(ctx context.Context, req *api.GetBuildScriptRequest) (*api.GetBuildScriptResponse, error) {
- r, err := search.GetScript(req.Repository, req.Name)
- if err == search.ErrScriptNotFound {
- return nil, twirp.NewError(twirp.NotFound, err.Error())
- } else if err == search.ErrInvalidArgument {
- return nil, twirp.NewError(twirp.InvalidArgument, err.Error())
- } else if err != nil {
- return nil, err
- }
-
- data, err := io.ReadAll(r)
- if err != nil {
- return nil, err
- }
-
- return &api.GetBuildScriptResponse{Script: string(data)}, nil
-}
-
-func searchPkgsToAPI(ctx context.Context, pkgs []search.Package) []*api.Package {
- out := make([]*api.Package, len(pkgs))
- for i, pkg := range pkgs {
- out[i] = searchPkgToAPI(ctx, pkg)
- }
- return out
-}
-
-func searchPkgToAPI(ctx context.Context, pkg search.Package) *api.Package {
- return &api.Package{
- Name: pkg.Name,
- Repository: pkg.Repository,
- Version: pkg.Version,
- Release: int64(pkg.Release),
- Epoch: ptr(int64(pkg.Epoch)),
- Description: performTranslation(ctx, pkg.Description),
- Homepage: performTranslation(ctx, pkg.Homepage),
- Maintainer: performTranslation(ctx, pkg.Maintainer),
- Architectures: pkg.Architectures,
- Licenses: pkg.Licenses,
- Provides: pkg.Provides,
- Conflicts: pkg.Conflicts,
- Replaces: pkg.Replaces,
- Depends: mapToAPI(pkg.Depends),
- BuildDepends: mapToAPI(pkg.BuildDepends),
- }
-}
-
-func ptr[T any](v T) *T {
- return &v
-}
-
-func mapToAPI(m map[string][]string) map[string]*api.StringList {
- out := make(map[string]*api.StringList, len(m))
- for override, list := range m {
- out[override] = &api.StringList{Entries: list}
- }
- return out
-}
-
-func performTranslation(ctx context.Context, v map[string]string) *string {
- alVal := ctx.Value(acceptLanguageKey{})
- langVal := ctx.Value(langParameterKey{})
-
- if alVal == nil && langVal == nil {
- val, ok := v[""]
- if !ok {
- return ptr("")
- }
- return &val
- }
-
- al, _ := alVal.(string)
- lang, _ := langVal.(string)
-
- tags, _, err := language.ParseAcceptLanguage(al)
- if err != nil {
- log.Warn("Error parsing Accept-Language header").Err(err).Send()
- }
-
- var bases []string
- if lang != "" {
- langTag, err := language.Parse(lang)
- if err != nil {
- log.Warn("Error parsing lang parameter").Err(err).Send()
- bases = getLangBases(tags)
- } else {
- bases = getLangBases(append([]language.Tag{langTag}, tags...))
- }
- } else {
- bases = getLangBases(tags)
- }
-
- if len(bases) == 1 {
- bases = []string{"en", ""}
- }
-
- for _, name := range bases {
- val, ok := v[name]
- if !ok {
- continue
- }
- return &val
- }
-
- return ptr("")
-}
-
-func getLangBases(langs []language.Tag) []string {
- out := make([]string, len(langs)+1)
- for i, lang := range langs {
- base, _ := lang.Base()
- out[i] = base.String()
- }
- out[len(out)-1] = ""
- return out
-}
diff --git a/cmd/lure-api-server/badge-logo.txt b/cmd/lure-api-server/badge-logo.txt
deleted file mode 100644
index 37767cc..0000000
--- a/cmd/lure-api-server/badge-logo.txt
+++ /dev/null
@@ -1 +0,0 @@
-data:image/png;base64,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
\ No newline at end of file
diff --git a/cmd/lure-api-server/badge.go b/cmd/lure-api-server/badge.go
deleted file mode 100644
index b926cb7..0000000
--- a/cmd/lure-api-server/badge.go
+++ /dev/null
@@ -1,58 +0,0 @@
-package main
-
-import (
- _ "embed"
- "net/http"
- "net/url"
- "strconv"
- "strings"
-
- "github.com/go-chi/chi/v5"
- "go.elara.ws/lure/pkg/search"
-)
-
-//go:embed badge-logo.txt
-var logoData string
-
-var _ http.HandlerFunc
-
-func handleBadge() http.HandlerFunc {
- return func(res http.ResponseWriter, req *http.Request) {
- repo := chi.URLParam(req, "repo")
- name := chi.URLParam(req, "pkg")
-
- pkg, err := search.GetPkg(repo, name)
- if err != nil {
- http.Error(res, err.Error(), http.StatusInternalServerError)
- return
- }
-
- http.Redirect(res, req, genBadgeURL(pkg.Name, genVersion(pkg)), http.StatusFound)
- }
-}
-
-func genVersion(pkg search.Package) string {
- sb := strings.Builder{}
- if pkg.Epoch != 0 {
- sb.WriteString(strconv.Itoa(int(pkg.Epoch)))
- sb.WriteByte(':')
- }
-
- sb.WriteString(pkg.Version)
-
- if pkg.Release != 0 {
- sb.WriteByte('-')
- sb.WriteString(strconv.Itoa(pkg.Release))
- }
- return sb.String()
-}
-
-func genBadgeURL(pkgName, pkgVersion string) string {
- v := url.Values{}
- v.Set("label", pkgName)
- v.Set("message", pkgVersion)
- v.Set("logo", logoData)
- v.Set("color", "blue")
- u := &url.URL{Scheme: "https", Host: "img.shields.io", Path: "/static/v1", RawQuery: v.Encode()}
- return u.String()
-}
diff --git a/cmd/lure-api-server/docker.sh b/cmd/lure-api-server/docker.sh
deleted file mode 100755
index c79de3e..0000000
--- a/cmd/lure-api-server/docker.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/bash
-
-CGO_ENABLED=0 GOARCH=amd64 GOOS=linux go build
-docker buildx build --platform linux/amd64 --tag elara6331/lure-api-server:amd64 --no-cache .
-
-CGO_ENABLED=0 GOARCH=arm64 GOOS=linux go build
-docker buildx build --platform linux/arm64/v8 --tag elara6331/lure-api-server:arm64 --no-cache .
-
-docker login
-docker push elara6331/lure-api-server -a
-
-docker manifest rm elara6331/lure-api-server:latest
-docker manifest create elara6331/lure-api-server:latest --amend elara6331/lure-api-server:arm64 --amend elara6331/lure-api-server:amd64
-docker manifest push elara6331/lure-api-server:latest
diff --git a/cmd/lure-api-server/internal/api/gen.go b/cmd/lure-api-server/internal/api/gen.go
deleted file mode 100644
index 00575f5..0000000
--- a/cmd/lure-api-server/internal/api/gen.go
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * LURE - Linux User REpository
- * Copyright (C) 2023 Elara Musayelyan
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package api
-
-//go:generate protoc --twirp_out=. lure.proto
-//go:generate protoc --go_out=. lure.proto
diff --git a/cmd/lure-api-server/internal/api/lure.pb.go b/cmd/lure-api-server/internal/api/lure.pb.go
deleted file mode 100644
index c2e43a9..0000000
--- a/cmd/lure-api-server/internal/api/lure.pb.go
+++ /dev/null
@@ -1,888 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// versions:
-// protoc-gen-go v1.31.0
-// protoc v4.24.2
-// source: lure.proto
-
-package api
-
-import (
- reflect "reflect"
- sync "sync"
-
- protoreflect "google.golang.org/protobuf/reflect/protoreflect"
- protoimpl "google.golang.org/protobuf/runtime/protoimpl"
-)
-
-const (
- // Verify that this generated code is sufficiently up-to-date.
- _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
- // Verify that runtime/protoimpl is sufficiently up-to-date.
- _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
-)
-
-// SORT_BY represents possible things to sort packages by
-type SORT_BY int32
-
-const (
- SORT_BY_UNSORTED SORT_BY = 0
- SORT_BY_NAME SORT_BY = 1
- SORT_BY_REPOSITORY SORT_BY = 2
- SORT_BY_VERSION SORT_BY = 3
-)
-
-// Enum value maps for SORT_BY.
-var (
- SORT_BY_name = map[int32]string{
- 0: "UNSORTED",
- 1: "NAME",
- 2: "REPOSITORY",
- 3: "VERSION",
- }
- SORT_BY_value = map[string]int32{
- "UNSORTED": 0,
- "NAME": 1,
- "REPOSITORY": 2,
- "VERSION": 3,
- }
-)
-
-func (x SORT_BY) Enum() *SORT_BY {
- p := new(SORT_BY)
- *p = x
- return p
-}
-
-func (x SORT_BY) String() string {
- return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
-}
-
-func (SORT_BY) Descriptor() protoreflect.EnumDescriptor {
- return file_lure_proto_enumTypes[0].Descriptor()
-}
-
-func (SORT_BY) Type() protoreflect.EnumType {
- return &file_lure_proto_enumTypes[0]
-}
-
-func (x SORT_BY) Number() protoreflect.EnumNumber {
- return protoreflect.EnumNumber(x)
-}
-
-// Deprecated: Use SORT_BY.Descriptor instead.
-func (SORT_BY) EnumDescriptor() ([]byte, []int) {
- return file_lure_proto_rawDescGZIP(), []int{0}
-}
-
-// FILTER_TYPE represents possible filters for packages
-type FILTER_TYPE int32
-
-const (
- FILTER_TYPE_NO_FILTER FILTER_TYPE = 0
- FILTER_TYPE_IN_REPOSITORY FILTER_TYPE = 1
- FILTER_TYPE_SUPPORTS_ARCH FILTER_TYPE = 2
-)
-
-// Enum value maps for FILTER_TYPE.
-var (
- FILTER_TYPE_name = map[int32]string{
- 0: "NO_FILTER",
- 1: "IN_REPOSITORY",
- 2: "SUPPORTS_ARCH",
- }
- FILTER_TYPE_value = map[string]int32{
- "NO_FILTER": 0,
- "IN_REPOSITORY": 1,
- "SUPPORTS_ARCH": 2,
- }
-)
-
-func (x FILTER_TYPE) Enum() *FILTER_TYPE {
- p := new(FILTER_TYPE)
- *p = x
- return p
-}
-
-func (x FILTER_TYPE) String() string {
- return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
-}
-
-func (FILTER_TYPE) Descriptor() protoreflect.EnumDescriptor {
- return file_lure_proto_enumTypes[1].Descriptor()
-}
-
-func (FILTER_TYPE) Type() protoreflect.EnumType {
- return &file_lure_proto_enumTypes[1]
-}
-
-func (x FILTER_TYPE) Number() protoreflect.EnumNumber {
- return protoreflect.EnumNumber(x)
-}
-
-// Deprecated: Use FILTER_TYPE.Descriptor instead.
-func (FILTER_TYPE) EnumDescriptor() ([]byte, []int) {
- return file_lure_proto_rawDescGZIP(), []int{1}
-}
-
-// SearchRequest is a request to search for packages
-type SearchRequest struct {
- state protoimpl.MessageState
- sizeCache protoimpl.SizeCache
- unknownFields protoimpl.UnknownFields
-
- Query string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"`
- Limit int64 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"`
- SortBy SORT_BY `protobuf:"varint,3,opt,name=sort_by,json=sortBy,proto3,enum=lure.SORT_BY" json:"sort_by,omitempty"`
- FilterType FILTER_TYPE `protobuf:"varint,4,opt,name=filter_type,json=filterType,proto3,enum=lure.FILTER_TYPE" json:"filter_type,omitempty"`
- FilterValue *string `protobuf:"bytes,5,opt,name=filter_value,json=filterValue,proto3,oneof" json:"filter_value,omitempty"`
-}
-
-func (x *SearchRequest) Reset() {
- *x = SearchRequest{}
- if protoimpl.UnsafeEnabled {
- mi := &file_lure_proto_msgTypes[0]
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- ms.StoreMessageInfo(mi)
- }
-}
-
-func (x *SearchRequest) String() string {
- return protoimpl.X.MessageStringOf(x)
-}
-
-func (*SearchRequest) ProtoMessage() {}
-
-func (x *SearchRequest) ProtoReflect() protoreflect.Message {
- mi := &file_lure_proto_msgTypes[0]
- if protoimpl.UnsafeEnabled && x != nil {
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- if ms.LoadMessageInfo() == nil {
- ms.StoreMessageInfo(mi)
- }
- return ms
- }
- return mi.MessageOf(x)
-}
-
-// Deprecated: Use SearchRequest.ProtoReflect.Descriptor instead.
-func (*SearchRequest) Descriptor() ([]byte, []int) {
- return file_lure_proto_rawDescGZIP(), []int{0}
-}
-
-func (x *SearchRequest) GetQuery() string {
- if x != nil {
- return x.Query
- }
- return ""
-}
-
-func (x *SearchRequest) GetLimit() int64 {
- if x != nil {
- return x.Limit
- }
- return 0
-}
-
-func (x *SearchRequest) GetSortBy() SORT_BY {
- if x != nil {
- return x.SortBy
- }
- return SORT_BY_UNSORTED
-}
-
-func (x *SearchRequest) GetFilterType() FILTER_TYPE {
- if x != nil {
- return x.FilterType
- }
- return FILTER_TYPE_NO_FILTER
-}
-
-func (x *SearchRequest) GetFilterValue() string {
- if x != nil && x.FilterValue != nil {
- return *x.FilterValue
- }
- return ""
-}
-
-// StringList contains a list of strings
-type StringList struct {
- state protoimpl.MessageState
- sizeCache protoimpl.SizeCache
- unknownFields protoimpl.UnknownFields
-
- Entries []string `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries,omitempty"`
-}
-
-func (x *StringList) Reset() {
- *x = StringList{}
- if protoimpl.UnsafeEnabled {
- mi := &file_lure_proto_msgTypes[1]
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- ms.StoreMessageInfo(mi)
- }
-}
-
-func (x *StringList) String() string {
- return protoimpl.X.MessageStringOf(x)
-}
-
-func (*StringList) ProtoMessage() {}
-
-func (x *StringList) ProtoReflect() protoreflect.Message {
- mi := &file_lure_proto_msgTypes[1]
- if protoimpl.UnsafeEnabled && x != nil {
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- if ms.LoadMessageInfo() == nil {
- ms.StoreMessageInfo(mi)
- }
- return ms
- }
- return mi.MessageOf(x)
-}
-
-// Deprecated: Use StringList.ProtoReflect.Descriptor instead.
-func (*StringList) Descriptor() ([]byte, []int) {
- return file_lure_proto_rawDescGZIP(), []int{1}
-}
-
-func (x *StringList) GetEntries() []string {
- if x != nil {
- return x.Entries
- }
- return nil
-}
-
-// Package represents a LURE package
-type Package struct {
- state protoimpl.MessageState
- sizeCache protoimpl.SizeCache
- unknownFields protoimpl.UnknownFields
-
- Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
- Repository string `protobuf:"bytes,2,opt,name=repository,proto3" json:"repository,omitempty"`
- Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"`
- Release int64 `protobuf:"varint,4,opt,name=release,proto3" json:"release,omitempty"`
- Epoch *int64 `protobuf:"varint,5,opt,name=epoch,proto3,oneof" json:"epoch,omitempty"`
- Description *string `protobuf:"bytes,6,opt,name=description,proto3,oneof" json:"description,omitempty"`
- Homepage *string `protobuf:"bytes,7,opt,name=homepage,proto3,oneof" json:"homepage,omitempty"`
- Maintainer *string `protobuf:"bytes,8,opt,name=maintainer,proto3,oneof" json:"maintainer,omitempty"`
- Architectures []string `protobuf:"bytes,9,rep,name=architectures,proto3" json:"architectures,omitempty"`
- Licenses []string `protobuf:"bytes,10,rep,name=licenses,proto3" json:"licenses,omitempty"`
- Provides []string `protobuf:"bytes,11,rep,name=provides,proto3" json:"provides,omitempty"`
- Conflicts []string `protobuf:"bytes,12,rep,name=conflicts,proto3" json:"conflicts,omitempty"`
- Replaces []string `protobuf:"bytes,13,rep,name=replaces,proto3" json:"replaces,omitempty"`
- Depends map[string]*StringList `protobuf:"bytes,14,rep,name=depends,proto3" json:"depends,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
- BuildDepends map[string]*StringList `protobuf:"bytes,15,rep,name=build_depends,json=buildDepends,proto3" json:"build_depends,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
-}
-
-func (x *Package) Reset() {
- *x = Package{}
- if protoimpl.UnsafeEnabled {
- mi := &file_lure_proto_msgTypes[2]
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- ms.StoreMessageInfo(mi)
- }
-}
-
-func (x *Package) String() string {
- return protoimpl.X.MessageStringOf(x)
-}
-
-func (*Package) ProtoMessage() {}
-
-func (x *Package) ProtoReflect() protoreflect.Message {
- mi := &file_lure_proto_msgTypes[2]
- if protoimpl.UnsafeEnabled && x != nil {
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- if ms.LoadMessageInfo() == nil {
- ms.StoreMessageInfo(mi)
- }
- return ms
- }
- return mi.MessageOf(x)
-}
-
-// Deprecated: Use Package.ProtoReflect.Descriptor instead.
-func (*Package) Descriptor() ([]byte, []int) {
- return file_lure_proto_rawDescGZIP(), []int{2}
-}
-
-func (x *Package) GetName() string {
- if x != nil {
- return x.Name
- }
- return ""
-}
-
-func (x *Package) GetRepository() string {
- if x != nil {
- return x.Repository
- }
- return ""
-}
-
-func (x *Package) GetVersion() string {
- if x != nil {
- return x.Version
- }
- return ""
-}
-
-func (x *Package) GetRelease() int64 {
- if x != nil {
- return x.Release
- }
- return 0
-}
-
-func (x *Package) GetEpoch() int64 {
- if x != nil && x.Epoch != nil {
- return *x.Epoch
- }
- return 0
-}
-
-func (x *Package) GetDescription() string {
- if x != nil && x.Description != nil {
- return *x.Description
- }
- return ""
-}
-
-func (x *Package) GetHomepage() string {
- if x != nil && x.Homepage != nil {
- return *x.Homepage
- }
- return ""
-}
-
-func (x *Package) GetMaintainer() string {
- if x != nil && x.Maintainer != nil {
- return *x.Maintainer
- }
- return ""
-}
-
-func (x *Package) GetArchitectures() []string {
- if x != nil {
- return x.Architectures
- }
- return nil
-}
-
-func (x *Package) GetLicenses() []string {
- if x != nil {
- return x.Licenses
- }
- return nil
-}
-
-func (x *Package) GetProvides() []string {
- if x != nil {
- return x.Provides
- }
- return nil
-}
-
-func (x *Package) GetConflicts() []string {
- if x != nil {
- return x.Conflicts
- }
- return nil
-}
-
-func (x *Package) GetReplaces() []string {
- if x != nil {
- return x.Replaces
- }
- return nil
-}
-
-func (x *Package) GetDepends() map[string]*StringList {
- if x != nil {
- return x.Depends
- }
- return nil
-}
-
-func (x *Package) GetBuildDepends() map[string]*StringList {
- if x != nil {
- return x.BuildDepends
- }
- return nil
-}
-
-type GetPackageRequest struct {
- state protoimpl.MessageState
- sizeCache protoimpl.SizeCache
- unknownFields protoimpl.UnknownFields
-
- Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
- Repository string `protobuf:"bytes,2,opt,name=repository,proto3" json:"repository,omitempty"`
-}
-
-func (x *GetPackageRequest) Reset() {
- *x = GetPackageRequest{}
- if protoimpl.UnsafeEnabled {
- mi := &file_lure_proto_msgTypes[3]
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- ms.StoreMessageInfo(mi)
- }
-}
-
-func (x *GetPackageRequest) String() string {
- return protoimpl.X.MessageStringOf(x)
-}
-
-func (*GetPackageRequest) ProtoMessage() {}
-
-func (x *GetPackageRequest) ProtoReflect() protoreflect.Message {
- mi := &file_lure_proto_msgTypes[3]
- if protoimpl.UnsafeEnabled && x != nil {
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- if ms.LoadMessageInfo() == nil {
- ms.StoreMessageInfo(mi)
- }
- return ms
- }
- return mi.MessageOf(x)
-}
-
-// Deprecated: Use GetPackageRequest.ProtoReflect.Descriptor instead.
-func (*GetPackageRequest) Descriptor() ([]byte, []int) {
- return file_lure_proto_rawDescGZIP(), []int{3}
-}
-
-func (x *GetPackageRequest) GetName() string {
- if x != nil {
- return x.Name
- }
- return ""
-}
-
-func (x *GetPackageRequest) GetRepository() string {
- if x != nil {
- return x.Repository
- }
- return ""
-}
-
-// SearchResponse contains returned packages
-type SearchResponse struct {
- state protoimpl.MessageState
- sizeCache protoimpl.SizeCache
- unknownFields protoimpl.UnknownFields
-
- Packages []*Package `protobuf:"bytes,1,rep,name=packages,proto3" json:"packages,omitempty"`
-}
-
-func (x *SearchResponse) Reset() {
- *x = SearchResponse{}
- if protoimpl.UnsafeEnabled {
- mi := &file_lure_proto_msgTypes[4]
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- ms.StoreMessageInfo(mi)
- }
-}
-
-func (x *SearchResponse) String() string {
- return protoimpl.X.MessageStringOf(x)
-}
-
-func (*SearchResponse) ProtoMessage() {}
-
-func (x *SearchResponse) ProtoReflect() protoreflect.Message {
- mi := &file_lure_proto_msgTypes[4]
- if protoimpl.UnsafeEnabled && x != nil {
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- if ms.LoadMessageInfo() == nil {
- ms.StoreMessageInfo(mi)
- }
- return ms
- }
- return mi.MessageOf(x)
-}
-
-// Deprecated: Use SearchResponse.ProtoReflect.Descriptor instead.
-func (*SearchResponse) Descriptor() ([]byte, []int) {
- return file_lure_proto_rawDescGZIP(), []int{4}
-}
-
-func (x *SearchResponse) GetPackages() []*Package {
- if x != nil {
- return x.Packages
- }
- return nil
-}
-
-type GetBuildScriptRequest struct {
- state protoimpl.MessageState
- sizeCache protoimpl.SizeCache
- unknownFields protoimpl.UnknownFields
-
- Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
- Repository string `protobuf:"bytes,2,opt,name=repository,proto3" json:"repository,omitempty"`
-}
-
-func (x *GetBuildScriptRequest) Reset() {
- *x = GetBuildScriptRequest{}
- if protoimpl.UnsafeEnabled {
- mi := &file_lure_proto_msgTypes[5]
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- ms.StoreMessageInfo(mi)
- }
-}
-
-func (x *GetBuildScriptRequest) String() string {
- return protoimpl.X.MessageStringOf(x)
-}
-
-func (*GetBuildScriptRequest) ProtoMessage() {}
-
-func (x *GetBuildScriptRequest) ProtoReflect() protoreflect.Message {
- mi := &file_lure_proto_msgTypes[5]
- if protoimpl.UnsafeEnabled && x != nil {
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- if ms.LoadMessageInfo() == nil {
- ms.StoreMessageInfo(mi)
- }
- return ms
- }
- return mi.MessageOf(x)
-}
-
-// Deprecated: Use GetBuildScriptRequest.ProtoReflect.Descriptor instead.
-func (*GetBuildScriptRequest) Descriptor() ([]byte, []int) {
- return file_lure_proto_rawDescGZIP(), []int{5}
-}
-
-func (x *GetBuildScriptRequest) GetName() string {
- if x != nil {
- return x.Name
- }
- return ""
-}
-
-func (x *GetBuildScriptRequest) GetRepository() string {
- if x != nil {
- return x.Repository
- }
- return ""
-}
-
-type GetBuildScriptResponse struct {
- state protoimpl.MessageState
- sizeCache protoimpl.SizeCache
- unknownFields protoimpl.UnknownFields
-
- Script string `protobuf:"bytes,1,opt,name=script,proto3" json:"script,omitempty"`
-}
-
-func (x *GetBuildScriptResponse) Reset() {
- *x = GetBuildScriptResponse{}
- if protoimpl.UnsafeEnabled {
- mi := &file_lure_proto_msgTypes[6]
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- ms.StoreMessageInfo(mi)
- }
-}
-
-func (x *GetBuildScriptResponse) String() string {
- return protoimpl.X.MessageStringOf(x)
-}
-
-func (*GetBuildScriptResponse) ProtoMessage() {}
-
-func (x *GetBuildScriptResponse) ProtoReflect() protoreflect.Message {
- mi := &file_lure_proto_msgTypes[6]
- if protoimpl.UnsafeEnabled && x != nil {
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- if ms.LoadMessageInfo() == nil {
- ms.StoreMessageInfo(mi)
- }
- return ms
- }
- return mi.MessageOf(x)
-}
-
-// Deprecated: Use GetBuildScriptResponse.ProtoReflect.Descriptor instead.
-func (*GetBuildScriptResponse) Descriptor() ([]byte, []int) {
- return file_lure_proto_rawDescGZIP(), []int{6}
-}
-
-func (x *GetBuildScriptResponse) GetScript() string {
- if x != nil {
- return x.Script
- }
- return ""
-}
-
-var File_lure_proto protoreflect.FileDescriptor
-
-var file_lure_proto_rawDesc = []byte{
- 0x0a, 0x0a, 0x6c, 0x75, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x6c, 0x75,
- 0x72, 0x65, 0x22, 0xd0, 0x01, 0x0a, 0x0d, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71,
- 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69,
- 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74,
- 0x12, 0x26, 0x0a, 0x07, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x62, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28,
- 0x0e, 0x32, 0x0d, 0x2e, 0x6c, 0x75, 0x72, 0x65, 0x2e, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x42, 0x59,
- 0x52, 0x06, 0x73, 0x6f, 0x72, 0x74, 0x42, 0x79, 0x12, 0x32, 0x0a, 0x0b, 0x66, 0x69, 0x6c, 0x74,
- 0x65, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e,
- 0x6c, 0x75, 0x72, 0x65, 0x2e, 0x46, 0x49, 0x4c, 0x54, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45,
- 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x26, 0x0a, 0x0c,
- 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01,
- 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75,
- 0x65, 0x88, 0x01, 0x01, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x5f,
- 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x26, 0x0a, 0x0a, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4c,
- 0x69, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01,
- 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x22, 0xe4, 0x05,
- 0x0a, 0x07, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
- 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a,
- 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x18, 0x0a,
- 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
- 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x6c, 0x65, 0x61,
- 0x73, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73,
- 0x65, 0x12, 0x19, 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03,
- 0x48, 0x00, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x88, 0x01, 0x01, 0x12, 0x25, 0x0a, 0x0b,
- 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28,
- 0x09, 0x48, 0x01, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
- 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x68, 0x6f, 0x6d, 0x65, 0x70, 0x61, 0x67, 0x65, 0x18,
- 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x08, 0x68, 0x6f, 0x6d, 0x65, 0x70, 0x61, 0x67,
- 0x65, 0x88, 0x01, 0x01, 0x12, 0x23, 0x0a, 0x0a, 0x6d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e,
- 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, 0x0a, 0x6d, 0x61, 0x69, 0x6e,
- 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x72, 0x63,
- 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09,
- 0x52, 0x0d, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12,
- 0x1a, 0x0a, 0x08, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28,
- 0x09, 0x52, 0x08, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x70,
- 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x70,
- 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x66, 0x6c,
- 0x69, 0x63, 0x74, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x66,
- 0x6c, 0x69, 0x63, 0x74, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65,
- 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65,
- 0x73, 0x12, 0x34, 0x0a, 0x07, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x73, 0x18, 0x0e, 0x20, 0x03,
- 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6c, 0x75, 0x72, 0x65, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67,
- 0x65, 0x2e, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07,
- 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x73, 0x12, 0x44, 0x0a, 0x0d, 0x62, 0x75, 0x69, 0x6c, 0x64,
- 0x5f, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f,
- 0x2e, 0x6c, 0x75, 0x72, 0x65, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x2e, 0x42, 0x75,
- 0x69, 0x6c, 0x64, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52,
- 0x0c, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x73, 0x1a, 0x4c, 0x0a,
- 0x0c, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a,
- 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
- 0x26, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10,
- 0x2e, 0x6c, 0x75, 0x72, 0x65, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74,
- 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x51, 0x0a, 0x11, 0x42,
- 0x75, 0x69, 0x6c, 0x64, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79,
- 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b,
- 0x65, 0x79, 0x12, 0x26, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x10, 0x2e, 0x6c, 0x75, 0x72, 0x65, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4c,
- 0x69, 0x73, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x08,
- 0x0a, 0x06, 0x5f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x64, 0x65, 0x73,
- 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x68, 0x6f, 0x6d,
- 0x65, 0x70, 0x61, 0x67, 0x65, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x74, 0x61,
- 0x69, 0x6e, 0x65, 0x72, 0x22, 0x47, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x50, 0x61, 0x63, 0x6b, 0x61,
- 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
- 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a,
- 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x3b, 0x0a,
- 0x0e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
- 0x29, 0x0a, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
- 0x0b, 0x32, 0x0d, 0x2e, 0x6c, 0x75, 0x72, 0x65, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65,
- 0x52, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x22, 0x4b, 0x0a, 0x15, 0x47, 0x65,
- 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75,
- 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73,
- 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x70,
- 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x30, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x42, 0x75,
- 0x69, 0x6c, 0x64, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
- 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x06, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x2a, 0x3e, 0x0a, 0x07, 0x53, 0x4f, 0x52,
- 0x54, 0x5f, 0x42, 0x59, 0x12, 0x0c, 0x0a, 0x08, 0x55, 0x4e, 0x53, 0x4f, 0x52, 0x54, 0x45, 0x44,
- 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a,
- 0x52, 0x45, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x4f, 0x52, 0x59, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07,
- 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x03, 0x2a, 0x42, 0x0a, 0x0b, 0x46, 0x49, 0x4c,
- 0x54, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x5f, 0x46,
- 0x49, 0x4c, 0x54, 0x45, 0x52, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x49, 0x4e, 0x5f, 0x52, 0x45,
- 0x50, 0x4f, 0x53, 0x49, 0x54, 0x4f, 0x52, 0x59, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x55,
- 0x50, 0x50, 0x4f, 0x52, 0x54, 0x53, 0x5f, 0x41, 0x52, 0x43, 0x48, 0x10, 0x02, 0x32, 0xb9, 0x01,
- 0x0a, 0x03, 0x41, 0x50, 0x49, 0x12, 0x33, 0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12,
- 0x13, 0x2e, 0x6c, 0x75, 0x72, 0x65, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71,
- 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x6c, 0x75, 0x72, 0x65, 0x2e, 0x53, 0x65, 0x61, 0x72,
- 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x06, 0x47, 0x65,
- 0x74, 0x50, 0x6b, 0x67, 0x12, 0x17, 0x2e, 0x6c, 0x75, 0x72, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x50,
- 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0d, 0x2e,
- 0x6c, 0x75, 0x72, 0x65, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x4b, 0x0a, 0x0e,
- 0x47, 0x65, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x1b,
- 0x2e, 0x6c, 0x75, 0x72, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x63,
- 0x72, 0x69, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x75,
- 0x72, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x63, 0x72, 0x69, 0x70,
- 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x08, 0x5a, 0x06, 0x2e, 0x2e, 0x2f,
- 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
-}
-
-var (
- file_lure_proto_rawDescOnce sync.Once
- file_lure_proto_rawDescData = file_lure_proto_rawDesc
-)
-
-func file_lure_proto_rawDescGZIP() []byte {
- file_lure_proto_rawDescOnce.Do(func() {
- file_lure_proto_rawDescData = protoimpl.X.CompressGZIP(file_lure_proto_rawDescData)
- })
- return file_lure_proto_rawDescData
-}
-
-var (
- file_lure_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
- file_lure_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
- file_lure_proto_goTypes = []interface{}{
- (SORT_BY)(0), // 0: lure.SORT_BY
- (FILTER_TYPE)(0), // 1: lure.FILTER_TYPE
- (*SearchRequest)(nil), // 2: lure.SearchRequest
- (*StringList)(nil), // 3: lure.StringList
- (*Package)(nil), // 4: lure.Package
- (*GetPackageRequest)(nil), // 5: lure.GetPackageRequest
- (*SearchResponse)(nil), // 6: lure.SearchResponse
- (*GetBuildScriptRequest)(nil), // 7: lure.GetBuildScriptRequest
- (*GetBuildScriptResponse)(nil), // 8: lure.GetBuildScriptResponse
- nil, // 9: lure.Package.DependsEntry
- nil, // 10: lure.Package.BuildDependsEntry
- }
-)
-var file_lure_proto_depIdxs = []int32{
- 0, // 0: lure.SearchRequest.sort_by:type_name -> lure.SORT_BY
- 1, // 1: lure.SearchRequest.filter_type:type_name -> lure.FILTER_TYPE
- 9, // 2: lure.Package.depends:type_name -> lure.Package.DependsEntry
- 10, // 3: lure.Package.build_depends:type_name -> lure.Package.BuildDependsEntry
- 4, // 4: lure.SearchResponse.packages:type_name -> lure.Package
- 3, // 5: lure.Package.DependsEntry.value:type_name -> lure.StringList
- 3, // 6: lure.Package.BuildDependsEntry.value:type_name -> lure.StringList
- 2, // 7: lure.API.Search:input_type -> lure.SearchRequest
- 5, // 8: lure.API.GetPkg:input_type -> lure.GetPackageRequest
- 7, // 9: lure.API.GetBuildScript:input_type -> lure.GetBuildScriptRequest
- 6, // 10: lure.API.Search:output_type -> lure.SearchResponse
- 4, // 11: lure.API.GetPkg:output_type -> lure.Package
- 8, // 12: lure.API.GetBuildScript:output_type -> lure.GetBuildScriptResponse
- 10, // [10:13] is the sub-list for method output_type
- 7, // [7:10] is the sub-list for method input_type
- 7, // [7:7] is the sub-list for extension type_name
- 7, // [7:7] is the sub-list for extension extendee
- 0, // [0:7] is the sub-list for field type_name
-}
-
-func init() { file_lure_proto_init() }
-func file_lure_proto_init() {
- if File_lure_proto != nil {
- return
- }
- if !protoimpl.UnsafeEnabled {
- file_lure_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*SearchRequest); i {
- case 0:
- return &v.state
- case 1:
- return &v.sizeCache
- case 2:
- return &v.unknownFields
- default:
- return nil
- }
- }
- file_lure_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*StringList); i {
- case 0:
- return &v.state
- case 1:
- return &v.sizeCache
- case 2:
- return &v.unknownFields
- default:
- return nil
- }
- }
- file_lure_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*Package); i {
- case 0:
- return &v.state
- case 1:
- return &v.sizeCache
- case 2:
- return &v.unknownFields
- default:
- return nil
- }
- }
- file_lure_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*GetPackageRequest); i {
- case 0:
- return &v.state
- case 1:
- return &v.sizeCache
- case 2:
- return &v.unknownFields
- default:
- return nil
- }
- }
- file_lure_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*SearchResponse); i {
- case 0:
- return &v.state
- case 1:
- return &v.sizeCache
- case 2:
- return &v.unknownFields
- default:
- return nil
- }
- }
- file_lure_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*GetBuildScriptRequest); i {
- case 0:
- return &v.state
- case 1:
- return &v.sizeCache
- case 2:
- return &v.unknownFields
- default:
- return nil
- }
- }
- file_lure_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*GetBuildScriptResponse); i {
- case 0:
- return &v.state
- case 1:
- return &v.sizeCache
- case 2:
- return &v.unknownFields
- default:
- return nil
- }
- }
- }
- file_lure_proto_msgTypes[0].OneofWrappers = []interface{}{}
- file_lure_proto_msgTypes[2].OneofWrappers = []interface{}{}
- type x struct{}
- out := protoimpl.TypeBuilder{
- File: protoimpl.DescBuilder{
- GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
- RawDescriptor: file_lure_proto_rawDesc,
- NumEnums: 2,
- NumMessages: 9,
- NumExtensions: 0,
- NumServices: 1,
- },
- GoTypes: file_lure_proto_goTypes,
- DependencyIndexes: file_lure_proto_depIdxs,
- EnumInfos: file_lure_proto_enumTypes,
- MessageInfos: file_lure_proto_msgTypes,
- }.Build()
- File_lure_proto = out.File
- file_lure_proto_rawDesc = nil
- file_lure_proto_goTypes = nil
- file_lure_proto_depIdxs = nil
-}
diff --git a/cmd/lure-api-server/internal/api/lure.proto b/cmd/lure-api-server/internal/api/lure.proto
deleted file mode 100644
index 06c2105..0000000
--- a/cmd/lure-api-server/internal/api/lure.proto
+++ /dev/null
@@ -1,82 +0,0 @@
-syntax = "proto3";
-package lure;
-
-// Slight hack to provide protoc with a package name
-option go_package = "../api";
-
-// SORT_BY represents possible things to sort packages by
-enum SORT_BY {
- UNSORTED = 0;
- NAME = 1;
- REPOSITORY = 2;
- VERSION = 3;
-}
-
-// FILTER_TYPE represents possible filters for packages
-enum FILTER_TYPE {
- NO_FILTER = 0;
- IN_REPOSITORY = 1;
- SUPPORTS_ARCH = 2;
-}
-
-// SearchRequest is a request to search for packages
-message SearchRequest {
- string query = 1;
- int64 limit = 2;
- SORT_BY sort_by = 3;
- FILTER_TYPE filter_type = 4;
- optional string filter_value = 5;
-}
-
-// StringList contains a list of strings
-message StringList {
- repeated string entries = 1;
-}
-
-// Package represents a LURE package
-message Package {
- string name = 1;
- string repository = 2;
- string version = 3;
- int64 release = 4;
- optional int64 epoch = 5;
- optional string description = 6;
- optional string homepage = 7;
- optional string maintainer = 8;
- repeated string architectures = 9;
- repeated string licenses = 10;
- repeated string provides = 11;
- repeated string conflicts = 12;
- repeated string replaces = 13;
- map depends = 14;
- map build_depends = 15;
-}
-
-message GetPackageRequest {
- string name = 1;
- string repository = 2;
-}
-
-// SearchResponse contains returned packages
-message SearchResponse {
- repeated Package packages = 1;
-}
-
-message GetBuildScriptRequest {
- string name = 1;
- string repository = 2;
-}
-
-message GetBuildScriptResponse {
- string script = 1;
-}
-
-// Web is the LURE Web service
-service API {
- // Search searches through LURE packages in the database
- rpc Search(SearchRequest) returns (SearchResponse);
- // GetPkg gets a single LURE package from the database
- rpc GetPkg(GetPackageRequest) returns (Package);
- // GetBuildScript returns the build script for the given package
- rpc GetBuildScript(GetBuildScriptRequest) returns (GetBuildScriptResponse);
-}
\ No newline at end of file
diff --git a/cmd/lure-api-server/internal/api/lure.twirp.go b/cmd/lure-api-server/internal/api/lure.twirp.go
deleted file mode 100644
index c2e1927..0000000
--- a/cmd/lure-api-server/internal/api/lure.twirp.go
+++ /dev/null
@@ -1,1709 +0,0 @@
-// Code generated by protoc-gen-twirp v8.1.3, DO NOT EDIT.
-// source: lure.proto
-
-package api
-
-import (
- context "context"
- fmt "fmt"
- http "net/http"
- io "io"
- json "encoding/json"
- strconv "strconv"
- strings "strings"
-)
-
-import (
- protojson "google.golang.org/protobuf/encoding/protojson"
- proto "google.golang.org/protobuf/proto"
- twirp "github.com/twitchtv/twirp"
- ctxsetters "github.com/twitchtv/twirp/ctxsetters"
-)
-
-import (
- bytes "bytes"
- errors "errors"
- path "path"
- url "net/url"
-)
-
-// Version compatibility assertion.
-// If the constant is not defined in the package, that likely means
-// the package needs to be updated to work with this generated code.
-// See https://twitchtv.github.io/twirp/docs/version_matrix.html
-const _ = twirp.TwirpPackageMinVersion_8_1_0
-
-// =============
-// API Interface
-// =============
-
-// Web is the LURE Web service
-type API interface {
- // Search searches through LURE packages in the database
- Search(context.Context, *SearchRequest) (*SearchResponse, error)
-
- // GetPkg gets a single LURE package from the database
- GetPkg(context.Context, *GetPackageRequest) (*Package, error)
-
- // GetBuildScript returns the build script for the given package
- GetBuildScript(context.Context, *GetBuildScriptRequest) (*GetBuildScriptResponse, error)
-}
-
-// ===================
-// API Protobuf Client
-// ===================
-
-type aPIProtobufClient struct {
- client HTTPClient
- urls [3]string
- interceptor twirp.Interceptor
- opts twirp.ClientOptions
-}
-
-// NewAPIProtobufClient creates a Protobuf client that implements the API interface.
-// It communicates using Protobuf and can be configured with a custom HTTPClient.
-func NewAPIProtobufClient(baseURL string, client HTTPClient, opts ...twirp.ClientOption) API {
- if c, ok := client.(*http.Client); ok {
- client = withoutRedirects(c)
- }
-
- clientOpts := twirp.ClientOptions{}
- for _, o := range opts {
- o(&clientOpts)
- }
-
- // Using ReadOpt allows backwards and forwards compatibility with new options in the future
- literalURLs := false
- _ = clientOpts.ReadOpt("literalURLs", &literalURLs)
- var pathPrefix string
- if ok := clientOpts.ReadOpt("pathPrefix", &pathPrefix); !ok {
- pathPrefix = "/twirp" // default prefix
- }
-
- // Build method URLs: []/./
- serviceURL := sanitizeBaseURL(baseURL)
- serviceURL += baseServicePath(pathPrefix, "lure", "API")
- urls := [3]string{
- serviceURL + "Search",
- serviceURL + "GetPkg",
- serviceURL + "GetBuildScript",
- }
-
- return &aPIProtobufClient{
- client: client,
- urls: urls,
- interceptor: twirp.ChainInterceptors(clientOpts.Interceptors...),
- opts: clientOpts,
- }
-}
-
-func (c *aPIProtobufClient) Search(ctx context.Context, in *SearchRequest) (*SearchResponse, error) {
- ctx = ctxsetters.WithPackageName(ctx, "lure")
- ctx = ctxsetters.WithServiceName(ctx, "API")
- ctx = ctxsetters.WithMethodName(ctx, "Search")
- caller := c.callSearch
- if c.interceptor != nil {
- caller = func(ctx context.Context, req *SearchRequest) (*SearchResponse, error) {
- resp, err := c.interceptor(
- func(ctx context.Context, req interface{}) (interface{}, error) {
- typedReq, ok := req.(*SearchRequest)
- if !ok {
- return nil, twirp.InternalError("failed type assertion req.(*SearchRequest) when calling interceptor")
- }
- return c.callSearch(ctx, typedReq)
- },
- )(ctx, req)
- if resp != nil {
- typedResp, ok := resp.(*SearchResponse)
- if !ok {
- return nil, twirp.InternalError("failed type assertion resp.(*SearchResponse) when calling interceptor")
- }
- return typedResp, err
- }
- return nil, err
- }
- }
- return caller(ctx, in)
-}
-
-func (c *aPIProtobufClient) callSearch(ctx context.Context, in *SearchRequest) (*SearchResponse, error) {
- out := new(SearchResponse)
- ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[0], in, out)
- if err != nil {
- twerr, ok := err.(twirp.Error)
- if !ok {
- twerr = twirp.InternalErrorWith(err)
- }
- callClientError(ctx, c.opts.Hooks, twerr)
- return nil, err
- }
-
- callClientResponseReceived(ctx, c.opts.Hooks)
-
- return out, nil
-}
-
-func (c *aPIProtobufClient) GetPkg(ctx context.Context, in *GetPackageRequest) (*Package, error) {
- ctx = ctxsetters.WithPackageName(ctx, "lure")
- ctx = ctxsetters.WithServiceName(ctx, "API")
- ctx = ctxsetters.WithMethodName(ctx, "GetPkg")
- caller := c.callGetPkg
- if c.interceptor != nil {
- caller = func(ctx context.Context, req *GetPackageRequest) (*Package, error) {
- resp, err := c.interceptor(
- func(ctx context.Context, req interface{}) (interface{}, error) {
- typedReq, ok := req.(*GetPackageRequest)
- if !ok {
- return nil, twirp.InternalError("failed type assertion req.(*GetPackageRequest) when calling interceptor")
- }
- return c.callGetPkg(ctx, typedReq)
- },
- )(ctx, req)
- if resp != nil {
- typedResp, ok := resp.(*Package)
- if !ok {
- return nil, twirp.InternalError("failed type assertion resp.(*Package) when calling interceptor")
- }
- return typedResp, err
- }
- return nil, err
- }
- }
- return caller(ctx, in)
-}
-
-func (c *aPIProtobufClient) callGetPkg(ctx context.Context, in *GetPackageRequest) (*Package, error) {
- out := new(Package)
- ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[1], in, out)
- if err != nil {
- twerr, ok := err.(twirp.Error)
- if !ok {
- twerr = twirp.InternalErrorWith(err)
- }
- callClientError(ctx, c.opts.Hooks, twerr)
- return nil, err
- }
-
- callClientResponseReceived(ctx, c.opts.Hooks)
-
- return out, nil
-}
-
-func (c *aPIProtobufClient) GetBuildScript(ctx context.Context, in *GetBuildScriptRequest) (*GetBuildScriptResponse, error) {
- ctx = ctxsetters.WithPackageName(ctx, "lure")
- ctx = ctxsetters.WithServiceName(ctx, "API")
- ctx = ctxsetters.WithMethodName(ctx, "GetBuildScript")
- caller := c.callGetBuildScript
- if c.interceptor != nil {
- caller = func(ctx context.Context, req *GetBuildScriptRequest) (*GetBuildScriptResponse, error) {
- resp, err := c.interceptor(
- func(ctx context.Context, req interface{}) (interface{}, error) {
- typedReq, ok := req.(*GetBuildScriptRequest)
- if !ok {
- return nil, twirp.InternalError("failed type assertion req.(*GetBuildScriptRequest) when calling interceptor")
- }
- return c.callGetBuildScript(ctx, typedReq)
- },
- )(ctx, req)
- if resp != nil {
- typedResp, ok := resp.(*GetBuildScriptResponse)
- if !ok {
- return nil, twirp.InternalError("failed type assertion resp.(*GetBuildScriptResponse) when calling interceptor")
- }
- return typedResp, err
- }
- return nil, err
- }
- }
- return caller(ctx, in)
-}
-
-func (c *aPIProtobufClient) callGetBuildScript(ctx context.Context, in *GetBuildScriptRequest) (*GetBuildScriptResponse, error) {
- out := new(GetBuildScriptResponse)
- ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[2], in, out)
- if err != nil {
- twerr, ok := err.(twirp.Error)
- if !ok {
- twerr = twirp.InternalErrorWith(err)
- }
- callClientError(ctx, c.opts.Hooks, twerr)
- return nil, err
- }
-
- callClientResponseReceived(ctx, c.opts.Hooks)
-
- return out, nil
-}
-
-// ===============
-// API JSON Client
-// ===============
-
-type aPIJSONClient struct {
- client HTTPClient
- urls [3]string
- interceptor twirp.Interceptor
- opts twirp.ClientOptions
-}
-
-// NewAPIJSONClient creates a JSON client that implements the API interface.
-// It communicates using JSON and can be configured with a custom HTTPClient.
-func NewAPIJSONClient(baseURL string, client HTTPClient, opts ...twirp.ClientOption) API {
- if c, ok := client.(*http.Client); ok {
- client = withoutRedirects(c)
- }
-
- clientOpts := twirp.ClientOptions{}
- for _, o := range opts {
- o(&clientOpts)
- }
-
- // Using ReadOpt allows backwards and forwards compatibility with new options in the future
- literalURLs := false
- _ = clientOpts.ReadOpt("literalURLs", &literalURLs)
- var pathPrefix string
- if ok := clientOpts.ReadOpt("pathPrefix", &pathPrefix); !ok {
- pathPrefix = "/twirp" // default prefix
- }
-
- // Build method URLs: []/./
- serviceURL := sanitizeBaseURL(baseURL)
- serviceURL += baseServicePath(pathPrefix, "lure", "API")
- urls := [3]string{
- serviceURL + "Search",
- serviceURL + "GetPkg",
- serviceURL + "GetBuildScript",
- }
-
- return &aPIJSONClient{
- client: client,
- urls: urls,
- interceptor: twirp.ChainInterceptors(clientOpts.Interceptors...),
- opts: clientOpts,
- }
-}
-
-func (c *aPIJSONClient) Search(ctx context.Context, in *SearchRequest) (*SearchResponse, error) {
- ctx = ctxsetters.WithPackageName(ctx, "lure")
- ctx = ctxsetters.WithServiceName(ctx, "API")
- ctx = ctxsetters.WithMethodName(ctx, "Search")
- caller := c.callSearch
- if c.interceptor != nil {
- caller = func(ctx context.Context, req *SearchRequest) (*SearchResponse, error) {
- resp, err := c.interceptor(
- func(ctx context.Context, req interface{}) (interface{}, error) {
- typedReq, ok := req.(*SearchRequest)
- if !ok {
- return nil, twirp.InternalError("failed type assertion req.(*SearchRequest) when calling interceptor")
- }
- return c.callSearch(ctx, typedReq)
- },
- )(ctx, req)
- if resp != nil {
- typedResp, ok := resp.(*SearchResponse)
- if !ok {
- return nil, twirp.InternalError("failed type assertion resp.(*SearchResponse) when calling interceptor")
- }
- return typedResp, err
- }
- return nil, err
- }
- }
- return caller(ctx, in)
-}
-
-func (c *aPIJSONClient) callSearch(ctx context.Context, in *SearchRequest) (*SearchResponse, error) {
- out := new(SearchResponse)
- ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[0], in, out)
- if err != nil {
- twerr, ok := err.(twirp.Error)
- if !ok {
- twerr = twirp.InternalErrorWith(err)
- }
- callClientError(ctx, c.opts.Hooks, twerr)
- return nil, err
- }
-
- callClientResponseReceived(ctx, c.opts.Hooks)
-
- return out, nil
-}
-
-func (c *aPIJSONClient) GetPkg(ctx context.Context, in *GetPackageRequest) (*Package, error) {
- ctx = ctxsetters.WithPackageName(ctx, "lure")
- ctx = ctxsetters.WithServiceName(ctx, "API")
- ctx = ctxsetters.WithMethodName(ctx, "GetPkg")
- caller := c.callGetPkg
- if c.interceptor != nil {
- caller = func(ctx context.Context, req *GetPackageRequest) (*Package, error) {
- resp, err := c.interceptor(
- func(ctx context.Context, req interface{}) (interface{}, error) {
- typedReq, ok := req.(*GetPackageRequest)
- if !ok {
- return nil, twirp.InternalError("failed type assertion req.(*GetPackageRequest) when calling interceptor")
- }
- return c.callGetPkg(ctx, typedReq)
- },
- )(ctx, req)
- if resp != nil {
- typedResp, ok := resp.(*Package)
- if !ok {
- return nil, twirp.InternalError("failed type assertion resp.(*Package) when calling interceptor")
- }
- return typedResp, err
- }
- return nil, err
- }
- }
- return caller(ctx, in)
-}
-
-func (c *aPIJSONClient) callGetPkg(ctx context.Context, in *GetPackageRequest) (*Package, error) {
- out := new(Package)
- ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[1], in, out)
- if err != nil {
- twerr, ok := err.(twirp.Error)
- if !ok {
- twerr = twirp.InternalErrorWith(err)
- }
- callClientError(ctx, c.opts.Hooks, twerr)
- return nil, err
- }
-
- callClientResponseReceived(ctx, c.opts.Hooks)
-
- return out, nil
-}
-
-func (c *aPIJSONClient) GetBuildScript(ctx context.Context, in *GetBuildScriptRequest) (*GetBuildScriptResponse, error) {
- ctx = ctxsetters.WithPackageName(ctx, "lure")
- ctx = ctxsetters.WithServiceName(ctx, "API")
- ctx = ctxsetters.WithMethodName(ctx, "GetBuildScript")
- caller := c.callGetBuildScript
- if c.interceptor != nil {
- caller = func(ctx context.Context, req *GetBuildScriptRequest) (*GetBuildScriptResponse, error) {
- resp, err := c.interceptor(
- func(ctx context.Context, req interface{}) (interface{}, error) {
- typedReq, ok := req.(*GetBuildScriptRequest)
- if !ok {
- return nil, twirp.InternalError("failed type assertion req.(*GetBuildScriptRequest) when calling interceptor")
- }
- return c.callGetBuildScript(ctx, typedReq)
- },
- )(ctx, req)
- if resp != nil {
- typedResp, ok := resp.(*GetBuildScriptResponse)
- if !ok {
- return nil, twirp.InternalError("failed type assertion resp.(*GetBuildScriptResponse) when calling interceptor")
- }
- return typedResp, err
- }
- return nil, err
- }
- }
- return caller(ctx, in)
-}
-
-func (c *aPIJSONClient) callGetBuildScript(ctx context.Context, in *GetBuildScriptRequest) (*GetBuildScriptResponse, error) {
- out := new(GetBuildScriptResponse)
- ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[2], in, out)
- if err != nil {
- twerr, ok := err.(twirp.Error)
- if !ok {
- twerr = twirp.InternalErrorWith(err)
- }
- callClientError(ctx, c.opts.Hooks, twerr)
- return nil, err
- }
-
- callClientResponseReceived(ctx, c.opts.Hooks)
-
- return out, nil
-}
-
-// ==================
-// API Server Handler
-// ==================
-
-type aPIServer struct {
- API
- interceptor twirp.Interceptor
- hooks *twirp.ServerHooks
- pathPrefix string // prefix for routing
- jsonSkipDefaults bool // do not include unpopulated fields (default values) in the response
- jsonCamelCase bool // JSON fields are serialized as lowerCamelCase rather than keeping the original proto names
-}
-
-// NewAPIServer builds a TwirpServer that can be used as an http.Handler to handle
-// HTTP requests that are routed to the right method in the provided svc implementation.
-// The opts are twirp.ServerOption modifiers, for example twirp.WithServerHooks(hooks).
-func NewAPIServer(svc API, opts ...interface{}) TwirpServer {
- serverOpts := newServerOpts(opts)
-
- // Using ReadOpt allows backwards and forwards compatibility with new options in the future
- jsonSkipDefaults := false
- _ = serverOpts.ReadOpt("jsonSkipDefaults", &jsonSkipDefaults)
- jsonCamelCase := false
- _ = serverOpts.ReadOpt("jsonCamelCase", &jsonCamelCase)
- var pathPrefix string
- if ok := serverOpts.ReadOpt("pathPrefix", &pathPrefix); !ok {
- pathPrefix = "/twirp" // default prefix
- }
-
- return &aPIServer{
- API: svc,
- hooks: serverOpts.Hooks,
- interceptor: twirp.ChainInterceptors(serverOpts.Interceptors...),
- pathPrefix: pathPrefix,
- jsonSkipDefaults: jsonSkipDefaults,
- jsonCamelCase: jsonCamelCase,
- }
-}
-
-// writeError writes an HTTP response with a valid Twirp error format, and triggers hooks.
-// If err is not a twirp.Error, it will get wrapped with twirp.InternalErrorWith(err)
-func (s *aPIServer) writeError(ctx context.Context, resp http.ResponseWriter, err error) {
- writeError(ctx, resp, err, s.hooks)
-}
-
-// handleRequestBodyError is used to handle error when the twirp server cannot read request
-func (s *aPIServer) handleRequestBodyError(ctx context.Context, resp http.ResponseWriter, msg string, err error) {
- if context.Canceled == ctx.Err() {
- s.writeError(ctx, resp, twirp.NewError(twirp.Canceled, "failed to read request: context canceled"))
- return
- }
- if context.DeadlineExceeded == ctx.Err() {
- s.writeError(ctx, resp, twirp.NewError(twirp.DeadlineExceeded, "failed to read request: deadline exceeded"))
- return
- }
- s.writeError(ctx, resp, twirp.WrapError(malformedRequestError(msg), err))
-}
-
-// APIPathPrefix is a convenience constant that may identify URL paths.
-// Should be used with caution, it only matches routes generated by Twirp Go clients,
-// with the default "/twirp" prefix and default CamelCase service and method names.
-// More info: https://twitchtv.github.io/twirp/docs/routing.html
-const APIPathPrefix = "/twirp/lure.API/"
-
-func (s *aPIServer) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
- ctx := req.Context()
- ctx = ctxsetters.WithPackageName(ctx, "lure")
- ctx = ctxsetters.WithServiceName(ctx, "API")
- ctx = ctxsetters.WithResponseWriter(ctx, resp)
-
- var err error
- ctx, err = callRequestReceived(ctx, s.hooks)
- if err != nil {
- s.writeError(ctx, resp, err)
- return
- }
-
- if req.Method != "POST" {
- msg := fmt.Sprintf("unsupported method %q (only POST is allowed)", req.Method)
- s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path))
- return
- }
-
- // Verify path format: []/./
- prefix, pkgService, method := parseTwirpPath(req.URL.Path)
- if pkgService != "lure.API" {
- msg := fmt.Sprintf("no handler for path %q", req.URL.Path)
- s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path))
- return
- }
- if prefix != s.pathPrefix {
- msg := fmt.Sprintf("invalid path prefix %q, expected %q, on path %q", prefix, s.pathPrefix, req.URL.Path)
- s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path))
- return
- }
-
- switch method {
- case "Search":
- s.serveSearch(ctx, resp, req)
- return
- case "GetPkg":
- s.serveGetPkg(ctx, resp, req)
- return
- case "GetBuildScript":
- s.serveGetBuildScript(ctx, resp, req)
- return
- default:
- msg := fmt.Sprintf("no handler for path %q", req.URL.Path)
- s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path))
- return
- }
-}
-
-func (s *aPIServer) serveSearch(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
- header := req.Header.Get("Content-Type")
- i := strings.Index(header, ";")
- if i == -1 {
- i = len(header)
- }
- switch strings.TrimSpace(strings.ToLower(header[:i])) {
- case "application/json":
- s.serveSearchJSON(ctx, resp, req)
- case "application/protobuf":
- s.serveSearchProtobuf(ctx, resp, req)
- default:
- msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type"))
- twerr := badRouteError(msg, req.Method, req.URL.Path)
- s.writeError(ctx, resp, twerr)
- }
-}
-
-func (s *aPIServer) serveSearchJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
- var err error
- ctx = ctxsetters.WithMethodName(ctx, "Search")
- ctx, err = callRequestRouted(ctx, s.hooks)
- if err != nil {
- s.writeError(ctx, resp, err)
- return
- }
-
- d := json.NewDecoder(req.Body)
- rawReqBody := json.RawMessage{}
- if err := d.Decode(&rawReqBody); err != nil {
- s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err)
- return
- }
- reqContent := new(SearchRequest)
- unmarshaler := protojson.UnmarshalOptions{DiscardUnknown: true}
- if err = unmarshaler.Unmarshal(rawReqBody, reqContent); err != nil {
- s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err)
- return
- }
-
- handler := s.API.Search
- if s.interceptor != nil {
- handler = func(ctx context.Context, req *SearchRequest) (*SearchResponse, error) {
- resp, err := s.interceptor(
- func(ctx context.Context, req interface{}) (interface{}, error) {
- typedReq, ok := req.(*SearchRequest)
- if !ok {
- return nil, twirp.InternalError("failed type assertion req.(*SearchRequest) when calling interceptor")
- }
- return s.API.Search(ctx, typedReq)
- },
- )(ctx, req)
- if resp != nil {
- typedResp, ok := resp.(*SearchResponse)
- if !ok {
- return nil, twirp.InternalError("failed type assertion resp.(*SearchResponse) when calling interceptor")
- }
- return typedResp, err
- }
- return nil, err
- }
- }
-
- // Call service method
- var respContent *SearchResponse
- func() {
- defer ensurePanicResponses(ctx, resp, s.hooks)
- respContent, err = handler(ctx, reqContent)
- }()
-
- if err != nil {
- s.writeError(ctx, resp, err)
- return
- }
- if respContent == nil {
- s.writeError(ctx, resp, twirp.InternalError("received a nil *SearchResponse and nil error while calling Search. nil responses are not supported"))
- return
- }
-
- ctx = callResponsePrepared(ctx, s.hooks)
-
- marshaler := &protojson.MarshalOptions{UseProtoNames: !s.jsonCamelCase, EmitUnpopulated: !s.jsonSkipDefaults}
- respBytes, err := marshaler.Marshal(respContent)
- if err != nil {
- s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response"))
- return
- }
-
- ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
- resp.Header().Set("Content-Type", "application/json")
- resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
- resp.WriteHeader(http.StatusOK)
-
- if n, err := resp.Write(respBytes); err != nil {
- msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
- twerr := twirp.NewError(twirp.Unknown, msg)
- ctx = callError(ctx, s.hooks, twerr)
- }
- callResponseSent(ctx, s.hooks)
-}
-
-func (s *aPIServer) serveSearchProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
- var err error
- ctx = ctxsetters.WithMethodName(ctx, "Search")
- ctx, err = callRequestRouted(ctx, s.hooks)
- if err != nil {
- s.writeError(ctx, resp, err)
- return
- }
-
- buf, err := io.ReadAll(req.Body)
- if err != nil {
- s.handleRequestBodyError(ctx, resp, "failed to read request body", err)
- return
- }
- reqContent := new(SearchRequest)
- if err = proto.Unmarshal(buf, reqContent); err != nil {
- s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
- return
- }
-
- handler := s.API.Search
- if s.interceptor != nil {
- handler = func(ctx context.Context, req *SearchRequest) (*SearchResponse, error) {
- resp, err := s.interceptor(
- func(ctx context.Context, req interface{}) (interface{}, error) {
- typedReq, ok := req.(*SearchRequest)
- if !ok {
- return nil, twirp.InternalError("failed type assertion req.(*SearchRequest) when calling interceptor")
- }
- return s.API.Search(ctx, typedReq)
- },
- )(ctx, req)
- if resp != nil {
- typedResp, ok := resp.(*SearchResponse)
- if !ok {
- return nil, twirp.InternalError("failed type assertion resp.(*SearchResponse) when calling interceptor")
- }
- return typedResp, err
- }
- return nil, err
- }
- }
-
- // Call service method
- var respContent *SearchResponse
- func() {
- defer ensurePanicResponses(ctx, resp, s.hooks)
- respContent, err = handler(ctx, reqContent)
- }()
-
- if err != nil {
- s.writeError(ctx, resp, err)
- return
- }
- if respContent == nil {
- s.writeError(ctx, resp, twirp.InternalError("received a nil *SearchResponse and nil error while calling Search. nil responses are not supported"))
- return
- }
-
- ctx = callResponsePrepared(ctx, s.hooks)
-
- respBytes, err := proto.Marshal(respContent)
- if err != nil {
- s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response"))
- return
- }
-
- ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
- resp.Header().Set("Content-Type", "application/protobuf")
- resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
- resp.WriteHeader(http.StatusOK)
- if n, err := resp.Write(respBytes); err != nil {
- msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
- twerr := twirp.NewError(twirp.Unknown, msg)
- ctx = callError(ctx, s.hooks, twerr)
- }
- callResponseSent(ctx, s.hooks)
-}
-
-func (s *aPIServer) serveGetPkg(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
- header := req.Header.Get("Content-Type")
- i := strings.Index(header, ";")
- if i == -1 {
- i = len(header)
- }
- switch strings.TrimSpace(strings.ToLower(header[:i])) {
- case "application/json":
- s.serveGetPkgJSON(ctx, resp, req)
- case "application/protobuf":
- s.serveGetPkgProtobuf(ctx, resp, req)
- default:
- msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type"))
- twerr := badRouteError(msg, req.Method, req.URL.Path)
- s.writeError(ctx, resp, twerr)
- }
-}
-
-func (s *aPIServer) serveGetPkgJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
- var err error
- ctx = ctxsetters.WithMethodName(ctx, "GetPkg")
- ctx, err = callRequestRouted(ctx, s.hooks)
- if err != nil {
- s.writeError(ctx, resp, err)
- return
- }
-
- d := json.NewDecoder(req.Body)
- rawReqBody := json.RawMessage{}
- if err := d.Decode(&rawReqBody); err != nil {
- s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err)
- return
- }
- reqContent := new(GetPackageRequest)
- unmarshaler := protojson.UnmarshalOptions{DiscardUnknown: true}
- if err = unmarshaler.Unmarshal(rawReqBody, reqContent); err != nil {
- s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err)
- return
- }
-
- handler := s.API.GetPkg
- if s.interceptor != nil {
- handler = func(ctx context.Context, req *GetPackageRequest) (*Package, error) {
- resp, err := s.interceptor(
- func(ctx context.Context, req interface{}) (interface{}, error) {
- typedReq, ok := req.(*GetPackageRequest)
- if !ok {
- return nil, twirp.InternalError("failed type assertion req.(*GetPackageRequest) when calling interceptor")
- }
- return s.API.GetPkg(ctx, typedReq)
- },
- )(ctx, req)
- if resp != nil {
- typedResp, ok := resp.(*Package)
- if !ok {
- return nil, twirp.InternalError("failed type assertion resp.(*Package) when calling interceptor")
- }
- return typedResp, err
- }
- return nil, err
- }
- }
-
- // Call service method
- var respContent *Package
- func() {
- defer ensurePanicResponses(ctx, resp, s.hooks)
- respContent, err = handler(ctx, reqContent)
- }()
-
- if err != nil {
- s.writeError(ctx, resp, err)
- return
- }
- if respContent == nil {
- s.writeError(ctx, resp, twirp.InternalError("received a nil *Package and nil error while calling GetPkg. nil responses are not supported"))
- return
- }
-
- ctx = callResponsePrepared(ctx, s.hooks)
-
- marshaler := &protojson.MarshalOptions{UseProtoNames: !s.jsonCamelCase, EmitUnpopulated: !s.jsonSkipDefaults}
- respBytes, err := marshaler.Marshal(respContent)
- if err != nil {
- s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response"))
- return
- }
-
- ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
- resp.Header().Set("Content-Type", "application/json")
- resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
- resp.WriteHeader(http.StatusOK)
-
- if n, err := resp.Write(respBytes); err != nil {
- msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
- twerr := twirp.NewError(twirp.Unknown, msg)
- ctx = callError(ctx, s.hooks, twerr)
- }
- callResponseSent(ctx, s.hooks)
-}
-
-func (s *aPIServer) serveGetPkgProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
- var err error
- ctx = ctxsetters.WithMethodName(ctx, "GetPkg")
- ctx, err = callRequestRouted(ctx, s.hooks)
- if err != nil {
- s.writeError(ctx, resp, err)
- return
- }
-
- buf, err := io.ReadAll(req.Body)
- if err != nil {
- s.handleRequestBodyError(ctx, resp, "failed to read request body", err)
- return
- }
- reqContent := new(GetPackageRequest)
- if err = proto.Unmarshal(buf, reqContent); err != nil {
- s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
- return
- }
-
- handler := s.API.GetPkg
- if s.interceptor != nil {
- handler = func(ctx context.Context, req *GetPackageRequest) (*Package, error) {
- resp, err := s.interceptor(
- func(ctx context.Context, req interface{}) (interface{}, error) {
- typedReq, ok := req.(*GetPackageRequest)
- if !ok {
- return nil, twirp.InternalError("failed type assertion req.(*GetPackageRequest) when calling interceptor")
- }
- return s.API.GetPkg(ctx, typedReq)
- },
- )(ctx, req)
- if resp != nil {
- typedResp, ok := resp.(*Package)
- if !ok {
- return nil, twirp.InternalError("failed type assertion resp.(*Package) when calling interceptor")
- }
- return typedResp, err
- }
- return nil, err
- }
- }
-
- // Call service method
- var respContent *Package
- func() {
- defer ensurePanicResponses(ctx, resp, s.hooks)
- respContent, err = handler(ctx, reqContent)
- }()
-
- if err != nil {
- s.writeError(ctx, resp, err)
- return
- }
- if respContent == nil {
- s.writeError(ctx, resp, twirp.InternalError("received a nil *Package and nil error while calling GetPkg. nil responses are not supported"))
- return
- }
-
- ctx = callResponsePrepared(ctx, s.hooks)
-
- respBytes, err := proto.Marshal(respContent)
- if err != nil {
- s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response"))
- return
- }
-
- ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
- resp.Header().Set("Content-Type", "application/protobuf")
- resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
- resp.WriteHeader(http.StatusOK)
- if n, err := resp.Write(respBytes); err != nil {
- msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
- twerr := twirp.NewError(twirp.Unknown, msg)
- ctx = callError(ctx, s.hooks, twerr)
- }
- callResponseSent(ctx, s.hooks)
-}
-
-func (s *aPIServer) serveGetBuildScript(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
- header := req.Header.Get("Content-Type")
- i := strings.Index(header, ";")
- if i == -1 {
- i = len(header)
- }
- switch strings.TrimSpace(strings.ToLower(header[:i])) {
- case "application/json":
- s.serveGetBuildScriptJSON(ctx, resp, req)
- case "application/protobuf":
- s.serveGetBuildScriptProtobuf(ctx, resp, req)
- default:
- msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type"))
- twerr := badRouteError(msg, req.Method, req.URL.Path)
- s.writeError(ctx, resp, twerr)
- }
-}
-
-func (s *aPIServer) serveGetBuildScriptJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
- var err error
- ctx = ctxsetters.WithMethodName(ctx, "GetBuildScript")
- ctx, err = callRequestRouted(ctx, s.hooks)
- if err != nil {
- s.writeError(ctx, resp, err)
- return
- }
-
- d := json.NewDecoder(req.Body)
- rawReqBody := json.RawMessage{}
- if err := d.Decode(&rawReqBody); err != nil {
- s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err)
- return
- }
- reqContent := new(GetBuildScriptRequest)
- unmarshaler := protojson.UnmarshalOptions{DiscardUnknown: true}
- if err = unmarshaler.Unmarshal(rawReqBody, reqContent); err != nil {
- s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err)
- return
- }
-
- handler := s.API.GetBuildScript
- if s.interceptor != nil {
- handler = func(ctx context.Context, req *GetBuildScriptRequest) (*GetBuildScriptResponse, error) {
- resp, err := s.interceptor(
- func(ctx context.Context, req interface{}) (interface{}, error) {
- typedReq, ok := req.(*GetBuildScriptRequest)
- if !ok {
- return nil, twirp.InternalError("failed type assertion req.(*GetBuildScriptRequest) when calling interceptor")
- }
- return s.API.GetBuildScript(ctx, typedReq)
- },
- )(ctx, req)
- if resp != nil {
- typedResp, ok := resp.(*GetBuildScriptResponse)
- if !ok {
- return nil, twirp.InternalError("failed type assertion resp.(*GetBuildScriptResponse) when calling interceptor")
- }
- return typedResp, err
- }
- return nil, err
- }
- }
-
- // Call service method
- var respContent *GetBuildScriptResponse
- func() {
- defer ensurePanicResponses(ctx, resp, s.hooks)
- respContent, err = handler(ctx, reqContent)
- }()
-
- if err != nil {
- s.writeError(ctx, resp, err)
- return
- }
- if respContent == nil {
- s.writeError(ctx, resp, twirp.InternalError("received a nil *GetBuildScriptResponse and nil error while calling GetBuildScript. nil responses are not supported"))
- return
- }
-
- ctx = callResponsePrepared(ctx, s.hooks)
-
- marshaler := &protojson.MarshalOptions{UseProtoNames: !s.jsonCamelCase, EmitUnpopulated: !s.jsonSkipDefaults}
- respBytes, err := marshaler.Marshal(respContent)
- if err != nil {
- s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response"))
- return
- }
-
- ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
- resp.Header().Set("Content-Type", "application/json")
- resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
- resp.WriteHeader(http.StatusOK)
-
- if n, err := resp.Write(respBytes); err != nil {
- msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
- twerr := twirp.NewError(twirp.Unknown, msg)
- ctx = callError(ctx, s.hooks, twerr)
- }
- callResponseSent(ctx, s.hooks)
-}
-
-func (s *aPIServer) serveGetBuildScriptProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
- var err error
- ctx = ctxsetters.WithMethodName(ctx, "GetBuildScript")
- ctx, err = callRequestRouted(ctx, s.hooks)
- if err != nil {
- s.writeError(ctx, resp, err)
- return
- }
-
- buf, err := io.ReadAll(req.Body)
- if err != nil {
- s.handleRequestBodyError(ctx, resp, "failed to read request body", err)
- return
- }
- reqContent := new(GetBuildScriptRequest)
- if err = proto.Unmarshal(buf, reqContent); err != nil {
- s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
- return
- }
-
- handler := s.API.GetBuildScript
- if s.interceptor != nil {
- handler = func(ctx context.Context, req *GetBuildScriptRequest) (*GetBuildScriptResponse, error) {
- resp, err := s.interceptor(
- func(ctx context.Context, req interface{}) (interface{}, error) {
- typedReq, ok := req.(*GetBuildScriptRequest)
- if !ok {
- return nil, twirp.InternalError("failed type assertion req.(*GetBuildScriptRequest) when calling interceptor")
- }
- return s.API.GetBuildScript(ctx, typedReq)
- },
- )(ctx, req)
- if resp != nil {
- typedResp, ok := resp.(*GetBuildScriptResponse)
- if !ok {
- return nil, twirp.InternalError("failed type assertion resp.(*GetBuildScriptResponse) when calling interceptor")
- }
- return typedResp, err
- }
- return nil, err
- }
- }
-
- // Call service method
- var respContent *GetBuildScriptResponse
- func() {
- defer ensurePanicResponses(ctx, resp, s.hooks)
- respContent, err = handler(ctx, reqContent)
- }()
-
- if err != nil {
- s.writeError(ctx, resp, err)
- return
- }
- if respContent == nil {
- s.writeError(ctx, resp, twirp.InternalError("received a nil *GetBuildScriptResponse and nil error while calling GetBuildScript. nil responses are not supported"))
- return
- }
-
- ctx = callResponsePrepared(ctx, s.hooks)
-
- respBytes, err := proto.Marshal(respContent)
- if err != nil {
- s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response"))
- return
- }
-
- ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
- resp.Header().Set("Content-Type", "application/protobuf")
- resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
- resp.WriteHeader(http.StatusOK)
- if n, err := resp.Write(respBytes); err != nil {
- msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
- twerr := twirp.NewError(twirp.Unknown, msg)
- ctx = callError(ctx, s.hooks, twerr)
- }
- callResponseSent(ctx, s.hooks)
-}
-
-func (s *aPIServer) ServiceDescriptor() ([]byte, int) {
- return twirpFileDescriptor0, 0
-}
-
-func (s *aPIServer) ProtocGenTwirpVersion() string {
- return "v8.1.3"
-}
-
-// PathPrefix returns the base service path, in the form: "//./"
-// that is everything in a Twirp route except for the . This can be used for routing,
-// for example to identify the requests that are targeted to this service in a mux.
-func (s *aPIServer) PathPrefix() string {
- return baseServicePath(s.pathPrefix, "lure", "API")
-}
-
-// =====
-// Utils
-// =====
-
-// HTTPClient is the interface used by generated clients to send HTTP requests.
-// It is fulfilled by *(net/http).Client, which is sufficient for most users.
-// Users can provide their own implementation for special retry policies.
-//
-// HTTPClient implementations should not follow redirects. Redirects are
-// automatically disabled if *(net/http).Client is passed to client
-// constructors. See the withoutRedirects function in this file for more
-// details.
-type HTTPClient interface {
- Do(req *http.Request) (*http.Response, error)
-}
-
-// TwirpServer is the interface generated server structs will support: they're
-// HTTP handlers with additional methods for accessing metadata about the
-// service. Those accessors are a low-level API for building reflection tools.
-// Most people can think of TwirpServers as just http.Handlers.
-type TwirpServer interface {
- http.Handler
-
- // ServiceDescriptor returns gzipped bytes describing the .proto file that
- // this service was generated from. Once unzipped, the bytes can be
- // unmarshalled as a
- // google.golang.org/protobuf/types/descriptorpb.FileDescriptorProto.
- //
- // The returned integer is the index of this particular service within that
- // FileDescriptorProto's 'Service' slice of ServiceDescriptorProtos. This is a
- // low-level field, expected to be used for reflection.
- ServiceDescriptor() ([]byte, int)
-
- // ProtocGenTwirpVersion is the semantic version string of the version of
- // twirp used to generate this file.
- ProtocGenTwirpVersion() string
-
- // PathPrefix returns the HTTP URL path prefix for all methods handled by this
- // service. This can be used with an HTTP mux to route Twirp requests.
- // The path prefix is in the form: "//./"
- // that is, everything in a Twirp route except for the at the end.
- PathPrefix() string
-}
-
-func newServerOpts(opts []interface{}) *twirp.ServerOptions {
- serverOpts := &twirp.ServerOptions{}
- for _, opt := range opts {
- switch o := opt.(type) {
- case twirp.ServerOption:
- o(serverOpts)
- case *twirp.ServerHooks: // backwards compatibility, allow to specify hooks as an argument
- twirp.WithServerHooks(o)(serverOpts)
- case nil: // backwards compatibility, allow nil value for the argument
- continue
- default:
- panic(fmt.Sprintf("Invalid option type %T, please use a twirp.ServerOption", o))
- }
- }
- return serverOpts
-}
-
-// WriteError writes an HTTP response with a valid Twirp error format (code, msg, meta).
-// Useful outside of the Twirp server (e.g. http middleware), but does not trigger hooks.
-// If err is not a twirp.Error, it will get wrapped with twirp.InternalErrorWith(err)
-func WriteError(resp http.ResponseWriter, err error) {
- writeError(context.Background(), resp, err, nil)
-}
-
-// writeError writes Twirp errors in the response and triggers hooks.
-func writeError(ctx context.Context, resp http.ResponseWriter, err error, hooks *twirp.ServerHooks) {
- // Convert to a twirp.Error. Non-twirp errors are converted to internal errors.
- var twerr twirp.Error
- if !errors.As(err, &twerr) {
- twerr = twirp.InternalErrorWith(err)
- }
-
- statusCode := twirp.ServerHTTPStatusFromErrorCode(twerr.Code())
- ctx = ctxsetters.WithStatusCode(ctx, statusCode)
- ctx = callError(ctx, hooks, twerr)
-
- respBody := marshalErrorToJSON(twerr)
-
- resp.Header().Set("Content-Type", "application/json") // Error responses are always JSON
- resp.Header().Set("Content-Length", strconv.Itoa(len(respBody)))
- resp.WriteHeader(statusCode) // set HTTP status code and send response
-
- _, writeErr := resp.Write(respBody)
- if writeErr != nil {
- // We have three options here. We could log the error, call the Error
- // hook, or just silently ignore the error.
- //
- // Logging is unacceptable because we don't have a user-controlled
- // logger; writing out to stderr without permission is too rude.
- //
- // Calling the Error hook would confuse users: it would mean the Error
- // hook got called twice for one request, which is likely to lead to
- // duplicated log messages and metrics, no matter how well we document
- // the behavior.
- //
- // Silently ignoring the error is our least-bad option. It's highly
- // likely that the connection is broken and the original 'err' says
- // so anyway.
- _ = writeErr
- }
-
- callResponseSent(ctx, hooks)
-}
-
-// sanitizeBaseURL parses the the baseURL, and adds the "http" scheme if needed.
-// If the URL is unparsable, the baseURL is returned unchanged.
-func sanitizeBaseURL(baseURL string) string {
- u, err := url.Parse(baseURL)
- if err != nil {
- return baseURL // invalid URL will fail later when making requests
- }
- if u.Scheme == "" {
- u.Scheme = "http"
- }
- return u.String()
-}
-
-// baseServicePath composes the path prefix for the service (without ).
-// e.g.: baseServicePath("/twirp", "my.pkg", "MyService")
-//
-// returns => "/twirp/my.pkg.MyService/"
-//
-// e.g.: baseServicePath("", "", "MyService")
-//
-// returns => "/MyService/"
-func baseServicePath(prefix, pkg, service string) string {
- fullServiceName := service
- if pkg != "" {
- fullServiceName = pkg + "." + service
- }
- return path.Join("/", prefix, fullServiceName) + "/"
-}
-
-// parseTwirpPath extracts path components form a valid Twirp route.
-// Expected format: "[]/./"
-// e.g.: prefix, pkgService, method := parseTwirpPath("/twirp/pkg.Svc/MakeHat")
-func parseTwirpPath(path string) (string, string, string) {
- parts := strings.Split(path, "/")
- if len(parts) < 2 {
- return "", "", ""
- }
- method := parts[len(parts)-1]
- pkgService := parts[len(parts)-2]
- prefix := strings.Join(parts[0:len(parts)-2], "/")
- return prefix, pkgService, method
-}
-
-// getCustomHTTPReqHeaders retrieves a copy of any headers that are set in
-// a context through the twirp.WithHTTPRequestHeaders function.
-// If there are no headers set, or if they have the wrong type, nil is returned.
-func getCustomHTTPReqHeaders(ctx context.Context) http.Header {
- header, ok := twirp.HTTPRequestHeaders(ctx)
- if !ok || header == nil {
- return nil
- }
- copied := make(http.Header)
- for k, vv := range header {
- if vv == nil {
- copied[k] = nil
- continue
- }
- copied[k] = make([]string, len(vv))
- copy(copied[k], vv)
- }
- return copied
-}
-
-// newRequest makes an http.Request from a client, adding common headers.
-func newRequest(ctx context.Context, url string, reqBody io.Reader, contentType string) (*http.Request, error) {
- req, err := http.NewRequest("POST", url, reqBody)
- if err != nil {
- return nil, err
- }
- req = req.WithContext(ctx)
- if customHeader := getCustomHTTPReqHeaders(ctx); customHeader != nil {
- req.Header = customHeader
- }
- req.Header.Set("Accept", contentType)
- req.Header.Set("Content-Type", contentType)
- req.Header.Set("Twirp-Version", "v8.1.3")
- return req, nil
-}
-
-// JSON serialization for errors
-type twerrJSON struct {
- Code string `json:"code"`
- Msg string `json:"msg"`
- Meta map[string]string `json:"meta,omitempty"`
-}
-
-// marshalErrorToJSON returns JSON from a twirp.Error, that can be used as HTTP error response body.
-// If serialization fails, it will use a descriptive Internal error instead.
-func marshalErrorToJSON(twerr twirp.Error) []byte {
- // make sure that msg is not too large
- msg := twerr.Msg()
- if len(msg) > 1e6 {
- msg = msg[:1e6]
- }
-
- tj := twerrJSON{
- Code: string(twerr.Code()),
- Msg: msg,
- Meta: twerr.MetaMap(),
- }
-
- buf, err := json.Marshal(&tj)
- if err != nil {
- buf = []byte("{\"type\": \"" + twirp.Internal + "\", \"msg\": \"There was an error but it could not be serialized into JSON\"}") // fallback
- }
-
- return buf
-}
-
-// errorFromResponse builds a twirp.Error from a non-200 HTTP response.
-// If the response has a valid serialized Twirp error, then it's returned.
-// If not, the response status code is used to generate a similar twirp
-// error. See twirpErrorFromIntermediary for more info on intermediary errors.
-func errorFromResponse(resp *http.Response) twirp.Error {
- statusCode := resp.StatusCode
- statusText := http.StatusText(statusCode)
-
- if isHTTPRedirect(statusCode) {
- // Unexpected redirect: it must be an error from an intermediary.
- // Twirp clients don't follow redirects automatically, Twirp only handles
- // POST requests, redirects should only happen on GET and HEAD requests.
- location := resp.Header.Get("Location")
- msg := fmt.Sprintf("unexpected HTTP status code %d %q received, Location=%q", statusCode, statusText, location)
- return twirpErrorFromIntermediary(statusCode, msg, location)
- }
-
- respBodyBytes, err := io.ReadAll(resp.Body)
- if err != nil {
- return wrapInternal(err, "failed to read server error response body")
- }
-
- var tj twerrJSON
- dec := json.NewDecoder(bytes.NewReader(respBodyBytes))
- dec.DisallowUnknownFields()
- if err := dec.Decode(&tj); err != nil || tj.Code == "" {
- // Invalid JSON response; it must be an error from an intermediary.
- msg := fmt.Sprintf("Error from intermediary with HTTP status code %d %q", statusCode, statusText)
- return twirpErrorFromIntermediary(statusCode, msg, string(respBodyBytes))
- }
-
- errorCode := twirp.ErrorCode(tj.Code)
- if !twirp.IsValidErrorCode(errorCode) {
- msg := "invalid type returned from server error response: " + tj.Code
- return twirp.InternalError(msg).WithMeta("body", string(respBodyBytes))
- }
-
- twerr := twirp.NewError(errorCode, tj.Msg)
- for k, v := range tj.Meta {
- twerr = twerr.WithMeta(k, v)
- }
- return twerr
-}
-
-// twirpErrorFromIntermediary maps HTTP errors from non-twirp sources to twirp errors.
-// The mapping is similar to gRPC: https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md.
-// Returned twirp Errors have some additional metadata for inspection.
-func twirpErrorFromIntermediary(status int, msg string, bodyOrLocation string) twirp.Error {
- var code twirp.ErrorCode
- if isHTTPRedirect(status) { // 3xx
- code = twirp.Internal
- } else {
- switch status {
- case 400: // Bad Request
- code = twirp.Internal
- case 401: // Unauthorized
- code = twirp.Unauthenticated
- case 403: // Forbidden
- code = twirp.PermissionDenied
- case 404: // Not Found
- code = twirp.BadRoute
- case 429: // Too Many Requests
- code = twirp.ResourceExhausted
- case 502, 503, 504: // Bad Gateway, Service Unavailable, Gateway Timeout
- code = twirp.Unavailable
- default: // All other codes
- code = twirp.Unknown
- }
- }
-
- twerr := twirp.NewError(code, msg)
- twerr = twerr.WithMeta("http_error_from_intermediary", "true") // to easily know if this error was from intermediary
- twerr = twerr.WithMeta("status_code", strconv.Itoa(status))
- if isHTTPRedirect(status) {
- twerr = twerr.WithMeta("location", bodyOrLocation)
- } else {
- twerr = twerr.WithMeta("body", bodyOrLocation)
- }
- return twerr
-}
-
-func isHTTPRedirect(status int) bool {
- return status >= 300 && status <= 399
-}
-
-// wrapInternal wraps an error with a prefix as an Internal error.
-// The original error cause is accessible by github.com/pkg/errors.Cause.
-func wrapInternal(err error, prefix string) twirp.Error {
- return twirp.InternalErrorWith(&wrappedError{prefix: prefix, cause: err})
-}
-
-type wrappedError struct {
- prefix string
- cause error
-}
-
-func (e *wrappedError) Error() string { return e.prefix + ": " + e.cause.Error() }
-func (e *wrappedError) Unwrap() error { return e.cause } // for go1.13 + errors.Is/As
-func (e *wrappedError) Cause() error { return e.cause } // for github.com/pkg/errors
-
-// ensurePanicResponses makes sure that rpc methods causing a panic still result in a Twirp Internal
-// error response (status 500), and error hooks are properly called with the panic wrapped as an error.
-// The panic is re-raised so it can be handled normally with middleware.
-func ensurePanicResponses(ctx context.Context, resp http.ResponseWriter, hooks *twirp.ServerHooks) {
- if r := recover(); r != nil {
- // Wrap the panic as an error so it can be passed to error hooks.
- // The original error is accessible from error hooks, but not visible in the response.
- err := errFromPanic(r)
- twerr := &internalWithCause{msg: "Internal service panic", cause: err}
- // Actually write the error
- writeError(ctx, resp, twerr, hooks)
- // If possible, flush the error to the wire.
- f, ok := resp.(http.Flusher)
- if ok {
- f.Flush()
- }
-
- panic(r)
- }
-}
-
-// errFromPanic returns the typed error if the recovered panic is an error, otherwise formats as error.
-func errFromPanic(p interface{}) error {
- if err, ok := p.(error); ok {
- return err
- }
- return fmt.Errorf("panic: %v", p)
-}
-
-// internalWithCause is a Twirp Internal error wrapping an original error cause,
-// but the original error message is not exposed on Msg(). The original error
-// can be checked with go1.13+ errors.Is/As, and also by (github.com/pkg/errors).Unwrap
-type internalWithCause struct {
- msg string
- cause error
-}
-
-func (e *internalWithCause) Unwrap() error { return e.cause } // for go1.13 + errors.Is/As
-func (e *internalWithCause) Cause() error { return e.cause } // for github.com/pkg/errors
-func (e *internalWithCause) Error() string { return e.msg + ": " + e.cause.Error() }
-func (e *internalWithCause) Code() twirp.ErrorCode { return twirp.Internal }
-func (e *internalWithCause) Msg() string { return e.msg }
-func (e *internalWithCause) Meta(key string) string { return "" }
-func (e *internalWithCause) MetaMap() map[string]string { return nil }
-func (e *internalWithCause) WithMeta(key string, val string) twirp.Error { return e }
-
-// malformedRequestError is used when the twirp server cannot unmarshal a request
-func malformedRequestError(msg string) twirp.Error {
- return twirp.NewError(twirp.Malformed, msg)
-}
-
-// badRouteError is used when the twirp server cannot route a request
-func badRouteError(msg string, method, url string) twirp.Error {
- err := twirp.NewError(twirp.BadRoute, msg)
- err = err.WithMeta("twirp_invalid_route", method+" "+url)
- return err
-}
-
-// withoutRedirects makes sure that the POST request can not be redirected.
-// The standard library will, by default, redirect requests (including POSTs) if it gets a 302 or
-// 303 response, and also 301s in go1.8. It redirects by making a second request, changing the
-// method to GET and removing the body. This produces very confusing error messages, so instead we
-// set a redirect policy that always errors. This stops Go from executing the redirect.
-//
-// We have to be a little careful in case the user-provided http.Client has its own CheckRedirect
-// policy - if so, we'll run through that policy first.
-//
-// Because this requires modifying the http.Client, we make a new copy of the client and return it.
-func withoutRedirects(in *http.Client) *http.Client {
- copy := *in
- copy.CheckRedirect = func(req *http.Request, via []*http.Request) error {
- if in.CheckRedirect != nil {
- // Run the input's redirect if it exists, in case it has side effects, but ignore any error it
- // returns, since we want to use ErrUseLastResponse.
- err := in.CheckRedirect(req, via)
- _ = err // Silly, but this makes sure generated code passes errcheck -blank, which some people use.
- }
- return http.ErrUseLastResponse
- }
- return ©
-}
-
-// doProtobufRequest makes a Protobuf request to the remote Twirp service.
-func doProtobufRequest(ctx context.Context, client HTTPClient, hooks *twirp.ClientHooks, url string, in, out proto.Message) (_ context.Context, err error) {
- reqBodyBytes, err := proto.Marshal(in)
- if err != nil {
- return ctx, wrapInternal(err, "failed to marshal proto request")
- }
- reqBody := bytes.NewBuffer(reqBodyBytes)
- if err = ctx.Err(); err != nil {
- return ctx, wrapInternal(err, "aborted because context was done")
- }
-
- req, err := newRequest(ctx, url, reqBody, "application/protobuf")
- if err != nil {
- return ctx, wrapInternal(err, "could not build request")
- }
- ctx, err = callClientRequestPrepared(ctx, hooks, req)
- if err != nil {
- return ctx, err
- }
-
- req = req.WithContext(ctx)
- resp, err := client.Do(req)
- if err != nil {
- return ctx, wrapInternal(err, "failed to do request")
- }
- defer func() { _ = resp.Body.Close() }()
-
- if err = ctx.Err(); err != nil {
- return ctx, wrapInternal(err, "aborted because context was done")
- }
-
- if resp.StatusCode != 200 {
- return ctx, errorFromResponse(resp)
- }
-
- respBodyBytes, err := io.ReadAll(resp.Body)
- if err != nil {
- return ctx, wrapInternal(err, "failed to read response body")
- }
- if err = ctx.Err(); err != nil {
- return ctx, wrapInternal(err, "aborted because context was done")
- }
-
- if err = proto.Unmarshal(respBodyBytes, out); err != nil {
- return ctx, wrapInternal(err, "failed to unmarshal proto response")
- }
- return ctx, nil
-}
-
-// doJSONRequest makes a JSON request to the remote Twirp service.
-func doJSONRequest(ctx context.Context, client HTTPClient, hooks *twirp.ClientHooks, url string, in, out proto.Message) (_ context.Context, err error) {
- marshaler := &protojson.MarshalOptions{UseProtoNames: true}
- reqBytes, err := marshaler.Marshal(in)
- if err != nil {
- return ctx, wrapInternal(err, "failed to marshal json request")
- }
- if err = ctx.Err(); err != nil {
- return ctx, wrapInternal(err, "aborted because context was done")
- }
-
- req, err := newRequest(ctx, url, bytes.NewReader(reqBytes), "application/json")
- if err != nil {
- return ctx, wrapInternal(err, "could not build request")
- }
- ctx, err = callClientRequestPrepared(ctx, hooks, req)
- if err != nil {
- return ctx, err
- }
-
- req = req.WithContext(ctx)
- resp, err := client.Do(req)
- if err != nil {
- return ctx, wrapInternal(err, "failed to do request")
- }
-
- defer func() {
- cerr := resp.Body.Close()
- if err == nil && cerr != nil {
- err = wrapInternal(cerr, "failed to close response body")
- }
- }()
-
- if err = ctx.Err(); err != nil {
- return ctx, wrapInternal(err, "aborted because context was done")
- }
-
- if resp.StatusCode != 200 {
- return ctx, errorFromResponse(resp)
- }
-
- d := json.NewDecoder(resp.Body)
- rawRespBody := json.RawMessage{}
- if err := d.Decode(&rawRespBody); err != nil {
- return ctx, wrapInternal(err, "failed to unmarshal json response")
- }
- unmarshaler := protojson.UnmarshalOptions{DiscardUnknown: true}
- if err = unmarshaler.Unmarshal(rawRespBody, out); err != nil {
- return ctx, wrapInternal(err, "failed to unmarshal json response")
- }
- if err = ctx.Err(); err != nil {
- return ctx, wrapInternal(err, "aborted because context was done")
- }
- return ctx, nil
-}
-
-// Call twirp.ServerHooks.RequestReceived if the hook is available
-func callRequestReceived(ctx context.Context, h *twirp.ServerHooks) (context.Context, error) {
- if h == nil || h.RequestReceived == nil {
- return ctx, nil
- }
- return h.RequestReceived(ctx)
-}
-
-// Call twirp.ServerHooks.RequestRouted if the hook is available
-func callRequestRouted(ctx context.Context, h *twirp.ServerHooks) (context.Context, error) {
- if h == nil || h.RequestRouted == nil {
- return ctx, nil
- }
- return h.RequestRouted(ctx)
-}
-
-// Call twirp.ServerHooks.ResponsePrepared if the hook is available
-func callResponsePrepared(ctx context.Context, h *twirp.ServerHooks) context.Context {
- if h == nil || h.ResponsePrepared == nil {
- return ctx
- }
- return h.ResponsePrepared(ctx)
-}
-
-// Call twirp.ServerHooks.ResponseSent if the hook is available
-func callResponseSent(ctx context.Context, h *twirp.ServerHooks) {
- if h == nil || h.ResponseSent == nil {
- return
- }
- h.ResponseSent(ctx)
-}
-
-// Call twirp.ServerHooks.Error if the hook is available
-func callError(ctx context.Context, h *twirp.ServerHooks, err twirp.Error) context.Context {
- if h == nil || h.Error == nil {
- return ctx
- }
- return h.Error(ctx, err)
-}
-
-func callClientResponseReceived(ctx context.Context, h *twirp.ClientHooks) {
- if h == nil || h.ResponseReceived == nil {
- return
- }
- h.ResponseReceived(ctx)
-}
-
-func callClientRequestPrepared(ctx context.Context, h *twirp.ClientHooks, req *http.Request) (context.Context, error) {
- if h == nil || h.RequestPrepared == nil {
- return ctx, nil
- }
- return h.RequestPrepared(ctx, req)
-}
-
-func callClientError(ctx context.Context, h *twirp.ClientHooks, err twirp.Error) {
- if h == nil || h.Error == nil {
- return
- }
- h.Error(ctx, err)
-}
-
-var twirpFileDescriptor0 = []byte{
- // 791 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0xdd, 0x6e, 0xdb, 0x36,
- 0x14, 0x8e, 0xac, 0xf8, 0xef, 0xc8, 0x72, 0x1d, 0xae, 0xeb, 0x34, 0xaf, 0x58, 0x0d, 0x6f, 0x0b,
- 0xbc, 0x5e, 0x78, 0x85, 0xbb, 0x8b, 0x61, 0x03, 0x06, 0x44, 0x8b, 0x97, 0x18, 0xcd, 0x6c, 0x8f,
- 0x72, 0x0b, 0x64, 0x37, 0x82, 0x22, 0x9f, 0x26, 0x44, 0x14, 0x49, 0x25, 0xe9, 0x00, 0x7e, 0x83,
- 0xbe, 0xd2, 0xde, 0x62, 0x0f, 0xb1, 0x07, 0x19, 0x48, 0x4a, 0xae, 0xbc, 0xec, 0x6a, 0xbd, 0xd3,
- 0xf7, 0x73, 0x0e, 0xc9, 0x73, 0x0e, 0x29, 0x80, 0x64, 0xc3, 0x71, 0x9c, 0xf3, 0x4c, 0x66, 0xe4,
- 0x50, 0x7d, 0x0f, 0xff, 0xb2, 0xc0, 0x0d, 0x30, 0xe2, 0xf1, 0x0d, 0xc5, 0x77, 0x1b, 0x14, 0x92,
- 0x3c, 0x86, 0xfa, 0xbb, 0x0d, 0xf2, 0xad, 0x67, 0x0d, 0xac, 0x51, 0x9b, 0x1a, 0xa0, 0xd8, 0x84,
- 0xdd, 0x31, 0xe9, 0xd5, 0x06, 0xd6, 0xc8, 0xa6, 0x06, 0x90, 0x63, 0x68, 0x8a, 0x8c, 0xcb, 0xf0,
- 0x6a, 0xeb, 0xd9, 0x03, 0x6b, 0xd4, 0x9d, 0xb8, 0x63, 0xbd, 0x42, 0xb0, 0xa0, 0xab, 0xd0, 0xbf,
- 0xa4, 0x0d, 0xa5, 0xfa, 0x5b, 0x32, 0x01, 0xe7, 0x2d, 0x4b, 0x24, 0xf2, 0x50, 0x6e, 0x73, 0xf4,
- 0x0e, 0xb5, 0xf7, 0xc8, 0x78, 0x7f, 0x9d, 0x5d, 0xac, 0xa6, 0x34, 0x5c, 0x5d, 0x2e, 0xa7, 0x14,
- 0x8c, 0x6b, 0xb5, 0xcd, 0x91, 0x1c, 0x43, 0xa7, 0x88, 0xb9, 0x8f, 0x92, 0x0d, 0x7a, 0x75, 0xb5,
- 0x9d, 0xf3, 0x03, 0x5a, 0x64, 0x7a, 0xa3, 0xc8, 0xf7, 0x96, 0xe5, 0x3f, 0x02, 0x37, 0xac, 0x1a,
- 0x87, 0xc7, 0x00, 0x81, 0xe4, 0x2c, 0xbd, 0xbe, 0x60, 0x42, 0x12, 0x0f, 0x9a, 0x98, 0x4a, 0xce,
- 0x50, 0x78, 0xd6, 0xc0, 0x1e, 0xb5, 0x69, 0x09, 0x87, 0x7f, 0xd7, 0xa1, 0xb9, 0x8c, 0xe2, 0xdb,
- 0xe8, 0x1a, 0x09, 0x81, 0xc3, 0x34, 0xba, 0xc3, 0xe2, 0xcc, 0xfa, 0x9b, 0x7c, 0x09, 0xc0, 0x31,
- 0xcf, 0x04, 0x93, 0x19, 0xdf, 0xea, 0x73, 0xb7, 0x69, 0x85, 0x51, 0x99, 0xef, 0x91, 0x0b, 0x96,
- 0xa5, 0xfa, 0xf0, 0x6d, 0x5a, 0x42, 0xa5, 0x70, 0x4c, 0x30, 0x12, 0xe6, 0xa8, 0x36, 0x2d, 0x21,
- 0xf9, 0x1c, 0xea, 0x98, 0x67, 0xf1, 0x8d, 0x3e, 0x8d, 0x7d, 0x7e, 0x40, 0x0d, 0x7c, 0x6f, 0x59,
- 0xe4, 0x1b, 0x70, 0xd6, 0x28, 0x62, 0xce, 0x72, 0xa9, 0x52, 0x36, 0xf4, 0x71, 0x2d, 0x5a, 0x25,
- 0x95, 0xed, 0x19, 0xb4, 0x6e, 0xb2, 0x3b, 0xcc, 0xa3, 0x6b, 0xf4, 0x9a, 0xda, 0x53, 0xa3, 0x3b,
- 0x46, 0x19, 0xbe, 0x02, 0xb8, 0x8b, 0x58, 0x2a, 0x23, 0x96, 0x22, 0xf7, 0x5a, 0xda, 0x62, 0xd3,
- 0x0a, 0xa7, 0x4c, 0x5f, 0x83, 0xab, 0x7a, 0xce, 0x24, 0xc6, 0x72, 0xc3, 0x51, 0x78, 0x6d, 0x5d,
- 0x9b, 0x7d, 0x92, 0xf4, 0xa1, 0x95, 0xb0, 0x18, 0x53, 0x81, 0xc2, 0x03, 0x6d, 0xd8, 0x61, 0xa5,
- 0xe5, 0x3c, 0xbb, 0x67, 0x6b, 0x14, 0x9e, 0x63, 0xb4, 0x12, 0x93, 0xa7, 0xd0, 0x8e, 0xb3, 0xf4,
- 0x6d, 0xc2, 0x62, 0x29, 0xbc, 0x8e, 0x16, 0x3f, 0x10, 0x2a, 0x92, 0x63, 0x9e, 0x44, 0x31, 0x0a,
- 0xcf, 0x35, 0x91, 0x25, 0x26, 0xdf, 0x43, 0x73, 0x8d, 0x39, 0xa6, 0x6b, 0xe1, 0x75, 0x07, 0xf6,
- 0xc8, 0x99, 0xf4, 0xcd, 0x90, 0x14, 0x7d, 0x1a, 0x9f, 0x1a, 0x71, 0x9a, 0x4a, 0xbe, 0xa5, 0xa5,
- 0x95, 0x9c, 0x82, 0x7b, 0xb5, 0x61, 0xc9, 0x3a, 0x2c, 0x63, 0x1f, 0xe9, 0xd8, 0x67, 0xfb, 0xb1,
- 0xbe, 0xb2, 0xec, 0x25, 0xe8, 0x5c, 0x55, 0xa8, 0xfe, 0x05, 0x74, 0xaa, 0x2a, 0xe9, 0x81, 0x7d,
- 0x8b, 0xe5, 0x35, 0x50, 0x9f, 0xe4, 0x18, 0xea, 0x66, 0x16, 0xd5, 0x30, 0x38, 0x93, 0x5e, 0x31,
- 0xec, 0xbb, 0x61, 0xa3, 0x46, 0xfe, 0xb1, 0xf6, 0x83, 0xd5, 0xff, 0x1d, 0x8e, 0x1e, 0x2c, 0xf8,
- 0x71, 0x29, 0xfd, 0x16, 0x34, 0x42, 0x3d, 0x2e, 0x7e, 0x17, 0x3a, 0x61, 0x65, 0x2e, 0x7c, 0x07,
- 0xda, 0x61, 0x39, 0x03, 0xbe, 0x0b, 0x4e, 0xf8, 0xa1, 0xdb, 0xc3, 0x33, 0x38, 0x3a, 0x43, 0x59,
- 0x14, 0xa1, 0xbc, 0xe4, 0xff, 0x63, 0xde, 0x87, 0x3f, 0x41, 0xb7, 0x7c, 0x29, 0x44, 0x9e, 0xa5,
- 0x02, 0xc9, 0xb7, 0xd0, 0xca, 0x4d, 0x5e, 0x73, 0xb9, 0x9c, 0xf2, 0xfe, 0x97, 0xab, 0xed, 0xe4,
- 0xe1, 0x2b, 0xf8, 0xf4, 0x0c, 0xa5, 0xae, 0x48, 0xa0, 0xb7, 0xfd, 0x31, 0x3b, 0x79, 0x01, 0x4f,
- 0xfe, 0x9d, 0xac, 0xd8, 0xd1, 0x13, 0x68, 0x98, 0xaa, 0x14, 0xf9, 0x0a, 0xf4, 0xfc, 0x67, 0x68,
- 0x16, 0x6f, 0x12, 0xe9, 0x40, 0xeb, 0xf5, 0x5c, 0x81, 0xe9, 0x69, 0xef, 0x80, 0xb4, 0xe0, 0x70,
- 0x7e, 0xf2, 0xdb, 0xb4, 0x67, 0x91, 0x2e, 0x00, 0x9d, 0x2e, 0x17, 0xc1, 0x6c, 0xb5, 0xa0, 0x97,
- 0xbd, 0x1a, 0x71, 0xa0, 0xf9, 0x66, 0x4a, 0x83, 0xd9, 0x62, 0xde, 0xb3, 0x9f, 0xfb, 0xe0, 0x54,
- 0xde, 0x29, 0xe2, 0x42, 0x7b, 0xbe, 0x08, 0x0d, 0xd3, 0x3b, 0x20, 0x47, 0xe0, 0xce, 0xe6, 0x61,
- 0x25, 0xda, 0x52, 0x54, 0xf0, 0x7a, 0xb9, 0x5c, 0xd0, 0x55, 0x10, 0x9e, 0xd0, 0x5f, 0xce, 0x7b,
- 0xb5, 0xc9, 0x9f, 0x16, 0xd8, 0x27, 0xcb, 0x19, 0x79, 0x09, 0x0d, 0x53, 0x47, 0xf2, 0x49, 0xd1,
- 0xed, 0xea, 0xfb, 0xdb, 0x7f, 0xbc, 0x4f, 0x16, 0x07, 0x7b, 0x01, 0x0d, 0xd5, 0xc5, 0xdb, 0x6b,
- 0xf2, 0x99, 0xd1, 0x1f, 0xf4, 0xb4, 0xbf, 0x5f, 0x7b, 0xf2, 0x0a, 0xba, 0xfb, 0x45, 0x22, 0x5f,
- 0xec, 0x22, 0x1f, 0xf6, 0xa1, 0xff, 0xf4, 0xbf, 0x45, 0xb3, 0xbc, 0xdf, 0xfa, 0xa3, 0x31, 0x1e,
- 0x7f, 0x17, 0xe5, 0xec, 0xaa, 0xa1, 0xff, 0x1e, 0x2f, 0xff, 0x09, 0x00, 0x00, 0xff, 0xff, 0xed,
- 0x6c, 0xfc, 0x7a, 0x4b, 0x06, 0x00, 0x00,
-}
diff --git a/cmd/lure-api-server/main.go b/cmd/lure-api-server/main.go
deleted file mode 100644
index 10ea657..0000000
--- a/cmd/lure-api-server/main.go
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * LURE - Linux User REpository
- * Copyright (C) 2023 Elara Musayelyan
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package main
-
-import (
- "context"
- "flag"
- "net"
- "net/http"
- "os"
-
- "github.com/go-chi/chi/v5"
- "github.com/twitchtv/twirp"
- "go.elara.ws/logger"
- "go.elara.ws/lure/cmd/lure-api-server/internal/api"
- "go.elara.ws/lure/internal/log"
- "go.elara.ws/lure/pkg/repos"
-)
-
-func init() {
- log.Logger = logger.NewPretty(os.Stderr)
-}
-
-func main() {
- ctx := context.Background()
-
- addr := flag.String("a", ":8080", "Listen address for API server")
- logFile := flag.String("l", "", "Output file for JSON log")
- flag.Parse()
-
- if *logFile != "" {
- fl, err := os.Create(*logFile)
- if err != nil {
- log.Fatal("Error creating log file").Err(err).Send()
- }
- defer fl.Close()
-
- log.Logger = logger.NewMulti(log.Logger, logger.NewJSON(fl))
- }
-
- err := repos.Pull(ctx, nil)
- if err != nil {
- log.Fatal("Error pulling repositories").Err(err).Send()
- }
-
- sigCh := make(chan struct{}, 200)
- go repoPullWorker(ctx, sigCh)
-
- apiServer := api.NewAPIServer(
- lureWebAPI{},
- twirp.WithServerPathPrefix(""),
- )
-
- r := chi.NewRouter()
- r.With(allowAllCORSHandler, withAcceptLanguage).Handle("/*", apiServer)
- r.Post("/webhook", handleWebhook(sigCh))
- r.Get("/badge/{repo}/{pkg}", handleBadge())
-
- ln, err := net.Listen("tcp", *addr)
- if err != nil {
- log.Fatal("Error starting listener").Err(err).Send()
- }
-
- log.Info("Starting HTTP API server").Str("addr", ln.Addr().String()).Send()
-
- err = http.Serve(ln, r)
- if err != nil {
- log.Fatal("Error while running server").Err(err).Send()
- }
-}
-
-func allowAllCORSHandler(h http.Handler) http.Handler {
- return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
- res.Header().Set("Access-Control-Allow-Origin", "*")
- res.Header().Set("Access-Control-Allow-Headers", "*")
- if req.Method == http.MethodOptions {
- return
- }
- h.ServeHTTP(res, req)
- })
-}
-
-type (
- acceptLanguageKey struct{}
- langParameterKey struct{}
-)
-
-func withAcceptLanguage(h http.Handler) http.Handler {
- return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
- ctx := req.Context()
-
- langs := req.Header.Get("Accept-Language")
- ctx = context.WithValue(ctx, acceptLanguageKey{}, langs)
-
- lang := req.URL.Query().Get("lang")
- ctx = context.WithValue(ctx, langParameterKey{}, lang)
-
- req = req.WithContext(ctx)
-
- h.ServeHTTP(res, req)
- })
-}
diff --git a/cmd/lure-api-server/webhook.go b/cmd/lure-api-server/webhook.go
deleted file mode 100644
index 63d0bc7..0000000
--- a/cmd/lure-api-server/webhook.go
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * LURE - Linux User REpository
- * Copyright (C) 2023 Elara Musayelyan
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package main
-
-import (
- "context"
- "crypto/hmac"
- "crypto/sha256"
- "encoding/hex"
- "errors"
- "io"
- "net/http"
- "os"
- "strings"
-
- "go.elara.ws/lure/internal/log"
- "go.elara.ws/lure/pkg/repos"
-)
-
-func handleWebhook(sigCh chan<- struct{}) http.HandlerFunc {
- return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
- if req.Header.Get("X-GitHub-Event") != "push" {
- http.Error(res, "Only push events are accepted by this bot", http.StatusBadRequest)
- return
- }
-
- err := verifySecure(req)
- if err != nil {
- http.Error(res, err.Error(), http.StatusForbidden)
- return
- }
-
- sigCh <- struct{}{}
- return
- })
-}
-
-func verifySecure(req *http.Request) error {
- sigStr := req.Header.Get("X-Hub-Signature-256")
- sig, err := hex.DecodeString(strings.TrimPrefix(sigStr, "sha256="))
- if err != nil {
- return err
- }
-
- secretStr, ok := os.LookupEnv("LURE_API_GITHUB_SECRET")
- if !ok {
- return errors.New("LURE_API_GITHUB_SECRET must be set to the secret used for setting up the github webhook\n\n")
- }
- secret := []byte(secretStr)
-
- h := hmac.New(sha256.New, secret)
- _, err = io.Copy(h, req.Body)
- if err != nil {
- return err
- }
-
- if !hmac.Equal(h.Sum(nil), sig) {
- log.Warn("Insecure webhook request").
- Str("from", req.RemoteAddr).
- Bytes("sig", sig).
- Bytes("hmac", h.Sum(nil)).
- Send()
-
- return errors.New("webhook signature mismatch")
- }
-
- return nil
-}
-
-func repoPullWorker(ctx context.Context, sigCh <-chan struct{}) {
- for {
- select {
- case <-sigCh:
- err := repos.Pull(ctx, nil)
- if err != nil {
- log.Warn("Error while pulling repositories").Err(err).Send()
- }
- case <-ctx.Done():
- return
- }
- }
-}
diff --git a/go.mod b/go.mod
index a11baca..83c9276 100644
--- a/go.mod
+++ b/go.mod
@@ -9,7 +9,6 @@ require (
github.com/charmbracelet/bubbles v0.16.1
github.com/charmbracelet/bubbletea v0.24.2
github.com/charmbracelet/lipgloss v0.8.0
- github.com/go-chi/chi/v5 v5.0.10
github.com/go-git/go-billy/v5 v5.5.0
github.com/go-git/go-git/v5 v5.9.0
github.com/goreleaser/nfpm/v2 v2.33.0
@@ -20,7 +19,6 @@ require (
github.com/muesli/reflow v0.3.0
github.com/pelletier/go-toml/v2 v2.1.0
github.com/schollz/progressbar/v3 v3.13.1
- github.com/twitchtv/twirp v8.1.3+incompatible
github.com/urfave/cli/v2 v2.25.7
github.com/vmihailenco/msgpack/v5 v5.3.5
go.elara.ws/logger v0.0.0-20230421022458-e80700db2090
@@ -29,7 +27,6 @@ require (
golang.org/x/exp v0.0.0-20230905200255-921286631fa9
golang.org/x/sys v0.12.0
golang.org/x/text v0.13.0
- google.golang.org/protobuf v1.31.0
gopkg.in/yaml.v3 v3.0.1
modernc.org/sqlite v1.25.0
mvdan.cc/sh/v3 v3.7.0
diff --git a/go.sum b/go.sum
index 75f9773..4a501ef 100644
--- a/go.sum
+++ b/go.sum
@@ -108,8 +108,6 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/frankban/quicktest v1.14.5 h1:dfYrrRyLtiqT9GyKXgdh+k4inNeTvmGbuSgZ3lx3GhA=
github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
-github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk=
-github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
@@ -139,7 +137,6 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
-github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@@ -148,7 +145,6 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
@@ -309,8 +305,6 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/therootcompany/xz v1.0.1 h1:CmOtsn1CbtmyYiusbfmhmkpAAETj0wBIH6kCYaX+xzw=
github.com/therootcompany/xz v1.0.1/go.mod h1:3K3UH1yCKgBneZYhuQUvJ9HPD19UEXEI0BWbMn8qNMY=
-github.com/twitchtv/twirp v8.1.3+incompatible h1:+F4TdErPgSUbMZMwp13Q/KgDVuI7HJXP61mNV3/7iuU=
-github.com/twitchtv/twirp v8.1.3+incompatible/go.mod h1:RRJoFSAmTEh2weEqWtpPE3vFK5YBhA6bqp2l1kfCC5A=
github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8=
github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
@@ -537,9 +531,6 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
-google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
-google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=