mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-04-20 03:11:35 +02:00
Merge branch 'forgejo' into upload_with_path_structure
This commit is contained in:
commit
c1e5e3c834
323 changed files with 5537 additions and 3728 deletions
|
@ -189,6 +189,7 @@ code.gitea.io/gitea/modules/translation
|
|||
MockLocale.TrN
|
||||
MockLocale.TrPluralString
|
||||
MockLocale.TrSize
|
||||
MockLocale.HasKey
|
||||
MockLocale.PrettyNumber
|
||||
|
||||
code.gitea.io/gitea/modules/util
|
||||
|
|
|
@ -27,6 +27,7 @@ runs:
|
|||
- name: "Get go environment information"
|
||||
id: go-environment
|
||||
run: |
|
||||
chmod 755 $HOME # ensure ${RUN_AS_USER} has permission when go is located in $HOME
|
||||
export GOROOT="$(go env GOROOT)"
|
||||
echo "modcache=$(su ${RUN_AS_USER} -c '${GOROOT}/bin/go env GOMODCACHE')" >> "$GITHUB_OUTPUT"
|
||||
echo "cache=$(su ${RUN_AS_USER} -c '${GOROOT}/bin/go env GOCACHE')" >> "$GITHUB_OUTPUT"
|
||||
|
|
|
@ -28,7 +28,7 @@ jobs:
|
|||
|
||||
runs-on: docker
|
||||
container:
|
||||
image: data.forgejo.org/renovate/renovate:39.178.1
|
||||
image: data.forgejo.org/renovate/renovate:39.185.0
|
||||
|
||||
steps:
|
||||
- name: Load renovate repo cache
|
||||
|
|
|
@ -19,12 +19,12 @@ linters:
|
|||
- revive
|
||||
- staticcheck
|
||||
- stylecheck
|
||||
- tenv
|
||||
- testifylint
|
||||
- typecheck
|
||||
- unconvert
|
||||
- unused
|
||||
- unparam
|
||||
- usetesting
|
||||
- wastedassign
|
||||
|
||||
run:
|
||||
|
|
35
Makefile
35
Makefile
|
@ -39,17 +39,17 @@ XGO_VERSION := go-1.21.x
|
|||
AIR_PACKAGE ?= github.com/air-verse/air@v1 # renovate: datasource=go
|
||||
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/v3/cmd/editorconfig-checker@v3.2.0 # renovate: datasource=go
|
||||
GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.7.0 # renovate: datasource=go
|
||||
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.62.2 # renovate: datasource=go
|
||||
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.64.6 # renovate: datasource=go
|
||||
GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.11 # renovate: datasource=go
|
||||
MISSPELL_PACKAGE ?= github.com/golangci/misspell/cmd/misspell@v0.6.0 # renovate: datasource=go
|
||||
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.31.0 # renovate: datasource=go
|
||||
XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
|
||||
GO_LICENSES_PACKAGE ?= github.com/google/go-licenses@v1.6.0 # renovate: datasource=go
|
||||
GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1 # renovate: datasource=go
|
||||
DEADCODE_PACKAGE ?= golang.org/x/tools/cmd/deadcode@v0.30.0 # renovate: datasource=go
|
||||
DEADCODE_PACKAGE ?= golang.org/x/tools/cmd/deadcode@v0.31.0 # renovate: datasource=go
|
||||
GOMOCK_PACKAGE ?= go.uber.org/mock/mockgen@v0.4.0 # renovate: datasource=go
|
||||
GOPLS_PACKAGE ?= golang.org/x/tools/gopls@v0.18.1 # renovate: datasource=go
|
||||
RENOVATE_NPM_PACKAGE ?= renovate@39.178.1 # renovate: datasource=docker packageName=data.forgejo.org/renovate/renovate
|
||||
RENOVATE_NPM_PACKAGE ?= renovate@39.185.0 # renovate: datasource=docker packageName=data.forgejo.org/renovate/renovate
|
||||
|
||||
# https://github.com/disposable-email-domains/disposable-email-domains/commits/main/
|
||||
DISPOSABLE_EMAILS_SHA ?= 0c27e671231d27cf66370034d7f6818037416989 # renovate: ...
|
||||
|
@ -59,20 +59,8 @@ ifeq ($(HAS_GO), yes)
|
|||
CGO_CFLAGS ?= $(shell $(GO) env CGO_CFLAGS) $(CGO_EXTRA_CFLAGS)
|
||||
endif
|
||||
|
||||
ifeq ($(GOOS),windows)
|
||||
IS_WINDOWS := yes
|
||||
else ifeq ($(patsubst Windows%,Windows,$(OS)),Windows)
|
||||
ifeq ($(GOOS),)
|
||||
IS_WINDOWS := yes
|
||||
endif
|
||||
endif
|
||||
ifeq ($(IS_WINDOWS),yes)
|
||||
GOFLAGS := -v -buildmode=exe
|
||||
EXECUTABLE ?= gitea.exe
|
||||
else
|
||||
GOFLAGS := -v
|
||||
EXECUTABLE ?= gitea
|
||||
endif
|
||||
GOFLAGS := -v
|
||||
EXECUTABLE ?= gitea
|
||||
|
||||
ifeq ($(shell sed --version 2>/dev/null | grep -q GNU && echo gnu),gnu)
|
||||
SED_INPLACE := sed -i
|
||||
|
@ -498,13 +486,6 @@ lint-go-fix:
|
|||
$(GO) run $(GOLANGCI_LINT_PACKAGE) run $(GOLANGCI_LINT_ARGS) --fix
|
||||
$(RUN_DEADCODE) > .deadcode-out
|
||||
|
||||
# workaround step for the lint-go-windows CI task because 'go run' can not
|
||||
# have distinct GOOS/GOARCH for its build and run steps
|
||||
.PHONY: lint-go-windows
|
||||
lint-go-windows:
|
||||
@GOOS= GOARCH= $(GO) install $(GOLANGCI_LINT_PACKAGE)
|
||||
golangci-lint run
|
||||
|
||||
.PHONY: lint-go-vet
|
||||
lint-go-vet:
|
||||
@echo "Running go vet..."
|
||||
|
@ -534,7 +515,7 @@ lint-templates: .venv node_modules
|
|||
|
||||
.PHONY: lint-yaml
|
||||
lint-yaml: .venv
|
||||
@poetry run yamllint .
|
||||
@poetry run yamllint -s .
|
||||
|
||||
.PHONY: security-check
|
||||
security-check:
|
||||
|
@ -877,10 +858,6 @@ sources-tarbal: frontend generate vendor release-sources release-check
|
|||
$(DIST_DIRS):
|
||||
mkdir -p $(DIST_DIRS)
|
||||
|
||||
.PHONY: release-windows
|
||||
release-windows: | $(DIST_DIRS)
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -buildmode exe -dest $(DIST)/binaries -tags 'osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION) .
|
||||
|
||||
.PHONY: release-linux
|
||||
release-linux: | $(DIST_DIRS)
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets '$(LINUX_ARCHS)' -out forgejo-$(VERSION) .
|
||||
|
|
10
assets/go-licenses.json
generated
10
assets/go-licenses.json
generated
|
@ -19,6 +19,11 @@
|
|||
"path": "code.forgejo.org/forgejo-contrib/go-libravatar/LICENSE",
|
||||
"licenseText": "Copyright (c) 2016 Sandro Santilli \u003cstrk@kbt.io\u003e\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
|
||||
},
|
||||
{
|
||||
"name": "code.forgejo.org/forgejo/levelqueue",
|
||||
"path": "code.forgejo.org/forgejo/levelqueue/LICENSE",
|
||||
"licenseText": "Copyright (c) 2019 Lunny Xiao\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
|
||||
},
|
||||
{
|
||||
"name": "code.forgejo.org/forgejo/reply",
|
||||
"path": "code.forgejo.org/forgejo/reply/LICENSE",
|
||||
|
@ -79,11 +84,6 @@
|
|||
"path": "git.sr.ht/~mariusor/go-xsd-duration/LICENSE",
|
||||
"licenseText": "MIT License\n\nCopyright (c) 2019 Go xsd:duration\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
|
||||
},
|
||||
{
|
||||
"name": "gitea.com/lunny/levelqueue",
|
||||
"path": "gitea.com/lunny/levelqueue/LICENSE",
|
||||
"licenseText": "Copyright (c) 2019 Lunny Xiao\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
|
||||
},
|
||||
{
|
||||
"name": "github.com/42wim/httpsig",
|
||||
"path": "github.com/42wim/httpsig/LICENSE",
|
||||
|
|
|
@ -6,7 +6,6 @@ package cmd
|
|||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
|
@ -42,7 +41,7 @@ func captureOutput(t *testing.T, stdFD *os.File) (finish func() (output string))
|
|||
}
|
||||
|
||||
func TestPktLine(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
t.Run("Read", func(t *testing.T) {
|
||||
s := strings.NewReader("0000")
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
@ -31,7 +30,7 @@ func createLocalStorage(t *testing.T) (storage.ObjectStorage, string) {
|
|||
p := t.TempDir()
|
||||
|
||||
storage, err := storage.NewLocalStorage(
|
||||
context.Background(),
|
||||
t.Context(),
|
||||
&setting.Storage{
|
||||
Path: p,
|
||||
})
|
||||
|
@ -72,7 +71,7 @@ func TestMigratePackages(t *testing.T) {
|
|||
assert.NotNil(t, v)
|
||||
assert.NotNil(t, f)
|
||||
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
dstStorage, p := createLocalStorage(t)
|
||||
|
||||
|
|
86
go.mod
86
go.mod
|
@ -2,11 +2,12 @@ module code.gitea.io/gitea
|
|||
|
||||
go 1.24
|
||||
|
||||
toolchain go1.24.0
|
||||
toolchain go1.24.1
|
||||
|
||||
require (
|
||||
code.forgejo.org/f3/gof3/v3 v3.10.2
|
||||
code.forgejo.org/f3/gof3/v3 v3.10.4
|
||||
code.forgejo.org/forgejo-contrib/go-libravatar v0.0.0-20191008002943-06d1c002b251
|
||||
code.forgejo.org/forgejo/levelqueue v1.0.0
|
||||
code.forgejo.org/forgejo/reply v1.0.2
|
||||
code.forgejo.org/go-chi/binding v1.0.0
|
||||
code.forgejo.org/go-chi/cache v1.0.0
|
||||
|
@ -16,18 +17,17 @@ require (
|
|||
code.gitea.io/sdk/gitea v0.20.0
|
||||
codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570
|
||||
connectrpc.com/connect v1.17.0
|
||||
gitea.com/lunny/levelqueue v0.4.2-0.20230414023320-3c0159fe0fe4
|
||||
github.com/42wim/httpsig v1.2.2
|
||||
github.com/42wim/sshsig v0.0.0-20211121163825-841cf5bbc121
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358
|
||||
github.com/ProtonMail/go-crypto v1.1.5
|
||||
github.com/PuerkitoBio/goquery v1.10.1
|
||||
github.com/ProtonMail/go-crypto v1.1.6
|
||||
github.com/PuerkitoBio/goquery v1.10.2
|
||||
github.com/SaveTheRbtz/zstd-seekable-format-go/pkg v0.7.2
|
||||
github.com/alecthomas/chroma/v2 v2.15.0
|
||||
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb
|
||||
github.com/blevesearch/bleve/v2 v2.4.4
|
||||
github.com/buildkite/terminal-to-html/v3 v3.16.6
|
||||
github.com/caddyserver/certmagic v0.21.7
|
||||
github.com/caddyserver/certmagic v0.22.0
|
||||
github.com/chi-middleware/proxy v1.1.1
|
||||
github.com/djherbis/buffer v1.2.0
|
||||
github.com/djherbis/nio/v3 v3.0.1
|
||||
|
@ -60,15 +60,15 @@ require (
|
|||
github.com/google/uuid v1.6.0
|
||||
github.com/gorilla/feeds v1.2.0
|
||||
github.com/gorilla/sessions v1.4.0
|
||||
github.com/hashicorp/go-version v1.6.0
|
||||
github.com/hashicorp/go-version v1.7.0
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7
|
||||
github.com/huandu/xstrings v1.5.0
|
||||
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056
|
||||
github.com/jhillyerd/enmime/v2 v2.0.0
|
||||
github.com/jhillyerd/enmime/v2 v2.1.0
|
||||
github.com/json-iterator/go v1.1.12
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
|
||||
github.com/klauspost/compress v1.17.11
|
||||
github.com/klauspost/cpuid/v2 v2.2.9
|
||||
github.com/klauspost/cpuid/v2 v2.2.10
|
||||
github.com/lib/pq v1.10.9
|
||||
github.com/markbates/goth v1.80.0
|
||||
github.com/mattn/go-isatty v0.0.20
|
||||
|
@ -82,9 +82,9 @@ require (
|
|||
github.com/niklasfasching/go-org v1.7.0
|
||||
github.com/olivere/elastic/v7 v7.0.32
|
||||
github.com/opencontainers/go-digest v1.0.0
|
||||
github.com/opencontainers/image-spec v1.1.0
|
||||
github.com/opencontainers/image-spec v1.1.1
|
||||
github.com/pquerna/otp v1.4.0
|
||||
github.com/prometheus/client_golang v1.21.0
|
||||
github.com/prometheus/client_golang v1.21.1
|
||||
github.com/redis/go-redis/v9 v9.7.0
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.1
|
||||
|
@ -94,22 +94,22 @@ require (
|
|||
github.com/stretchr/testify v1.10.0
|
||||
github.com/syndtr/goleveldb v1.0.0
|
||||
github.com/ulikunitz/xz v0.5.12
|
||||
github.com/urfave/cli/v2 v2.27.5
|
||||
github.com/urfave/cli/v2 v2.27.6
|
||||
github.com/valyala/fastjson v1.6.4
|
||||
github.com/yohcop/openid-go v1.0.1
|
||||
github.com/yuin/goldmark v1.7.8
|
||||
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
|
||||
gitlab.com/gitlab-org/api/client-go v0.119.0
|
||||
gitlab.com/gitlab-org/api/client-go v0.123.0
|
||||
go.uber.org/mock v0.4.0
|
||||
golang.org/x/crypto v0.35.0
|
||||
golang.org/x/image v0.23.0
|
||||
golang.org/x/net v0.35.0
|
||||
golang.org/x/oauth2 v0.24.0
|
||||
golang.org/x/sync v0.11.0
|
||||
golang.org/x/sys v0.30.0
|
||||
golang.org/x/text v0.22.0
|
||||
google.golang.org/grpc v1.70.0
|
||||
google.golang.org/protobuf v1.36.3
|
||||
golang.org/x/crypto v0.36.0
|
||||
golang.org/x/image v0.25.0
|
||||
golang.org/x/net v0.37.0
|
||||
golang.org/x/oauth2 v0.28.0
|
||||
golang.org/x/sync v0.12.0
|
||||
golang.org/x/sys v0.31.0
|
||||
golang.org/x/text v0.23.0
|
||||
google.golang.org/grpc v1.71.0
|
||||
google.golang.org/protobuf v1.36.4
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||
gopkg.in/ini.v1 v1.67.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
|
@ -119,11 +119,11 @@ require (
|
|||
)
|
||||
|
||||
require (
|
||||
cel.dev/expr v0.19.0 // indirect
|
||||
cel.dev/expr v0.19.1 // indirect
|
||||
cloud.google.com/go v0.116.0 // indirect
|
||||
cloud.google.com/go/auth v0.9.9 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.4 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.5.2 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.6.0 // indirect
|
||||
cloud.google.com/go/iam v1.2.1 // indirect
|
||||
cloud.google.com/go/longrunning v0.6.1 // indirect
|
||||
cloud.google.com/go/monitoring v1.21.1 // indirect
|
||||
|
@ -162,11 +162,10 @@ require (
|
|||
github.com/boombuler/barcode v1.0.1 // indirect
|
||||
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect
|
||||
github.com/caddyserver/zerossl v0.1.3 // indirect
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
|
||||
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/cloudflare/circl v1.3.8 // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.3.6 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
|
@ -175,8 +174,8 @@ require (
|
|||
github.com/dlclark/regexp2 v1.11.4 // indirect
|
||||
github.com/emersion/go-sasl v0.0.0-20231106173351-e73c9f7bad43 // indirect
|
||||
github.com/emirpasic/gods v1.18.1 // indirect
|
||||
github.com/envoyproxy/go-control-plane v0.13.1 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect
|
||||
github.com/envoyproxy/go-control-plane/envoy v1.32.4 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
|
||||
github.com/fatih/color v1.16.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
|
||||
|
@ -200,7 +199,7 @@ require (
|
|||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/btree v1.1.2 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/go-tpm v0.9.1 // indirect
|
||||
github.com/google/s2a-go v0.1.8 // indirect
|
||||
|
@ -216,13 +215,13 @@ require (
|
|||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/kevinburke/ssh_config v1.2.0 // indirect
|
||||
github.com/klauspost/pgzip v1.2.6 // indirect
|
||||
github.com/libdns/libdns v0.2.2 // indirect
|
||||
github.com/libdns/libdns v0.2.3 // indirect
|
||||
github.com/mailru/easyjson v0.9.0 // indirect
|
||||
github.com/markbates/going v1.0.3 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/mholt/acmez/v3 v3.0.1 // indirect
|
||||
github.com/miekg/dns v1.1.62 // indirect
|
||||
github.com/mholt/acmez/v3 v3.1.0 // indirect
|
||||
github.com/miekg/dns v1.1.63 // indirect
|
||||
github.com/minio/md5-simd v1.1.2 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
|
@ -256,25 +255,26 @@ require (
|
|||
github.com/zeebo/blake3 v0.2.4 // indirect
|
||||
go.etcd.io/bbolt v1.3.9 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.32.0 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.34.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect
|
||||
go.opentelemetry.io/otel v1.32.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.32.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.32.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.32.0 // indirect
|
||||
go.opentelemetry.io/otel v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.34.0 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
go.uber.org/zap/exp v0.3.0 // indirect
|
||||
golang.org/x/mod v0.22.0 // indirect
|
||||
golang.org/x/time v0.8.0 // indirect
|
||||
golang.org/x/tools v0.28.0 // indirect
|
||||
golang.org/x/mod v0.24.0 // indirect
|
||||
golang.org/x/time v0.9.0 // indirect
|
||||
golang.org/x/tools v0.31.0 // indirect
|
||||
google.golang.org/api v0.203.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20241015192408-796eee8c2d53 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241202173237-19429a94021a // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
)
|
||||
|
|
175
go.sum
175
go.sum
|
@ -1,5 +1,5 @@
|
|||
cel.dev/expr v0.19.0 h1:lXuo+nDhpyJSpWxpPVi5cPUwzKb+dsdOiw6IreM5yt0=
|
||||
cel.dev/expr v0.19.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw=
|
||||
cel.dev/expr v0.19.1 h1:NciYrtDRIR0lNCnH1LFJegdjspNx9fI59O7TWcua/W4=
|
||||
cel.dev/expr v0.19.1/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw=
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
|
@ -184,8 +184,8 @@ cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZ
|
|||
cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
|
||||
cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM=
|
||||
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
||||
cloud.google.com/go/compute/metadata v0.5.2 h1:UxK4uu/Tn+I3p2dYWTfiX4wva7aYlKixAHn3fyqngqo=
|
||||
cloud.google.com/go/compute/metadata v0.5.2/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k=
|
||||
cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I=
|
||||
cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg=
|
||||
cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY=
|
||||
cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck=
|
||||
cloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w=
|
||||
|
@ -610,8 +610,8 @@ cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoIS
|
|||
cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M=
|
||||
cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA=
|
||||
cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw=
|
||||
code.forgejo.org/f3/gof3/v3 v3.10.2 h1:EOlv9d8GR7l0BmvZF101O3LUuabb4g5Hw5fKYPiPZlI=
|
||||
code.forgejo.org/f3/gof3/v3 v3.10.2/go.mod h1:qApIHumpBkFkeBEokviO28+HK2WM11IsmMOhmjvCjFQ=
|
||||
code.forgejo.org/f3/gof3/v3 v3.10.4 h1:NOkw8lG3PhgYykdR5pJ19KFLdYmRFVII43YBSNKtpvk=
|
||||
code.forgejo.org/f3/gof3/v3 v3.10.4/go.mod h1:aQSlSGpISIf016g1dBrmm16h53WUKjCR7nSCuoO8dq8=
|
||||
code.forgejo.org/forgejo-contrib/go-libravatar v0.0.0-20191008002943-06d1c002b251 h1:HTZl3CBk3ABNYtFI6TPLvJgGKFIhKT5CBk0sbOtkDKU=
|
||||
code.forgejo.org/forgejo-contrib/go-libravatar v0.0.0-20191008002943-06d1c002b251/go.mod h1:PphB88CPbx601QrWPMZATeorACeVmQlyv3u+uUMbSaM=
|
||||
code.forgejo.org/forgejo/act v1.23.1 h1:4LU7u3FE380DicHz1oZ4ohsWU9I527OHeslVHnr9eP4=
|
||||
|
@ -620,6 +620,8 @@ code.forgejo.org/forgejo/archiver/v3 v3.5.1 h1:UmmbA7D5550uf71SQjarmrn6yKwOGxtEj
|
|||
code.forgejo.org/forgejo/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
|
||||
code.forgejo.org/forgejo/go-xsd-duration v0.0.0-20220703122237-02e73435a078 h1:RArF5AsF9LH4nEoJxqRxcP5r8hhRfWcId84G82YbqzA=
|
||||
code.forgejo.org/forgejo/go-xsd-duration v0.0.0-20220703122237-02e73435a078/go.mod h1:g/V2Hjas6Z1UHUp4yIx6bATpNzJ7DYtD0FG3+xARWxs=
|
||||
code.forgejo.org/forgejo/levelqueue v1.0.0 h1:9krYpU6BM+j/1Ntj6m+VCAIu0UNnne1/UfU/XgPpLuE=
|
||||
code.forgejo.org/forgejo/levelqueue v1.0.0/go.mod h1:fmG6zhVuqim2rxSFOoasgXO8V2W/k9U31VVYqLIRLhQ=
|
||||
code.forgejo.org/forgejo/reply v1.0.2 h1:dMhQCHV6/O3L5CLWNTol+dNzDAuyCK88z4J/lCdgFuQ=
|
||||
code.forgejo.org/forgejo/reply v1.0.2/go.mod h1:RyZUfzQLc+fuLIGjTSQWDAJWPiL4WtKXB/FifT5fM7U=
|
||||
code.forgejo.org/forgejo/ssh v0.0.0-20241211213324-5fc306ca0616 h1:kEZL84+02jY9RxXM4zHBWZ3Fml0B09cmP1LGkDsCfIA=
|
||||
|
@ -647,8 +649,6 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
|||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8=
|
||||
git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc=
|
||||
gitea.com/lunny/levelqueue v0.4.2-0.20230414023320-3c0159fe0fe4 h1:IFT+hup2xejHqdhS7keYWioqfmxdnfblFDTGoOwcZ+o=
|
||||
gitea.com/lunny/levelqueue v0.4.2-0.20230414023320-3c0159fe0fe4/go.mod h1:HBqmLbz56JWpfEGG0prskAV97ATNRoj5LDmPicD22hU=
|
||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
|
||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
||||
github.com/42wim/httpsig v1.2.2 h1:ofAYoHUNs/MJOLqQ8hIxeyz2QxOz8qdSVvp3PX/oPgA=
|
||||
|
@ -676,10 +676,10 @@ github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v
|
|||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/ProtonMail/go-crypto v1.1.5 h1:eoAQfK2dwL+tFSFpr7TbOaPNUbPiJj4fLYwwGE1FQO4=
|
||||
github.com/ProtonMail/go-crypto v1.1.5/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
|
||||
github.com/PuerkitoBio/goquery v1.10.1 h1:Y8JGYUkXWTGRB6Ars3+j3kN0xg1YqqlwvdTV8WTFQcU=
|
||||
github.com/PuerkitoBio/goquery v1.10.1/go.mod h1:IYiHrOMps66ag56LEH7QYDDupKXyo5A8qrjIx3ZtujY=
|
||||
github.com/ProtonMail/go-crypto v1.1.6 h1:ZcV+Ropw6Qn0AX9brlQLAUXfqLBc7Bl+f/DmNxpLfdw=
|
||||
github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
|
||||
github.com/PuerkitoBio/goquery v1.10.2 h1:7fh2BdHcG6VFZsK7toXBT/Bh1z5Wmy8Q9MV9HqT2AM8=
|
||||
github.com/PuerkitoBio/goquery v1.10.2/go.mod h1:0guWGjcLu9AYC7C1GHnpysHy056u9aEkUHwhdnePMCU=
|
||||
github.com/RoaringBitmap/roaring v1.9.3 h1:t4EbC5qQwnisr5PrP9nt0IRhRTb9gMUgQF4t4S2OByM=
|
||||
github.com/RoaringBitmap/roaring v1.9.3/go.mod h1:6AXUsoIEzDTFFQCe1RbGA6uFONMhvejWj5rqITANK90=
|
||||
github.com/SaveTheRbtz/zstd-seekable-format-go/pkg v0.7.2 h1:cSXom2MoKJ9KPPw29RoZtHvUETY4F4n/kXl8m9btnQ0=
|
||||
|
@ -769,13 +769,12 @@ github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
|
|||
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
|
||||
github.com/buildkite/terminal-to-html/v3 v3.16.6 h1:QKHWPjAnKQnV1hVG/Nb2TwYDr4pliSbvCQDENk8EaJo=
|
||||
github.com/buildkite/terminal-to-html/v3 v3.16.6/go.mod h1:PgzeBymbRFC8I2m46Sci3S18AbwonEgpaz3TGhD7EPs=
|
||||
github.com/caddyserver/certmagic v0.21.7 h1:66KJioPFJwttL43KYSWk7ErSmE6LfaJgCQuhm8Sg6fg=
|
||||
github.com/caddyserver/certmagic v0.21.7/go.mod h1:LCPG3WLxcnjVKl/xpjzM0gqh0knrKKKiO5WVttX2eEI=
|
||||
github.com/caddyserver/certmagic v0.22.0 h1:hi2skv2jouUw9uQUEyYSTTmqPZPHgf61dOANSIVCLOw=
|
||||
github.com/caddyserver/certmagic v0.22.0/go.mod h1:Vc0msarAPhOagbDc/SU6M2zbzdwVuZ0lkTh2EqtH4vs=
|
||||
github.com/caddyserver/zerossl v0.1.3 h1:onS+pxp3M8HnHpN5MMbOMyNjmTheJyWRaZYwn+YTAyA=
|
||||
github.com/caddyserver/zerossl v0.1.3/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/XofZnrYwGqG4=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=
|
||||
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a h1:MISbI8sU/PSK/ztvmWKFcI7UGb5/HQT7B+i3a2myKgI=
|
||||
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a/go.mod h1:2GxOXOlEPAMFPfp014mK1SWq8G8BN8o7/dfYqJrVGn8=
|
||||
|
@ -811,8 +810,8 @@ github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWH
|
|||
github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 h1:QVw89YDxXxEe+l8gU8ETbOasdwEV+avkR75ZzsVV9WI=
|
||||
github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
|
||||
github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3 h1:boJj011Hh+874zpIySeApCX4GeOjPl9qhRF3QuIZq+Q=
|
||||
github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
|
@ -870,14 +869,18 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.
|
|||
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
|
||||
github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34=
|
||||
github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go.mod h1:sfYdkwUW4BA3PbKjySwjJy+O4Pu0h62rlqCMHNk+K+Q=
|
||||
github.com/envoyproxy/go-control-plane v0.13.1 h1:vPfJZCkob6yTMEgS+0TwfTUfbHjfy/6vOJ8hUWX/uXE=
|
||||
github.com/envoyproxy/go-control-plane v0.13.1/go.mod h1:X45hY0mufo6Fd0KW3rqsGvQMw58jvjymeCzBU3mWyHw=
|
||||
github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M=
|
||||
github.com/envoyproxy/go-control-plane v0.13.4/go.mod h1:kDfuBlDVsSj2MjrLEtRWtHlsWIFcGyB2RMO44Dc5GZA=
|
||||
github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A=
|
||||
github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw=
|
||||
github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 h1:/G9QYbddjL25KvtKTv3an9lx6VBE2cnb8wp1vEGNYGI=
|
||||
github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU=
|
||||
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||
github.com/felixge/fgprof v0.9.5 h1:8+vR6yu2vvSKn08urWyEuxx75NWPEvybbkBirEpsbVY=
|
||||
|
@ -1031,7 +1034,6 @@ github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu
|
|||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
|
@ -1056,8 +1058,9 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/go-github/v64 v64.0.0 h1:4G61sozmY3eiPAjjoOHponXDBONm+utovTKbyUb2Qdg=
|
||||
github.com/google/go-github/v64 v64.0.0/go.mod h1:xB3vqMQNdHzilXBiO2I+M7iEFtHf+DP/omBOv6tQzVo=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
|
@ -1179,8 +1182,8 @@ github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 h1:iCHtR9CQykt
|
|||
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
github.com/jhillyerd/enmime/v2 v2.0.0 h1:I39PYf0peLGroKq+uX2yGB1ExH/78HcRJy4VmERQAVk=
|
||||
github.com/jhillyerd/enmime/v2 v2.0.0/go.mod h1:wQkz7BochDzSukAz5ajAQaXOB7pEg5Vh5QWs7m1uAPw=
|
||||
github.com/jhillyerd/enmime/v2 v2.1.0 h1:c8Qwi5Xq5EdtMN6byQWoZ/8I2RMTo6OJ7Xay+s1oPO0=
|
||||
github.com/jhillyerd/enmime/v2 v2.1.0/go.mod h1:EJ74dcRbBcqHSP2TBu08XRoy6y3Yx0cevwb1YkGMEmQ=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
|
@ -1205,8 +1208,8 @@ github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90
|
|||
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY=
|
||||
github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8=
|
||||
github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
|
||||
github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
|
||||
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
|
@ -1225,8 +1228,8 @@ github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+
|
|||
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/libdns/libdns v0.2.2 h1:O6ws7bAfRPaBsgAYt8MDe2HcNBGC29hkZ9MX2eUSX3s=
|
||||
github.com/libdns/libdns v0.2.2/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ=
|
||||
github.com/libdns/libdns v0.2.3 h1:ba30K4ObwMGB/QTmqUxf3H4/GmUrCAIkMWejeGl12v8=
|
||||
github.com/libdns/libdns v0.2.3/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ=
|
||||
github.com/lunny/vfsgen v0.0.0-20220105142115-2c99e1ffdfa0 h1:F/3FfGmKdiKFa8kL3YrpZ7pe9H4l4AzA1pbaOUnRvPI=
|
||||
github.com/lunny/vfsgen v0.0.0-20220105142115-2c99e1ffdfa0/go.mod h1:JEfTc3+2DF9Z4PXhLLvXL42zexJyh8rIq3OzUj/0rAk=
|
||||
github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA=
|
||||
|
@ -1253,12 +1256,12 @@ github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBW
|
|||
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/meilisearch/meilisearch-go v0.31.0 h1:yZRhY1qJqdH8h6GFZALGtkDLyj8f9v5aJpsNMyrUmnY=
|
||||
github.com/meilisearch/meilisearch-go v0.31.0/go.mod h1:aNtyuwurDg/ggxQIcKqWH6G9g2ptc8GyY7PLY4zMn/g=
|
||||
github.com/mholt/acmez/v3 v3.0.1 h1:4PcjKjaySlgXK857aTfDuRbmnM5gb3Ruz3tvoSJAUp8=
|
||||
github.com/mholt/acmez/v3 v3.0.1/go.mod h1:L1wOU06KKvq7tswuMDwKdcHeKpFFgkppZy/y0DFxagQ=
|
||||
github.com/mholt/acmez/v3 v3.1.0 h1:RlOx2SSZ8dIAM5GfkMe8TdaxjjkiHTGorlMUt8GeMzg=
|
||||
github.com/mholt/acmez/v3 v3.1.0/go.mod h1:L1wOU06KKvq7tswuMDwKdcHeKpFFgkppZy/y0DFxagQ=
|
||||
github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk=
|
||||
github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA=
|
||||
github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ=
|
||||
github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ=
|
||||
github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY=
|
||||
github.com/miekg/dns v1.1.63/go.mod h1:6NGHfjhpmr5lt3XPLuyfDJi5AXbNIPM9PY6H6sF1Nfs=
|
||||
github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY=
|
||||
github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE=
|
||||
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
||||
|
@ -1304,8 +1307,8 @@ github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
|
|||
github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
|
||||
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
|
||||
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
|
||||
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
|
||||
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
|
||||
github.com/paulmach/orb v0.11.1 h1:3koVegMC4X/WeiXYz9iswopaTwMem53NzTJuTF20JzU=
|
||||
github.com/paulmach/orb v0.11.1/go.mod h1:5mULz1xQfs3bmQm63QEJA6lNGujuRafwA5S/EnuLaLU=
|
||||
|
@ -1331,8 +1334,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
|
|||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pquerna/otp v1.4.0 h1:wZvl1TIVxKRThZIBiwOOHOGP/1+nZyWBil9Y2XNEDzg=
|
||||
github.com/pquerna/otp v1.4.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
|
||||
github.com/prometheus/client_golang v1.21.0 h1:DIsaGmiaBkSangBgMtWdNfxbMNdku5IK6iNhrEqWvdA=
|
||||
github.com/prometheus/client_golang v1.21.0/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
|
||||
github.com/prometheus/client_golang v1.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk=
|
||||
github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
|
||||
|
@ -1358,8 +1361,8 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
|
|||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
||||
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||
github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
|
||||
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
|
@ -1412,8 +1415,8 @@ github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oW
|
|||
github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
|
||||
github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w=
|
||||
github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
|
||||
github.com/urfave/cli/v2 v2.27.6 h1:VdRdS98FNhKZ8/Az8B7MTyGQmpIr36O1EHybx/LaZ4g=
|
||||
github.com/urfave/cli/v2 v2.27.6/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
|
||||
github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ=
|
||||
github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
|
||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
|
@ -1447,8 +1450,8 @@ github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCR
|
|||
github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo=
|
||||
github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
|
||||
github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=
|
||||
gitlab.com/gitlab-org/api/client-go v0.119.0 h1:YBZyx9XUTtEDBBYtY36cZWz6JmT7om/8HPSk37IS95g=
|
||||
gitlab.com/gitlab-org/api/client-go v0.119.0/go.mod h1:ygHmS3AU3TpvK+AC6DYO1QuAxLlv6yxYK+/Votr/WFQ=
|
||||
gitlab.com/gitlab-org/api/client-go v0.123.0 h1:W3LZ5QNyiSCJA0Zchkwz8nQIUzOuDoSWMZtRDT5DjPI=
|
||||
gitlab.com/gitlab-org/api/client-go v0.123.0/go.mod h1:Jh0qjLILEdbO6z/OY94RD+3NDQRUKiuFSFYozN6cpKM=
|
||||
go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI=
|
||||
go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
|
@ -1460,22 +1463,24 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
|||
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.32.0 h1:P78qWqkLSShicHmAzfECaTgvslqHxblNE9j62Ws1NK8=
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.32.0/go.mod h1:TVqo0Sda4Cv8gCIixd7LuLwW4EylumVWfhjZJjDD4DU=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.34.0 h1:JRxssobiPg23otYU5SbWtQC//snGVIM3Tx6QRzlQBao=
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.34.0/go.mod h1:cV4BMFcscUR/ckqLkbfQmF0PRsq8w/lMGzdbCSveBHo=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 h1:r6I7RJCN86bpD/FQwedZ0vSixDpwuWREjW9oRMsmqDc=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0/go.mod h1:B9yO6b04uB80CzjedvewuqDhxJxi11s7/GtiGa8bAjI=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8=
|
||||
go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U=
|
||||
go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg=
|
||||
go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M=
|
||||
go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8=
|
||||
go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4=
|
||||
go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
|
||||
go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM=
|
||||
go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8=
|
||||
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
|
||||
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
|
||||
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
|
||||
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
|
||||
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
|
||||
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
|
||||
go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
|
||||
|
@ -1507,8 +1512,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
|
|||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
|
@ -1539,8 +1544,8 @@ golang.org/x/image v0.0.0-20210607152325-775e3b0c77b9/go.mod h1:023OzeP/+EPmXeap
|
|||
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
|
||||
golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
|
||||
golang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
|
||||
golang.org/x/image v0.23.0 h1:HseQ7c2OpPKTPVzNjG5fwJsOTCiiwS4QdsYi5XU6H68=
|
||||
golang.org/x/image v0.23.0/go.mod h1:wJJBTdLfCCf3tiHa1fNxpZmUI4mmoZvwMCPP0ddoNKY=
|
||||
golang.org/x/image v0.25.0 h1:Y6uW6rH1y5y/LK1J8BPWZtr6yZ7hrsy6hFrXjgsc2fQ=
|
||||
golang.org/x/image v0.25.0/go.mod h1:tCAmOEGthTtkalusGp1g3xa2gke8J6c2N565dTyl9Rs=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
|
@ -1573,8 +1578,8 @@ golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
|||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
|
||||
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
|
||||
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
@ -1640,8 +1645,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
|||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
|
||||
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
|
||||
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
|
||||
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
@ -1671,8 +1676,8 @@ golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec
|
|||
golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
|
||||
golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw=
|
||||
golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4=
|
||||
golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE=
|
||||
golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc=
|
||||
golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -1693,8 +1698,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
|||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
||||
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
|
||||
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
@ -1786,8 +1791,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
|
@ -1802,8 +1807,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
|||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
||||
golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
|
||||
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
|
||||
golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
|
||||
golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
@ -1824,16 +1829,16 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
|||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
||||
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg=
|
||||
golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
|
||||
golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
@ -1898,8 +1903,8 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
|||
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
|
||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8=
|
||||
golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw=
|
||||
golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
|
||||
golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
@ -2116,10 +2121,10 @@ google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOl
|
|||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
|
||||
google.golang.org/genproto v0.0.0-20241015192408-796eee8c2d53 h1:Df6WuGvthPzc+JiQ/G+m+sNX24kc0aTBqoDN/0yyykE=
|
||||
google.golang.org/genproto v0.0.0-20241015192408-796eee8c2d53/go.mod h1:fheguH3Am2dGp1LfXkrvwqC/KlFq8F0nLq3LryOMrrE=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241202173237-19429a94021a h1:OAiGFfOiA0v9MRYsSidp3ubZaBnteRUyn3xB2ZQ5G/E=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241202173237-19429a94021a/go.mod h1:jehYqy3+AhJU9ve55aNOaSml7wUXjF9x6z2LcCfpAhY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a h1:hgh8P4EuoxpsuKMXX/To36nOFD7vixReXgn8lPGnt+o=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 h1:GVIKPyP/kLIyVOgOnTwFOrvQaQUzOzGMCxgFUOEmm24=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422/go.mod h1:b6h1vNKhxaSoEI+5jc3PJUCustfli/mRab7295pY7rw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
|
@ -2161,8 +2166,8 @@ google.golang.org/grpc v1.52.3/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5v
|
|||
google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw=
|
||||
google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g=
|
||||
google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
|
||||
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
|
||||
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
|
||||
google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
|
||||
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
|
@ -2181,8 +2186,8 @@ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw
|
|||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.36.3 h1:82DV7MYdb8anAVi3qge1wSnMDrnKK7ebr+I0hHRN1BU=
|
||||
google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
|
||||
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
"code.gitea.io/gitea/modules/translation"
|
||||
webhook_module "code.gitea.io/gitea/modules/webhook"
|
||||
|
||||
"xorm.io/builder"
|
||||
|
@ -112,14 +113,14 @@ type StatusInfo struct {
|
|||
}
|
||||
|
||||
// GetStatusInfoList returns a slice of StatusInfo
|
||||
func GetStatusInfoList(ctx context.Context) []StatusInfo {
|
||||
func GetStatusInfoList(ctx context.Context, lang translation.Locale) []StatusInfo {
|
||||
// same as those in aggregateJobStatus
|
||||
allStatus := []Status{StatusSuccess, StatusFailure, StatusWaiting, StatusRunning}
|
||||
statusInfoList := make([]StatusInfo, 0, 4)
|
||||
for _, s := range allStatus {
|
||||
statusInfoList = append(statusInfoList, StatusInfo{
|
||||
Status: int(s),
|
||||
DisplayedStatus: s.String(),
|
||||
DisplayedStatus: s.LocaleString(lang),
|
||||
})
|
||||
}
|
||||
return statusInfoList
|
||||
|
|
|
@ -44,7 +44,7 @@ func init() {
|
|||
// TranslatableMessage represents JSON struct that can be translated with a Locale
|
||||
type TranslatableMessage struct {
|
||||
Format string
|
||||
Args []any `json:"omitempty"`
|
||||
Args []any `json:",omitempty"`
|
||||
}
|
||||
|
||||
// LoadRepo loads repository of the task
|
||||
|
|
|
@ -87,19 +87,16 @@ func appendAuthorizedKeysToFile(keys ...*PublicKey) error {
|
|||
}
|
||||
defer f.Close()
|
||||
|
||||
// Note: chmod command does not support in Windows.
|
||||
if !setting.IsWindows {
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// .ssh directory should have mode 700, and authorized_keys file should have mode 600.
|
||||
if fi.Mode().Perm() > 0o600 {
|
||||
log.Error("authorized_keys file has unusual permission flags: %s - setting to -rw-------", fi.Mode().Perm().String())
|
||||
if err = f.Chmod(0o600); err != nil {
|
||||
return err
|
||||
}
|
||||
// .ssh directory should have mode 700, and authorized_keys file should have mode 600.
|
||||
if fi.Mode().Perm() > 0o600 {
|
||||
log.Error("authorized_keys file has unusual permission flags: %s - setting to -rw-------", fi.Mode().Perm().String())
|
||||
if err = f.Chmod(0o600); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -98,6 +98,15 @@ func init() {
|
|||
|
||||
// NewAccessToken creates new access token.
|
||||
func NewAccessToken(ctx context.Context, t *AccessToken) error {
|
||||
err := generateAccessToken(t)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = db.GetEngine(ctx).Insert(t)
|
||||
return err
|
||||
}
|
||||
|
||||
func generateAccessToken(t *AccessToken) error {
|
||||
salt, err := util.CryptoRandomString(10)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -110,8 +119,7 @@ func NewAccessToken(ctx context.Context, t *AccessToken) error {
|
|||
t.Token = hex.EncodeToString(token)
|
||||
t.TokenHash = HashToken(t.Token, t.TokenSalt)
|
||||
t.TokenLastEight = t.Token[len(t.Token)-8:]
|
||||
_, err = db.GetEngine(ctx).Insert(t)
|
||||
return err
|
||||
return nil
|
||||
}
|
||||
|
||||
// DisplayPublicOnly whether to display this as a public-only token.
|
||||
|
@ -234,3 +242,25 @@ func DeleteAccessTokenByID(ctx context.Context, id, userID int64) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegenerateAccessTokenByID regenerates access token by given ID.
|
||||
// It regenerates token and salt, as well as updates the creation time.
|
||||
func RegenerateAccessTokenByID(ctx context.Context, id, userID int64) (*AccessToken, error) {
|
||||
t := &AccessToken{}
|
||||
found, err := db.GetEngine(ctx).Where("id = ? AND uid = ?", id, userID).Get(t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !found {
|
||||
return nil, ErrAccessTokenNotExist{}
|
||||
}
|
||||
|
||||
err = generateAccessToken(t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Reset the creation time, token is unused
|
||||
t.UpdatedUnix = timeutil.TimeStampNow()
|
||||
|
||||
return t, UpdateAccessToken(ctx, t)
|
||||
}
|
||||
|
|
|
@ -131,3 +131,28 @@ func TestDeleteAccessTokenByID(t *testing.T) {
|
|||
require.Error(t, err)
|
||||
assert.True(t, auth_model.IsErrAccessTokenNotExist(err))
|
||||
}
|
||||
|
||||
func TestRegenerateAccessTokenByID(t *testing.T) {
|
||||
require.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
token, err := auth_model.GetAccessTokenBySHA(db.DefaultContext, "4c6f36e6cf498e2a448662f915d932c09c5a146c")
|
||||
require.NoError(t, err)
|
||||
|
||||
newToken, err := auth_model.RegenerateAccessTokenByID(db.DefaultContext, token.ID, 1)
|
||||
require.NoError(t, err)
|
||||
unittest.AssertNotExistsBean(t, &auth_model.AccessToken{ID: token.ID, UID: token.UID, TokenHash: token.TokenHash})
|
||||
newToken = &auth_model.AccessToken{
|
||||
ID: newToken.ID,
|
||||
UID: newToken.UID,
|
||||
TokenHash: newToken.TokenHash,
|
||||
}
|
||||
unittest.AssertExistsAndLoadBean(t, newToken)
|
||||
|
||||
// Token has been recreated, new salt and hash, but should retain the same ID, UID, Name and Scope
|
||||
assert.Equal(t, token.ID, newToken.ID)
|
||||
assert.NotEqual(t, token.TokenHash, newToken.TokenHash)
|
||||
assert.NotEqual(t, token.TokenSalt, newToken.TokenSalt)
|
||||
assert.Equal(t, token.UID, newToken.UID)
|
||||
assert.Equal(t, token.Name, newToken.Name)
|
||||
assert.Equal(t, token.Scope, newToken.Scope)
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ const (
|
|||
PAM // 4
|
||||
DLDAP // 5
|
||||
OAuth2 // 6
|
||||
SSPI // 7
|
||||
_ // 7 (was SSPI)
|
||||
Remote // 8
|
||||
)
|
||||
|
||||
|
@ -53,7 +53,6 @@ var Names = map[Type]string{
|
|||
SMTP: "SMTP",
|
||||
PAM: "PAM",
|
||||
OAuth2: "OAuth2",
|
||||
SSPI: "SPNEGO with SSPI",
|
||||
Remote: "Remote",
|
||||
}
|
||||
|
||||
|
@ -178,11 +177,6 @@ func (source *Source) IsOAuth2() bool {
|
|||
return source.Type == OAuth2
|
||||
}
|
||||
|
||||
// IsSSPI returns true of this source is of the SSPI type.
|
||||
func (source *Source) IsSSPI() bool {
|
||||
return source.Type == SSPI
|
||||
}
|
||||
|
||||
func (source *Source) IsRemote() bool {
|
||||
return source.Type == Remote
|
||||
}
|
||||
|
@ -265,20 +259,6 @@ func (opts FindSourcesOptions) ToConds() builder.Cond {
|
|||
return conds
|
||||
}
|
||||
|
||||
// IsSSPIEnabled returns true if there is at least one activated login
|
||||
// source of type LoginSSPI
|
||||
func IsSSPIEnabled(ctx context.Context) bool {
|
||||
exist, err := db.Exist[Source](ctx, FindSourcesOptions{
|
||||
IsActive: optional.Some(true),
|
||||
LoginType: SSPI,
|
||||
}.ToConds())
|
||||
if err != nil {
|
||||
log.Error("IsSSPIEnabled: failed to query active SSPI sources: %v", err)
|
||||
return false
|
||||
}
|
||||
return exist
|
||||
}
|
||||
|
||||
// GetSourceByID returns login source by given ID.
|
||||
func GetSourceByID(ctx context.Context, id int64) (*Source, error) {
|
||||
source := new(Source)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
-
|
||||
id: 1001
|
||||
title: Org project that contains private issues
|
||||
title: Org project that contains private and public issues
|
||||
owner_id: 3
|
||||
repo_id: 0
|
||||
is_closed: false
|
||||
|
@ -12,7 +12,7 @@
|
|||
|
||||
-
|
||||
id: 1002
|
||||
title: User project that contains private issues
|
||||
title: User project that contains private and public issues
|
||||
owner_id: 2
|
||||
repo_id: 0
|
||||
is_closed: false
|
||||
|
|
|
@ -9,3 +9,15 @@
|
|||
issue_id: 7
|
||||
project_id: 1002
|
||||
project_board_id: 1002
|
||||
|
||||
-
|
||||
id: 1003
|
||||
issue_id: 16
|
||||
project_id: 1001
|
||||
project_board_id: 1001
|
||||
|
||||
-
|
||||
id: 1004
|
||||
issue_id: 1
|
||||
project_id: 1002
|
||||
project_board_id: 1002
|
||||
|
|
|
@ -14,5 +14,5 @@ type FollowingRepo struct {
|
|||
}
|
||||
|
||||
func CreateFollowingRepoTable(x *xorm.Engine) error {
|
||||
return x.Sync(new(FederatedUser))
|
||||
return x.Sync(new(FollowingRepo))
|
||||
}
|
||||
|
|
375
models/issues/action_aggregator.go
Normal file
375
models/issues/action_aggregator.go
Normal file
|
@ -0,0 +1,375 @@
|
|||
// Copyright 2025 The Forgejo Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package issues
|
||||
|
||||
import (
|
||||
"slices"
|
||||
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
)
|
||||
|
||||
type ActionAggregator struct {
|
||||
StartUnix int64
|
||||
AggAge int64
|
||||
PosterID int64
|
||||
StartInd int
|
||||
EndInd int
|
||||
|
||||
PrevClosed bool
|
||||
IsClosed bool
|
||||
|
||||
AddedLabels []*Label
|
||||
RemovedLabels []*Label
|
||||
|
||||
AddedRequestReview []RequestReviewTarget
|
||||
RemovedRequestReview []RequestReviewTarget
|
||||
}
|
||||
|
||||
// Get the time threshold for aggregation of multiple actions together
|
||||
func (agg *ActionAggregator) timeThreshold() int64 {
|
||||
if agg.AggAge > (60 * 60 * 24 * 30) { // Age > 1 month, aggregate by day
|
||||
return 60 * 60 * 24
|
||||
} else if agg.AggAge > (60 * 60 * 24) { // Age > 1 day, aggregate by hour
|
||||
return 60 * 60
|
||||
} else if agg.AggAge > (60 * 60) { // Age > 1 hour, aggregate by 10 mins
|
||||
return 60 * 10
|
||||
}
|
||||
// Else, aggregate by minute
|
||||
return 60
|
||||
}
|
||||
|
||||
// TODO Aggregate also
|
||||
// - Dependency added / removed
|
||||
// - Added / Removed due date
|
||||
// - Milestone Added / Removed
|
||||
func (agg *ActionAggregator) aggregateAction(c *Comment, index int) {
|
||||
if agg.StartInd == -1 {
|
||||
agg.StartInd = index
|
||||
}
|
||||
agg.EndInd = index
|
||||
|
||||
if c.Type == CommentTypeClose {
|
||||
agg.IsClosed = true
|
||||
} else if c.Type == CommentTypeReopen {
|
||||
agg.IsClosed = false
|
||||
} else if c.Type == CommentTypeReviewRequest {
|
||||
if c.AssigneeID > 0 {
|
||||
req := RequestReviewTarget{User: c.Assignee}
|
||||
if c.RemovedAssignee {
|
||||
agg.delReviewRequest(req)
|
||||
} else {
|
||||
agg.addReviewRequest(req)
|
||||
}
|
||||
} else if c.AssigneeTeamID > 0 {
|
||||
req := RequestReviewTarget{Team: c.AssigneeTeam}
|
||||
if c.RemovedAssignee {
|
||||
agg.delReviewRequest(req)
|
||||
} else {
|
||||
agg.addReviewRequest(req)
|
||||
}
|
||||
}
|
||||
|
||||
for _, r := range c.RemovedRequestReview {
|
||||
agg.delReviewRequest(r)
|
||||
}
|
||||
|
||||
for _, r := range c.AddedRequestReview {
|
||||
agg.addReviewRequest(r)
|
||||
}
|
||||
} else if c.Type == CommentTypeLabel {
|
||||
if c.Content == "1" {
|
||||
agg.addLabel(c.Label)
|
||||
} else {
|
||||
agg.delLabel(c.Label)
|
||||
}
|
||||
} else if c.Type == CommentTypeAggregator {
|
||||
agg.Merge(c.Aggregator)
|
||||
}
|
||||
}
|
||||
|
||||
// Merge a past CommentAggregator with the next one in the issue comments list
|
||||
func (agg *ActionAggregator) Merge(next *ActionAggregator) {
|
||||
agg.IsClosed = next.IsClosed
|
||||
|
||||
for _, l := range next.AddedLabels {
|
||||
agg.addLabel(l)
|
||||
}
|
||||
|
||||
for _, l := range next.RemovedLabels {
|
||||
agg.delLabel(l)
|
||||
}
|
||||
|
||||
for _, r := range next.AddedRequestReview {
|
||||
agg.addReviewRequest(r)
|
||||
}
|
||||
|
||||
for _, r := range next.RemovedRequestReview {
|
||||
agg.delReviewRequest(r)
|
||||
}
|
||||
}
|
||||
|
||||
// Check if a comment can be aggregated or not depending on its type
|
||||
func (agg *ActionAggregator) IsAggregated(t *CommentType) bool {
|
||||
switch *t {
|
||||
case CommentTypeAggregator, CommentTypeClose, CommentTypeReopen, CommentTypeLabel, CommentTypeReviewRequest:
|
||||
{
|
||||
return true
|
||||
}
|
||||
default:
|
||||
{
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add a label to the aggregated list
|
||||
func (agg *ActionAggregator) addLabel(lbl *Label) {
|
||||
for l, agglbl := range agg.RemovedLabels {
|
||||
if agglbl.ID == lbl.ID {
|
||||
agg.RemovedLabels = slices.Delete(agg.RemovedLabels, l, l+1)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if !slices.ContainsFunc(agg.AddedLabels, func(l *Label) bool { return l.ID == lbl.ID }) {
|
||||
agg.AddedLabels = append(agg.AddedLabels, lbl)
|
||||
}
|
||||
}
|
||||
|
||||
// Remove a label from the aggregated list
|
||||
func (agg *ActionAggregator) delLabel(lbl *Label) {
|
||||
for l, agglbl := range agg.AddedLabels {
|
||||
if agglbl.ID == lbl.ID {
|
||||
agg.AddedLabels = slices.Delete(agg.AddedLabels, l, l+1)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if !slices.ContainsFunc(agg.RemovedLabels, func(l *Label) bool { return l.ID == lbl.ID }) {
|
||||
agg.RemovedLabels = append(agg.RemovedLabels, lbl)
|
||||
}
|
||||
}
|
||||
|
||||
// Add a review request to the aggregated list
|
||||
func (agg *ActionAggregator) addReviewRequest(req RequestReviewTarget) {
|
||||
reqid := req.ID()
|
||||
reqty := req.Type()
|
||||
for r, aggreq := range agg.RemovedRequestReview {
|
||||
if (aggreq.ID() == reqid) && (aggreq.Type() == reqty) {
|
||||
agg.RemovedRequestReview = slices.Delete(agg.RemovedRequestReview, r, r+1)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if !slices.ContainsFunc(agg.AddedRequestReview, func(r RequestReviewTarget) bool { return (r.ID() == reqid) && (r.Type() == reqty) }) {
|
||||
agg.AddedRequestReview = append(agg.AddedRequestReview, req)
|
||||
}
|
||||
}
|
||||
|
||||
// Delete a review request from the aggregated list
|
||||
func (agg *ActionAggregator) delReviewRequest(req RequestReviewTarget) {
|
||||
reqid := req.ID()
|
||||
reqty := req.Type()
|
||||
for r, aggreq := range agg.AddedRequestReview {
|
||||
if (aggreq.ID() == reqid) && (aggreq.Type() == reqty) {
|
||||
agg.AddedRequestReview = slices.Delete(agg.AddedRequestReview, r, r+1)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if !slices.ContainsFunc(agg.RemovedRequestReview, func(r RequestReviewTarget) bool { return (r.ID() == reqid) && (r.Type() == reqty) }) {
|
||||
agg.RemovedRequestReview = append(agg.RemovedRequestReview, req)
|
||||
}
|
||||
}
|
||||
|
||||
// Check if anything has changed with this aggregated list of comments
|
||||
func (agg *ActionAggregator) Changed() bool {
|
||||
return (agg.IsClosed != agg.PrevClosed) ||
|
||||
(len(agg.AddedLabels) > 0) ||
|
||||
(len(agg.RemovedLabels) > 0) ||
|
||||
(len(agg.AddedRequestReview) > 0) ||
|
||||
(len(agg.RemovedRequestReview) > 0)
|
||||
}
|
||||
|
||||
func (agg *ActionAggregator) OnlyLabelsChanged() bool {
|
||||
return ((len(agg.AddedLabels) > 0) || (len(agg.RemovedLabels) > 0)) &&
|
||||
(len(agg.AddedRequestReview) == 0) && (len(agg.RemovedRequestReview) == 0) &&
|
||||
(agg.PrevClosed == agg.IsClosed)
|
||||
}
|
||||
|
||||
func (agg *ActionAggregator) OnlyRequestReview() bool {
|
||||
return ((len(agg.AddedRequestReview) > 0) || (len(agg.RemovedRequestReview) > 0)) &&
|
||||
(len(agg.AddedLabels) == 0) && (len(agg.RemovedLabels) == 0) &&
|
||||
(agg.PrevClosed == agg.IsClosed)
|
||||
}
|
||||
|
||||
func (agg *ActionAggregator) OnlyClosedReopened() bool {
|
||||
return (agg.IsClosed != agg.PrevClosed) &&
|
||||
(len(agg.AddedLabels) == 0) && (len(agg.RemovedLabels) == 0) &&
|
||||
(len(agg.AddedRequestReview) == 0) && (len(agg.RemovedRequestReview) == 0)
|
||||
}
|
||||
|
||||
// Reset the aggregator to start a new aggregating context
|
||||
func (agg *ActionAggregator) Reset(cur *Comment, now int64) {
|
||||
agg.StartUnix = int64(cur.CreatedUnix)
|
||||
agg.AggAge = now - agg.StartUnix
|
||||
agg.PosterID = cur.PosterID
|
||||
|
||||
agg.PrevClosed = agg.IsClosed
|
||||
|
||||
agg.StartInd = -1
|
||||
agg.EndInd = -1
|
||||
agg.AddedLabels = []*Label{}
|
||||
agg.RemovedLabels = []*Label{}
|
||||
agg.AddedRequestReview = []RequestReviewTarget{}
|
||||
agg.RemovedRequestReview = []RequestReviewTarget{}
|
||||
}
|
||||
|
||||
// Function that replaces all the comments aggregated with a single one
|
||||
// Its CommentType depend on whether multiple type of comments are been aggregated or not
|
||||
// If nothing has changed, we remove all the comments that get nullified
|
||||
//
|
||||
// The function returns how many comments has been removed, in order for the "for" loop
|
||||
// of the main algorithm to change its index
|
||||
func (agg *ActionAggregator) createAggregatedComment(issue *Issue, final bool) int {
|
||||
// If the aggregation of comments make the whole thing null, erase all the comments
|
||||
if !agg.Changed() {
|
||||
if final {
|
||||
issue.Comments = issue.Comments[:agg.StartInd]
|
||||
} else {
|
||||
issue.Comments = slices.Replace(issue.Comments, agg.StartInd, agg.EndInd+1)
|
||||
}
|
||||
return (agg.EndInd - agg.StartInd) + 1
|
||||
}
|
||||
|
||||
newAgg := *agg // Trigger a memory allocation, get a COPY of the aggregator
|
||||
|
||||
// Keep the same author, time, etc... But reset the parts we may want to use
|
||||
comment := issue.Comments[agg.StartInd]
|
||||
comment.Content = ""
|
||||
comment.Label = nil
|
||||
comment.Aggregator = nil
|
||||
comment.Assignee = nil
|
||||
comment.AssigneeID = 0
|
||||
comment.AssigneeTeam = nil
|
||||
comment.AssigneeTeamID = 0
|
||||
comment.RemovedAssignee = false
|
||||
comment.AddedLabels = nil
|
||||
comment.RemovedLabels = nil
|
||||
|
||||
// In case there's only a single change, create a comment of this type
|
||||
// instead of an aggregator
|
||||
if agg.OnlyLabelsChanged() {
|
||||
comment.Type = CommentTypeLabel
|
||||
} else if agg.OnlyClosedReopened() {
|
||||
if agg.IsClosed {
|
||||
comment.Type = CommentTypeClose
|
||||
} else {
|
||||
comment.Type = CommentTypeReopen
|
||||
}
|
||||
} else if agg.OnlyRequestReview() {
|
||||
comment.Type = CommentTypeReviewRequest
|
||||
} else {
|
||||
comment.Type = CommentTypeAggregator
|
||||
comment.Aggregator = &newAgg
|
||||
}
|
||||
|
||||
if len(newAgg.AddedLabels) > 0 {
|
||||
comment.AddedLabels = newAgg.AddedLabels
|
||||
}
|
||||
|
||||
if len(newAgg.RemovedLabels) > 0 {
|
||||
comment.RemovedLabels = newAgg.RemovedLabels
|
||||
}
|
||||
|
||||
if len(newAgg.AddedRequestReview) > 0 {
|
||||
comment.AddedRequestReview = newAgg.AddedRequestReview
|
||||
}
|
||||
|
||||
if len(newAgg.RemovedRequestReview) > 0 {
|
||||
comment.RemovedRequestReview = newAgg.RemovedRequestReview
|
||||
}
|
||||
|
||||
if final {
|
||||
issue.Comments = append(issue.Comments[:agg.StartInd], comment)
|
||||
} else {
|
||||
issue.Comments = slices.Replace(issue.Comments, agg.StartInd, agg.EndInd+1, comment)
|
||||
}
|
||||
return agg.EndInd - agg.StartInd
|
||||
}
|
||||
|
||||
// combineCommentsHistory combines nearby elements in the history as one
|
||||
func CombineCommentsHistory(issue *Issue, now int64) {
|
||||
if len(issue.Comments) < 1 {
|
||||
return
|
||||
}
|
||||
|
||||
// Initialise a new empty aggregator, ready to combine comments
|
||||
var agg ActionAggregator
|
||||
agg.Reset(issue.Comments[0], now)
|
||||
|
||||
for i := 0; i < len(issue.Comments); i++ {
|
||||
cur := issue.Comments[i]
|
||||
// If the comment we encounter is not accepted inside an aggregator
|
||||
if !agg.IsAggregated(&cur.Type) {
|
||||
// If we aggregated some data, create the resulting comment for it
|
||||
if agg.StartInd != -1 {
|
||||
i -= agg.createAggregatedComment(issue, false)
|
||||
}
|
||||
|
||||
agg.StartInd = -1
|
||||
if i+1 < len(issue.Comments) {
|
||||
agg.Reset(issue.Comments[i+1], now)
|
||||
}
|
||||
|
||||
// Do not need to continue the aggregation loop, skip to next comment
|
||||
continue
|
||||
}
|
||||
|
||||
// If the comment we encounter cannot be aggregated with the current aggregator,
|
||||
// we create a new empty aggregator
|
||||
threshold := agg.timeThreshold()
|
||||
if ((int64(cur.CreatedUnix) - agg.StartUnix) > threshold) || (cur.PosterID != agg.PosterID) {
|
||||
// First, create the aggregated comment if there's data in it
|
||||
if agg.StartInd != -1 {
|
||||
i -= agg.createAggregatedComment(issue, false)
|
||||
}
|
||||
agg.Reset(cur, now)
|
||||
}
|
||||
|
||||
agg.aggregateAction(cur, i)
|
||||
}
|
||||
|
||||
// Create the aggregated comment if there's data in it
|
||||
if agg.StartInd != -1 {
|
||||
agg.createAggregatedComment(issue, true)
|
||||
}
|
||||
}
|
||||
|
||||
type RequestReviewTarget struct {
|
||||
User *user_model.User
|
||||
Team *organization.Team
|
||||
}
|
||||
|
||||
func (t *RequestReviewTarget) ID() int64 {
|
||||
if t.User != nil {
|
||||
return t.User.ID
|
||||
}
|
||||
return t.Team.ID
|
||||
}
|
||||
|
||||
func (t *RequestReviewTarget) Name() string {
|
||||
if t.User != nil {
|
||||
return t.User.GetDisplayName()
|
||||
}
|
||||
return t.Team.Name
|
||||
}
|
||||
|
||||
func (t *RequestReviewTarget) Type() string {
|
||||
if t.User != nil {
|
||||
return "user"
|
||||
}
|
||||
return "team"
|
||||
}
|
|
@ -114,6 +114,8 @@ const (
|
|||
|
||||
CommentTypePin // 36 pin Issue
|
||||
CommentTypeUnpin // 37 unpin Issue
|
||||
|
||||
CommentTypeAggregator // 38 Aggregator of comments
|
||||
)
|
||||
|
||||
var commentStrings = []string{
|
||||
|
@ -155,6 +157,7 @@ var commentStrings = []string{
|
|||
"pull_cancel_scheduled_merge",
|
||||
"pin",
|
||||
"unpin",
|
||||
"action_aggregator",
|
||||
}
|
||||
|
||||
func (t CommentType) String() string {
|
||||
|
@ -236,12 +239,6 @@ func (r RoleInRepo) LocaleHelper(lang translation.Locale) string {
|
|||
return lang.TrString("repo.issues.role." + string(r) + "_helper")
|
||||
}
|
||||
|
||||
type RequestReviewTarget interface {
|
||||
ID() int64
|
||||
Name() string
|
||||
Type() string
|
||||
}
|
||||
|
||||
// Comment represents a comment in commit and issue page.
|
||||
type Comment struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
|
@ -254,6 +251,7 @@ type Comment struct {
|
|||
Issue *Issue `xorm:"-"`
|
||||
LabelID int64
|
||||
Label *Label `xorm:"-"`
|
||||
Aggregator *ActionAggregator `xorm:"-"`
|
||||
AddedLabels []*Label `xorm:"-"`
|
||||
RemovedLabels []*Label `xorm:"-"`
|
||||
AddedRequestReview []RequestReviewTarget `xorm:"-"`
|
||||
|
|
|
@ -56,12 +56,11 @@ func LoadIssuesFromColumn(ctx context.Context, b *project_model.Column, doer *us
|
|||
ProjectID: b.ProjectID,
|
||||
SortType: "project-column-sorting",
|
||||
IsClosed: isClosed,
|
||||
AllPublic: true,
|
||||
}
|
||||
if doer != nil {
|
||||
issueOpts.User = doer
|
||||
issueOpts.Org = org
|
||||
} else {
|
||||
issueOpts.AllPublic = true
|
||||
}
|
||||
|
||||
issueList, err := Issues(ctx, issueOpts)
|
||||
|
|
|
@ -33,12 +33,13 @@ func TestPrivateIssueProjects(t *testing.T) {
|
|||
defer tests.PrintCurrentTest(t)()
|
||||
issueList, err := issues.LoadIssuesFromColumn(db.DefaultContext, column, user2, org, optional.None[bool]())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, issueList, 1)
|
||||
assert.EqualValues(t, 6, issueList[0].ID)
|
||||
assert.Len(t, issueList, 2)
|
||||
assert.EqualValues(t, 16, issueList[0].ID)
|
||||
assert.EqualValues(t, 6, issueList[1].ID)
|
||||
|
||||
issuesNum, err := issues.NumIssuesInProject(db.DefaultContext, orgProject, user2, org, optional.None[bool]())
|
||||
require.NoError(t, err)
|
||||
assert.EqualValues(t, 1, issuesNum)
|
||||
assert.EqualValues(t, 2, issuesNum)
|
||||
|
||||
issuesNum, err = issues.NumIssuesInProject(db.DefaultContext, orgProject, user2, org, optional.Some(true))
|
||||
require.NoError(t, err)
|
||||
|
@ -46,18 +47,27 @@ func TestPrivateIssueProjects(t *testing.T) {
|
|||
|
||||
issuesNum, err = issues.NumIssuesInProject(db.DefaultContext, orgProject, user2, org, optional.Some(false))
|
||||
require.NoError(t, err)
|
||||
assert.EqualValues(t, 1, issuesNum)
|
||||
assert.EqualValues(t, 2, issuesNum)
|
||||
})
|
||||
|
||||
t.Run("Anonymous user", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
issueList, err := issues.LoadIssuesFromColumn(db.DefaultContext, column, nil, org, optional.None[bool]())
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, issueList)
|
||||
assert.Len(t, issueList, 1)
|
||||
assert.EqualValues(t, 16, issueList[0].ID)
|
||||
|
||||
issuesNum, err := issues.NumIssuesInProject(db.DefaultContext, orgProject, nil, org, optional.None[bool]())
|
||||
require.NoError(t, err)
|
||||
assert.EqualValues(t, 1, issuesNum)
|
||||
|
||||
issuesNum, err = issues.NumIssuesInProject(db.DefaultContext, orgProject, nil, org, optional.Some(true))
|
||||
require.NoError(t, err)
|
||||
assert.EqualValues(t, 0, issuesNum)
|
||||
|
||||
issuesNum, err = issues.NumIssuesInProject(db.DefaultContext, orgProject, nil, org, optional.Some(false))
|
||||
require.NoError(t, err)
|
||||
assert.EqualValues(t, 1, issuesNum)
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -69,12 +79,13 @@ func TestPrivateIssueProjects(t *testing.T) {
|
|||
defer tests.PrintCurrentTest(t)()
|
||||
issueList, err := issues.LoadIssuesFromColumn(db.DefaultContext, column, user2, nil, optional.None[bool]())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, issueList, 1)
|
||||
assert.Len(t, issueList, 2)
|
||||
assert.EqualValues(t, 7, issueList[0].ID)
|
||||
assert.EqualValues(t, 1, issueList[1].ID)
|
||||
|
||||
issuesNum, err := issues.NumIssuesInProject(db.DefaultContext, userProject, user2, nil, optional.None[bool]())
|
||||
require.NoError(t, err)
|
||||
assert.EqualValues(t, 1, issuesNum)
|
||||
assert.EqualValues(t, 2, issuesNum)
|
||||
|
||||
issuesNum, err = issues.NumIssuesInProject(db.DefaultContext, userProject, user2, nil, optional.Some(true))
|
||||
require.NoError(t, err)
|
||||
|
@ -82,19 +93,27 @@ func TestPrivateIssueProjects(t *testing.T) {
|
|||
|
||||
issuesNum, err = issues.NumIssuesInProject(db.DefaultContext, userProject, user2, nil, optional.Some(false))
|
||||
require.NoError(t, err)
|
||||
assert.EqualValues(t, 1, issuesNum)
|
||||
assert.EqualValues(t, 2, issuesNum)
|
||||
})
|
||||
|
||||
t.Run("Anonymous user", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
issueList, err := issues.LoadIssuesFromColumn(db.DefaultContext, column, nil, nil, optional.None[bool]())
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, issueList)
|
||||
assert.Len(t, issueList, 1)
|
||||
assert.EqualValues(t, 1, issueList[0].ID)
|
||||
|
||||
issuesNum, err := issues.NumIssuesInProject(db.DefaultContext, userProject, nil, nil, optional.None[bool]())
|
||||
require.NoError(t, err)
|
||||
assert.EqualValues(t, 1, issuesNum)
|
||||
|
||||
issuesNum, err = issues.NumIssuesInProject(db.DefaultContext, userProject, nil, nil, optional.Some(true))
|
||||
require.NoError(t, err)
|
||||
assert.EqualValues(t, 0, issuesNum)
|
||||
|
||||
issuesNum, err = issues.NumIssuesInProject(db.DefaultContext, userProject, nil, nil, optional.Some(false))
|
||||
require.NoError(t, err)
|
||||
assert.EqualValues(t, 1, issuesNum)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -49,9 +49,13 @@ type IssuesOptions struct { //nolint
|
|||
// prioritize issues from this repo
|
||||
PriorityRepoID int64
|
||||
IsArchived optional.Option[bool]
|
||||
Org *organization.Organization // issues permission scope
|
||||
Team *organization.Team // issues permission scope
|
||||
User *user_model.User // issues permission scope
|
||||
|
||||
// If combined with AllPublic, then private as well as public issues
|
||||
// that matches the criteria will be returned, if AllPublic is false
|
||||
// only the private issues will be returned.
|
||||
Org *organization.Organization // issues permission scope
|
||||
Team *organization.Team // issues permission scope
|
||||
User *user_model.User // issues permission scope
|
||||
}
|
||||
|
||||
// applySorts sort an issues-related session based on the provided
|
||||
|
@ -196,7 +200,8 @@ func applyRepoConditions(sess *xorm.Session, opts *IssuesOptions) {
|
|||
} else if len(opts.RepoIDs) > 1 {
|
||||
opts.RepoCond = builder.In("issue.repo_id", opts.RepoIDs)
|
||||
}
|
||||
if opts.AllPublic {
|
||||
// If permission scoping is set, then we set this condition at a later stage.
|
||||
if opts.AllPublic && opts.User == nil {
|
||||
if opts.RepoCond == nil {
|
||||
opts.RepoCond = builder.NewCond()
|
||||
}
|
||||
|
@ -268,7 +273,14 @@ func applyConditions(sess *xorm.Session, opts *IssuesOptions) {
|
|||
applyLabelsCondition(sess, opts)
|
||||
|
||||
if opts.User != nil {
|
||||
sess.And(issuePullAccessibleRepoCond("issue.repo_id", opts.User.ID, opts.Org, opts.Team, opts.IsPull.Value()))
|
||||
cond := issuePullAccessibleRepoCond("issue.repo_id", opts.User.ID, opts.Org, opts.Team, opts.IsPull.Value())
|
||||
// If AllPublic was set, then also consider all issues in public
|
||||
// repositories in addition to the private repositories the user has access
|
||||
// to.
|
||||
if opts.AllPublic {
|
||||
cond = cond.Or(builder.In("issue.repo_id", builder.Select("id").From("repository").Where(builder.Eq{"is_private": false})))
|
||||
}
|
||||
sess.And(cond)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
package issues_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"sync"
|
||||
|
@ -309,7 +308,7 @@ func TestIssue_ResolveMentions(t *testing.T) {
|
|||
func TestResourceIndex(t *testing.T) {
|
||||
require.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
beforeCount, err := issues_model.CountIssues(context.Background(), &issues_model.IssuesOptions{})
|
||||
beforeCount, err := issues_model.CountIssues(t.Context(), &issues_model.IssuesOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
|
@ -326,7 +325,7 @@ func TestResourceIndex(t *testing.T) {
|
|||
t.Parallel()
|
||||
|
||||
wg.Wait()
|
||||
afterCount, err := issues_model.CountIssues(context.Background(), &issues_model.IssuesOptions{})
|
||||
afterCount, err := issues_model.CountIssues(t.Context(), &issues_model.IssuesOptions{})
|
||||
require.NoError(t, err)
|
||||
assert.EqualValues(t, 100, afterCount-beforeCount)
|
||||
})
|
||||
|
@ -354,7 +353,7 @@ func TestCorrectIssueStats(t *testing.T) {
|
|||
wg.Wait()
|
||||
|
||||
// Now we will get all issueID's that match the "Bugs are nasty" query.
|
||||
issues, err := issues_model.Issues(context.TODO(), &issues_model.IssuesOptions{
|
||||
issues, err := issues_model.Issues(t.Context(), &issues_model.IssuesOptions{
|
||||
Paginator: &db.ListOptions{
|
||||
PageSize: issueAmount,
|
||||
},
|
||||
|
|
|
@ -64,6 +64,10 @@ func changeIssueStatus(ctx context.Context, issue *Issue, doer *user_model.User,
|
|||
}
|
||||
|
||||
func doChangeIssueStatus(ctx context.Context, issue *Issue, doer *user_model.User, isMergePull bool) (*Comment, error) {
|
||||
if user_model.IsBlockedMultiple(ctx, []int64{issue.Repo.OwnerID, issue.PosterID}, doer.ID) {
|
||||
return nil, user_model.ErrBlockedByUser
|
||||
}
|
||||
|
||||
// Check for open dependencies
|
||||
if issue.IsClosed && issue.Repo.IsDependenciesEnabled(ctx) {
|
||||
// only check if dependencies are enabled and we're about to close an issue, otherwise reopening an issue would fail when there are unsatisfied dependencies
|
||||
|
|
|
@ -11,7 +11,6 @@ import (
|
|||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -123,9 +122,6 @@ func MainTest(m *testing.M) {
|
|||
os.Exit(1)
|
||||
}
|
||||
giteaBinary := "gitea"
|
||||
if runtime.GOOS == "windows" {
|
||||
giteaBinary += ".exe"
|
||||
}
|
||||
setting.AppPath = path.Join(giteaRoot, giteaBinary)
|
||||
if _, err := os.Stat(setting.AppPath); err != nil {
|
||||
fmt.Printf("Could not find gitea binary at %s\n", setting.AppPath)
|
||||
|
|
|
@ -110,9 +110,12 @@ func GetPackageDescriptor(ctx context.Context, pv *PackageVersion) (*PackageDesc
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
repository, err := repo_model.GetRepositoryByID(ctx, p.RepoID)
|
||||
if err != nil && !repo_model.IsErrRepoNotExist(err) {
|
||||
return nil, err
|
||||
var repository *repo_model.Repository
|
||||
if p.RepoID > 0 {
|
||||
repository, err = repo_model.GetRepositoryByID(ctx, p.RepoID)
|
||||
if err != nil && !repo_model.IsErrRepoNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
creator, err := user_model.GetUserByID(ctx, pv.CreatorID)
|
||||
if err != nil {
|
||||
|
|
|
@ -242,6 +242,11 @@ func SetRepositoryLink(ctx context.Context, packageID, repoID int64) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func UnlinkRepository(ctx context.Context, packageID int64) error {
|
||||
_, err := db.GetEngine(ctx).ID(packageID).Cols("repo_id").Update(&Package{RepoID: 0})
|
||||
return err
|
||||
}
|
||||
|
||||
// UnlinkRepositoryFromAllPackages unlinks every package from the repository
|
||||
func UnlinkRepositoryFromAllPackages(ctx context.Context, repoID int64) error {
|
||||
_, err := db.GetEngine(ctx).Where("repo_id = ?", repoID).Cols("repo_id").Update(&Package{})
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/setting"
|
||||
)
|
||||
|
||||
func EvaluateDefault(used Used, forSubject LimitSubject) bool {
|
||||
func EvaluateDefault(used Used, forSubject LimitSubject) (bool, int64) {
|
||||
groups := GroupList{
|
||||
&Group{
|
||||
Name: "builtin-default-group",
|
||||
|
|
|
@ -5,6 +5,7 @@ package quota
|
|||
|
||||
import (
|
||||
"context"
|
||||
"math"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
|
@ -199,15 +200,20 @@ var affectsMap = map[LimitSubject]LimitSubjects{
|
|||
},
|
||||
}
|
||||
|
||||
func (g *Group) Evaluate(used Used, forSubject LimitSubject) (bool, bool) {
|
||||
// Evaluate returns whether the size used is acceptable for the topic if a rule
|
||||
// was found, and returns the smallest limit of all applicable rules or the
|
||||
// first limit found to be unacceptable for the size used.
|
||||
func (g *Group) Evaluate(used Used, forSubject LimitSubject) (bool, bool, int64) {
|
||||
var found bool
|
||||
foundLimit := int64(math.MaxInt64)
|
||||
for _, rule := range g.Rules {
|
||||
ok, has := rule.Evaluate(used, forSubject)
|
||||
if has {
|
||||
found = true
|
||||
if !ok {
|
||||
return false, true
|
||||
return false, true, rule.Limit
|
||||
}
|
||||
found = true
|
||||
foundLimit = min(foundLimit, rule.Limit)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -216,32 +222,35 @@ func (g *Group) Evaluate(used Used, forSubject LimitSubject) (bool, bool) {
|
|||
// subjects below
|
||||
|
||||
for _, subject := range affectsMap[forSubject] {
|
||||
ok, has := g.Evaluate(used, subject)
|
||||
ok, has, limit := g.Evaluate(used, subject)
|
||||
if has {
|
||||
found = true
|
||||
if !ok {
|
||||
return false, true
|
||||
return false, true, limit
|
||||
}
|
||||
found = true
|
||||
foundLimit = min(foundLimit, limit)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true, found
|
||||
return true, found, foundLimit
|
||||
}
|
||||
|
||||
func (gl *GroupList) Evaluate(used Used, forSubject LimitSubject) bool {
|
||||
// Evaluate returns if the used size is acceptable for the subject and the
|
||||
// lowest limit that is acceptable for the subject.
|
||||
func (gl *GroupList) Evaluate(used Used, forSubject LimitSubject) (bool, int64) {
|
||||
// If there are no groups, use the configured defaults:
|
||||
if gl == nil || len(*gl) == 0 {
|
||||
return EvaluateDefault(used, forSubject)
|
||||
}
|
||||
|
||||
for _, group := range *gl {
|
||||
ok, has := group.Evaluate(used, forSubject)
|
||||
ok, has, limit := group.Evaluate(used, forSubject)
|
||||
if has && ok {
|
||||
return true
|
||||
return true, limit
|
||||
}
|
||||
}
|
||||
return false
|
||||
return false, 0
|
||||
}
|
||||
|
||||
func GetGroupByName(ctx context.Context, name string) (*Group, error) {
|
||||
|
|
|
@ -32,5 +32,6 @@ func EvaluateForUser(ctx context.Context, userID int64, subject LimitSubject) (b
|
|||
return false, err
|
||||
}
|
||||
|
||||
return groups.Evaluate(*used, subject), nil
|
||||
acceptable, _ := groups.Evaluate(*used, subject)
|
||||
return acceptable, nil
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
package quota_test
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
quota_model "code.gitea.io/gitea/models/quota"
|
||||
|
@ -36,9 +37,10 @@ func TestQuotaGroupAllRulesMustPass(t *testing.T) {
|
|||
|
||||
// Within a group, *all* rules must pass. Thus, if we have a deny-all rule,
|
||||
// and an unlimited rule, that will always fail.
|
||||
ok, has := group.Evaluate(used, quota_model.LimitSubjectSizeAll)
|
||||
ok, has, limit := group.Evaluate(used, quota_model.LimitSubjectSizeAll)
|
||||
assert.True(t, has)
|
||||
assert.False(t, ok)
|
||||
assert.EqualValues(t, 0, limit)
|
||||
}
|
||||
|
||||
func TestQuotaGroupRuleScenario1(t *testing.T) {
|
||||
|
@ -66,21 +68,25 @@ func TestQuotaGroupRuleScenario1(t *testing.T) {
|
|||
used.Size.Assets.Packages.All = 256
|
||||
used.Size.Git.LFS = 16
|
||||
|
||||
ok, has := group.Evaluate(used, quota_model.LimitSubjectSizeAssetsAttachmentsReleases)
|
||||
ok, has, limit := group.Evaluate(used, quota_model.LimitSubjectSizeAssetsAttachmentsReleases)
|
||||
assert.True(t, has, "size:assets:attachments:releases is covered")
|
||||
assert.True(t, ok, "size:assets:attachments:releases passes")
|
||||
assert.EqualValues(t, 1024, limit)
|
||||
|
||||
ok, has = group.Evaluate(used, quota_model.LimitSubjectSizeAssetsPackagesAll)
|
||||
ok, has, limit = group.Evaluate(used, quota_model.LimitSubjectSizeAssetsPackagesAll)
|
||||
assert.True(t, has, "size:assets:packages:all is covered")
|
||||
assert.True(t, ok, "size:assets:packages:all passes")
|
||||
assert.EqualValues(t, 1024, limit)
|
||||
|
||||
ok, has = group.Evaluate(used, quota_model.LimitSubjectSizeGitLFS)
|
||||
ok, has, limit = group.Evaluate(used, quota_model.LimitSubjectSizeGitLFS)
|
||||
assert.True(t, has, "size:git:lfs is covered")
|
||||
assert.False(t, ok, "size:git:lfs fails")
|
||||
assert.EqualValues(t, 0, limit)
|
||||
|
||||
ok, has = group.Evaluate(used, quota_model.LimitSubjectSizeAll)
|
||||
ok, has, limit = group.Evaluate(used, quota_model.LimitSubjectSizeAll)
|
||||
assert.True(t, has, "size:all is covered")
|
||||
assert.False(t, ok, "size:all fails")
|
||||
assert.EqualValues(t, 0, limit)
|
||||
}
|
||||
|
||||
func TestQuotaGroupRuleCombination(t *testing.T) {
|
||||
|
@ -109,23 +115,27 @@ func TestQuotaGroupRuleCombination(t *testing.T) {
|
|||
}
|
||||
|
||||
// Git LFS isn't covered by any rule
|
||||
_, has := group.Evaluate(used, quota_model.LimitSubjectSizeGitLFS)
|
||||
_, has, limit := group.Evaluate(used, quota_model.LimitSubjectSizeGitLFS)
|
||||
assert.False(t, has)
|
||||
assert.EqualValues(t, math.MaxInt, limit)
|
||||
|
||||
// repos:all is covered, and is passing
|
||||
ok, has := group.Evaluate(used, quota_model.LimitSubjectSizeReposAll)
|
||||
ok, has, limit := group.Evaluate(used, quota_model.LimitSubjectSizeReposAll)
|
||||
assert.True(t, has)
|
||||
assert.True(t, ok)
|
||||
assert.EqualValues(t, 4096, limit)
|
||||
|
||||
// packages:all is covered, and is failing
|
||||
ok, has = group.Evaluate(used, quota_model.LimitSubjectSizeAssetsPackagesAll)
|
||||
ok, has, limit = group.Evaluate(used, quota_model.LimitSubjectSizeAssetsPackagesAll)
|
||||
assert.True(t, has)
|
||||
assert.False(t, ok)
|
||||
assert.EqualValues(t, 0, limit)
|
||||
|
||||
// size:all is covered, and is failing (due to packages:all being over quota)
|
||||
ok, has = group.Evaluate(used, quota_model.LimitSubjectSizeAll)
|
||||
ok, has, limit = group.Evaluate(used, quota_model.LimitSubjectSizeAll)
|
||||
assert.True(t, has, "size:all should be covered")
|
||||
assert.False(t, ok, "size:all should fail")
|
||||
assert.EqualValues(t, 0, limit)
|
||||
}
|
||||
|
||||
func TestQuotaGroupListsRequireOnlyOnePassing(t *testing.T) {
|
||||
|
@ -159,8 +169,9 @@ func TestQuotaGroupListsRequireOnlyOnePassing(t *testing.T) {
|
|||
used.Size.Repos.Public = 1024
|
||||
|
||||
// In a group list, if any group passes, the entire evaluation passes.
|
||||
ok := groups.Evaluate(used, quota_model.LimitSubjectSizeAll)
|
||||
ok, limit := groups.Evaluate(used, quota_model.LimitSubjectSizeAll)
|
||||
assert.True(t, ok)
|
||||
assert.EqualValues(t, -1, limit)
|
||||
}
|
||||
|
||||
func TestQuotaGroupListAllFailing(t *testing.T) {
|
||||
|
@ -193,8 +204,9 @@ func TestQuotaGroupListAllFailing(t *testing.T) {
|
|||
used := quota_model.Used{}
|
||||
used.Size.Repos.Public = 2048
|
||||
|
||||
ok := groups.Evaluate(used, quota_model.LimitSubjectSizeAll)
|
||||
ok, limit := groups.Evaluate(used, quota_model.LimitSubjectSizeAll)
|
||||
assert.False(t, ok)
|
||||
assert.EqualValues(t, 0, limit)
|
||||
}
|
||||
|
||||
func TestQuotaGroupListEmpty(t *testing.T) {
|
||||
|
@ -203,6 +215,7 @@ func TestQuotaGroupListEmpty(t *testing.T) {
|
|||
used := quota_model.Used{}
|
||||
used.Size.Repos.Public = 2048
|
||||
|
||||
ok := groups.Evaluate(used, quota_model.LimitSubjectSizeAll)
|
||||
ok, limit := groups.Evaluate(used, quota_model.LimitSubjectSizeAll)
|
||||
assert.True(t, ok)
|
||||
assert.EqualValues(t, -1, limit)
|
||||
}
|
||||
|
|
|
@ -20,6 +20,22 @@ func (r *Rule) TableName() string {
|
|||
return "quota_rule"
|
||||
}
|
||||
|
||||
func (r Rule) Acceptable(used Used) bool {
|
||||
if r.Limit == -1 {
|
||||
return true
|
||||
}
|
||||
|
||||
return r.Sum(used) <= r.Limit
|
||||
}
|
||||
|
||||
func (r Rule) Sum(used Used) int64 {
|
||||
var sum int64
|
||||
for _, subject := range r.Subjects {
|
||||
sum += used.CalculateFor(subject)
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
func (r Rule) Evaluate(used Used, forSubject LimitSubject) (bool, bool) {
|
||||
// If there's no limit, short circuit out
|
||||
if r.Limit == -1 {
|
||||
|
@ -31,11 +47,7 @@ func (r Rule) Evaluate(used Used, forSubject LimitSubject) (bool, bool) {
|
|||
return false, false
|
||||
}
|
||||
|
||||
var sum int64
|
||||
for _, subject := range r.Subjects {
|
||||
sum += used.CalculateFor(subject)
|
||||
}
|
||||
return sum <= r.Limit, true
|
||||
return r.Sum(used) <= r.Limit, true
|
||||
}
|
||||
|
||||
func (r *Rule) Edit(ctx context.Context, limit *int64, subjects *LimitSubjects) (*Rule, error) {
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"strings"
|
||||
"testing"
|
||||
|
@ -37,7 +36,7 @@ func TestUserAvatarGenerate(t *testing.T) {
|
|||
require.NoError(t, unittest.PrepareTestDatabase())
|
||||
var err error
|
||||
tmpDir := t.TempDir()
|
||||
storage.Avatars, err = storage.NewLocalStorage(context.Background(), &setting.Storage{Path: tmpDir})
|
||||
storage.Avatars, err = storage.NewLocalStorage(t.Context(), &setting.Storage{Path: tmpDir})
|
||||
require.NoError(t, err)
|
||||
|
||||
u := unittest.AssertExistsAndLoadBean(t, &User{ID: 2})
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
package user_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
@ -346,7 +345,7 @@ func TestCreateUserCustomTimestamps(t *testing.T) {
|
|||
err := user_model.CreateUser(db.DefaultContext, user)
|
||||
require.NoError(t, err)
|
||||
|
||||
fetched, err := user_model.GetUserByID(context.Background(), user.ID)
|
||||
fetched, err := user_model.GetUserByID(t.Context(), user.ID)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, creationTimestamp, fetched.CreatedUnix)
|
||||
assert.Equal(t, creationTimestamp, fetched.UpdatedUnix)
|
||||
|
@ -373,7 +372,7 @@ func TestCreateUserWithoutCustomTimestamps(t *testing.T) {
|
|||
|
||||
timestampEnd := time.Now().Unix()
|
||||
|
||||
fetched, err := user_model.GetUserByID(context.Background(), user.ID)
|
||||
fetched, err := user_model.GetUserByID(t.Context(), user.ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.LessOrEqual(t, timestampStart, fetched.CreatedUnix)
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
package webhook
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
@ -262,7 +261,7 @@ func TestCleanupHookTaskTable_PerWebhook_DeletesDelivered(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
unittest.AssertExistsAndLoadBean(t, hookTask)
|
||||
|
||||
require.NoError(t, CleanupHookTaskTable(context.Background(), PerWebhook, 168*time.Hour, 0))
|
||||
require.NoError(t, CleanupHookTaskTable(t.Context(), PerWebhook, 168*time.Hour, 0))
|
||||
unittest.AssertNotExistsBean(t, hookTask)
|
||||
}
|
||||
|
||||
|
@ -278,7 +277,7 @@ func TestCleanupHookTaskTable_PerWebhook_LeavesUndelivered(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
unittest.AssertExistsAndLoadBean(t, hookTask)
|
||||
|
||||
require.NoError(t, CleanupHookTaskTable(context.Background(), PerWebhook, 168*time.Hour, 0))
|
||||
require.NoError(t, CleanupHookTaskTable(t.Context(), PerWebhook, 168*time.Hour, 0))
|
||||
unittest.AssertExistsAndLoadBean(t, hookTask)
|
||||
}
|
||||
|
||||
|
@ -295,7 +294,7 @@ func TestCleanupHookTaskTable_PerWebhook_LeavesMostRecentTask(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
unittest.AssertExistsAndLoadBean(t, hookTask)
|
||||
|
||||
require.NoError(t, CleanupHookTaskTable(context.Background(), PerWebhook, 168*time.Hour, 1))
|
||||
require.NoError(t, CleanupHookTaskTable(t.Context(), PerWebhook, 168*time.Hour, 1))
|
||||
unittest.AssertExistsAndLoadBean(t, hookTask)
|
||||
}
|
||||
|
||||
|
@ -312,7 +311,7 @@ func TestCleanupHookTaskTable_OlderThan_DeletesDelivered(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
unittest.AssertExistsAndLoadBean(t, hookTask)
|
||||
|
||||
require.NoError(t, CleanupHookTaskTable(context.Background(), OlderThan, 168*time.Hour, 0))
|
||||
require.NoError(t, CleanupHookTaskTable(t.Context(), OlderThan, 168*time.Hour, 0))
|
||||
unittest.AssertNotExistsBean(t, hookTask)
|
||||
}
|
||||
|
||||
|
@ -328,7 +327,7 @@ func TestCleanupHookTaskTable_OlderThan_LeavesUndelivered(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
unittest.AssertExistsAndLoadBean(t, hookTask)
|
||||
|
||||
require.NoError(t, CleanupHookTaskTable(context.Background(), OlderThan, 168*time.Hour, 0))
|
||||
require.NoError(t, CleanupHookTaskTable(t.Context(), OlderThan, 168*time.Hour, 0))
|
||||
unittest.AssertExistsAndLoadBean(t, hookTask)
|
||||
}
|
||||
|
||||
|
@ -345,6 +344,6 @@ func TestCleanupHookTaskTable_OlderThan_LeavesTaskEarlierThanAgeToDelete(t *test
|
|||
require.NoError(t, err)
|
||||
unittest.AssertExistsAndLoadBean(t, hookTask)
|
||||
|
||||
require.NoError(t, CleanupHookTaskTable(context.Background(), OlderThan, 168*time.Hour, 0))
|
||||
require.NoError(t, CleanupHookTaskTable(t.Context(), OlderThan, 168*time.Hour, 0))
|
||||
unittest.AssertExistsAndLoadBean(t, hookTask)
|
||||
}
|
||||
|
|
5
modules/cache/context_test.go
vendored
5
modules/cache/context_test.go
vendored
|
@ -4,7 +4,6 @@
|
|||
package cache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
@ -13,7 +12,7 @@ import (
|
|||
)
|
||||
|
||||
func TestWithCacheContext(t *testing.T) {
|
||||
ctx := WithCacheContext(context.Background())
|
||||
ctx := WithCacheContext(t.Context())
|
||||
|
||||
v := GetContextData(ctx, "empty_field", "my_config1")
|
||||
assert.Nil(t, v)
|
||||
|
@ -53,7 +52,7 @@ func TestWithCacheContext(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestWithNoCacheContext(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
const field = "system_setting"
|
||||
|
||||
|
|
|
@ -139,7 +139,7 @@ func CreateBlameReader(ctx context.Context, objectFormat ObjectFormat, repoPath
|
|||
cmd := NewCommandContextNoGlobals(ctx, "blame", "--porcelain")
|
||||
if ignoreRevsFile != nil {
|
||||
// Possible improvement: use --ignore-revs-file /dev/stdin on unix
|
||||
// There is no equivalent on Windows. May be implemented if Gitea uses an external git backend.
|
||||
// This was not done in Gitea because it would not have been compatible with Windows.
|
||||
cmd.AddOptionValues("--ignore-revs-file", *ignoreRevsFile)
|
||||
}
|
||||
cmd.AddDynamicArguments(commit.ID.String()).
|
||||
|
|
|
@ -14,7 +14,7 @@ import (
|
|||
func TestReadingBlameOutputSha256(t *testing.T) {
|
||||
skipIfSHA256NotSupported(t)
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
t.Run("Without .git-blame-ignore-revs", func(t *testing.T) {
|
||||
|
|
|
@ -12,7 +12,7 @@ import (
|
|||
)
|
||||
|
||||
func TestReadingBlameOutput(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
t.Run("Without .git-blame-ignore-revs", func(t *testing.T) {
|
||||
|
|
|
@ -12,7 +12,6 @@ import (
|
|||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"runtime/trace"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -359,17 +358,6 @@ func (c *Command) Run(opts *RunOpts) error {
|
|||
log.Debug("slow git.Command.Run: %s (%s)", c, elapsed)
|
||||
}
|
||||
|
||||
// We need to check if the context is canceled by the program on Windows.
|
||||
// This is because Windows does not have signal checking when terminating the process.
|
||||
// It always returns exit code 1, unlike Linux, which has many exit codes for signals.
|
||||
if runtime.GOOS == "windows" &&
|
||||
err != nil &&
|
||||
err.Error() == "" &&
|
||||
cmd.ProcessState.ExitCode() == 1 &&
|
||||
ctx.Err() == context.Canceled {
|
||||
return ctx.Err()
|
||||
}
|
||||
|
||||
if err != nil && ctx.Err() != context.DeadlineExceeded {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
package git
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -12,13 +11,13 @@ import (
|
|||
)
|
||||
|
||||
func TestRunWithContextStd(t *testing.T) {
|
||||
cmd := NewCommand(context.Background(), "--version")
|
||||
cmd := NewCommand(t.Context(), "--version")
|
||||
stdout, stderr, err := cmd.RunStdString(&RunOpts{})
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, stderr)
|
||||
assert.Contains(t, stdout, "git version")
|
||||
|
||||
cmd = NewCommand(context.Background(), "--no-such-arg")
|
||||
cmd = NewCommand(t.Context(), "--no-such-arg")
|
||||
stdout, stderr, err = cmd.RunStdString(&RunOpts{})
|
||||
if assert.Error(t, err) {
|
||||
assert.Equal(t, stderr, err.Stderr())
|
||||
|
@ -27,16 +26,16 @@ func TestRunWithContextStd(t *testing.T) {
|
|||
assert.Empty(t, stdout)
|
||||
}
|
||||
|
||||
cmd = NewCommand(context.Background())
|
||||
cmd = NewCommand(t.Context())
|
||||
cmd.AddDynamicArguments("-test")
|
||||
require.ErrorIs(t, cmd.Run(&RunOpts{}), ErrBrokenCommand)
|
||||
|
||||
cmd = NewCommand(context.Background())
|
||||
cmd = NewCommand(t.Context())
|
||||
cmd.AddDynamicArguments("--test")
|
||||
require.ErrorIs(t, cmd.Run(&RunOpts{}), ErrBrokenCommand)
|
||||
|
||||
subCmd := "version"
|
||||
cmd = NewCommand(context.Background()).AddDynamicArguments(subCmd) // for test purpose only, the sub-command should never be dynamic for production
|
||||
cmd = NewCommand(t.Context()).AddDynamicArguments(subCmd) // for test purpose only, the sub-command should never be dynamic for production
|
||||
stdout, stderr, err = cmd.RunStdString(&RunOpts{})
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, stderr)
|
||||
|
@ -55,15 +54,15 @@ func TestGitArgument(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCommandString(t *testing.T) {
|
||||
cmd := NewCommandContextNoGlobals(context.Background(), "a", "-m msg", "it's a test", `say "hello"`)
|
||||
cmd := NewCommandContextNoGlobals(t.Context(), "a", "-m msg", "it's a test", `say "hello"`)
|
||||
assert.EqualValues(t, cmd.prog+` a "-m msg" "it's a test" "say \"hello\""`, cmd.String())
|
||||
|
||||
cmd = NewCommandContextNoGlobals(context.Background(), "url: https://a:b@c/")
|
||||
cmd = NewCommandContextNoGlobals(t.Context(), "url: https://a:b@c/")
|
||||
assert.EqualValues(t, cmd.prog+` "url: https://sanitized-credential@c/"`, cmd.toString(true))
|
||||
}
|
||||
|
||||
func TestGrepOnlyFunction(t *testing.T) {
|
||||
cmd := NewCommand(context.Background(), "anything-but-grep")
|
||||
cmd := NewCommand(t.Context(), "anything-but-grep")
|
||||
assert.Panics(t, func() {
|
||||
cmd.AddGitGrepExpression("whatever")
|
||||
})
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
package git
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -84,7 +83,7 @@ func testGetCommitsInfo(t *testing.T, repo1 *Repository) {
|
|||
}
|
||||
|
||||
// FIXME: Context.TODO() - if graceful has started we should use its Shutdown context otherwise use install signals in TestMain.
|
||||
commitsInfo, treeCommit, err := entries.GetCommitsInfo(context.TODO(), commit, testCase.Path)
|
||||
commitsInfo, treeCommit, err := entries.GetCommitsInfo(t.Context(), commit, testCase.Path)
|
||||
require.NoError(t, err, "Unable to get commit information for entries of subtree: %s in commit: %s from testcase due to error: %v", testCase.Path, testCase.CommitID, err)
|
||||
if err != nil {
|
||||
t.FailNow()
|
||||
|
@ -161,7 +160,7 @@ func BenchmarkEntries_GetCommitsInfo(b *testing.B) {
|
|||
b.ResetTimer()
|
||||
b.Run(benchmark.name, func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _, err := entries.GetCommitsInfo(context.Background(), commit, "")
|
||||
_, _, err := entries.GetCommitsInfo(b.Context(), commit, "")
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
|
|
@ -59,15 +59,7 @@ func loadGitVersion() error {
|
|||
return fmt.Errorf("invalid git version output: %s", stdout)
|
||||
}
|
||||
|
||||
var versionString string
|
||||
|
||||
// Handle special case on Windows.
|
||||
i := strings.Index(fields[2], "windows")
|
||||
if i >= 1 {
|
||||
versionString = fields[2][:i-1]
|
||||
} else {
|
||||
versionString = fields[2]
|
||||
}
|
||||
versionString := fields[2]
|
||||
|
||||
var err error
|
||||
gitVersion, err = version.NewVersion(versionString)
|
||||
|
@ -280,24 +272,11 @@ func syncGitConfig() (err error) {
|
|||
// Thus the owner uid/gid for files on these filesystems will be marked as root.
|
||||
// As Gitea now always use its internal git config file, and access to the git repositories is managed through Gitea,
|
||||
// it is now safe to set "safe.directory=*" for internal usage only.
|
||||
// Please note: the wildcard "*" is only supported by Git 2.30.4/2.31.3/2.32.2/2.33.3/2.34.3/2.35.3/2.36 and later
|
||||
// Although only supported by Git 2.30.4/2.31.3/2.32.2/2.33.3/2.34.3/2.35.3/2.36 and later - this setting is tolerated by earlier versions
|
||||
// Please note: the wildcard "*" is only supported by Git 2.30.4/2.31.3/2.32.2/2.33.3/2.34.3/2.35.3/2.36 and later,
|
||||
// but is tolerated by earlier versions
|
||||
if err := configAddNonExist("safe.directory", "*"); err != nil {
|
||||
return err
|
||||
}
|
||||
if runtime.GOOS == "windows" {
|
||||
if err := configSet("core.longpaths", "true"); err != nil {
|
||||
return err
|
||||
}
|
||||
if setting.Git.DisableCoreProtectNTFS {
|
||||
err = configSet("core.protectNTFS", "false")
|
||||
} else {
|
||||
err = configUnsetAll("core.protectNTFS", "false")
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// By default partial clones are disabled, enable them from git v2.22
|
||||
if !setting.Git.DisablePartialClone && CheckGitVersionAtLeast("2.22") == nil {
|
||||
|
|
|
@ -5,7 +5,6 @@ package git
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
@ -20,7 +19,7 @@ func TestGrepSearch(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
defer repo.Close()
|
||||
|
||||
res, err := GrepSearch(context.Background(), repo, "public", GrepOptions{})
|
||||
res, err := GrepSearch(t.Context(), repo, "public", GrepOptions{})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []*GrepResult{
|
||||
{
|
||||
|
@ -43,7 +42,7 @@ func TestGrepSearch(t *testing.T) {
|
|||
},
|
||||
}, res)
|
||||
|
||||
res, err = GrepSearch(context.Background(), repo, "void", GrepOptions{MaxResultLimit: 1, ContextLineNumber: 2})
|
||||
res, err = GrepSearch(t.Context(), repo, "void", GrepOptions{MaxResultLimit: 1, ContextLineNumber: 2})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []*GrepResult{
|
||||
{
|
||||
|
@ -60,7 +59,7 @@ func TestGrepSearch(t *testing.T) {
|
|||
},
|
||||
}, res)
|
||||
|
||||
res, err = GrepSearch(context.Background(), repo, "world", GrepOptions{MatchesPerFile: 1})
|
||||
res, err = GrepSearch(t.Context(), repo, "world", GrepOptions{MatchesPerFile: 1})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []*GrepResult{
|
||||
{
|
||||
|
@ -89,7 +88,7 @@ func TestGrepSearch(t *testing.T) {
|
|||
},
|
||||
}, res)
|
||||
|
||||
res, err = GrepSearch(context.Background(), repo, "world", GrepOptions{
|
||||
res, err = GrepSearch(t.Context(), repo, "world", GrepOptions{
|
||||
MatchesPerFile: 1,
|
||||
Filename: "java-hello/",
|
||||
})
|
||||
|
@ -103,11 +102,11 @@ func TestGrepSearch(t *testing.T) {
|
|||
},
|
||||
}, res)
|
||||
|
||||
res, err = GrepSearch(context.Background(), repo, "no-such-content", GrepOptions{})
|
||||
res, err = GrepSearch(t.Context(), repo, "no-such-content", GrepOptions{})
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, res)
|
||||
|
||||
res, err = GrepSearch(context.Background(), &Repository{Path: "no-such-git-repo"}, "no-such-content", GrepOptions{})
|
||||
res, err = GrepSearch(t.Context(), &Repository{Path: "no-such-git-repo"}, "no-such-content", GrepOptions{})
|
||||
require.Error(t, err)
|
||||
assert.Empty(t, res)
|
||||
}
|
||||
|
@ -131,7 +130,7 @@ func TestGrepDashesAreFine(t *testing.T) {
|
|||
err = CommitChanges(tmpDir, CommitChangesOptions{Message: "Dashes are cool sometimes"})
|
||||
require.NoError(t, err)
|
||||
|
||||
res, err := GrepSearch(context.Background(), gitRepo, "--", GrepOptions{})
|
||||
res, err := GrepSearch(t.Context(), gitRepo, "--", GrepOptions{})
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, res, 1)
|
||||
assert.Equal(t, "with-dashes", res[0].Filename)
|
||||
|
@ -156,7 +155,7 @@ func TestGrepNoBinary(t *testing.T) {
|
|||
err = CommitChanges(tmpDir, CommitChangesOptions{Message: "Binary and text files"})
|
||||
require.NoError(t, err)
|
||||
|
||||
res, err := GrepSearch(context.Background(), gitRepo, "BINARY", GrepOptions{})
|
||||
res, err := GrepSearch(t.Context(), gitRepo, "BINARY", GrepOptions{})
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, res, 1)
|
||||
assert.Equal(t, "TEXT", res[0].Filename)
|
||||
|
@ -180,7 +179,7 @@ func TestGrepLongFiles(t *testing.T) {
|
|||
err = CommitChanges(tmpDir, CommitChangesOptions{Message: "Long file"})
|
||||
require.NoError(t, err)
|
||||
|
||||
res, err := GrepSearch(context.Background(), gitRepo, "a", GrepOptions{})
|
||||
res, err := GrepSearch(t.Context(), gitRepo, "a", GrepOptions{})
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, res, 1)
|
||||
assert.Len(t, res[0].LineCodes[0], 65*1024)
|
||||
|
@ -210,7 +209,7 @@ func TestGrepRefs(t *testing.T) {
|
|||
err = CommitChanges(tmpDir, CommitChangesOptions{Message: "add BCD"})
|
||||
require.NoError(t, err)
|
||||
|
||||
res, err := GrepSearch(context.Background(), gitRepo, "a", GrepOptions{RefName: "v1"})
|
||||
res, err := GrepSearch(t.Context(), gitRepo, "a", GrepOptions{RefName: "v1"})
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, res, 1)
|
||||
assert.Equal(t, "A", res[0].LineCodes[0])
|
||||
|
@ -236,12 +235,12 @@ func TestGrepCanHazRegexOnDemand(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
// should find nothing by default...
|
||||
res, err := GrepSearch(context.Background(), gitRepo, "\\bmatch\\b", GrepOptions{})
|
||||
res, err := GrepSearch(t.Context(), gitRepo, "\\bmatch\\b", GrepOptions{})
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, res)
|
||||
|
||||
// ... unless configured explicitly
|
||||
res, err = GrepSearch(context.Background(), gitRepo, "\\bmatch\\b", GrepOptions{Mode: RegExpGrepMode})
|
||||
res, err = GrepSearch(t.Context(), gitRepo, "\\bmatch\\b", GrepOptions{Mode: RegExpGrepMode})
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, res, 1)
|
||||
assert.Equal(t, "matching", res[0].Filename)
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
package git_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
|
@ -32,7 +30,7 @@ func TestGetNotes(t *testing.T) {
|
|||
defer bareRepo1.Close()
|
||||
|
||||
note := git.Note{}
|
||||
err = git.GetNote(context.Background(), bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653", ¬e)
|
||||
err = git.GetNote(t.Context(), bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653", ¬e)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []byte("Note contents\n"), note.Message)
|
||||
assert.Equal(t, "Vladimir Panteleev", note.Commit.Author.Name)
|
||||
|
@ -45,10 +43,10 @@ func TestGetNestedNotes(t *testing.T) {
|
|||
defer repo.Close()
|
||||
|
||||
note := git.Note{}
|
||||
err = git.GetNote(context.Background(), repo, "3e668dbfac39cbc80a9ff9c61eb565d944453ba4", ¬e)
|
||||
err = git.GetNote(t.Context(), repo, "3e668dbfac39cbc80a9ff9c61eb565d944453ba4", ¬e)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []byte("Note 2"), note.Message)
|
||||
err = git.GetNote(context.Background(), repo, "ba0a96fa63532d6c5087ecef070b0250ed72fa47", ¬e)
|
||||
err = git.GetNote(t.Context(), repo, "ba0a96fa63532d6c5087ecef070b0250ed72fa47", ¬e)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []byte("Note 1"), note.Message)
|
||||
}
|
||||
|
@ -60,7 +58,7 @@ func TestGetNonExistentNotes(t *testing.T) {
|
|||
defer bareRepo1.Close()
|
||||
|
||||
note := git.Note{}
|
||||
err = git.GetNote(context.Background(), bareRepo1, "non_existent_sha", ¬e)
|
||||
err = git.GetNote(t.Context(), bareRepo1, "non_existent_sha", ¬e)
|
||||
require.Error(t, err)
|
||||
assert.IsType(t, git.ErrNotExist{}, err)
|
||||
}
|
||||
|
@ -68,19 +66,17 @@ func TestGetNonExistentNotes(t *testing.T) {
|
|||
func TestSetNote(t *testing.T) {
|
||||
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
||||
|
||||
tempDir, err := os.MkdirTemp("", "")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tempDir)
|
||||
tempDir := t.TempDir()
|
||||
require.NoError(t, unittest.CopyDir(bareRepo1Path, filepath.Join(tempDir, "repo1")))
|
||||
|
||||
bareRepo1, err := openRepositoryWithDefaultContext(filepath.Join(tempDir, "repo1"))
|
||||
require.NoError(t, err)
|
||||
defer bareRepo1.Close()
|
||||
|
||||
require.NoError(t, git.SetNote(context.Background(), bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653", "This is a new note", "Test", "test@test.com"))
|
||||
require.NoError(t, git.SetNote(t.Context(), bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653", "This is a new note", "Test", "test@test.com"))
|
||||
|
||||
note := git.Note{}
|
||||
err = git.GetNote(context.Background(), bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653", ¬e)
|
||||
err = git.GetNote(t.Context(), bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653", ¬e)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []byte("This is a new note\n"), note.Message)
|
||||
assert.Equal(t, "Test", note.Commit.Author.Name)
|
||||
|
@ -97,10 +93,10 @@ func TestRemoveNote(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
defer bareRepo1.Close()
|
||||
|
||||
require.NoError(t, git.RemoveNote(context.Background(), bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653"))
|
||||
require.NoError(t, git.RemoveNote(t.Context(), bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653"))
|
||||
|
||||
note := git.Note{}
|
||||
err = git.GetNote(context.Background(), bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653", ¬e)
|
||||
err = git.GetNote(t.Context(), bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653", ¬e)
|
||||
require.Error(t, err)
|
||||
assert.IsType(t, git.ErrNotExist{}, err)
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ import (
|
|||
|
||||
// This unit test relies on the implementation detail of CatFileBatch.
|
||||
func TestCatFileBatch(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
repo, err := OpenRepository(ctx, "./tests/repos/repo1_bare")
|
||||
|
@ -89,7 +89,7 @@ func TestCatFileBatch(t *testing.T) {
|
|||
|
||||
// This unit test relies on the implementation detail of CatFileBatchCheck.
|
||||
func TestCatFileBatchCheck(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
repo, err := OpenRepository(ctx, "./tests/repos/repo1_bare")
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
package git
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
|
@ -34,21 +33,21 @@ func TestRepoIsEmpty(t *testing.T) {
|
|||
|
||||
func TestRepoGetDivergingCommits(t *testing.T) {
|
||||
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
||||
do, err := GetDivergingCommits(context.Background(), bareRepo1Path, "master", "branch2")
|
||||
do, err := GetDivergingCommits(t.Context(), bareRepo1Path, "master", "branch2")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, DivergeObject{
|
||||
Ahead: 1,
|
||||
Behind: 5,
|
||||
}, do)
|
||||
|
||||
do, err = GetDivergingCommits(context.Background(), bareRepo1Path, "master", "master")
|
||||
do, err = GetDivergingCommits(t.Context(), bareRepo1Path, "master", "master")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, DivergeObject{
|
||||
Ahead: 0,
|
||||
Behind: 0,
|
||||
}, do)
|
||||
|
||||
do, err = GetDivergingCommits(context.Background(), bareRepo1Path, "master", "test")
|
||||
do, err = GetDivergingCommits(t.Context(), bareRepo1Path, "master", "test")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, DivergeObject{
|
||||
Ahead: 0,
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//go:build !windows
|
||||
|
||||
package graceful
|
||||
|
||||
import (
|
||||
|
|
|
@ -3,14 +3,13 @@
|
|||
|
||||
// This code is heavily inspired by the archived gofacebook/gracenet/net.go handler
|
||||
|
||||
//go:build !windows
|
||||
|
||||
package graceful
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
@ -237,9 +236,11 @@ func GetListenerUnix(network string, address *net.UnixAddr) (*net.UnixListener,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
fileMode := os.FileMode(setting.UnixSocketPermission)
|
||||
if err = os.Chmod(address.Name, fileMode); err != nil {
|
||||
return nil, fmt.Errorf("Failed to set permission of unix socket to %s: %w", fileMode.String(), err)
|
||||
if filepath.IsAbs(address.Name) {
|
||||
fileMode := os.FileMode(setting.UnixSocketPermission)
|
||||
if err = os.Chmod(address.Name, fileMode); err != nil {
|
||||
return nil, fmt.Errorf("Failed to set permission of unix socket to %s: %w", fileMode.String(), err)
|
||||
}
|
||||
}
|
||||
|
||||
activeListeners = append(activeListeners, l)
|
||||
|
|
15
modules/graceful/net_unix_linux_test.go
Normal file
15
modules/graceful/net_unix_linux_test.go
Normal file
|
@ -0,0 +1,15 @@
|
|||
// Copyright 2025 The Forgejo Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package graceful
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestAbstractUnixSocket(t *testing.T) {
|
||||
_, err := DefaultGetListener("unix", "@abc")
|
||||
require.NoError(t, err)
|
||||
}
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
// This code is heavily inspired by the archived gofacebook/gracenet/net.go handler
|
||||
|
||||
//go:build !windows
|
||||
|
||||
package graceful
|
||||
|
||||
import (
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
package code
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
|
@ -94,7 +93,7 @@ func testIndexer(name string, t *testing.T, indexer internal.Indexer) {
|
|||
|
||||
for _, kw := range keywords {
|
||||
t.Run(kw.Keyword, func(t *testing.T) {
|
||||
total, res, langs, err := indexer.Search(context.TODO(), &internal.SearchOptions{
|
||||
total, res, langs, err := indexer.Search(t.Context(), &internal.SearchOptions{
|
||||
RepoIDs: kw.RepoIDs,
|
||||
Keyword: kw.Keyword,
|
||||
Paginator: &db.ListOptions{
|
||||
|
@ -117,7 +116,7 @@ func testIndexer(name string, t *testing.T, indexer internal.Indexer) {
|
|||
})
|
||||
}
|
||||
|
||||
require.NoError(t, indexer.Delete(context.Background(), repoID))
|
||||
require.NoError(t, indexer.Delete(t.Context(), repoID))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -127,7 +126,7 @@ func TestBleveIndexAndSearch(t *testing.T) {
|
|||
dir := t.TempDir()
|
||||
|
||||
idx := bleve.NewIndexer(dir)
|
||||
_, err := idx.Init(context.Background())
|
||||
_, err := idx.Init(t.Context())
|
||||
if err != nil {
|
||||
if idx != nil {
|
||||
idx.Close()
|
||||
|
@ -149,7 +148,7 @@ func TestESIndexAndSearch(t *testing.T) {
|
|||
}
|
||||
|
||||
indexer := elasticsearch.NewIndexer(u, "gitea_codes")
|
||||
if _, err := indexer.Init(context.Background()); err != nil {
|
||||
if _, err := indexer.Init(t.Context()); err != nil {
|
||||
if indexer != nil {
|
||||
indexer.Close()
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
package issues
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
|
@ -82,7 +81,7 @@ func searchIssueWithKeyword(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, test := range tests {
|
||||
issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
|
||||
issueIDs, _, err := SearchIssues(t.Context(), &test.opts)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, test.expectedIDs, issueIDs)
|
||||
|
@ -127,7 +126,7 @@ func searchIssueInRepo(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, test := range tests {
|
||||
issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
|
||||
issueIDs, _, err := SearchIssues(t.Context(), &test.opts)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, test.expectedIDs, issueIDs)
|
||||
|
@ -198,7 +197,7 @@ func searchIssueByID(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, test := range tests {
|
||||
issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
|
||||
issueIDs, _, err := SearchIssues(t.Context(), &test.opts)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, test.expectedIDs, issueIDs)
|
||||
}
|
||||
|
@ -223,7 +222,7 @@ func searchIssueIsPull(t *testing.T) {
|
|||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
|
||||
issueIDs, _, err := SearchIssues(t.Context(), &test.opts)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, test.expectedIDs, issueIDs)
|
||||
|
@ -249,7 +248,7 @@ func searchIssueIsClosed(t *testing.T) {
|
|||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
|
||||
issueIDs, _, err := SearchIssues(t.Context(), &test.opts)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, test.expectedIDs, issueIDs)
|
||||
}
|
||||
|
@ -274,7 +273,7 @@ func searchIssueByMilestoneID(t *testing.T) {
|
|||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
|
||||
issueIDs, _, err := SearchIssues(t.Context(), &test.opts)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, test.expectedIDs, issueIDs)
|
||||
|
@ -306,7 +305,7 @@ func searchIssueByLabelID(t *testing.T) {
|
|||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
|
||||
issueIDs, _, err := SearchIssues(t.Context(), &test.opts)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, test.expectedIDs, issueIDs)
|
||||
|
@ -326,7 +325,7 @@ func searchIssueByTime(t *testing.T) {
|
|||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
|
||||
issueIDs, _, err := SearchIssues(t.Context(), &test.opts)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, test.expectedIDs, issueIDs)
|
||||
|
@ -346,7 +345,7 @@ func searchIssueWithOrder(t *testing.T) {
|
|||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
|
||||
issueIDs, _, err := SearchIssues(t.Context(), &test.opts)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, test.expectedIDs, issueIDs)
|
||||
|
@ -378,7 +377,7 @@ func searchIssueInProject(t *testing.T) {
|
|||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
|
||||
issueIDs, _, err := SearchIssues(t.Context(), &test.opts)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, test.expectedIDs, issueIDs)
|
||||
|
@ -402,7 +401,7 @@ func searchIssueWithPaginator(t *testing.T) {
|
|||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
issueIDs, total, err := SearchIssues(context.TODO(), &test.opts)
|
||||
issueIDs, total, err := SearchIssues(t.Context(), &test.opts)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, test.expectedIDs, issueIDs)
|
||||
|
|
|
@ -24,10 +24,10 @@ import (
|
|||
)
|
||||
|
||||
func TestIndexer(t *testing.T, indexer internal.Indexer) {
|
||||
_, err := indexer.Init(context.Background())
|
||||
_, err := indexer.Init(t.Context())
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, indexer.Ping(context.Background()))
|
||||
require.NoError(t, indexer.Ping(t.Context()))
|
||||
|
||||
var (
|
||||
ids []int64
|
||||
|
@ -39,32 +39,32 @@ func TestIndexer(t *testing.T, indexer internal.Indexer) {
|
|||
ids = append(ids, v.ID)
|
||||
data[v.ID] = v
|
||||
}
|
||||
require.NoError(t, indexer.Index(context.Background(), d...))
|
||||
require.NoError(t, indexer.Index(t.Context(), d...))
|
||||
require.NoError(t, waitData(indexer, int64(len(data))))
|
||||
}
|
||||
|
||||
defer func() {
|
||||
require.NoError(t, indexer.Delete(context.Background(), ids...))
|
||||
require.NoError(t, indexer.Delete(t.Context(), ids...))
|
||||
}()
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.Name, func(t *testing.T) {
|
||||
if len(c.ExtraData) > 0 {
|
||||
require.NoError(t, indexer.Index(context.Background(), c.ExtraData...))
|
||||
require.NoError(t, indexer.Index(t.Context(), c.ExtraData...))
|
||||
for _, v := range c.ExtraData {
|
||||
data[v.ID] = v
|
||||
}
|
||||
require.NoError(t, waitData(indexer, int64(len(data))))
|
||||
defer func() {
|
||||
for _, v := range c.ExtraData {
|
||||
require.NoError(t, indexer.Delete(context.Background(), v.ID))
|
||||
require.NoError(t, indexer.Delete(t.Context(), v.ID))
|
||||
delete(data, v.ID)
|
||||
}
|
||||
require.NoError(t, waitData(indexer, int64(len(data))))
|
||||
}()
|
||||
}
|
||||
|
||||
result, err := indexer.Search(context.Background(), c.SearchOptions)
|
||||
result, err := indexer.Search(t.Context(), c.SearchOptions)
|
||||
require.NoError(t, err)
|
||||
|
||||
if c.Expected != nil {
|
||||
|
@ -80,7 +80,7 @@ func TestIndexer(t *testing.T, indexer internal.Indexer) {
|
|||
|
||||
// test counting
|
||||
c.SearchOptions.Paginator = &db.ListOptions{PageSize: 0}
|
||||
countResult, err := indexer.Search(context.Background(), c.SearchOptions)
|
||||
countResult, err := indexer.Search(t.Context(), c.SearchOptions)
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, countResult.Hits)
|
||||
assert.Equal(t, result.Total, countResult.Total)
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
package stats
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
@ -42,7 +41,7 @@ func TestRepoStatsIndex(t *testing.T) {
|
|||
err = UpdateRepoIndexer(repo)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, queue.GetManager().FlushAll(context.Background(), 5*time.Second))
|
||||
require.NoError(t, queue.GetManager().FlushAll(t.Context(), 5*time.Second))
|
||||
|
||||
status, err := repo_model.GetIndexerStatus(db.DefaultContext, repo, repo_model.RepoIndexerTypeStats)
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -249,7 +249,7 @@ func TestHTTPClientDownload(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
err := client.Download(context.Background(), []Pointer{p}, func(p Pointer, content io.ReadCloser, objectError error) error {
|
||||
err := client.Download(t.Context(), []Pointer{p}, func(p Pointer, content io.ReadCloser, objectError error) error {
|
||||
if objectError != nil {
|
||||
return objectError
|
||||
}
|
||||
|
@ -349,7 +349,7 @@ func TestHTTPClientUpload(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
err := client.Upload(context.Background(), []Pointer{p}, func(p Pointer, objectError error) (io.ReadCloser, error) {
|
||||
err := client.Upload(t.Context(), []Pointer{p}, func(p Pointer, objectError error) (io.ReadCloser, error) {
|
||||
return io.NopCloser(new(bytes.Buffer)), objectError
|
||||
})
|
||||
if c.expectedError != "" {
|
||||
|
|
|
@ -5,7 +5,6 @@ package lfs
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
@ -95,7 +94,7 @@ func TestBasicTransferAdapter(t *testing.T) {
|
|||
}
|
||||
|
||||
for n, c := range cases {
|
||||
_, err := a.Download(context.Background(), c.link)
|
||||
_, err := a.Download(t.Context(), c.link)
|
||||
if len(c.expectederror) > 0 {
|
||||
assert.Contains(t, err.Error(), c.expectederror, "case %d: '%s' should contain '%s'", n, err.Error(), c.expectederror)
|
||||
} else {
|
||||
|
@ -128,7 +127,7 @@ func TestBasicTransferAdapter(t *testing.T) {
|
|||
}
|
||||
|
||||
for n, c := range cases {
|
||||
err := a.Upload(context.Background(), c.link, p, bytes.NewBufferString("dummy"))
|
||||
err := a.Upload(t.Context(), c.link, p, bytes.NewBufferString("dummy"))
|
||||
if len(c.expectederror) > 0 {
|
||||
assert.Contains(t, err.Error(), c.expectederror, "case %d: '%s' should contain '%s'", n, err.Error(), c.expectederror)
|
||||
} else {
|
||||
|
@ -161,7 +160,7 @@ func TestBasicTransferAdapter(t *testing.T) {
|
|||
}
|
||||
|
||||
for n, c := range cases {
|
||||
err := a.Verify(context.Background(), c.link, p)
|
||||
err := a.Verify(t.Context(), c.link, p)
|
||||
if len(c.expectederror) > 0 {
|
||||
assert.Contains(t, err.Error(), c.expectederror, "case %d: '%s' should contain '%s'", n, err.Error(), c.expectederror)
|
||||
} else {
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//go:build !windows
|
||||
|
||||
package log
|
||||
|
||||
import (
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package log
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/mattn/go-isatty"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
func enableVTMode(console windows.Handle) bool {
|
||||
mode := uint32(0)
|
||||
err := windows.GetConsoleMode(console, &mode)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// EnableVirtualTerminalProcessing is the console mode to allow ANSI code
|
||||
// interpretation on the console. See:
|
||||
// https://docs.microsoft.com/en-us/windows/console/setconsolemode
|
||||
// It only works on Windows 10. Earlier terminals will fail with an err which we will
|
||||
// handle to say don't color
|
||||
mode |= windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING
|
||||
err = windows.SetConsoleMode(console, mode)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
if isatty.IsTerminal(os.Stdout.Fd()) {
|
||||
CanColorStdout = enableVTMode(windows.Stdout)
|
||||
} else {
|
||||
CanColorStdout = isatty.IsCygwinTerminal(os.Stderr.Fd())
|
||||
}
|
||||
|
||||
if isatty.IsTerminal(os.Stderr.Fd()) {
|
||||
CanColorStderr = enableVTMode(windows.Stderr)
|
||||
} else {
|
||||
CanColorStderr = isatty.IsCygwinTerminal(os.Stderr.Fd())
|
||||
}
|
||||
}
|
|
@ -4,7 +4,6 @@
|
|||
package log_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
|
@ -23,7 +22,7 @@ func TestBufferLogger(t *testing.T) {
|
|||
Expression: expected,
|
||||
})
|
||||
|
||||
logger := log.NewLoggerWithWriters(context.Background(), "test", bufferWriter)
|
||||
logger := log.NewLoggerWithWriters(t.Context(), "test", bufferWriter)
|
||||
|
||||
logger.SendLogEvent(&log.Event{
|
||||
Level: log.INFO,
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
package log
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
|
@ -41,7 +40,7 @@ func TestConnLogger(t *testing.T) {
|
|||
level := INFO
|
||||
flags := LstdFlags | LUTC | Lfuncname
|
||||
|
||||
logger := NewLoggerWithWriters(context.Background(), "test", NewEventWriterConn("test-conn", WriterMode{
|
||||
logger := NewLoggerWithWriters(t.Context(), "test", NewEventWriterConn("test-conn", WriterMode{
|
||||
Level: level,
|
||||
Prefix: prefix,
|
||||
Flags: FlagsFromBits(flags),
|
||||
|
|
|
@ -12,7 +12,7 @@ import (
|
|||
)
|
||||
|
||||
func Test_getGoroutineLabels(t *testing.T) {
|
||||
pprof.Do(context.Background(), pprof.Labels(), func(ctx context.Context) {
|
||||
pprof.Do(t.Context(), pprof.Labels(), func(ctx context.Context) {
|
||||
currentLabels := getGoroutineLabels()
|
||||
pprof.ForLabels(ctx, func(key, value string) bool {
|
||||
assert.EqualValues(t, value, currentLabels[key])
|
||||
|
|
|
@ -191,7 +191,7 @@ func (l *LoggerImpl) Log(skip int, level Level, format string, logArgs ...any) {
|
|||
if ok {
|
||||
fn := runtime.FuncForPC(pc)
|
||||
if fn != nil {
|
||||
event.Caller = fn.Name() + "()"
|
||||
event.Caller = strings.TrimSuffix(fn.Name(), "[...]") + "()"
|
||||
}
|
||||
}
|
||||
event.Filename, event.Line = strings.TrimPrefix(filename, projectPackagePrefix), line
|
||||
|
|
27
modules/log/logger_impl_test.go
Normal file
27
modules/log/logger_impl_test.go
Normal file
|
@ -0,0 +1,27 @@
|
|||
// Copyright 2025 The Forgejo Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package log
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func testGeneric[T any](log *LoggerImpl, t T) {
|
||||
log.Log(0, INFO, "Just testing the logging of a generic function %v", t)
|
||||
}
|
||||
|
||||
func TestLog(t *testing.T) {
|
||||
bufferWriter := NewEventWriterBuffer("test-buffer", WriterMode{
|
||||
Level: INFO,
|
||||
})
|
||||
|
||||
logger := NewLoggerWithWriters(t.Context(), "test", bufferWriter)
|
||||
|
||||
testGeneric(logger, "I'm the generic value!")
|
||||
logger.Close()
|
||||
|
||||
assert.Contains(t, bufferWriter.Buffer.String(), ".../logger_impl_test.go:13:testGeneric() [I] Just testing the logging of a generic function I'm the generic value!")
|
||||
}
|
|
@ -4,7 +4,6 @@
|
|||
package log
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -53,7 +52,7 @@ func newDummyWriter(name string, level Level, delay time.Duration) *dummyWriter
|
|||
}
|
||||
|
||||
func TestLogger(t *testing.T) {
|
||||
logger := NewLoggerWithWriters(context.Background(), "test")
|
||||
logger := NewLoggerWithWriters(t.Context(), "test")
|
||||
|
||||
dump := logger.DumpWriters()
|
||||
assert.Empty(t, dump)
|
||||
|
@ -88,7 +87,7 @@ func TestLogger(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestLoggerPause(t *testing.T) {
|
||||
logger := NewLoggerWithWriters(context.Background(), "test")
|
||||
logger := NewLoggerWithWriters(t.Context(), "test")
|
||||
|
||||
w1 := newDummyWriter("dummy-1", DEBUG, 0)
|
||||
logger.AddWriters(w1)
|
||||
|
@ -117,7 +116,7 @@ func (t testLogString) LogString() string {
|
|||
}
|
||||
|
||||
func TestLoggerLogString(t *testing.T) {
|
||||
logger := NewLoggerWithWriters(context.Background(), "test")
|
||||
logger := NewLoggerWithWriters(t.Context(), "test")
|
||||
|
||||
w1 := newDummyWriter("dummy-1", DEBUG, 0)
|
||||
w1.Mode.Colorize = true
|
||||
|
@ -130,7 +129,7 @@ func TestLoggerLogString(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestLoggerExpressionFilter(t *testing.T) {
|
||||
logger := NewLoggerWithWriters(context.Background(), "test")
|
||||
logger := NewLoggerWithWriters(t.Context(), "test")
|
||||
|
||||
w1 := newDummyWriter("dummy-1", DEBUG, 0)
|
||||
w1.Mode.Expression = "foo.*"
|
||||
|
|
4
modules/markup/external/external.go
vendored
4
modules/markup/external/external.go
vendored
|
@ -9,7 +9,6 @@ import (
|
|||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/graceful"
|
||||
|
@ -70,9 +69,6 @@ func (p *Renderer) DisplayInIFrame() bool {
|
|||
}
|
||||
|
||||
func envMark(envName string) string {
|
||||
if runtime.GOOS == "windows" {
|
||||
return "%" + envName + "%"
|
||||
}
|
||||
return "$" + envName
|
||||
}
|
||||
|
||||
|
|
|
@ -680,7 +680,7 @@ func TestRender_FilePreview(t *testing.T) {
|
|||
defer test.MockVariableValue(&setting.StaticRootPath, "../../")()
|
||||
defer test.MockVariableValue(&setting.Names, []string{"english"})()
|
||||
defer test.MockVariableValue(&setting.Langs, []string{"en-US"})()
|
||||
translation.InitLocales(context.Background())
|
||||
translation.InitLocales(t.Context())
|
||||
|
||||
setting.AppURL = markup.TestAppURL
|
||||
markup.Init(&markup.ProcessorHelper{
|
||||
|
|
|
@ -1190,7 +1190,7 @@ space</p>
|
|||
}
|
||||
|
||||
for i, c := range cases {
|
||||
result, err := markdown.RenderString(&markup.RenderContext{Ctx: context.Background(), Links: c.Links, IsWiki: c.IsWiki}, input)
|
||||
result, err := markdown.RenderString(&markup.RenderContext{Ctx: t.Context(), Links: c.Links, IsWiki: c.IsWiki}, input)
|
||||
require.NoError(t, err, "Unexpected error in testcase: %v", i)
|
||||
assert.Equal(t, template.HTML(c.Expected), result, "Unexpected result in testcase %v", i)
|
||||
}
|
||||
|
|
|
@ -57,12 +57,21 @@ type Package struct {
|
|||
|
||||
// Metadata represents the metadata of a Nuget package
|
||||
type Metadata struct {
|
||||
Title string `json:"title,omitempty"`
|
||||
Language string `json:"language,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
ReleaseNotes string `json:"release_notes,omitempty"`
|
||||
Readme string `json:"readme,omitempty"`
|
||||
Authors string `json:"authors,omitempty"`
|
||||
Owners string `json:"owners,omitempty"`
|
||||
Copyright string `json:"copyright,omitempty"`
|
||||
ProjectURL string `json:"project_url,omitempty"`
|
||||
RepositoryURL string `json:"repository_url,omitempty"`
|
||||
LicenseURL string `json:"license_url,omitempty"`
|
||||
IconURL string `json:"icon_url,omitempty"`
|
||||
MinClientVersion string `json:"min_client_version,omitempty"`
|
||||
Tags string `json:"tags,omitempty"`
|
||||
DevelopmentDependency bool `json:"development_dependency,omitempty"`
|
||||
RequireLicenseAcceptance bool `json:"require_license_acceptance"`
|
||||
Dependencies map[string][]Dependency `json:"dependencies,omitempty"`
|
||||
}
|
||||
|
@ -77,13 +86,22 @@ type Dependency struct {
|
|||
type nuspecPackage struct {
|
||||
Metadata struct {
|
||||
ID string `xml:"id"`
|
||||
Title string `xml:"title"`
|
||||
Language string `xml:"language"`
|
||||
Version string `xml:"version"`
|
||||
Authors string `xml:"authors"`
|
||||
Owners string `xml:"owners"`
|
||||
Copyright string `xml:"copyright"`
|
||||
DevelopmentDependency bool `xml:"developmentDependency"`
|
||||
RequireLicenseAcceptance bool `xml:"requireLicenseAcceptance"`
|
||||
ProjectURL string `xml:"projectUrl"`
|
||||
LicenseURL string `xml:"licenseUrl"`
|
||||
IconURL string `xml:"iconUrl"`
|
||||
Description string `xml:"description"`
|
||||
ReleaseNotes string `xml:"releaseNotes"`
|
||||
Readme string `xml:"readme"`
|
||||
Tags string `xml:"tags"`
|
||||
MinClientVersion string `xml:"minClientVersion,attr"`
|
||||
PackageTypes struct {
|
||||
PackageType []struct {
|
||||
Name string `xml:"name,attr"`
|
||||
|
@ -167,11 +185,20 @@ func ParseNuspecMetaData(archive *zip.Reader, r io.Reader) (*Package, error) {
|
|||
}
|
||||
|
||||
m := &Metadata{
|
||||
Title: p.Metadata.Title,
|
||||
Language: p.Metadata.Language,
|
||||
Description: p.Metadata.Description,
|
||||
ReleaseNotes: p.Metadata.ReleaseNotes,
|
||||
Authors: p.Metadata.Authors,
|
||||
Owners: p.Metadata.Owners,
|
||||
Copyright: p.Metadata.Copyright,
|
||||
ProjectURL: p.Metadata.ProjectURL,
|
||||
RepositoryURL: p.Metadata.Repository.URL,
|
||||
LicenseURL: p.Metadata.LicenseURL,
|
||||
IconURL: p.Metadata.IconURL,
|
||||
MinClientVersion: p.Metadata.MinClientVersion,
|
||||
Tags: p.Metadata.Tags,
|
||||
DevelopmentDependency: p.Metadata.DevelopmentDependency,
|
||||
RequireLicenseAcceptance: p.Metadata.RequireLicenseAcceptance,
|
||||
Dependencies: make(map[string][]Dependency),
|
||||
}
|
||||
|
|
|
@ -13,14 +13,22 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
id = "System.Gitea"
|
||||
id = "System.Forgejo"
|
||||
title = "Package Title"
|
||||
language = "Package Language"
|
||||
semver = "1.0.1"
|
||||
authors = "Gitea Authors"
|
||||
projectURL = "https://gitea.io"
|
||||
authors = "Forgejo Authors"
|
||||
owners = "Package Owners"
|
||||
copyright = "Package Copyright"
|
||||
projectURL = "https://forgejo.org"
|
||||
licenseURL = "https://forgejo.org/docs/latest/license/"
|
||||
iconURL = "https://codeberg.org/forgejo/governance/raw/branch/main/branding/logo/forgejo.png"
|
||||
description = "Package Description"
|
||||
releaseNotes = "Package Release Notes"
|
||||
readme = "Readme"
|
||||
repositoryURL = "https://gitea.io/gitea/gitea"
|
||||
tags = "tag_1 tag_2 tag_3"
|
||||
minClientVersion = "1.0.0.0"
|
||||
repositoryURL = "https://codeberg.org/forgejo"
|
||||
targetFramework = ".NETStandard2.1"
|
||||
dependencyID = "System.Text.Json"
|
||||
dependencyVersion = "5.0.0"
|
||||
|
@ -28,16 +36,24 @@ const (
|
|||
|
||||
const nuspecContent = `<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
|
||||
<metadata>
|
||||
<metadata minClientVersion="` + minClientVersion + `">
|
||||
<id>` + id + `</id>
|
||||
<title>` + title + `</title>
|
||||
<language>` + language + `</language>
|
||||
<version>` + semver + `</version>
|
||||
<authors>` + authors + `</authors>
|
||||
<owners>` + owners + `</owners>
|
||||
<copyright>` + copyright + `</copyright>
|
||||
<developmentDependency>true</developmentDependency>
|
||||
<requireLicenseAcceptance>true</requireLicenseAcceptance>
|
||||
<projectUrl>` + projectURL + `</projectUrl>
|
||||
<licenseUrl>` + licenseURL + `</licenseUrl>
|
||||
<iconUrl>` + iconURL + `</iconUrl>
|
||||
<description>` + description + `</description>
|
||||
<releaseNotes>` + releaseNotes + `</releaseNotes>
|
||||
<repository url="` + repositoryURL + `" />
|
||||
<readme>README.md</readme>
|
||||
<tags>` + tags + `</tags>
|
||||
<dependencies>
|
||||
<group targetFramework="` + targetFramework + `">
|
||||
<dependency id="` + dependencyID + `" version="` + dependencyVersion + `" exclude="Build,Analyzers" />
|
||||
|
@ -142,12 +158,22 @@ func TestParsePackageMetaData(t *testing.T) {
|
|||
assert.Equal(t, DependencyPackage, np.PackageType)
|
||||
|
||||
assert.Equal(t, id, np.ID)
|
||||
assert.Equal(t, title, np.Metadata.Title)
|
||||
assert.Equal(t, language, np.Metadata.Language)
|
||||
assert.Equal(t, semver, np.Version)
|
||||
assert.Equal(t, authors, np.Metadata.Authors)
|
||||
assert.Equal(t, owners, np.Metadata.Owners)
|
||||
assert.Equal(t, copyright, np.Metadata.Copyright)
|
||||
assert.True(t, np.Metadata.DevelopmentDependency)
|
||||
assert.True(t, np.Metadata.RequireLicenseAcceptance)
|
||||
assert.Equal(t, projectURL, np.Metadata.ProjectURL)
|
||||
assert.Equal(t, licenseURL, np.Metadata.LicenseURL)
|
||||
assert.Equal(t, iconURL, np.Metadata.IconURL)
|
||||
assert.Equal(t, description, np.Metadata.Description)
|
||||
assert.Equal(t, releaseNotes, np.Metadata.ReleaseNotes)
|
||||
assert.Equal(t, readme, np.Metadata.Readme)
|
||||
assert.Equal(t, tags, np.Metadata.Tags)
|
||||
assert.Equal(t, minClientVersion, np.Metadata.MinClientVersion)
|
||||
assert.Equal(t, repositoryURL, np.Metadata.RepositoryURL)
|
||||
assert.Len(t, np.Metadata.Dependencies, 1)
|
||||
assert.Contains(t, np.Metadata.Dependencies, targetFramework)
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
package process
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -12,13 +11,13 @@ import (
|
|||
)
|
||||
|
||||
func TestProcessStacktraces(t *testing.T) {
|
||||
_, _, finish := GetManager().AddContext(context.Background(), "Normal process")
|
||||
_, _, finish := GetManager().AddContext(t.Context(), "Normal process")
|
||||
defer finish()
|
||||
parentCtx, _, finish := GetManager().AddContext(context.Background(), "Children normal process")
|
||||
parentCtx, _, finish := GetManager().AddContext(t.Context(), "Children normal process")
|
||||
defer finish()
|
||||
_, _, finish = GetManager().AddContext(parentCtx, "Children process")
|
||||
defer finish()
|
||||
_, _, finish = GetManager().AddTypedContext(context.Background(), "System process", SystemProcessType, true)
|
||||
_, _, finish = GetManager().AddTypedContext(t.Context(), "System process", SystemProcessType, true)
|
||||
defer finish()
|
||||
|
||||
t.Run("No flat with no system process", func(t *testing.T) {
|
||||
|
|
|
@ -23,7 +23,7 @@ func TestGetManager(t *testing.T) {
|
|||
func TestManager_AddContext(t *testing.T) {
|
||||
pm := Manager{processMap: make(map[IDType]*process), next: 1}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
p1Ctx, _, finished := pm.AddContext(ctx, "foo")
|
||||
|
@ -42,7 +42,7 @@ func TestManager_AddContext(t *testing.T) {
|
|||
func TestManager_Cancel(t *testing.T) {
|
||||
pm := Manager{processMap: make(map[IDType]*process), next: 1}
|
||||
|
||||
ctx, _, finished := pm.AddContext(context.Background(), "foo")
|
||||
ctx, _, finished := pm.AddContext(t.Context(), "foo")
|
||||
defer finished()
|
||||
|
||||
pm.Cancel(GetPID(ctx))
|
||||
|
@ -54,7 +54,7 @@ func TestManager_Cancel(t *testing.T) {
|
|||
}
|
||||
finished()
|
||||
|
||||
ctx, cancel, finished := pm.AddContext(context.Background(), "foo")
|
||||
ctx, cancel, finished := pm.AddContext(t.Context(), "foo")
|
||||
defer finished()
|
||||
|
||||
cancel()
|
||||
|
@ -70,7 +70,7 @@ func TestManager_Cancel(t *testing.T) {
|
|||
func TestManager_Remove(t *testing.T) {
|
||||
pm := Manager{processMap: make(map[IDType]*process), next: 1}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
p1Ctx, _, finished := pm.AddContext(ctx, "foo")
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//go:build !windows
|
||||
|
||||
package process
|
||||
|
||||
import (
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/nosql"
|
||||
"code.gitea.io/gitea/modules/queue/lqinternal"
|
||||
|
||||
"gitea.com/lunny/levelqueue"
|
||||
"code.forgejo.org/forgejo/levelqueue"
|
||||
"github.com/syndtr/goleveldb/leveldb"
|
||||
)
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
|
||||
"code.gitea.io/gitea/modules/nosql"
|
||||
|
||||
"gitea.com/lunny/levelqueue"
|
||||
"code.forgejo.org/forgejo/levelqueue"
|
||||
"github.com/syndtr/goleveldb/leveldb"
|
||||
)
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/queue/lqinternal"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"gitea.com/lunny/levelqueue"
|
||||
"code.forgejo.org/forgejo/levelqueue"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/syndtr/goleveldb/leveldb"
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/nosql"
|
||||
"code.gitea.io/gitea/modules/queue/lqinternal"
|
||||
|
||||
"gitea.com/lunny/levelqueue"
|
||||
"code.forgejo.org/forgejo/levelqueue"
|
||||
"github.com/syndtr/goleveldb/leveldb"
|
||||
)
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ func testQueueBasic(t *testing.T, newFn func(cfg *BaseConfig) (baseQueue, error)
|
|||
q, err := newFn(cfg)
|
||||
require.NoError(t, err)
|
||||
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
_ = q.RemoveAll(ctx)
|
||||
cnt, err := q.Len(ctx)
|
||||
require.NoError(t, err)
|
||||
|
@ -122,7 +122,7 @@ func TestBaseDummy(t *testing.T) {
|
|||
q, err := newBaseDummy(&BaseConfig{}, true)
|
||||
require.NoError(t, err)
|
||||
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
require.NoError(t, q.PushItem(ctx, []byte("foo")))
|
||||
|
||||
cnt, err := q.Len(ctx)
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
package queue
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
|
@ -81,7 +80,7 @@ MAX_WORKERS = 123
|
|||
|
||||
require.NoError(t, err)
|
||||
|
||||
q1 := createWorkerPoolQueue[string](context.Background(), "no-such", cfgProvider, nil, false)
|
||||
q1 := createWorkerPoolQueue[string](t.Context(), "no-such", cfgProvider, nil, false)
|
||||
assert.Equal(t, "no-such", q1.GetName())
|
||||
assert.Equal(t, "dummy", q1.GetType()) // no handler, so it becomes dummy
|
||||
assert.Equal(t, filepath.Join(setting.AppDataPath, "queues/dir1"), q1.baseConfig.DataFullDir)
|
||||
|
@ -97,7 +96,7 @@ MAX_WORKERS = 123
|
|||
assert.Equal(t, "string", q1.GetItemTypeName())
|
||||
qid1 := GetManager().qidCounter
|
||||
|
||||
q2 := createWorkerPoolQueue(context.Background(), "sub", cfgProvider, func(s ...int) (unhandled []int) { return nil }, false)
|
||||
q2 := createWorkerPoolQueue(t.Context(), "sub", cfgProvider, func(s ...int) (unhandled []int) { return nil }, false)
|
||||
assert.Equal(t, "sub", q2.GetName())
|
||||
assert.Equal(t, "level", q2.GetType())
|
||||
assert.Equal(t, filepath.Join(setting.AppDataPath, "queues/dir2"), q2.baseConfig.DataFullDir)
|
||||
|
@ -119,7 +118,7 @@ MAX_WORKERS = 123
|
|||
assert.Equal(t, 120, q1.workerMaxNum)
|
||||
|
||||
stop := runWorkerPoolQueue(q2)
|
||||
require.NoError(t, GetManager().GetManagedQueue(qid2).FlushWithContext(context.Background(), 0))
|
||||
require.NoError(t, GetManager().FlushAll(context.Background(), 0))
|
||||
require.NoError(t, GetManager().GetManagedQueue(qid2).FlushWithContext(t.Context(), 0))
|
||||
require.NoError(t, GetManager().FlushAll(t.Context(), 0))
|
||||
stop()
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ package queue
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
@ -59,7 +58,7 @@ func TestWorkerPoolQueueUnhandled(t *testing.T) {
|
|||
testRecorder.Record("push:%v", i)
|
||||
require.NoError(t, q.Push(i))
|
||||
}
|
||||
require.NoError(t, q.FlushWithContext(context.Background(), 0))
|
||||
require.NoError(t, q.FlushWithContext(t.Context(), 0))
|
||||
stop()
|
||||
|
||||
ok := true
|
||||
|
@ -167,7 +166,7 @@ func testWorkerPoolQueuePersistence(t *testing.T, queueSetting setting.QueueSett
|
|||
|
||||
q, _ := newWorkerPoolQueueForTest("pr_patch_checker_test", queueSetting, testHandler, true)
|
||||
stop := runWorkerPoolQueue(q)
|
||||
require.NoError(t, q.FlushWithContext(context.Background(), 0))
|
||||
require.NoError(t, q.FlushWithContext(t.Context(), 0))
|
||||
stop()
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
@ -146,10 +145,6 @@ func CreateDelegateHooks(repoPath string) (err error) {
|
|||
}
|
||||
|
||||
func checkExecutable(filename string) bool {
|
||||
// windows has no concept of a executable bit
|
||||
if runtime.GOOS == "windows" {
|
||||
return true
|
||||
}
|
||||
fileInfo, err := os.Stat(filename)
|
||||
if err != nil {
|
||||
return false
|
||||
|
|
|
@ -27,7 +27,7 @@ func AesEncrypt(key, text []byte) ([]byte, error) {
|
|||
if _, err = io.ReadFull(rand.Reader, iv); err != nil {
|
||||
return nil, fmt.Errorf("AesEncrypt unable to read IV: %w", err)
|
||||
}
|
||||
cfb := cipher.NewCFBEncrypter(block, iv)
|
||||
cfb := cipher.NewCFBEncrypter(block, iv) //nolint:staticcheck
|
||||
cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(b))
|
||||
return ciphertext, nil
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ func AesDecrypt(key, text []byte) ([]byte, error) {
|
|||
}
|
||||
iv := text[:aes.BlockSize]
|
||||
text = text[aes.BlockSize:]
|
||||
cfb := cipher.NewCFBDecrypter(block, iv)
|
||||
cfb := cipher.NewCFBDecrypter(block, iv) //nolint:staticcheck
|
||||
cfb.XORKeyStream(text, text)
|
||||
data, err := base64.StdEncoding.DecodeString(string(text))
|
||||
if err != nil {
|
||||
|
|
|
@ -34,11 +34,7 @@ var (
|
|||
func getAppPath() (string, error) {
|
||||
var appPath string
|
||||
var err error
|
||||
if IsWindows && filepath.IsAbs(os.Args[0]) {
|
||||
appPath = filepath.Clean(os.Args[0])
|
||||
} else {
|
||||
appPath, err = exec.LookPath(os.Args[0])
|
||||
}
|
||||
appPath, err = exec.LookPath(os.Args[0])
|
||||
if err != nil {
|
||||
if !errors.Is(err, exec.ErrDot) {
|
||||
return "", err
|
||||
|
|
|
@ -265,7 +265,7 @@ func loadServerFrom(rootCfg ConfigProvider) {
|
|||
}
|
||||
|
||||
UnixSocketPermission = uint32(UnixSocketPermissionParsed)
|
||||
if !filepath.IsAbs(HTTPAddr) {
|
||||
if HTTPAddr[0] != '@' && !filepath.IsAbs(HTTPAddr) {
|
||||
HTTPAddr = filepath.Join(AppWorkPath, HTTPAddr)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,3 +73,16 @@ MAX_USER_REDIRECTS = 8`
|
|||
assert.EqualValues(t, 3, Service.UsernameCooldownPeriod)
|
||||
assert.EqualValues(t, 8, Service.MaxUserRedirects)
|
||||
}
|
||||
|
||||
func TestUnixSocketAbstractNamespace(t *testing.T) {
|
||||
iniStr := `
|
||||
[server]
|
||||
PROTOCOL=http+unix
|
||||
HTTP_ADDR=@forgejo
|
||||
`
|
||||
cfg, err := NewConfigProviderFromData(iniStr)
|
||||
require.NoError(t, err)
|
||||
loadServerFrom(cfg)
|
||||
|
||||
assert.EqualValues(t, "@forgejo", HTTPAddr)
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ package setting
|
|||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -34,7 +33,6 @@ var (
|
|||
RunMode string
|
||||
RunUser string
|
||||
IsProd bool
|
||||
IsWindows bool
|
||||
|
||||
// IsInTesting indicates whether the testing is running. A lot of unreliable code causes a lot of nonsense error logs during testing
|
||||
// TODO: this is only a temporary solution, we should make the test code more reliable
|
||||
|
@ -42,22 +40,18 @@ var (
|
|||
)
|
||||
|
||||
func init() {
|
||||
IsWindows = runtime.GOOS == "windows"
|
||||
if AppVer == "" {
|
||||
AppVer = "dev"
|
||||
}
|
||||
|
||||
// We can rely on log.CanColorStdout being set properly because modules/log/console_windows.go comes before modules/setting/setting.go lexicographically
|
||||
// By default set this logger at Info - we'll change it later, but we need to start with something.
|
||||
log.SetConsoleLogger(log.DEFAULT, "console", log.INFO)
|
||||
}
|
||||
|
||||
// IsRunUserMatchCurrentUser returns false if configured run user does not match
|
||||
// actual user that runs the app. The first return value is the actual user name.
|
||||
// This check is ignored under Windows since SSH remote login is not the main
|
||||
// method to login on Windows.
|
||||
func IsRunUserMatchCurrentUser(runUser string) (string, bool) {
|
||||
if IsWindows || SSH.StartBuiltinServer {
|
||||
if SSH.StartBuiltinServer {
|
||||
return "", true
|
||||
}
|
||||
|
||||
|
|
|
@ -46,12 +46,12 @@ var testMetas = map[string]string{
|
|||
}
|
||||
|
||||
func TestApostrophesInMentions(t *testing.T) {
|
||||
rendered := RenderMarkdownToHtml(context.Background(), "@mention-user's comment")
|
||||
rendered := RenderMarkdownToHtml(t.Context(), "@mention-user's comment")
|
||||
assert.EqualValues(t, template.HTML("<p><a href=\"/mention-user\" class=\"mention\" rel=\"nofollow\">@mention-user</a>'s comment</p>\n"), rendered)
|
||||
}
|
||||
|
||||
func TestNonExistantUserMention(t *testing.T) {
|
||||
rendered := RenderMarkdownToHtml(context.Background(), "@ThisUserDoesNotExist @mention-user")
|
||||
rendered := RenderMarkdownToHtml(t.Context(), "@ThisUserDoesNotExist @mention-user")
|
||||
assert.EqualValues(t, template.HTML("<p>@ThisUserDoesNotExist <a href=\"/mention-user\" class=\"mention\" rel=\"nofollow\">@mention-user</a></p>\n"), rendered)
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ func TestRenderCommitBody(t *testing.T) {
|
|||
{
|
||||
name: "multiple lines",
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
ctx: t.Context(),
|
||||
msg: "first line\nsecond line",
|
||||
},
|
||||
want: "second line",
|
||||
|
@ -77,7 +77,7 @@ func TestRenderCommitBody(t *testing.T) {
|
|||
{
|
||||
name: "multiple lines with leading newlines",
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
ctx: t.Context(),
|
||||
msg: "\n\n\n\nfirst line\nsecond line",
|
||||
},
|
||||
want: "second line",
|
||||
|
@ -85,7 +85,7 @@ func TestRenderCommitBody(t *testing.T) {
|
|||
{
|
||||
name: "multiple lines with trailing newlines",
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
ctx: t.Context(),
|
||||
msg: "first line\nsecond line\n\n\n",
|
||||
},
|
||||
want: "second line",
|
||||
|
@ -117,19 +117,19 @@ com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
|
|||
<a href="/user13/repo11/issues/123" class="ref-issue">#123</a>
|
||||
space
|
||||
` + "`code <span class=\"emoji\" aria-label=\"thumbs up\" data-alias=\"+1\">👍</span> <a href=\"/user13/repo11/issues/123\" class=\"ref-issue\">#123</a> code`"
|
||||
assert.EqualValues(t, expected, RenderCommitBody(context.Background(), testInput, testMetas))
|
||||
assert.EqualValues(t, expected, RenderCommitBody(t.Context(), testInput, testMetas))
|
||||
}
|
||||
|
||||
func TestRenderCommitMessage(t *testing.T) {
|
||||
expected := `space <a href="/mention-user" class="mention">@mention-user</a> `
|
||||
|
||||
assert.EqualValues(t, expected, RenderCommitMessage(context.Background(), testInput, testMetas))
|
||||
assert.EqualValues(t, expected, RenderCommitMessage(t.Context(), testInput, testMetas))
|
||||
}
|
||||
|
||||
func TestRenderCommitMessageLinkSubject(t *testing.T) {
|
||||
expected := `<a href="https://example.com/link" class="default-link muted">space </a><a href="/mention-user" class="mention">@mention-user</a>`
|
||||
|
||||
assert.EqualValues(t, expected, RenderCommitMessageLinkSubject(context.Background(), testInput, "https://example.com/link", testMetas))
|
||||
assert.EqualValues(t, expected, RenderCommitMessageLinkSubject(t.Context(), testInput, "https://example.com/link", testMetas))
|
||||
}
|
||||
|
||||
func TestRenderIssueTitle(t *testing.T) {
|
||||
|
@ -155,7 +155,7 @@ mail@domain.com
|
|||
space
|
||||
<code class="inline-code-block">code :+1: #123 code</code>
|
||||
`
|
||||
assert.EqualValues(t, expected, RenderIssueTitle(context.Background(), testInput, testMetas))
|
||||
assert.EqualValues(t, expected, RenderIssueTitle(t.Context(), testInput, testMetas))
|
||||
}
|
||||
|
||||
func TestRenderRefIssueTitle(t *testing.T) {
|
||||
|
@ -181,7 +181,7 @@ mail@domain.com
|
|||
space
|
||||
<code class="inline-code-block">code :+1: #123 code</code>
|
||||
`
|
||||
assert.EqualValues(t, expected, RenderRefIssueTitle(context.Background(), testInput))
|
||||
assert.EqualValues(t, expected, RenderRefIssueTitle(t.Context(), testInput))
|
||||
}
|
||||
|
||||
func TestRenderMarkdownToHtml(t *testing.T) {
|
||||
|
@ -207,7 +207,7 @@ com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
|
|||
space
|
||||
<code>code :+1: #123 code</code></p>
|
||||
`
|
||||
assert.EqualValues(t, expected, RenderMarkdownToHtml(context.Background(), testInput))
|
||||
assert.EqualValues(t, expected, RenderMarkdownToHtml(t.Context(), testInput))
|
||||
}
|
||||
|
||||
func TestRenderLabels(t *testing.T) {
|
||||
|
|
117
modules/test/distant_federation_server_mock.go
Normal file
117
modules/test/distant_federation_server_mock.go
Normal file
|
@ -0,0 +1,117 @@
|
|||
// Copyright 2025 The Forgejo Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type FederationServerMockPerson struct {
|
||||
ID int64
|
||||
Name string
|
||||
PubKey string
|
||||
}
|
||||
type FederationServerMockRepository struct {
|
||||
ID int64
|
||||
}
|
||||
type FederationServerMock struct {
|
||||
Persons []FederationServerMockPerson
|
||||
Repositories []FederationServerMockRepository
|
||||
LastPost string
|
||||
}
|
||||
|
||||
func NewFederationServerMockPerson(id int64, name string) FederationServerMockPerson {
|
||||
return FederationServerMockPerson{
|
||||
ID: id,
|
||||
Name: name,
|
||||
PubKey: `"-----BEGIN PUBLIC KEY-----\nMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA18H5s7N6ItZUAh9tneII\nIuZdTTa3cZlLa/9ejWAHTkcp3WLW+/zbsumlMrWYfBy2/yTm56qasWt38iY4D6ul\n` +
|
||||
`CPiwhAqX3REvVq8tM79a2CEqZn9ka6vuXoDgBg/sBf/BUWqf7orkjUXwk/U0Egjf\nk5jcurF4vqf1u+rlAHH37dvSBaDjNj6Qnj4OP12bjfaY/yvs7+jue/eNXFHjzN4E\n` +
|
||||
`T2H4B/yeKTJ4UuAwTlLaNbZJul2baLlHelJPAsxiYaziVuV5P+IGWckY6RSerRaZ\nAkc4mmGGtjAyfN9aewe+lNVfwS7ElFx546PlLgdQgjmeSwLX8FWxbPE5A/PmaXCs\n` +
|
||||
`nx+nou+3dD7NluULLtdd7K+2x02trObKXCAzmi5/Dc+yKTzpFqEz+hLNCz7TImP/\ncK//NV9Q+X67J9O27baH9R9ZF4zMw8rv2Pg0WLSw1z7lLXwlgIsDapeMCsrxkVO4\n` +
|
||||
`LXX5AQ1xQNtlssnVoUBqBrvZsX2jUUKUocvZqMGuE4hfAgMBAAE=\n-----END PUBLIC KEY-----\n"`,
|
||||
}
|
||||
}
|
||||
|
||||
func NewFederationServerMockRepository(id int64) FederationServerMockRepository {
|
||||
return FederationServerMockRepository{
|
||||
ID: id,
|
||||
}
|
||||
}
|
||||
|
||||
func (p FederationServerMockPerson) marshal(host string) string {
|
||||
return fmt.Sprintf(`{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1"],`+
|
||||
`"id":"http://%[1]v/api/activitypub/user-id/%[2]v",`+
|
||||
`"type":"Person",`+
|
||||
`"icon":{"type":"Image","mediaType":"image/png","url":"http://%[1]v/avatars/1bb05d9a5f6675ed0272af9ea193063c"},`+
|
||||
`"url":"http://%[1]v/%[2]v",`+
|
||||
`"inbox":"http://%[1]v/api/activitypub/user-id/%[2]v/inbox",`+
|
||||
`"outbox":"http://%[1]v/api/activitypub/user-id/%[2]v/outbox",`+
|
||||
`"preferredUsername":"%[3]v",`+
|
||||
`"publicKey":{"id":"http://%[1]v/api/activitypub/user-id/%[2]v#main-key",`+
|
||||
`"owner":"http://%[1]v/api/activitypub/user-id/%[2]v",`+
|
||||
`"publicKeyPem":%[4]v}}`, host, p.ID, p.Name, p.PubKey)
|
||||
}
|
||||
|
||||
func NewFederationServerMock() *FederationServerMock {
|
||||
return &FederationServerMock{
|
||||
Persons: []FederationServerMockPerson{
|
||||
NewFederationServerMockPerson(15, "stargoose1"),
|
||||
NewFederationServerMockPerson(30, "stargoose2"),
|
||||
},
|
||||
Repositories: []FederationServerMockRepository{
|
||||
NewFederationServerMockRepository(1),
|
||||
},
|
||||
LastPost: "",
|
||||
}
|
||||
}
|
||||
|
||||
func (mock *FederationServerMock) DistantServer(t *testing.T) *httptest.Server {
|
||||
federatedRoutes := http.NewServeMux()
|
||||
federatedRoutes.HandleFunc("/.well-known/nodeinfo",
|
||||
func(res http.ResponseWriter, req *http.Request) {
|
||||
// curl -H "Accept: application/json" https://federated-repo.prod.meissa.de/.well-known/nodeinfo
|
||||
// TODO: as soon as content-type will become important: content-type: application/json;charset=utf-8
|
||||
fmt.Fprintf(res, `{"links":[{"href":"http://%s/api/v1/nodeinfo","rel":"http://nodeinfo.diaspora.software/ns/schema/2.1"}]}`, req.Host)
|
||||
})
|
||||
federatedRoutes.HandleFunc("/api/v1/nodeinfo",
|
||||
func(res http.ResponseWriter, req *http.Request) {
|
||||
// curl -H "Accept: application/json" https://federated-repo.prod.meissa.de/api/v1/nodeinfo
|
||||
fmt.Fprint(res, `{"version":"2.1","software":{"name":"forgejo","version":"1.20.0+dev-3183-g976d79044",`+
|
||||
`"repository":"https://codeberg.org/forgejo/forgejo.git","homepage":"https://forgejo.org/"},`+
|
||||
`"protocols":["activitypub"],"services":{"inbound":[],"outbound":["rss2.0"]},`+
|
||||
`"openRegistrations":true,"usage":{"users":{"total":14,"activeHalfyear":2}},"metadata":{}}`)
|
||||
})
|
||||
for _, person := range mock.Persons {
|
||||
federatedRoutes.HandleFunc(fmt.Sprintf("/api/v1/activitypub/user-id/%v", person.ID),
|
||||
func(res http.ResponseWriter, req *http.Request) {
|
||||
// curl -H "Accept: application/json" https://federated-repo.prod.meissa.de/api/v1/activitypub/user-id/2
|
||||
fmt.Fprint(res, person.marshal(req.Host))
|
||||
})
|
||||
}
|
||||
for _, repository := range mock.Repositories {
|
||||
federatedRoutes.HandleFunc(fmt.Sprintf("/api/v1/activitypub/repository-id/%v/inbox/", repository.ID),
|
||||
func(res http.ResponseWriter, req *http.Request) {
|
||||
if req.Method != "POST" {
|
||||
t.Errorf("POST expected at: %q", req.URL.EscapedPath())
|
||||
}
|
||||
buf := new(strings.Builder)
|
||||
_, err := io.Copy(buf, req.Body)
|
||||
if err != nil {
|
||||
t.Errorf("Error reading body: %q", err)
|
||||
}
|
||||
mock.LastPost = buf.String()
|
||||
})
|
||||
}
|
||||
federatedRoutes.HandleFunc("/",
|
||||
func(res http.ResponseWriter, req *http.Request) {
|
||||
t.Errorf("Unhandled request: %q", req.URL.EscapedPath())
|
||||
})
|
||||
federatedSrv := httptest.NewServer(federatedRoutes)
|
||||
return federatedSrv
|
||||
}
|
|
@ -471,7 +471,7 @@ func PrintCurrentTest(t testing.TB, skip ...int) func() {
|
|||
_, _ = fmt.Fprintf(os.Stdout, "+++ %s ... still flushing after %v ...\n", t.Name(), SlowFlush)
|
||||
}
|
||||
})
|
||||
if err := queue.GetManager().FlushAll(context.Background(), time.Minute); err != nil {
|
||||
if err := queue.GetManager().FlushAll(t.Context(), time.Minute); err != nil {
|
||||
t.Errorf("Flushing queues failed with error %v", err)
|
||||
}
|
||||
timer.Stop()
|
||||
|
|
|
@ -156,7 +156,15 @@ commits = fallback value for commits
|
|||
assert.ElementsMatch(t, []string{"lang1", "lang2"}, langs)
|
||||
assert.ElementsMatch(t, []string{"Lang1", "Lang2"}, descs)
|
||||
|
||||
found := lang1.HasKey("no-such")
|
||||
// Test HasKey for JSON
|
||||
found := lang2.HasKey("section.json")
|
||||
assert.True(t, found)
|
||||
|
||||
// Test HasKey for INI
|
||||
found = lang2.HasKey("section.sub")
|
||||
assert.True(t, found)
|
||||
|
||||
found = lang1.HasKey("no-such")
|
||||
assert.False(t, found)
|
||||
assert.EqualValues(t, "no-such", lang1.TrString("no-such"))
|
||||
require.NoError(t, ls.Close())
|
||||
|
|
|
@ -303,6 +303,10 @@ func (l *locale) TrPluralString(count any, trKey string, trArgs ...any) template
|
|||
|
||||
// HasKey returns whether a key is present in this locale or not
|
||||
func (l *locale) HasKey(trKey string) bool {
|
||||
_, ok := l.newStyleMessages[trKey]
|
||||
if ok {
|
||||
return true
|
||||
}
|
||||
idx, ok := l.store.trKeyToIdxMap[trKey]
|
||||
if !ok {
|
||||
return false
|
||||
|
|
|
@ -39,6 +39,10 @@ func (l MockLocale) TrSize(s int64) ReadableSize {
|
|||
return ReadableSize{fmt.Sprint(s), ""}
|
||||
}
|
||||
|
||||
func (l MockLocale) HasKey(key string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (l MockLocale) PrettyNumber(v any) string {
|
||||
return fmt.Sprint(v)
|
||||
}
|
||||
|
|
|
@ -39,6 +39,8 @@ type Locale interface {
|
|||
|
||||
TrSize(size int64) ReadableSize
|
||||
|
||||
HasKey(trKey string) bool
|
||||
|
||||
PrettyNumber(v any) string
|
||||
}
|
||||
|
||||
|
|
|
@ -6,8 +6,6 @@ package user
|
|||
import (
|
||||
"os"
|
||||
"os/user"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// CurrentUsername return current login OS user name
|
||||
|
@ -16,12 +14,7 @@ func CurrentUsername() string {
|
|||
if err != nil {
|
||||
return fallbackCurrentUsername()
|
||||
}
|
||||
username := userinfo.Username
|
||||
if runtime.GOOS == "windows" {
|
||||
parts := strings.Split(username, "\\")
|
||||
username = parts[len(parts)-1]
|
||||
}
|
||||
return username
|
||||
return userinfo.Username
|
||||
}
|
||||
|
||||
// Old method, used if new method doesn't work on your OS for some reason
|
||||
|
|
|
@ -5,7 +5,6 @@ package user
|
|||
|
||||
import (
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
@ -23,10 +22,6 @@ func TestCurrentUsername(t *testing.T) {
|
|||
if len(user) == 0 {
|
||||
t.Errorf("expected non-empty user, got: %s", user)
|
||||
}
|
||||
// Windows whoami is weird, so just skip remaining tests
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("skipped test because of weird whoami on Windows")
|
||||
}
|
||||
whoami, err := getWhoamiOutput()
|
||||
if err != nil {
|
||||
t.Errorf("failed to run whoami to test current user: %f", err)
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//go:build !windows
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//go:build !windows
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
|
|
|
@ -10,8 +10,6 @@ import (
|
|||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
@ -78,11 +76,7 @@ func FilePathJoinAbs(base string, sub ...string) string {
|
|||
|
||||
// POSIX filesystem can have `\` in file names. Windows: `\` and `/` are both used for path separators
|
||||
// to keep the behavior consistent, we do not allow `\` in file names, replace all `\` with `/`
|
||||
if isOSWindows() {
|
||||
elems[0] = filepath.Clean(base)
|
||||
} else {
|
||||
elems[0] = filepath.Clean(strings.ReplaceAll(base, "\\", pathSeparator))
|
||||
}
|
||||
elems[0] = filepath.Clean(strings.ReplaceAll(base, "\\", pathSeparator))
|
||||
if !filepath.IsAbs(elems[0]) {
|
||||
// This shouldn't happen. If there is really necessary to pass in relative path, return the full path with filepath.Abs() instead
|
||||
panic(fmt.Sprintf("FilePathJoinAbs: %q (for path %v) is not absolute, do not guess a relative path based on current working directory", elems[0], elems))
|
||||
|
@ -91,11 +85,7 @@ func FilePathJoinAbs(base string, sub ...string) string {
|
|||
if s == "" {
|
||||
continue
|
||||
}
|
||||
if isOSWindows() {
|
||||
elems = append(elems, filepath.Clean(pathSeparator+s))
|
||||
} else {
|
||||
elems = append(elems, filepath.Clean(pathSeparator+strings.ReplaceAll(s, "\\", pathSeparator)))
|
||||
}
|
||||
elems = append(elems, filepath.Clean(pathSeparator+strings.ReplaceAll(s, "\\", pathSeparator)))
|
||||
}
|
||||
// the elems[0] must be an absolute path, just join them together
|
||||
return filepath.Join(elems...)
|
||||
|
@ -217,12 +207,6 @@ func StatDir(rootPath string, includeDir ...bool) ([]string, error) {
|
|||
return statDir(rootPath, "", isIncludeDir, false, false)
|
||||
}
|
||||
|
||||
func isOSWindows() bool {
|
||||
return runtime.GOOS == "windows"
|
||||
}
|
||||
|
||||
var driveLetterRegexp = regexp.MustCompile("/[A-Za-z]:/")
|
||||
|
||||
// FileURLToPath extracts the path information from a file://... url.
|
||||
// It returns an error only if the URL is not a file URL.
|
||||
func FileURLToPath(u *url.URL) (string, error) {
|
||||
|
@ -230,17 +214,7 @@ func FileURLToPath(u *url.URL) (string, error) {
|
|||
return "", errors.New("URL scheme is not 'file': " + u.String())
|
||||
}
|
||||
|
||||
path := u.Path
|
||||
|
||||
if !isOSWindows() {
|
||||
return path, nil
|
||||
}
|
||||
|
||||
// If it looks like there's a Windows drive letter at the beginning, strip off the leading slash.
|
||||
if driveLetterRegexp.MatchString(path) {
|
||||
return path[1:], nil
|
||||
}
|
||||
return path, nil
|
||||
return u.Path, nil
|
||||
}
|
||||
|
||||
// HomeDir returns path of '~'(in Linux) on Windows,
|
||||
|
@ -249,14 +223,7 @@ func HomeDir() (home string, err error) {
|
|||
// TODO: some users run Gitea with mismatched uid and "HOME=xxx" (they set HOME=xxx by environment manually)
|
||||
// TODO: when running gitea as a sub command inside git, the HOME directory is not the user's home directory
|
||||
// so at the moment we can not use `user.Current().HomeDir`
|
||||
if isOSWindows() {
|
||||
home = os.Getenv("USERPROFILE")
|
||||
if home == "" {
|
||||
home = os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
|
||||
}
|
||||
} else {
|
||||
home = os.Getenv("HOME")
|
||||
}
|
||||
home = os.Getenv("HOME")
|
||||
|
||||
if home == "" {
|
||||
return "", errors.New("cannot get home directory")
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue