mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	
							
								
								
									
										15
									
								
								assets/go-licenses.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										15
									
								
								assets/go-licenses.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -1357,13 +1357,13 @@ ROUTER = console
 | 
			
		||||
;; Issue Indexer settings
 | 
			
		||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
			
		||||
;;
 | 
			
		||||
;; Issue indexer type, currently support: bleve, db or elasticsearch, default is bleve
 | 
			
		||||
;; Issue indexer type, currently support: bleve, db, elasticsearch or meilisearch default is bleve
 | 
			
		||||
;ISSUE_INDEXER_TYPE = bleve
 | 
			
		||||
;;
 | 
			
		||||
;; Issue indexer storage path, available when ISSUE_INDEXER_TYPE is bleve
 | 
			
		||||
;ISSUE_INDEXER_PATH = indexers/issues.bleve ; Relative paths will be made absolute against _`AppWorkPath`_.
 | 
			
		||||
;;
 | 
			
		||||
;; Issue indexer connection string, available when ISSUE_INDEXER_TYPE is elasticsearch
 | 
			
		||||
;; Issue indexer connection string, available when ISSUE_INDEXER_TYPE is elasticsearch or meilisearch
 | 
			
		||||
;ISSUE_INDEXER_CONN_STR = http://elastic:changeme@localhost:9200
 | 
			
		||||
;;
 | 
			
		||||
;; Issue indexer name, available when ISSUE_INDEXER_TYPE is elasticsearch
 | 
			
		||||
 
 | 
			
		||||
@@ -456,8 +456,8 @@ relation to port exhaustion.
 | 
			
		||||
 | 
			
		||||
## Indexer (`indexer`)
 | 
			
		||||
 | 
			
		||||
- `ISSUE_INDEXER_TYPE`: **bleve**: Issue indexer type, currently supported: `bleve`, `db` or `elasticsearch`.
 | 
			
		||||
- `ISSUE_INDEXER_CONN_STR`: ****: Issue indexer connection string, available when ISSUE_INDEXER_TYPE is elasticsearch. i.e. http://elastic:changeme@localhost:9200
 | 
			
		||||
- `ISSUE_INDEXER_TYPE`: **bleve**: Issue indexer type, currently supported: `bleve`, `db`, `elasticsearch` or `meilisearch`.
 | 
			
		||||
- `ISSUE_INDEXER_CONN_STR`: ****: Issue indexer connection string, available when ISSUE_INDEXER_TYPE is elasticsearch, or meilisearch. i.e. http://elastic:changeme@localhost:9200
 | 
			
		||||
- `ISSUE_INDEXER_NAME`: **gitea_issues**: Issue indexer name, available when ISSUE_INDEXER_TYPE is elasticsearch
 | 
			
		||||
- `ISSUE_INDEXER_PATH`: **indexers/issues.bleve**: Index file used for issue search; available when ISSUE_INDEXER_TYPE is bleve and elasticsearch. Relative paths will be made absolute against _`AppWorkPath`_.
 | 
			
		||||
