mirror of
https://github.com/go-gitea/gitea.git
synced 2025-10-03 00:02:14 -04:00
Compare commits
13 Commits
2847a23d83
...
97773e061f
Author | SHA1 | Date | |
---|---|---|---|
|
97773e061f | ||
|
b907b9fb1a | ||
|
c5d74e5869 | ||
|
216663465d | ||
|
d364bd651c | ||
|
c7b3bf3d58 | ||
|
646c509bb1 | ||
|
af97cabef4 | ||
|
2454ab6569 | ||
|
334eb9ecb6 | ||
|
db4813a2dd | ||
|
bb8f1cf902 | ||
|
2abef737df |
6
go.mod
6
go.mod
@ -109,7 +109,7 @@ require (
|
|||||||
github.com/ulikunitz/xz v0.5.15
|
github.com/ulikunitz/xz v0.5.15
|
||||||
github.com/urfave/cli-docs/v3 v3.0.0-alpha6
|
github.com/urfave/cli-docs/v3 v3.0.0-alpha6
|
||||||
github.com/urfave/cli/v3 v3.4.1
|
github.com/urfave/cli/v3 v3.4.1
|
||||||
github.com/wneessen/go-mail v0.6.2
|
github.com/wneessen/go-mail v0.7.1
|
||||||
github.com/xeipuuv/gojsonschema v1.2.0
|
github.com/xeipuuv/gojsonschema v1.2.0
|
||||||
github.com/yohcop/openid-go v1.0.1
|
github.com/yohcop/openid-go v1.0.1
|
||||||
github.com/yuin/goldmark v1.7.13
|
github.com/yuin/goldmark v1.7.13
|
||||||
@ -120,9 +120,9 @@ require (
|
|||||||
golang.org/x/image v0.30.0
|
golang.org/x/image v0.30.0
|
||||||
golang.org/x/net v0.43.0
|
golang.org/x/net v0.43.0
|
||||||
golang.org/x/oauth2 v0.30.0
|
golang.org/x/oauth2 v0.30.0
|
||||||
golang.org/x/sync v0.16.0
|
golang.org/x/sync v0.17.0
|
||||||
golang.org/x/sys v0.35.0
|
golang.org/x/sys v0.35.0
|
||||||
golang.org/x/text v0.28.0
|
golang.org/x/text v0.29.0
|
||||||
google.golang.org/grpc v1.75.0
|
google.golang.org/grpc v1.75.0
|
||||||
google.golang.org/protobuf v1.36.8
|
google.golang.org/protobuf v1.36.8
|
||||||
gopkg.in/ini.v1 v1.67.0
|
gopkg.in/ini.v1 v1.67.0
|
||||||
|
17
go.sum
17
go.sum
@ -765,8 +765,8 @@ github.com/urfave/cli/v3 v3.4.1/go.mod h1:FJSKtM/9AiiTOJL4fJ6TbMUkxBXn7GO9guZqoZ
|
|||||||
github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ=
|
github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ=
|
||||||
github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
|
github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
|
||||||
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||||
github.com/wneessen/go-mail v0.6.2 h1:c6V7c8D2mz868z9WJ+8zDKtUyLfZ1++uAZmo2GRFji8=
|
github.com/wneessen/go-mail v0.7.1 h1:rvy63sp14N06/kdGqCYwW8Na5gDCXjTQM1E7So4PuKk=
|
||||||
github.com/wneessen/go-mail v0.6.2/go.mod h1:L/PYjPK3/2ZlNb2/FjEBIn9n1rUWjW+Toy531oVmeb4=
|
github.com/wneessen/go-mail v0.7.1/go.mod h1:+TkW6QP3EVkgTEqHtVmnAE/1MRhmzb8Y9/W3pweuS+k=
|
||||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||||
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
||||||
@ -837,7 +837,6 @@ golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDf
|
|||||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
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.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||||
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||||
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
|
|
||||||
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
||||||
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
@ -930,9 +929,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.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sync v0.7.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.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
|
||||||
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||||
golang.org/x/sync v0.16.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-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-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
@ -974,7 +972,6 @@ 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.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.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
|
||||||
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
||||||
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||||
@ -987,7 +984,6 @@ 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.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||||
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
||||||
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
|
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
|
||||||
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
|
|
||||||
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
|
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
|
||||||
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
|
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
@ -1003,9 +999,8 @@ 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.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
golang.org/x/text v0.15.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.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||||
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
|
||||||
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
|
||||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
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-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
|
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
|
||||||
|
@ -8,36 +8,13 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Batch struct {
|
type batchCatFile struct {
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
Reader *bufio.Reader
|
Reader *bufio.Reader
|
||||||
Writer WriteCloserError
|
Writer WriteCloserError
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBatch creates a new batch for the given repository, the Close must be invoked before release the batch
|
func (b *batchCatFile) Close() {
|
||||||
func NewBatch(ctx context.Context, repoPath string) (*Batch, error) {
|
|
||||||
// Now because of some insanity with git cat-file not immediately failing if not run in a valid git directory we need to run git rev-parse first!
|
|
||||||
if err := ensureValidGitRepository(ctx, repoPath); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var batch Batch
|
|
||||||
batch.Writer, batch.Reader, batch.cancel = catFileBatch(ctx, repoPath)
|
|
||||||
return &batch, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewBatchCheck(ctx context.Context, repoPath string) (*Batch, error) {
|
|
||||||
// Now because of some insanity with git cat-file not immediately failing if not run in a valid git directory we need to run git rev-parse first!
|
|
||||||
if err := ensureValidGitRepository(ctx, repoPath); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var check Batch
|
|
||||||
check.Writer, check.Reader, check.cancel = catFileBatchCheck(ctx, repoPath)
|
|
||||||
return &check, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Batch) Close() {
|
|
||||||
if b.cancel != nil {
|
if b.cancel != nil {
|
||||||
b.cancel()
|
b.cancel()
|
||||||
b.Reader = nil
|
b.Reader = nil
|
||||||
@ -45,3 +22,110 @@ func (b *Batch) Close() {
|
|||||||
b.cancel = nil
|
b.cancel = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Batch interface {
|
||||||
|
Write([]byte) (int, error)
|
||||||
|
WriteCheck([]byte) (int, error)
|
||||||
|
Reader() *bufio.Reader
|
||||||
|
CheckReader() *bufio.Reader
|
||||||
|
Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
// batchCatFileWithCheck implements the Batch interface using the "cat-file --batch" command and "cat-file --batch-check" command
|
||||||
|
// ref: https://git-scm.com/docs/git-cat-file#Documentation/git-cat-file.txt---batch
|
||||||
|
// To align with --batch-command, we creates the two commands both at the same time if git version is lower than 2.36
|
||||||
|
type batchCatFileWithCheck struct {
|
||||||
|
batch *batchCatFile
|
||||||
|
batchCheck *batchCatFile
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ Batch = &batchCatFileWithCheck{}
|
||||||
|
|
||||||
|
// newBatchCatFileWithCheck creates a new batch and a new batch check for the given repository, the Close must be invoked before release the batch
|
||||||
|
func newBatchCatFileWithCheck(ctx context.Context, repoPath string) (*batchCatFileWithCheck, error) {
|
||||||
|
// Now because of some insanity with git cat-file not immediately failing if not run in a valid git directory we need to run git rev-parse first!
|
||||||
|
if err := ensureValidGitRepository(ctx, repoPath); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &batchCatFileWithCheck{
|
||||||
|
batch: newCatFileBatch(ctx, repoPath, "--batch"),
|
||||||
|
batchCheck: newCatFileBatch(ctx, repoPath, "--batch-check"),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *batchCatFileWithCheck) Write(bs []byte) (int, error) {
|
||||||
|
return b.batch.Writer.Write(bs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *batchCatFileWithCheck) WriteCheck(bs []byte) (int, error) {
|
||||||
|
return b.batchCheck.Writer.Write(bs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *batchCatFileWithCheck) Reader() *bufio.Reader {
|
||||||
|
return b.batch.Reader
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *batchCatFileWithCheck) CheckReader() *bufio.Reader {
|
||||||
|
return b.batchCheck.Reader
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *batchCatFileWithCheck) Close() {
|
||||||
|
if b.batch != nil {
|
||||||
|
b.batch.Close()
|
||||||
|
b.batch = nil
|
||||||
|
}
|
||||||
|
if b.batchCheck != nil {
|
||||||
|
b.batchCheck.Close()
|
||||||
|
b.batchCheck = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// batchCommandCatFile implements the Batch interface using the "cat-file --batch-command" command
|
||||||
|
// ref: https://git-scm.com/docs/git-cat-file#Documentation/git-cat-file.txt---batch-command
|
||||||
|
type batchCommandCatFile struct {
|
||||||
|
batch *batchCatFile
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ Batch = &batchCommandCatFile{}
|
||||||
|
|
||||||
|
func newBatchCommandCatFile(ctx context.Context, repoPath string) (*batchCommandCatFile, error) {
|
||||||
|
// Now because of some insanity with git cat-file not immediately failing if not run in a valid git directory we need to run git rev-parse first!
|
||||||
|
if err := ensureValidGitRepository(ctx, repoPath); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &batchCommandCatFile{
|
||||||
|
batch: newCatFileBatch(ctx, repoPath, "--batch-command"),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *batchCommandCatFile) Write(bs []byte) (int, error) {
|
||||||
|
return b.batch.Writer.Write(append([]byte("contents "), bs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *batchCommandCatFile) WriteCheck(bs []byte) (int, error) {
|
||||||
|
return b.batch.Writer.Write(append([]byte("info "), bs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *batchCommandCatFile) Reader() *bufio.Reader {
|
||||||
|
return b.batch.Reader
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *batchCommandCatFile) CheckReader() *bufio.Reader {
|
||||||
|
return b.batch.Reader
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *batchCommandCatFile) Close() {
|
||||||
|
if b.batch != nil {
|
||||||
|
b.batch.Close()
|
||||||
|
b.batch = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBatch(ctx context.Context, repoPath string) (Batch, error) {
|
||||||
|
if DefaultFeatures().SupportCatFileBatchCommand {
|
||||||
|
return newBatchCommandCatFile(ctx, repoPath)
|
||||||
|
}
|
||||||
|
return newBatchCatFileWithCheck(ctx, repoPath)
|
||||||
|
}
|
||||||
|
@ -41,54 +41,13 @@ func ensureValidGitRepository(ctx context.Context, repoPath string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// catFileBatchCheck opens git cat-file --batch-check in the provided repo and returns a stdin pipe, a stdout reader and cancel function
|
// newCatFileBatch opens git cat-file --batch in the provided repo and returns a stdin pipe, a stdout reader and cancel function
|
||||||
func catFileBatchCheck(ctx context.Context, repoPath string) (WriteCloserError, *bufio.Reader, func()) {
|
// batchArg is the argument to pass to cat-file --batch, it could be "--batch", "--batch-command" or "--batch-check".
|
||||||
batchStdinReader, batchStdinWriter := io.Pipe()
|
func newCatFileBatch(ctx context.Context, repoPath, batchArg string) *batchCatFile {
|
||||||
batchStdoutReader, batchStdoutWriter := io.Pipe()
|
if batchArg != "--batch" && batchArg != "--batch-command" && batchArg != "--batch-check" {
|
||||||
ctx, ctxCancel := context.WithCancel(ctx)
|
panic("invalid batchArg: " + batchArg)
|
||||||
closed := make(chan struct{})
|
|
||||||
cancel := func() {
|
|
||||||
ctxCancel()
|
|
||||||
_ = batchStdoutReader.Close()
|
|
||||||
_ = batchStdinWriter.Close()
|
|
||||||
<-closed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure cancel is called as soon as the provided context is cancelled
|
|
||||||
go func() {
|
|
||||||
<-ctx.Done()
|
|
||||||
cancel()
|
|
||||||
}()
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
stderr := strings.Builder{}
|
|
||||||
err := gitcmd.NewCommand("cat-file", "--batch-check").
|
|
||||||
Run(ctx, &gitcmd.RunOpts{
|
|
||||||
Dir: repoPath,
|
|
||||||
Stdin: batchStdinReader,
|
|
||||||
Stdout: batchStdoutWriter,
|
|
||||||
Stderr: &stderr,
|
|
||||||
|
|
||||||
UseContextTimeout: true,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
_ = batchStdoutWriter.CloseWithError(gitcmd.ConcatenateError(err, (&stderr).String()))
|
|
||||||
_ = batchStdinReader.CloseWithError(gitcmd.ConcatenateError(err, (&stderr).String()))
|
|
||||||
} else {
|
|
||||||
_ = batchStdoutWriter.Close()
|
|
||||||
_ = batchStdinReader.Close()
|
|
||||||
}
|
|
||||||
close(closed)
|
|
||||||
}()
|
|
||||||
|
|
||||||
// For simplicities sake we'll use a buffered reader to read from the cat-file --batch-check
|
|
||||||
batchReader := bufio.NewReader(batchStdoutReader)
|
|
||||||
|
|
||||||
return batchStdinWriter, batchReader, cancel
|
|
||||||
}
|
|
||||||
|
|
||||||
// catFileBatch opens git cat-file --batch in the provided repo and returns a stdin pipe, a stdout reader and cancel function
|
|
||||||
func catFileBatch(ctx context.Context, repoPath string) (WriteCloserError, *bufio.Reader, func()) {
|
|
||||||
// We often want to feed the commits in order into cat-file --batch, followed by their trees and sub trees as necessary.
|
// We often want to feed the commits in order into cat-file --batch, followed by their trees and sub trees as necessary.
|
||||||
// so let's create a batch stdin and stdout
|
// so let's create a batch stdin and stdout
|
||||||
batchStdinReader, batchStdinWriter := io.Pipe()
|
batchStdinReader, batchStdinWriter := io.Pipe()
|
||||||
@ -110,7 +69,8 @@ func catFileBatch(ctx context.Context, repoPath string) (WriteCloserError, *bufi
|
|||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
stderr := strings.Builder{}
|
stderr := strings.Builder{}
|
||||||
err := gitcmd.NewCommand("cat-file", "--batch").
|
err := gitcmd.NewCommand("cat-file").
|
||||||
|
AddArguments(gitcmd.ToTrustCmdArg(batchArg)).
|
||||||
Run(ctx, &gitcmd.RunOpts{
|
Run(ctx, &gitcmd.RunOpts{
|
||||||
Dir: repoPath,
|
Dir: repoPath,
|
||||||
Stdin: batchStdinReader,
|
Stdin: batchStdinReader,
|
||||||
@ -132,7 +92,11 @@ func catFileBatch(ctx context.Context, repoPath string) (WriteCloserError, *bufi
|
|||||||
// For simplicities sake we'll us a buffered reader to read from the cat-file --batch
|
// For simplicities sake we'll us a buffered reader to read from the cat-file --batch
|
||||||
batchReader := bufio.NewReaderSize(batchStdoutReader, 32*1024)
|
batchReader := bufio.NewReaderSize(batchStdoutReader, 32*1024)
|
||||||
|
|
||||||
return batchStdinWriter, batchReader, cancel
|
return &batchCatFile{
|
||||||
|
Writer: batchStdinWriter,
|
||||||
|
Reader: batchReader,
|
||||||
|
cancel: cancel,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadBatchLine reads the header line from cat-file --batch
|
// ReadBatchLine reads the header line from cat-file --batch
|
||||||
|
@ -26,16 +26,17 @@ type Blob struct {
|
|||||||
// DataAsync gets a ReadCloser for the contents of a blob without reading it all.
|
// DataAsync gets a ReadCloser for the contents of a blob without reading it all.
|
||||||
// Calling the Close function on the result will discard all unread output.
|
// Calling the Close function on the result will discard all unread output.
|
||||||
func (b *Blob) DataAsync() (io.ReadCloser, error) {
|
func (b *Blob) DataAsync() (io.ReadCloser, error) {
|
||||||
wr, rd, cancel, err := b.repo.CatFileBatch(b.repo.Ctx)
|
batch, cancel, err := b.repo.CatFileBatch(b.repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = wr.Write([]byte(b.ID.String() + "\n"))
|
_, err = batch.Write([]byte(b.ID.String() + "\n"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cancel()
|
cancel()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
rd := batch.Reader()
|
||||||
_, _, size, err := ReadBatchLine(rd)
|
_, _, size, err := ReadBatchLine(rd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cancel()
|
cancel()
|
||||||
@ -67,18 +68,18 @@ func (b *Blob) Size() int64 {
|
|||||||
return b.size
|
return b.size
|
||||||
}
|
}
|
||||||
|
|
||||||
wr, rd, cancel, err := b.repo.CatFileBatchCheck(b.repo.Ctx)
|
batch, cancel, err := b.repo.CatFileBatch(b.repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug("error whilst reading size for %s in %s. Error: %v", b.ID.String(), b.repo.Path, err)
|
log.Debug("error whilst reading size for %s in %s. Error: %v", b.ID.String(), b.repo.Path, err)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
defer cancel()
|
defer cancel()
|
||||||
_, err = wr.Write([]byte(b.ID.String() + "\n"))
|
_, err = batch.WriteCheck([]byte(b.ID.String() + "\n"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug("error whilst reading size for %s in %s. Error: %v", b.ID.String(), b.repo.Path, err)
|
log.Debug("error whilst reading size for %s in %s. Error: %v", b.ID.String(), b.repo.Path, err)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
_, _, b.size, err = ReadBatchLine(rd)
|
_, _, b.size, err = ReadBatchLine(batch.CheckReader())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug("error whilst reading size for %s in %s. Error: %v", b.ID.String(), b.repo.Path, err)
|
log.Debug("error whilst reading size for %s in %s. Error: %v", b.ID.String(), b.repo.Path, err)
|
||||||
return 0
|
return 0
|
||||||
|
@ -26,11 +26,12 @@ const RequiredVersion = "2.0.0" // the minimum Git version required
|
|||||||
type Features struct {
|
type Features struct {
|
||||||
gitVersion *version.Version
|
gitVersion *version.Version
|
||||||
|
|
||||||
UsingGogit bool
|
UsingGogit bool
|
||||||
SupportProcReceive bool // >= 2.29
|
SupportProcReceive bool // >= 2.29
|
||||||
SupportHashSha256 bool // >= 2.42, SHA-256 repositories no longer an ‘experimental curiosity’
|
SupportHashSha256 bool // >= 2.42, SHA-256 repositories no longer an ‘experimental curiosity’
|
||||||
SupportedObjectFormats []ObjectFormat // sha1, sha256
|
SupportedObjectFormats []ObjectFormat // sha1, sha256
|
||||||
SupportCheckAttrOnBare bool // >= 2.40
|
SupportCheckAttrOnBare bool // >= 2.40
|
||||||
|
SupportCatFileBatchCommand bool // >= 2.36, support `git cat-file --batch-command`
|
||||||
}
|
}
|
||||||
|
|
||||||
var defaultFeatures *Features
|
var defaultFeatures *Features
|
||||||
@ -75,6 +76,7 @@ func loadGitVersionFeatures() (*Features, error) {
|
|||||||
features.SupportedObjectFormats = append(features.SupportedObjectFormats, Sha256ObjectFormat)
|
features.SupportedObjectFormats = append(features.SupportedObjectFormats, Sha256ObjectFormat)
|
||||||
}
|
}
|
||||||
features.SupportCheckAttrOnBare = features.CheckVersionAtLeast("2.40")
|
features.SupportCheckAttrOnBare = features.CheckVersionAtLeast("2.40")
|
||||||
|
features.SupportCatFileBatchCommand = features.CheckVersionAtLeast("2.36")
|
||||||
return features, nil
|
return features, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,6 +184,12 @@ func (c *Command) AddConfig(key, value string) *Command {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToTrustCmdArg converts a string (trusted as argument) to CmdArg
|
||||||
|
// In most cases, it shouldn't be used. Use AddXxx function instead
|
||||||
|
func ToTrustCmdArg(arg string) internal.CmdArg {
|
||||||
|
return internal.CmdArg(arg)
|
||||||
|
}
|
||||||
|
|
||||||
// ToTrustedCmdArgs converts a list of strings (trusted as argument) to TrustedCmdArgs
|
// ToTrustedCmdArgs converts a list of strings (trusted as argument) to TrustedCmdArgs
|
||||||
// In most cases, it shouldn't be used. Use NewCommand().AddXxx() function instead
|
// In most cases, it shouldn't be used. Use NewCommand().AddXxx() function instead
|
||||||
func ToTrustedCmdArgs(args []string) TrustedCmdArgs {
|
func ToTrustedCmdArgs(args []string) TrustedCmdArgs {
|
||||||
|
@ -22,20 +22,21 @@ import (
|
|||||||
func GetLanguageStats(repo *git.Repository, commitID string) (map[string]int64, error) {
|
func GetLanguageStats(repo *git.Repository, commitID string) (map[string]int64, error) {
|
||||||
// We will feed the commit IDs in order into cat-file --batch, followed by blobs as necessary.
|
// We will feed the commit IDs in order into cat-file --batch, followed by blobs as necessary.
|
||||||
// so let's create a batch stdin and stdout
|
// so let's create a batch stdin and stdout
|
||||||
batchStdinWriter, batchReader, cancel, err := repo.CatFileBatch(repo.Ctx)
|
batch, cancel, err := repo.CatFileBatch(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
writeID := func(id string) error {
|
writeID := func(id string) error {
|
||||||
_, err := batchStdinWriter.Write([]byte(id + "\n"))
|
_, err := batch.Write([]byte(id + "\n"))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := writeID(commitID); err != nil {
|
if err := writeID(commitID); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
batchReader := batch.Reader()
|
||||||
shaBytes, typ, size, err := git.ReadBatchLine(batchReader)
|
shaBytes, typ, size, err := git.ReadBatchLine(batchReader)
|
||||||
if typ != "commit" {
|
if typ != "commit" {
|
||||||
log.Debug("Unable to get commit for: %s. Err: %v", commitID, err)
|
log.Debug("Unable to get commit for: %s. Err: %v", commitID, err)
|
||||||
|
@ -47,7 +47,7 @@ func FindLFSFile(repo *git.Repository, objectID git.ObjectID) ([]*LFSResult, err
|
|||||||
|
|
||||||
// Next feed the commits in order into cat-file --batch, followed by their trees and sub trees as necessary.
|
// Next feed the commits in order into cat-file --batch, followed by their trees and sub trees as necessary.
|
||||||
// so let's create a batch stdin and stdout
|
// so let's create a batch stdin and stdout
|
||||||
batchStdinWriter, batchReader, cancel, err := repo.CatFileBatch(repo.Ctx)
|
batch, cancel, err := repo.CatFileBatch(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -61,17 +61,14 @@ func FindLFSFile(repo *git.Repository, objectID git.ObjectID) ([]*LFSResult, err
|
|||||||
fnameBuf := make([]byte, 4096)
|
fnameBuf := make([]byte, 4096)
|
||||||
modeBuf := make([]byte, 40)
|
modeBuf := make([]byte, 40)
|
||||||
workingShaBuf := make([]byte, objectID.Type().FullLength()/2)
|
workingShaBuf := make([]byte, objectID.Type().FullLength()/2)
|
||||||
|
batchReader := batch.Reader()
|
||||||
|
|
||||||
for scan.Scan() {
|
for scan.Scan() {
|
||||||
// Get the next commit ID
|
// Get the next commit ID
|
||||||
commitID := scan.Bytes()
|
commitID := scan.Bytes()
|
||||||
|
|
||||||
// push the commit to the cat-file --batch process
|
// push the commit to the cat-file --batch process
|
||||||
_, err := batchStdinWriter.Write(commitID)
|
_, err := batch.Write(append(commitID, '\n'))
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
_, err = batchStdinWriter.Write([]byte{'\n'})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -93,7 +90,7 @@ func FindLFSFile(repo *git.Repository, objectID git.ObjectID) ([]*LFSResult, err
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
_, err = batchStdinWriter.Write([]byte(id + "\n"))
|
_, err = batch.Write([]byte(id + "\n"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -108,7 +105,7 @@ func FindLFSFile(repo *git.Repository, objectID git.ObjectID) ([]*LFSResult, err
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := batchStdinWriter.Write([]byte(curCommit.Tree.ID.String() + "\n")); err != nil {
|
if _, err := batch.Write([]byte(curCommit.Tree.ID.String() + "\n")); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
curPath = ""
|
curPath = ""
|
||||||
@ -140,11 +137,7 @@ func FindLFSFile(repo *git.Repository, objectID git.ObjectID) ([]*LFSResult, err
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(trees) > 0 {
|
if len(trees) > 0 {
|
||||||
_, err := batchStdinWriter.Write(trees[len(trees)-1])
|
_, err := batch.Write(append(trees[len(trees)-1], '\n'))
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
_, err = batchStdinWriter.Write([]byte("\n"))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
package git
|
package git
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"context"
|
"context"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
@ -26,10 +25,7 @@ type Repository struct {
|
|||||||
gpgSettings *GPGSettings
|
gpgSettings *GPGSettings
|
||||||
|
|
||||||
batchInUse bool
|
batchInUse bool
|
||||||
batch *Batch
|
batch Batch
|
||||||
|
|
||||||
checkInUse bool
|
|
||||||
check *Batch
|
|
||||||
|
|
||||||
Ctx context.Context
|
Ctx context.Context
|
||||||
LastCommitCache *LastCommitCache
|
LastCommitCache *LastCommitCache
|
||||||
@ -59,18 +55,18 @@ func OpenRepository(ctx context.Context, repoPath string) (*Repository, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CatFileBatch obtains a CatFileBatch for this repository
|
// CatFileBatch obtains a CatFileBatch for this repository
|
||||||
func (repo *Repository) CatFileBatch(ctx context.Context) (WriteCloserError, *bufio.Reader, func(), error) {
|
func (repo *Repository) CatFileBatch(ctx context.Context) (Batch, func(), error) {
|
||||||
if repo.batch == nil {
|
if repo.batch == nil {
|
||||||
var err error
|
var err error
|
||||||
repo.batch, err = NewBatch(ctx, repo.Path)
|
repo.batch, err = NewBatch(ctx, repo.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !repo.batchInUse {
|
if !repo.batchInUse {
|
||||||
repo.batchInUse = true
|
repo.batchInUse = true
|
||||||
return repo.batch.Writer, repo.batch.Reader, func() {
|
return repo.batch, func() {
|
||||||
repo.batchInUse = false
|
repo.batchInUse = false
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@ -78,34 +74,9 @@ func (repo *Repository) CatFileBatch(ctx context.Context) (WriteCloserError, *bu
|
|||||||
log.Debug("Opening temporary cat file batch for: %s", repo.Path)
|
log.Debug("Opening temporary cat file batch for: %s", repo.Path)
|
||||||
tempBatch, err := NewBatch(ctx, repo.Path)
|
tempBatch, err := NewBatch(ctx, repo.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
return tempBatch.Writer, tempBatch.Reader, tempBatch.Close, nil
|
return tempBatch, tempBatch.Close, nil
|
||||||
}
|
|
||||||
|
|
||||||
// CatFileBatchCheck obtains a CatFileBatchCheck for this repository
|
|
||||||
func (repo *Repository) CatFileBatchCheck(ctx context.Context) (WriteCloserError, *bufio.Reader, func(), error) {
|
|
||||||
if repo.check == nil {
|
|
||||||
var err error
|
|
||||||
repo.check, err = NewBatchCheck(ctx, repo.Path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !repo.checkInUse {
|
|
||||||
repo.checkInUse = true
|
|
||||||
return repo.check.Writer, repo.check.Reader, func() {
|
|
||||||
repo.checkInUse = false
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debug("Opening temporary cat file batch-check for: %s", repo.Path)
|
|
||||||
tempBatchCheck, err := NewBatchCheck(ctx, repo.Path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, nil, err
|
|
||||||
}
|
|
||||||
return tempBatchCheck.Writer, tempBatchCheck.Reader, tempBatchCheck.Close, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *Repository) Close() error {
|
func (repo *Repository) Close() error {
|
||||||
@ -117,11 +88,7 @@ func (repo *Repository) Close() error {
|
|||||||
repo.batch = nil
|
repo.batch = nil
|
||||||
repo.batchInUse = false
|
repo.batchInUse = false
|
||||||
}
|
}
|
||||||
if repo.check != nil {
|
|
||||||
repo.check.Close()
|
|
||||||
repo.check = nil
|
|
||||||
repo.checkInUse = false
|
|
||||||
}
|
|
||||||
repo.LastCommitCache = nil
|
repo.LastCommitCache = nil
|
||||||
repo.tagCache = nil
|
repo.tagCache = nil
|
||||||
return nil
|
return nil
|
||||||
|
@ -23,18 +23,18 @@ func (repo *Repository) IsObjectExist(name string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
wr, rd, cancel, err := repo.CatFileBatchCheck(repo.Ctx)
|
batch, cancel, err := repo.CatFileBatch(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug("Error writing to CatFileBatchCheck %v", err)
|
log.Debug("Error writing to CatFileBatchCheck %v", err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
defer cancel()
|
defer cancel()
|
||||||
_, err = wr.Write([]byte(name + "\n"))
|
_, err = batch.WriteCheck([]byte(name + "\n"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug("Error writing to CatFileBatchCheck %v", err)
|
log.Debug("Error writing to CatFileBatchCheck %v", err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
sha, _, _, err := ReadBatchLine(rd)
|
sha, _, _, err := ReadBatchLine(batch.CheckReader())
|
||||||
return err == nil && bytes.HasPrefix(sha, []byte(strings.TrimSpace(name)))
|
return err == nil && bytes.HasPrefix(sha, []byte(strings.TrimSpace(name)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,18 +44,18 @@ func (repo *Repository) IsReferenceExist(name string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
wr, rd, cancel, err := repo.CatFileBatchCheck(repo.Ctx)
|
batch, cancel, err := repo.CatFileBatch(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug("Error writing to CatFileBatchCheck %v", err)
|
log.Debug("Error writing to CatFileBatchCheck %v", err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
defer cancel()
|
defer cancel()
|
||||||
_, err = wr.Write([]byte(name + "\n"))
|
_, err = batch.WriteCheck([]byte(name + "\n"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug("Error writing to CatFileBatchCheck %v", err)
|
log.Debug("Error writing to CatFileBatchCheck %v", err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
_, _, _, err = ReadBatchLine(rd)
|
_, _, _, err = ReadBatchLine(batch.CheckReader())
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
package git
|
package git
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
@ -34,16 +33,16 @@ func (repo *Repository) ResolveReference(name string) (string, error) {
|
|||||||
|
|
||||||
// GetRefCommitID returns the last commit ID string of given reference (branch or tag).
|
// GetRefCommitID returns the last commit ID string of given reference (branch or tag).
|
||||||
func (repo *Repository) GetRefCommitID(name string) (string, error) {
|
func (repo *Repository) GetRefCommitID(name string) (string, error) {
|
||||||
wr, rd, cancel, err := repo.CatFileBatchCheck(repo.Ctx)
|
batch, cancel, err := repo.CatFileBatch(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
defer cancel()
|
defer cancel()
|
||||||
_, err = wr.Write([]byte(name + "\n"))
|
_, err = batch.WriteCheck([]byte(name + "\n"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
shaBs, _, _, err := ReadBatchLine(rd)
|
shaBs, _, _, err := ReadBatchLine(batch.CheckReader())
|
||||||
if IsErrNotExist(err) {
|
if IsErrNotExist(err) {
|
||||||
return "", ErrNotExist{name, ""}
|
return "", ErrNotExist{name, ""}
|
||||||
}
|
}
|
||||||
@ -62,19 +61,19 @@ func (repo *Repository) IsCommitExist(name string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (repo *Repository) getCommit(id ObjectID) (*Commit, error) {
|
func (repo *Repository) getCommit(id ObjectID) (*Commit, error) {
|
||||||
wr, rd, cancel, err := repo.CatFileBatch(repo.Ctx)
|
batch, cancel, err := repo.CatFileBatch(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
_, _ = wr.Write([]byte(id.String() + "\n"))
|
_, _ = batch.Write([]byte(id.String() + "\n"))
|
||||||
|
|
||||||
return repo.getCommitFromBatchReader(wr, rd, id)
|
return repo.getCommitFromBatchReader(batch, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *Repository) getCommitFromBatchReader(wr WriteCloserError, rd *bufio.Reader, id ObjectID) (*Commit, error) {
|
func (repo *Repository) getCommitFromBatchReader(batch Batch, id ObjectID) (*Commit, error) {
|
||||||
_, typ, size, err := ReadBatchLine(rd)
|
_, typ, size, err := ReadBatchLine(batch.Reader())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, io.EOF) || IsErrNotExist(err) {
|
if errors.Is(err, io.EOF) || IsErrNotExist(err) {
|
||||||
return nil, ErrNotExist{ID: id.String()}
|
return nil, ErrNotExist{ID: id.String()}
|
||||||
@ -88,11 +87,11 @@ func (repo *Repository) getCommitFromBatchReader(wr WriteCloserError, rd *bufio.
|
|||||||
case "tag":
|
case "tag":
|
||||||
// then we need to parse the tag
|
// then we need to parse the tag
|
||||||
// and load the commit
|
// and load the commit
|
||||||
data, err := io.ReadAll(io.LimitReader(rd, size))
|
data, err := io.ReadAll(io.LimitReader(batch.Reader(), size))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
_, err = rd.Discard(1)
|
_, err = batch.Reader().Discard(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -101,22 +100,22 @@ func (repo *Repository) getCommitFromBatchReader(wr WriteCloserError, rd *bufio.
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := wr.Write([]byte(tag.Object.String() + "\n")); err != nil {
|
if _, err := batch.Write([]byte(tag.Object.String() + "\n")); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
commit, err := repo.getCommitFromBatchReader(wr, rd, tag.Object)
|
commit, err := repo.getCommitFromBatchReader(batch, tag.Object)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return commit, nil
|
return commit, nil
|
||||||
case "commit":
|
case "commit":
|
||||||
commit, err := CommitFromReader(repo, id, io.LimitReader(rd, size))
|
commit, err := CommitFromReader(repo, id, io.LimitReader(batch.Reader(), size))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
_, err = rd.Discard(1)
|
_, err = batch.Reader().Discard(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -124,7 +123,7 @@ func (repo *Repository) getCommitFromBatchReader(wr WriteCloserError, rd *bufio.
|
|||||||
return commit, nil
|
return commit, nil
|
||||||
default:
|
default:
|
||||||
log.Debug("Unknown typ: %s", typ)
|
log.Debug("Unknown typ: %s", typ)
|
||||||
if err := DiscardFull(rd, size+1); err != nil {
|
if err := DiscardFull(batch.Reader(), size+1); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return nil, ErrNotExist{
|
return nil, ErrNotExist{
|
||||||
@ -146,16 +145,16 @@ func (repo *Repository) ConvertToGitID(commitID string) (ObjectID, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wr, rd, cancel, err := repo.CatFileBatchCheck(repo.Ctx)
|
batch, cancel, err := repo.CatFileBatch(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer cancel()
|
defer cancel()
|
||||||
_, err = wr.Write([]byte(commitID + "\n"))
|
_, err = batch.WriteCheck([]byte(commitID + "\n"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sha, _, _, err := ReadBatchLine(rd)
|
sha, _, _, err := ReadBatchLine(batch.CheckReader())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if IsErrNotExist(err) {
|
if IsErrNotExist(err) {
|
||||||
return nil, ErrNotExist{commitID, ""}
|
return nil, ErrNotExist{commitID, ""}
|
||||||
|
@ -24,16 +24,16 @@ func (repo *Repository) IsTagExist(name string) bool {
|
|||||||
|
|
||||||
// GetTagType gets the type of the tag, either commit (simple) or tag (annotated)
|
// GetTagType gets the type of the tag, either commit (simple) or tag (annotated)
|
||||||
func (repo *Repository) GetTagType(id ObjectID) (string, error) {
|
func (repo *Repository) GetTagType(id ObjectID) (string, error) {
|
||||||
wr, rd, cancel, err := repo.CatFileBatchCheck(repo.Ctx)
|
batch, cancel, err := repo.CatFileBatch(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
defer cancel()
|
defer cancel()
|
||||||
_, err = wr.Write([]byte(id.String() + "\n"))
|
_, err = batch.WriteCheck([]byte(id.String() + "\n"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
_, typ, _, err := ReadBatchLine(rd)
|
_, typ, _, err := ReadBatchLine(batch.CheckReader())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if IsErrNotExist(err) {
|
if IsErrNotExist(err) {
|
||||||
return "", ErrNotExist{ID: id.String()}
|
return "", ErrNotExist{ID: id.String()}
|
||||||
@ -88,15 +88,16 @@ func (repo *Repository) getTag(tagID ObjectID, name string) (*Tag, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The tag is an annotated tag with a message.
|
// The tag is an annotated tag with a message.
|
||||||
wr, rd, cancel, err := repo.CatFileBatch(repo.Ctx)
|
batch, cancel, err := repo.CatFileBatch(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
if _, err := wr.Write([]byte(tagID.String() + "\n")); err != nil {
|
if _, err := batch.Write([]byte(tagID.String() + "\n")); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
rd := batch.Reader()
|
||||||
_, typ, size, err := ReadBatchLine(rd)
|
_, typ, size, err := ReadBatchLine(rd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, io.EOF) || IsErrNotExist(err) {
|
if errors.Is(err, io.EOF) || IsErrNotExist(err) {
|
||||||
|
@ -10,13 +10,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (repo *Repository) getTree(id ObjectID) (*Tree, error) {
|
func (repo *Repository) getTree(id ObjectID) (*Tree, error) {
|
||||||
wr, rd, cancel, err := repo.CatFileBatch(repo.Ctx)
|
batch, cancel, err := repo.CatFileBatch(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
_, _ = wr.Write([]byte(id.String() + "\n"))
|
_, _ = batch.Write([]byte(id.String() + "\n"))
|
||||||
|
|
||||||
|
rd := batch.Reader()
|
||||||
|
|
||||||
// ignore the SHA
|
// ignore the SHA
|
||||||
_, typ, size, err := ReadBatchLine(rd)
|
_, typ, size, err := ReadBatchLine(rd)
|
||||||
@ -36,10 +38,10 @@ func (repo *Repository) getTree(id ObjectID) (*Tree, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := wr.Write([]byte(tag.Object.String() + "\n")); err != nil {
|
if _, err := batch.Write([]byte(tag.Object.String() + "\n")); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
commit, err := repo.getCommitFromBatchReader(wr, rd, tag.Object)
|
commit, err := repo.getCommitFromBatchReader(batch, tag.Object)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -36,18 +36,18 @@ func (te *TreeEntry) Size() int64 {
|
|||||||
return te.size
|
return te.size
|
||||||
}
|
}
|
||||||
|
|
||||||
wr, rd, cancel, err := te.ptree.repo.CatFileBatchCheck(te.ptree.repo.Ctx)
|
batch, cancel, err := te.ptree.repo.CatFileBatch(te.ptree.repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug("error whilst reading size for %s in %s. Error: %v", te.ID.String(), te.ptree.repo.Path, err)
|
log.Debug("error whilst reading size for %s in %s. Error: %v", te.ID.String(), te.ptree.repo.Path, err)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
defer cancel()
|
defer cancel()
|
||||||
_, err = wr.Write([]byte(te.ID.String() + "\n"))
|
_, err = batch.WriteCheck([]byte(te.ID.String() + "\n"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug("error whilst reading size for %s in %s. Error: %v", te.ID.String(), te.ptree.repo.Path, err)
|
log.Debug("error whilst reading size for %s in %s. Error: %v", te.ID.String(), te.ptree.repo.Path, err)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
_, _, te.size, err = ReadBatchLine(rd)
|
_, _, te.size, err = ReadBatchLine(batch.CheckReader())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug("error whilst reading size for %s in %s. Error: %v", te.ID.String(), te.ptree.repo.Path, err)
|
log.Debug("error whilst reading size for %s in %s. Error: %v", te.ID.String(), te.ptree.repo.Path, err)
|
||||||
return 0
|
return 0
|
||||||
|
@ -35,13 +35,15 @@ func (t *Tree) ListEntries() (Entries, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if t.repo != nil {
|
if t.repo != nil {
|
||||||
wr, rd, cancel, err := t.repo.CatFileBatch(t.repo.Ctx)
|
batch, cancel, err := t.repo.CatFileBatch(t.repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
_, _ = wr.Write([]byte(t.ID.String() + "\n"))
|
rd := batch.Reader()
|
||||||
|
|
||||||
|
_, _ = batch.Write([]byte(t.ID.String() + "\n"))
|
||||||
_, typ, sz, err := ReadBatchLine(rd)
|
_, typ, sz, err := ReadBatchLine(rd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -51,7 +53,7 @@ func (t *Tree) ListEntries() (Entries, error) {
|
|||||||
if err != nil && err != io.EOF {
|
if err != nil && err != io.EOF {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
_, _ = wr.Write([]byte(treeID + "\n"))
|
_, _ = batch.Write([]byte(treeID + "\n"))
|
||||||
_, typ, sz, err = ReadBatchLine(rd)
|
_, typ, sz, err = ReadBatchLine(rd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package bleve
|
package bleve
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@ -150,7 +149,7 @@ func NewIndexer(indexDir string) *Indexer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Indexer) addUpdate(ctx context.Context, batchWriter git.WriteCloserError, batchReader *bufio.Reader, commitSha string,
|
func (b *Indexer) addUpdate(ctx context.Context, gitBatch git.Batch, commitSha string,
|
||||||
update internal.FileUpdate, repo *repo_model.Repository, batch *inner_bleve.FlushingBatch,
|
update internal.FileUpdate, repo *repo_model.Repository, batch *inner_bleve.FlushingBatch,
|
||||||
) error {
|
) error {
|
||||||
// Ignore vendored files in code search
|
// Ignore vendored files in code search
|
||||||
@ -176,10 +175,12 @@ func (b *Indexer) addUpdate(ctx context.Context, batchWriter git.WriteCloserErro
|
|||||||
return b.addDelete(update.Filename, repo, batch)
|
return b.addDelete(update.Filename, repo, batch)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := batchWriter.Write([]byte(update.BlobSha + "\n")); err != nil {
|
if _, err := gitBatch.Write([]byte(update.BlobSha + "\n")); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
batchReader := gitBatch.Reader()
|
||||||
|
|
||||||
_, _, size, err = git.ReadBatchLine(batchReader)
|
_, _, size, err = git.ReadBatchLine(batchReader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -224,7 +225,7 @@ func (b *Indexer) Index(ctx context.Context, repo *repo_model.Repository, sha st
|
|||||||
defer gitBatch.Close()
|
defer gitBatch.Close()
|
||||||
|
|
||||||
for _, update := range changes.Updates {
|
for _, update := range changes.Updates {
|
||||||
if err := b.addUpdate(ctx, gitBatch.Writer, gitBatch.Reader, sha, update, repo, batch); err != nil {
|
if err := b.addUpdate(ctx, gitBatch, sha, update, repo, batch); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package elasticsearch
|
package elasticsearch
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@ -138,7 +137,7 @@ const (
|
|||||||
}`
|
}`
|
||||||
)
|
)
|
||||||
|
|
||||||
func (b *Indexer) addUpdate(ctx context.Context, batchWriter git.WriteCloserError, batchReader *bufio.Reader, sha string, update internal.FileUpdate, repo *repo_model.Repository) ([]elastic.BulkableRequest, error) {
|
func (b *Indexer) addUpdate(ctx context.Context, batch git.Batch, sha string, update internal.FileUpdate, repo *repo_model.Repository) ([]elastic.BulkableRequest, error) {
|
||||||
// Ignore vendored files in code search
|
// Ignore vendored files in code search
|
||||||
if setting.Indexer.ExcludeVendored && analyze.IsVendor(update.Filename) {
|
if setting.Indexer.ExcludeVendored && analyze.IsVendor(update.Filename) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@ -161,10 +160,12 @@ func (b *Indexer) addUpdate(ctx context.Context, batchWriter git.WriteCloserErro
|
|||||||
return []elastic.BulkableRequest{b.addDelete(update.Filename, repo)}, nil
|
return []elastic.BulkableRequest{b.addDelete(update.Filename, repo)}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := batchWriter.Write([]byte(update.BlobSha + "\n")); err != nil {
|
if _, err := batch.Write([]byte(update.BlobSha + "\n")); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
batchReader := batch.Reader()
|
||||||
|
|
||||||
_, _, size, err = git.ReadBatchLine(batchReader)
|
_, _, size, err = git.ReadBatchLine(batchReader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -216,7 +217,7 @@ func (b *Indexer) Index(ctx context.Context, repo *repo_model.Repository, sha st
|
|||||||
defer batch.Close()
|
defer batch.Close()
|
||||||
|
|
||||||
for _, update := range changes.Updates {
|
for _, update := range changes.Updates {
|
||||||
updateReqs, err := b.addUpdate(ctx, batch.Writer, batch.Reader, sha, update, repo)
|
updateReqs, err := b.addUpdate(ctx, batch, sha, update, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"include": [
|
"include": [
|
||||||
"${configDir}/.*",
|
|
||||||
"${configDir}/*",
|
"${configDir}/*",
|
||||||
|
"${configDir}/.*",
|
||||||
"${configDir}/tests/e2e/**/*",
|
"${configDir}/tests/e2e/**/*",
|
||||||
"${configDir}/tests/e2e/**/.*",
|
"${configDir}/tests/e2e/**/.*",
|
||||||
"${configDir}/tools/**/*",
|
"${configDir}/tools/**/*",
|
||||||
@ -17,27 +17,31 @@
|
|||||||
"allowImportingTsExtensions": true,
|
"allowImportingTsExtensions": true,
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"allowUnreachableCode": false,
|
||||||
|
"allowUnusedLabels": false,
|
||||||
"alwaysStrict": true,
|
"alwaysStrict": true,
|
||||||
"erasableSyntaxOnly": true,
|
"erasableSyntaxOnly": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
|
"exactOptionalPropertyTypes": false,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"libReplacement": false,
|
"libReplacement": false,
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noImplicitThis": true,
|
||||||
|
"noPropertyAccessFromIndexSignature": false,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"verbatimModuleSyntax": true,
|
"sourceMap": true,
|
||||||
"stripInternal": true,
|
|
||||||
"strict": false,
|
"strict": false,
|
||||||
"strictBindCallApply": true,
|
"strictBindCallApply": true,
|
||||||
"strictBuiltinIteratorReturn": true,
|
"strictBuiltinIteratorReturn": true,
|
||||||
"strictFunctionTypes": true,
|
"strictFunctionTypes": true,
|
||||||
"noImplicitAny": true,
|
"stripInternal": true,
|
||||||
"noImplicitThis": true,
|
"verbatimModuleSyntax": true,
|
||||||
"noUnusedLocals": true,
|
|
||||||
"noUnusedParameters": true,
|
|
||||||
"noPropertyAccessFromIndexSignature": false,
|
|
||||||
"exactOptionalPropertyTypes": false,
|
|
||||||
"sourceMap": true,
|
|
||||||
"types": [
|
"types": [
|
||||||
"vitest/globals",
|
"vitest/globals",
|
||||||
"./web_src/js/globals.d.ts",
|
"./web_src/js/globals.d.ts",
|
||||||
|
@ -10,7 +10,7 @@ export function initTableSort() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function tableSort(normSort: string, revSort: string, isDefault: string) {
|
function tableSort(normSort: string, revSort: string, isDefault: string) {
|
||||||
if (!normSort) return false;
|
if (!normSort) return;
|
||||||
if (!revSort) revSort = '';
|
if (!revSort) revSort = '';
|
||||||
|
|
||||||
const url = new URL(window.location.href);
|
const url = new URL(window.location.href);
|
||||||
|
@ -43,7 +43,7 @@ type ToastOpts = {
|
|||||||
type ToastifyElement = HTMLElement & {_giteaToastifyInstance?: Toast};
|
type ToastifyElement = HTMLElement & {_giteaToastifyInstance?: Toast};
|
||||||
|
|
||||||
/** See https://github.com/apvarun/toastify-js#api for options */
|
/** See https://github.com/apvarun/toastify-js#api for options */
|
||||||
function showToast(message: string, level: Intent, {gravity, position, duration, useHtmlBody, preventDuplicates = true, ...other}: ToastOpts = {}): Toast {
|
function showToast(message: string, level: Intent, {gravity, position, duration, useHtmlBody, preventDuplicates = true, ...other}: ToastOpts = {}): Toast | null {
|
||||||
const body = useHtmlBody ? message : htmlEscape(message);
|
const body = useHtmlBody ? message : htmlEscape(message);
|
||||||
const parent = document.querySelector('.ui.dimmer.active') ?? document.body;
|
const parent = document.querySelector('.ui.dimmer.active') ?? document.body;
|
||||||
const duplicateKey = preventDuplicates ? (preventDuplicates === true ? `${level}-${body}` : preventDuplicates) : '';
|
const duplicateKey = preventDuplicates ? (preventDuplicates === true ? `${level}-${body}` : preventDuplicates) : '';
|
||||||
@ -56,7 +56,7 @@ function showToast(message: string, level: Intent, {gravity, position, duration,
|
|||||||
showElem(toastDupNumEl);
|
showElem(toastDupNumEl);
|
||||||
toastDupNumEl.textContent = String(Number(toastDupNumEl.textContent) + 1);
|
toastDupNumEl.textContent = String(Number(toastDupNumEl.textContent) + 1);
|
||||||
animateOnce(toastDupNumEl, 'pulse-1p5-200');
|
animateOnce(toastDupNumEl, 'pulse-1p5-200');
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,15 +83,15 @@ function showToast(message: string, level: Intent, {gravity, position, duration,
|
|||||||
return toast;
|
return toast;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function showInfoToast(message: string, opts?: ToastOpts): Toast {
|
export function showInfoToast(message: string, opts?: ToastOpts): Toast | null {
|
||||||
return showToast(message, 'info', opts);
|
return showToast(message, 'info', opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function showWarningToast(message: string, opts?: ToastOpts): Toast {
|
export function showWarningToast(message: string, opts?: ToastOpts): Toast | null {
|
||||||
return showToast(message, 'warning', opts);
|
return showToast(message, 'warning', opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function showErrorToast(message: string, opts?: ToastOpts): Toast {
|
export function showErrorToast(message: string, opts?: ToastOpts): Toast | null {
|
||||||
return showToast(message, 'error', opts);
|
return showToast(message, 'error', opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user