- The next 4 configuration values are deprecated and should be set in `queue.issue_indexer` however are kept for backwards compatibility:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										5
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								go.mod
									
									
									
									
									
								
							@@ -73,6 +73,7 @@ require (
 | 
			
		||||
	github.com/markbates/goth v1.76.0
 | 
			
		||||
	github.com/mattn/go-isatty v0.0.17
 | 
			
		||||
	github.com/mattn/go-sqlite3 v1.14.16
 | 
			
		||||
	github.com/meilisearch/meilisearch-go v0.23.0
 | 
			
		||||
	github.com/mholt/archiver/v3 v3.5.1
 | 
			
		||||
	github.com/microcosm-cc/bluemonday v1.0.22
 | 
			
		||||
	github.com/minio/minio-go/v7 v7.0.49
 | 
			
		||||
@@ -218,7 +219,7 @@ require (
 | 
			
		||||
	github.com/mattn/go-colorable v0.1.13 // indirect
 | 
			
		||||
	github.com/mattn/go-runewidth v0.0.14 // indirect
 | 
			
		||||
	github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
 | 
			
		||||
	github.com/mholt/acmez v1.1.0 // indirect
 | 
			
		||||
	github.com/mholt/acmez v1.0.4 // indirect
 | 
			
		||||
	github.com/miekg/dns v1.1.50 // indirect
 | 
			
		||||
	github.com/minio/md5-simd v1.1.2 // indirect
 | 
			
		||||
	github.com/mitchellh/copystructure v1.2.0 // indirect
 | 
			
		||||
@@ -259,6 +260,8 @@ require (
 | 
			
		||||
	github.com/toqueteos/webbrowser v1.2.0 // indirect
 | 
			
		||||
	github.com/ulikunitz/xz v0.5.11 // indirect
 | 
			
		||||
	github.com/unknwon/com v1.0.1 // indirect
 | 
			
		||||
	github.com/valyala/bytebufferpool v1.0.0 // indirect
 | 
			
		||||
	github.com/valyala/fasthttp v1.44.0 // indirect
 | 
			
		||||
	github.com/valyala/fastjson v1.6.4 // indirect
 | 
			
		||||
	github.com/x448/float16 v0.8.4 // indirect
 | 
			
		||||
	github.com/xanzy/ssh-agent v0.3.3 // indirect
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										26
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								go.sum
									
									
									
									
									
								
							@@ -127,6 +127,7 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
 | 
			
		||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 | 
			
		||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
 | 
			
		||||
github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
 | 
			
		||||
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
 | 
			
		||||
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
 | 
			
		||||
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
 | 
			
		||||
github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c=
 | 
			
		||||
@@ -151,6 +152,7 @@ github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZw
 | 
			
		||||
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
 | 
			
		||||
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
 | 
			
		||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
 | 
			
		||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
 | 
			
		||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
 | 
			
		||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
 | 
			
		||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
 | 
			
		||||
@@ -496,6 +498,7 @@ github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14/go.mod h1:jPoNZLWDAqA5N3
 | 
			
		||||
github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85 h1:UjoPNDAQ5JPCjlxoJd6K8ALZqSDDhk2ymieAZOVaDg0=
 | 
			
		||||
github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85/go.mod h1:fR6z1Ie6rtF7kl/vBYMfgD5/G5B1blui7z426/sj2DU=
 | 
			
		||||
github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
 | 
			
		||||
github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
 | 
			
		||||
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
 | 
			
		||||
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
 | 
			
		||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
 | 
			
		||||
@@ -771,6 +774,9 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
 | 
			
		||||
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
 | 
			
		||||
github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
 | 
			
		||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
 | 
			
		||||
github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
 | 
			
		||||
github.com/klauspost/compress v1.15.6/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
 | 
			
		||||
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
 | 
			
		||||
github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw=
 | 
			
		||||
github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4=
 | 
			
		||||
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
 | 
			
		||||
@@ -862,8 +868,10 @@ github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwp
 | 
			
		||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
 | 
			
		||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
 | 
			
		||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 | 
			
		||||
github.com/mholt/acmez v1.1.0 h1:IQ9CGHKOHokorxnffsqDvmmE30mDenO1lptYZ1AYkHY=
 | 
			
		||||
github.com/mholt/acmez v1.1.0/go.mod h1:zwo5+fbLLTowAX8o8ETfQzbDtwGEXnPhkmGdKIP+bgs=
 | 
			
		||||
github.com/meilisearch/meilisearch-go v0.23.0 h1:CuqB+/NyEJKXF2SovTetAZW7lX+nSH+QTqbgSH6bv+Q=
 | 
			
		||||
github.com/meilisearch/meilisearch-go v0.23.0/go.mod h1:sAPJgywANHUCFUo/spCQ8SoP6sJhmfIKFWIXu7Dd5GQ=
 | 
			
		||||
github.com/mholt/acmez v1.0.4 h1:N3cE4Pek+dSolbsofIkAYz6H1d3pE+2G0os7QHslf80=
 | 
			
		||||
github.com/mholt/acmez v1.0.4/go.mod h1:qFGLZ4u+ehWINeJZjzPlsnjJBCPAADWTcIqE/7DAYQY=
 | 
			
		||||
github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo=
 | 
			
		||||
github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
 | 
			
		||||
github.com/microcosm-cc/bluemonday v1.0.22 h1:p2tT7RNzRdCi0qmwxG+HbqD6ILkmwter1ZwVZn1oTxA=
 | 
			
		||||
@@ -1181,9 +1189,15 @@ github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX
 | 
			
		||||
github.com/urfave/cli v1.22.12 h1:igJgVw1JdKH+trcLWLeLwZjU9fEfPesQ+9/e4MQ44S8=
 | 
			
		||||
github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8=
 | 
			
		||||
github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
 | 
			
		||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
 | 
			
		||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
 | 
			
		||||
github.com/valyala/fasthttp v1.37.1-0.20220607072126-8a320890c08d/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I=
 | 
			
		||||
github.com/valyala/fasthttp v1.44.0 h1:R+gLUhldIsfg1HokMuQjdQ5bh9nuXHPIfvkYUu9eR5Q=
 | 
			
		||||
github.com/valyala/fasthttp v1.44.0/go.mod h1:f6VbjjoI3z1NDOZOv17o6RvtRSWxC77seBFc2uWtgiY=
 | 
			
		||||
github.com/valyala/fastjson v1.6.3/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
 | 
			
		||||
github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ=
 | 
			
		||||
github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
 | 
			
		||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
 | 
			
		||||
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
 | 
			
		||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
 | 
			
		||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
 | 
			
		||||
@@ -1249,18 +1263,22 @@ go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 | 
			
		||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 | 
			
		||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
 | 
			
		||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
 | 
			
		||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
 | 
			
		||||
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
 | 
			
		||||
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
 | 
			
		||||
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
 | 
			
		||||
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
 | 
			
		||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
 | 
			
		||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
 | 
			
		||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
 | 
			
		||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
 | 
			
		||||
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
 | 
			
		||||
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
 | 
			
		||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
 | 
			
		||||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
 | 
			
		||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
 | 
			
		||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
 | 
			
		||||
go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
 | 
			
		||||
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
 | 
			
		||||
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 | 
			
		||||
@@ -1383,8 +1401,10 @@ golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qx
 | 
			
		||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 | 
			
		||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
 | 
			
		||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
 | 
			
		||||
golang.org/x/net v0.0.0-20220630215102-69896b714898/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 | 
			
		||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 | 
			
		||||
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
 | 
			
		||||
golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
 | 
			
		||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
 | 
			
		||||
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
 | 
			
		||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 | 
			
		||||
@@ -1492,6 +1512,7 @@ golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBc
 | 
			
		||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
@@ -1591,6 +1612,7 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f
 | 
			
		||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 | 
			
		||||
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 | 
			
		||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
 | 
			
		||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 | 
			
		||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 | 
			
		||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
 | 
			
		||||
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
 | 
			
		||||
 
 | 
			
		||||
@@ -107,7 +107,7 @@ func InitIssueIndexer(syncReindex bool) {
 | 
			
		||||
 | 
			
		||||
	// Create the Queue
 | 
			
		||||
	switch setting.Indexer.IssueType {
 | 
			
		||||
	case "bleve", "elasticsearch":
 | 
			
		||||
	case "bleve", "elasticsearch", "meilisearch":
 | 
			
		||||
		handler := func(data ...queue.Data) []queue.Data {
 | 
			
		||||
			indexer := holder.get()
 | 
			
		||||
			if indexer == nil {
 | 
			
		||||
@@ -220,6 +220,21 @@ func InitIssueIndexer(syncReindex bool) {
 | 
			
		||||
			issueIndexer := &DBIndexer{}
 | 
			
		||||
			holder.set(issueIndexer)
 | 
			
		||||
			graceful.GetManager().RunAtTerminate(finished)
 | 
			
		||||
		case "meilisearch":
 | 
			
		||||
			graceful.GetManager().RunWithShutdownFns(func(_, atTerminate func(func())) {
 | 
			
		||||
				pprof.SetGoroutineLabels(ctx)
 | 
			
		||||
				issueIndexer, err := NewMeilisearchIndexer(setting.Indexer.IssueConnStr, setting.Indexer.IssueConnAuth, setting.Indexer.IssueIndexerName)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					log.Fatal("Unable to initialize Meilisearch Issue Indexer at connection: %s Error: %v", setting.Indexer.IssueConnStr, err)
 | 
			
		||||
				}
 | 
			
		||||
				exist, err := issueIndexer.Init()
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					log.Fatal("Unable to issueIndexer.Init with connection %s Error: %v", setting.Indexer.IssueConnStr, err)
 | 
			
		||||
				}
 | 
			
		||||
				populate = !exist
 | 
			
		||||
				holder.set(issueIndexer)
 | 
			
		||||
				atTerminate(finished)
 | 
			
		||||
			})
 | 
			
		||||
		default:
 | 
			
		||||
			holder.cancel()
 | 
			
		||||
			log.Fatal("Unknown issue indexer type: %s", setting.Indexer.IssueType)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										183
									
								
								modules/indexer/issues/meilisearch.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										183
									
								
								modules/indexer/issues/meilisearch.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,183 @@
 | 
			
		||||
// Copyright 2023 The Gitea Authors. All rights reserved.
 | 
			
		||||
// SPDX-License-Identifier: MIT
 | 
			
		||||
 | 
			
		||||
package issues
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/meilisearch/meilisearch-go"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var _ Indexer = &MeilisearchIndexer{}
 | 
			
		||||
 | 
			
		||||
// MeilisearchIndexer implements Indexer interface
 | 
			
		||||
type MeilisearchIndexer struct {
 | 
			
		||||
	client               *meilisearch.Client
 | 
			
		||||
	indexerName          string
 | 
			
		||||
	available            bool
 | 
			
		||||
	availabilityCallback func(bool)
 | 
			
		||||
	stopTimer            chan struct{}
 | 
			
		||||
	lock                 sync.RWMutex
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MeilisearchIndexer creates a new meilisearch indexer
 | 
			
		||||
func NewMeilisearchIndexer(url, apiKey, indexerName string) (*MeilisearchIndexer, error) {
 | 
			
		||||
	client := meilisearch.NewClient(meilisearch.ClientConfig{
 | 
			
		||||
		Host:   url,
 | 
			
		||||
		APIKey: apiKey,
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	indexer := &MeilisearchIndexer{
 | 
			
		||||
		client:      client,
 | 
			
		||||
		indexerName: indexerName,
 | 
			
		||||
		available:   true,
 | 
			
		||||
		stopTimer:   make(chan struct{}),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ticker := time.NewTicker(10 * time.Second)
 | 
			
		||||
	go func() {
 | 
			
		||||
		for {
 | 
			
		||||
			select {
 | 
			
		||||
			case <-ticker.C:
 | 
			
		||||
				indexer.checkAvailability()
 | 
			
		||||
			case <-indexer.stopTimer:
 | 
			
		||||
				ticker.Stop()
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	return indexer, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Init will initialize the indexer
 | 
			
		||||
func (b *MeilisearchIndexer) Init() (bool, error) {
 | 
			
		||||
	_, err := b.client.GetIndex(b.indexerName)
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		return true, nil
 | 
			
		||||
	}
 | 
			
		||||
	_, err = b.client.CreateIndex(&meilisearch.IndexConfig{
 | 
			
		||||
		Uid:        b.indexerName,
 | 
			
		||||
		PrimaryKey: "id",
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return false, b.checkError(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, err = b.client.Index(b.indexerName).UpdateFilterableAttributes(&[]string{"repo_id"})
 | 
			
		||||
	return false, b.checkError(err)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetAvailabilityChangeCallback sets callback that will be triggered when availability changes
 | 
			
		||||
func (b *MeilisearchIndexer) SetAvailabilityChangeCallback(callback func(bool)) {
 | 
			
		||||
	b.lock.Lock()
 | 
			
		||||
	defer b.lock.Unlock()
 | 
			
		||||
	b.availabilityCallback = callback
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Ping checks if meilisearch is available
 | 
			
		||||
func (b *MeilisearchIndexer) Ping() bool {
 | 
			
		||||
	b.lock.RLock()
 | 
			
		||||
	defer b.lock.RUnlock()
 | 
			
		||||
	return b.available
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Index will save the index data
 | 
			
		||||
func (b *MeilisearchIndexer) Index(issues []*IndexerData) error {
 | 
			
		||||
	if len(issues) == 0 {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	for _, issue := range issues {
 | 
			
		||||
		_, err := b.client.Index(b.indexerName).AddDocuments(issue)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return b.checkError(err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// TODO: bulk send index data
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Delete deletes indexes by ids
 | 
			
		||||
func (b *MeilisearchIndexer) Delete(ids ...int64) error {
 | 
			
		||||
	if len(ids) == 0 {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, id := range ids {
 | 
			
		||||
		_, err := b.client.Index(b.indexerName).DeleteDocument(strconv.FormatInt(id, 10))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return b.checkError(err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// TODO: bulk send deletes
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Search searches for issues by given conditions.
 | 
			
		||||
// Returns the matching issue IDs
 | 
			
		||||
func (b *MeilisearchIndexer) Search(ctx context.Context, keyword string, repoIDs []int64, limit, start int) (*SearchResult, error) {
 | 
			
		||||
	filter := make([][]string, 0, len(repoIDs))
 | 
			
		||||
	for _, repoID := range repoIDs {
 | 
			
		||||
		filter = append(filter, []string{"repo_id = " + strconv.FormatInt(repoID, 10)})
 | 
			
		||||
	}
 | 
			
		||||
	searchRes, err := b.client.Index(b.indexerName).Search(keyword, &meilisearch.SearchRequest{
 | 
			
		||||
		Filter: filter,
 | 
			
		||||
		Limit:  int64(limit),
 | 
			
		||||
		Offset: int64(start),
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, b.checkError(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	hits := make([]Match, 0, len(searchRes.Hits))
 | 
			
		||||
	for _, hit := range searchRes.Hits {
 | 
			
		||||
		hits = append(hits, Match{
 | 
			
		||||
			ID: int64(hit.(map[string]interface{})["id"].(float64)),
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	return &SearchResult{
 | 
			
		||||
		Total: searchRes.TotalHits,
 | 
			
		||||
		Hits:  hits,
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Close implements indexer
 | 
			
		||||
func (b *MeilisearchIndexer) Close() {
 | 
			
		||||
	select {
 | 
			
		||||
	case <-b.stopTimer:
 | 
			
		||||
	default:
 | 
			
		||||
		close(b.stopTimer)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *MeilisearchIndexer) checkError(err error) error {
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *MeilisearchIndexer) checkAvailability() {
 | 
			
		||||
	_, err := b.client.Health()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		b.setAvailability(false)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	b.setAvailability(true)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *MeilisearchIndexer) setAvailability(available bool) {
 | 
			
		||||
	b.lock.Lock()
 | 
			
		||||
	defer b.lock.Unlock()
 | 
			
		||||
 | 
			
		||||
	if b.available == available {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	b.available = available
 | 
			
		||||
	if b.availabilityCallback != nil {
 | 
			
		||||
		// Call the callback from within the lock to ensure that the ordering remains correct
 | 
			
		||||
		b.availabilityCallback(b.available)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -4,6 +4,7 @@
 | 
			
		||||
package setting
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
@@ -18,6 +19,7 @@ var Indexer = struct {
 | 
			
		||||
	IssueType        string
 | 
			
		||||
	IssuePath        string
 | 
			
		||||
	IssueConnStr     string
 | 
			
		||||
	IssueConnAuth    string
 | 
			
		||||
	IssueIndexerName string
 | 
			
		||||
	StartupTimeout   time.Duration
 | 
			
		||||
 | 
			
		||||
@@ -34,6 +36,7 @@ var Indexer = struct {
 | 
			
		||||
	IssueType:        "bleve",
 | 
			
		||||
	IssuePath:        "indexers/issues.bleve",
 | 
			
		||||
	IssueConnStr:     "",
 | 
			
		||||
	IssueConnAuth:    "",
 | 
			
		||||
	IssueIndexerName: "gitea_issues",
 | 
			
		||||
 | 
			
		||||
	RepoIndexerEnabled: false,
 | 
			
		||||
@@ -53,6 +56,18 @@ func loadIndexerFrom(rootCfg ConfigProvider) {
 | 
			
		||||
		Indexer.IssuePath = filepath.ToSlash(filepath.Join(AppWorkPath, Indexer.IssuePath))
 | 
			
		||||
	}
 | 
			
		||||
	Indexer.IssueConnStr = sec.Key("ISSUE_INDEXER_CONN_STR").MustString(Indexer.IssueConnStr)
 | 
			
		||||
 | 
			
		||||
	if Indexer.IssueType == "meilisearch" {
 | 
			
		||||
		u, err := url.Parse(Indexer.IssueConnStr)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Warn("Failed to parse ISSUE_INDEXER_CONN_STR: %v", err)
 | 
			
		||||
			u = &url.URL{}
 | 
			
		||||
		}
 | 
			
		||||
		Indexer.IssueConnAuth, _ = u.User.Password()
 | 
			
		||||
		u.User = nil
 | 
			
		||||
		Indexer.IssueConnStr = u.String()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Indexer.IssueIndexerName = sec.Key("ISSUE_INDEXER_NAME").MustString(Indexer.IssueIndexerName)
 | 
			
		||||
 | 
			
		||||
	// The following settings are deprecated and can be overridden by settings in [queue] or [queue.issue_indexer]
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user