Skip to content

Commit 0579c7b

Browse files
committed
Merge remote-tracking branch 'giteaoffical/main'
* giteaoffical/main: Place inline diff comment dialogs on split diff in 4th and 8th columns (go-gitea#18403) API: Return primary language and repository language stats API URL (go-gitea#18396) Update to work with latest VS Code go debugger (go-gitea#18397) Fix restore without topic failure (go-gitea#18387) [skip ci] Updated translations via Crowdin Make WrappedQueues and PersistableChannelUniqueQueues Pausable (go-gitea#18393) Fix commit's time (go-gitea#18375) Prevent showing webauthn error for every time visiting `/user/settings/security` (go-gitea#18385)
2 parents ab961b4 + 93250bf commit 0579c7b

File tree

24 files changed

+155
-28
lines changed

24 files changed

+155
-28
lines changed

contrib/ide/vscode/launch.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
"request": "launch",
88
"mode": "debug",
99
"buildFlags": "",
10-
"port": 2345,
11-
"host": "127.0.0.1",
1210
"program": "${workspaceRoot}/main.go",
13-
"env": {},
11+
"env": {
12+
"GITEA_WORK_DIR": "${workspaceRoot}",
13+
},
1414
"args": ["web"],
1515
"showLog": true
1616
},
@@ -20,10 +20,10 @@
2020
"request": "launch",
2121
"mode": "debug",
2222
"buildFlags": "-tags='sqlite sqlite_unlock_notify'",
23-
"port": 2345,
24-
"host": "127.0.0.1",
2523
"program": "${workspaceRoot}/main.go",
26-
"env": {},
24+
"env": {
25+
"GITEA_WORK_DIR": "${workspaceRoot}",
26+
},
2727
"args": ["web"],
2828
"showLog": true
2929
}

models/repo/repo.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,30 @@ func (repo *Repository) MustOwner() *user_model.User {
222222
return repo.mustOwner(db.DefaultContext)
223223
}
224224

225+
// LoadAttributes loads attributes of the repository.
226+
func (repo *Repository) LoadAttributes(ctx context.Context) error {
227+
// Load owner
228+
if err := repo.GetOwner(ctx); err != nil {
229+
return fmt.Errorf("load owner: %w", err)
230+
}
231+
232+
// Load primary language
233+
stats := make(LanguageStatList, 0, 1)
234+
if err := db.GetEngine(ctx).
235+
Where("`repo_id` = ? AND `is_primary` = ? AND `language` != ?", repo.ID, true, "other").
236+
Find(&stats); err != nil {
237+
return fmt.Errorf("find primary languages: %w", err)
238+
}
239+
stats.LoadAttributes()
240+
for _, st := range stats {
241+
if st.RepoID == repo.ID {
242+
repo.PrimaryLanguage = st
243+
break
244+
}
245+
}
246+
return nil
247+
}
248+
225249
// FullName returns the repository full name
226250
func (repo *Repository) FullName() string {
227251
return repo.OwnerName + "/" + repo.Name

models/repo_list.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ func FindUserAccessibleRepoIDs(user *user_model.User) ([]int64, error) {
623623
}
624624

625625
// GetUserRepositories returns a list of repositories of given user.
626-
func GetUserRepositories(opts *SearchRepoOptions) ([]*repo_model.Repository, int64, error) {
626+
func GetUserRepositories(opts *SearchRepoOptions) (RepositoryList, int64, error) {
627627
if len(opts.OrderBy) == 0 {
628628
opts.OrderBy = "updated_unix DESC"
629629
}
@@ -646,6 +646,6 @@ func GetUserRepositories(opts *SearchRepoOptions) ([]*repo_model.Repository, int
646646
}
647647

648648
sess = sess.Where(cond).OrderBy(opts.OrderBy.String())
649-
repos := make([]*repo_model.Repository, 0, opts.PageSize)
649+
repos := make(RepositoryList, 0, opts.PageSize)
650650
return repos, count, db.SetSessionPagination(sess, opts).Find(&repos)
651651
}

modules/convert/repository.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,13 @@ func innerToRepo(repo *repo_model.Repository, mode perm.AccessMode, isParent boo
125125
}
126126
}
127127

128+
var language string
129+
if repo.PrimaryLanguage != nil {
130+
language = repo.PrimaryLanguage.Language
131+
}
132+
133+
repoAPIURL := repo.APIURL()
134+
128135
return &api.Repository{
129136
ID: repo.ID,
130137
Owner: ToUserWithAccessMode(repo.Owner, mode),
@@ -144,6 +151,8 @@ func innerToRepo(repo *repo_model.Repository, mode perm.AccessMode, isParent boo
144151
CloneURL: cloneLink.HTTPS,
145152
OriginalURL: repo.SanitizedOriginalURL(),
146153
Website: repo.Website,
154+
Language: language,
155+
LanguagesURL: repoAPIURL + "/languages",
147156
Stars: repo.NumStars,
148157
Forks: repo.NumForks,
149158
Watchers: repo.NumWatches,

modules/queue/queue.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ func RegisteredTypesAsString() []string {
196196
func NewQueue(queueType Type, handlerFunc HandlerFunc, opts, exemplar interface{}) (Queue, error) {
197197
newFn, ok := queuesMap[queueType]
198198
if !ok {
199-
return nil, fmt.Errorf("Unsupported queue type: %v", queueType)
199+
return nil, fmt.Errorf("unsupported queue type: %v", queueType)
200200
}
201201
return newFn(handlerFunc, opts, exemplar)
202202
}

modules/queue/queue_bytefifo.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ func (q *ByteFIFOQueue) Push(data Data) error {
9292
// PushBack pushes data to the fifo
9393
func (q *ByteFIFOQueue) PushBack(data Data) error {
9494
if !assignableTo(data, q.exemplar) {
95-
return fmt.Errorf("Unable to assign data: %v to same type as exemplar: %v in %s", data, q.exemplar, q.name)
95+
return fmt.Errorf("unable to assign data: %v to same type as exemplar: %v in %s", data, q.exemplar, q.name)
9696
}
9797
bs, err := json.Marshal(data)
9898
if err != nil {
@@ -110,7 +110,7 @@ func (q *ByteFIFOQueue) PushBack(data Data) error {
110110
// PushFunc pushes data to the fifo
111111
func (q *ByteFIFOQueue) PushFunc(data Data, fn func() error) error {
112112
if !assignableTo(data, q.exemplar) {
113-
return fmt.Errorf("Unable to assign data: %v to same type as exemplar: %v in %s", data, q.exemplar, q.name)
113+
return fmt.Errorf("unable to assign data: %v to same type as exemplar: %v in %s", data, q.exemplar, q.name)
114114
}
115115
bs, err := json.Marshal(data)
116116
if err != nil {
@@ -398,7 +398,7 @@ func NewByteFIFOUniqueQueue(typ Type, byteFIFO UniqueByteFIFO, handle HandlerFun
398398
// Has checks if the provided data is in the queue
399399
func (q *ByteFIFOUniqueQueue) Has(data Data) (bool, error) {
400400
if !assignableTo(data, q.exemplar) {
401-
return false, fmt.Errorf("Unable to assign data: %v to same type as exemplar: %v in %s", data, q.exemplar, q.name)
401+
return false, fmt.Errorf("unable to assign data: %v to same type as exemplar: %v in %s", data, q.exemplar, q.name)
402402
}
403403
bs, err := json.Marshal(data)
404404
if err != nil {

modules/queue/queue_channel.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func (q *ChannelQueue) Run(atShutdown, atTerminate func(func())) {
9393
// Push will push data into the queue
9494
func (q *ChannelQueue) Push(data Data) error {
9595
if !assignableTo(data, q.exemplar) {
96-
return fmt.Errorf("Unable to assign data: %v to same type as exemplar: %v in queue: %s", data, q.exemplar, q.name)
96+
return fmt.Errorf("unable to assign data: %v to same type as exemplar: %v in queue: %s", data, q.exemplar, q.name)
9797
}
9898
q.WorkerPool.Push(data)
9999
return nil

modules/queue/queue_wrapped.go

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func (q *delayedStarter) setInternal(atShutdown func(func()), handle HandlerFunc
5959
if s, ok := cfg.([]byte); ok {
6060
cfg = string(s)
6161
}
62-
return fmt.Errorf("Timedout creating queue %v with cfg %#v in %s", q.underlying, cfg, q.name)
62+
return fmt.Errorf("timedout creating queue %v with cfg %#v in %s", q.underlying, cfg, q.name)
6363
default:
6464
queue, err := NewQueue(q.underlying, handle, q.cfg, exemplar)
6565
if err == nil {
@@ -76,9 +76,9 @@ func (q *delayedStarter) setInternal(atShutdown func(func()), handle HandlerFunc
7676
i++
7777
if q.maxAttempts > 0 && i > q.maxAttempts {
7878
if bs, ok := q.cfg.([]byte); ok {
79-
return fmt.Errorf("Unable to create queue %v for %s with cfg %s by max attempts: error: %v", q.underlying, q.name, string(bs), err)
79+
return fmt.Errorf("unable to create queue %v for %s with cfg %s by max attempts: error: %v", q.underlying, q.name, string(bs), err)
8080
}
81-
return fmt.Errorf("Unable to create queue %v for %s with cfg %#v by max attempts: error: %v", q.underlying, q.name, q.cfg, err)
81+
return fmt.Errorf("unable to create queue %v for %s with cfg %#v by max attempts: error: %v", q.underlying, q.name, q.cfg, err)
8282
}
8383
sleepTime := 100 * time.Millisecond
8484
if q.timeout > 0 && q.maxAttempts > 0 {
@@ -271,6 +271,46 @@ func (q *WrappedQueue) Terminate() {
271271
log.Debug("WrappedQueue: %s Terminated", q.name)
272272
}
273273

274+
// IsPaused will return if the pool or queue is paused
275+
func (q *WrappedQueue) IsPaused() bool {
276+
q.lock.Lock()
277+
defer q.lock.Unlock()
278+
pausable, ok := q.internal.(Pausable)
279+
return ok && pausable.IsPaused()
280+
}
281+
282+
// Pause will pause the pool or queue
283+
func (q *WrappedQueue) Pause() {
284+
q.lock.Lock()
285+
defer q.lock.Unlock()
286+
if pausable, ok := q.internal.(Pausable); ok {
287+
pausable.Pause()
288+
}
289+
}
290+
291+
// Resume will resume the pool or queue
292+
func (q *WrappedQueue) Resume() {
293+
q.lock.Lock()
294+
defer q.lock.Unlock()
295+
if pausable, ok := q.internal.(Pausable); ok {
296+
pausable.Resume()
297+
}
298+
}
299+
300+
// IsPausedIsResumed will return a bool indicating if the pool or queue is paused and a channel that will be closed when it is resumed
301+
func (q *WrappedQueue) IsPausedIsResumed() (paused, resumed <-chan struct{}) {
302+
q.lock.Lock()
303+
defer q.lock.Unlock()
304+
if pausable, ok := q.internal.(Pausable); ok {
305+
return pausable.IsPausedIsResumed()
306+
}
307+
return context.Background().Done(), closedChan
308+
}
309+
310+
var closedChan chan struct{}
311+
274312
func init() {
275313
queuesMap[WrappedQueueType] = NewWrappedQueue
314+
closedChan = make(chan struct{})
315+
close(closedChan)
276316
}

modules/queue/setting.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func validType(t string) (Type, error) {
2222
return typ, nil
2323
}
2424
}
25-
return PersistableChannelQueueType, fmt.Errorf("Unknown queue type: %s defaulting to %s", t, string(PersistableChannelQueueType))
25+
return PersistableChannelQueueType, fmt.Errorf("unknown queue type: %s defaulting to %s", t, string(PersistableChannelQueueType))
2626
}
2727

2828
func getQueueSettings(name string) (setting.QueueSettings, []byte) {

modules/queue/unique_queue_channel.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ func (q *ChannelUniqueQueue) Push(data Data) error {
111111
// PushFunc will push data into the queue
112112
func (q *ChannelUniqueQueue) PushFunc(data Data, fn func() error) error {
113113
if !assignableTo(data, q.exemplar) {
114-
return fmt.Errorf("Unable to assign data: %v to same type as exemplar: %v in queue: %s", data, q.exemplar, q.name)
114+
return fmt.Errorf("unable to assign data: %v to same type as exemplar: %v in queue: %s", data, q.exemplar, q.name)
115115
}
116116

117117
bs, err := json.Marshal(data)

modules/queue/unique_queue_disk_channel.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,26 @@ func (q *PersistableChannelUniqueQueue) IsEmpty() bool {
239239
return q.channelQueue.IsEmpty()
240240
}
241241

242+
// IsPaused will return if the pool or queue is paused
243+
func (q *PersistableChannelUniqueQueue) IsPaused() bool {
244+
return q.channelQueue.IsPaused()
245+
}
246+
247+
// Pause will pause the pool or queue
248+
func (q *PersistableChannelUniqueQueue) Pause() {
249+
q.channelQueue.Pause()
250+
}
251+
252+
// Resume will resume the pool or queue
253+
func (q *PersistableChannelUniqueQueue) Resume() {
254+
q.channelQueue.Resume()
255+
}
256+
257+
// IsPausedIsResumed will return a bool indicating if the pool or queue is paused and a channel that will be closed when it is resumed
258+
func (q *PersistableChannelUniqueQueue) IsPausedIsResumed() (paused, resumed <-chan struct{}) {
259+
return q.channelQueue.IsPausedIsResumed()
260+
}
261+
242262
// Shutdown processing this queue
243263
func (q *PersistableChannelUniqueQueue) Shutdown() {
244264
log.Trace("PersistableChannelUniqueQueue: %s Shutting down", q.delayedStarter.name)

modules/queue/unique_queue_wrapped.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ func (q *WrappedUniqueQueue) Push(data Data) error {
105105
// PushFunc will push the data to the internal channel checking it against the exemplar
106106
func (q *WrappedUniqueQueue) PushFunc(data Data, fn func() error) error {
107107
if !assignableTo(data, q.exemplar) {
108-
return fmt.Errorf("Unable to assign data: %v to same type as exemplar: %v in %s", data, q.exemplar, q.name)
108+
return fmt.Errorf("unable to assign data: %v to same type as exemplar: %v in %s", data, q.exemplar, q.name)
109109
}
110110

111111
q.tlock.Lock()

modules/queue/workerpool.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,12 @@ func NewWorkerPool(handle HandlerFunc, config WorkerPoolConfiguration) *WorkerPo
5757
ctx, cancel := context.WithCancel(context.Background())
5858

5959
dataChan := make(chan Data, config.QueueLength)
60-
resumed := make(chan struct{})
61-
close(resumed)
6260
pool := &WorkerPool{
6361
baseCtx: ctx,
6462
baseCtxCancel: cancel,
6563
batchLength: config.BatchLength,
6664
dataChan: dataChan,
67-
resumed: resumed,
65+
resumed: closedChan,
6866
paused: make(chan struct{}),
6967
handle: handle,
7068
blockTimeout: config.BlockTimeout,

modules/structs/repo.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ type Repository struct {
5959
Parent *Repository `json:"parent"`
6060
Mirror bool `json:"mirror"`
6161
Size int `json:"size"`
62+
Language string `json:"language"`
63+
LanguagesURL string `json:"languages_url"`
6264
HTMLURL string `json:"html_url"`
6365
SSHURL string `json:"ssh_url"`
6466
CloneURL string `json:"clone_url"`

options/locale/locale_pt-PT.ini

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1931,6 +1931,10 @@ settings.add_matrix_hook_desc=Integrar <a href="%s">Matrix</a> no seu repositór
19311931
settings.add_msteams_hook_desc=Integrar <a href="%s">Microsoft Teams</a> no seu repositório.
19321932
settings.add_feishu_hook_desc=Integrar <a href="%s">Feishu</a> no seu repositório.
19331933
settings.add_Wechat_hook_desc=Integrar <a href="%s">Wechatwork</a> no seu repositório.
1934+
settings.add_packagist_hook_desc=Integrar <a href="%s">Packagist</a> no seu repositório.
1935+
settings.packagist_username=Nome de utilizador no Packagist
1936+
settings.packagist_api_token=Código da API
1937+
settings.packagist_package_url=URL do pacote Packagist
19341938
settings.deploy_keys=Chaves de instalação
19351939
settings.add_deploy_key=Adicionar chave de instalação
19361940
settings.deploy_key_desc=Chaves de instalação têm acesso para puxar do repositório apenas em modo de leitura.

options/locale/locale_zh-CN.ini

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1947,6 +1947,10 @@ settings.add_matrix_hook_desc=将 <a href="%s">Matrix</a> 集成到您的仓库
19471947
settings.add_msteams_hook_desc=将 <a href="%s">Microsoft Teams</a> 集成到您的仓库中。
19481948
settings.add_feishu_hook_desc=将 <a href="%s">Feishu</a> 集成到您的仓库中。
19491949
settings.add_Wechat_hook_desc=将 <a href="%s">企业微信</a> 集成到您的仓库中。
1950+
settings.add_packagist_hook_desc=将 <a href="%s">Packagist</a> 集成到您的仓库中。
1951+
settings.packagist_username=Packagist 用户名
1952+
settings.packagist_api_token=API 令牌
1953+
settings.packagist_package_url=Packagist 软件包 URL
19501954
settings.deploy_keys=部署密钥
19511955
settings.add_deploy_key=添加部署密钥
19521956
settings.deploy_key_desc=部署密钥具有对仓库的只读拉取权限。

routers/api/v1/repo/repo.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,11 @@ func Get(ctx *context.APIContext) {
533533
// "200":
534534
// "$ref": "#/responses/Repository"
535535

536+
if err := ctx.Repo.Repository.LoadAttributes(ctx); err != nil {
537+
ctx.Error(http.StatusInternalServerError, "Repository.LoadAttributes", err)
538+
return
539+
}
540+
536541
ctx.JSON(http.StatusOK, convert.ToRepo(ctx.Repo.Repository, ctx.Repo.AccessMode))
537542
}
538543

routers/api/v1/user/repo.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ func listUserRepos(ctx *context.APIContext, u *user_model.User, private bool) {
3232
return
3333
}
3434

35+
if err := repos.LoadAttributes(); err != nil {
36+
ctx.Error(http.StatusInternalServerError, "RepositoryList.LoadAttributes", err)
37+
return
38+
}
39+
3540
apiRepos := make([]*api.Repository, 0, len(repos))
3641
for i := range repos {
3742
access, err := models.AccessLevel(ctx.User, repos[i])

services/migrations/restore.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ func (r *RepositoryRestorer) GetTopics() ([]string, error) {
9797

9898
bs, err := os.ReadFile(p)
9999
if err != nil {
100+
if os.IsNotExist(err) {
101+
return nil, nil
102+
}
100103
return nil, err
101104
}
102105

templates/repo/commits_list.tmpl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,11 @@
7575
<pre class="commit-body" style="display: none;">{{RenderCommitBody $.Context .Message $commitRepoLink $.Repository.ComposeMetas}}</pre>
7676
{{end}}
7777
</td>
78-
<td class="text right aligned">{{TimeSince .Author.When $.Lang}}</td>
78+
{{if .Committer}}
79+
<td class="text right aligned">{{TimeSince .Committer.When $.Lang}}</td>
80+
{{else}}
81+
<td class="text right aligned">{{TimeSince .Author.When $.Lang}}</td>
82+
{{end}}
7983
</tr>
8084
{{end}}
8185
</tbody>

templates/repo/view_list.tmpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
</span>
3535
{{end}}
3636
</th>
37-
<th class="text grey right age">{{if .LatestCommit}}{{if .LatestCommit.Author}}{{TimeSince .LatestCommit.Author.When $.Lang}}{{end}}{{end}}</th>
37+
<th class="text grey right age">{{if .LatestCommit}}{{if .LatestCommit.Committer}}{{TimeSince .LatestCommit.Committer.When $.Lang}}{{end}}{{end}}</th>
3838
</tr>
3939
</thead>
4040
<tbody>

templates/swagger/v1_json.tmpl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17188,6 +17188,14 @@
1718817188
"internal_tracker": {
1718917189
"$ref": "#/definitions/InternalTracker"
1719017190
},
17191+
"language": {
17192+
"type": "string",
17193+
"x-go-name": "Language"
17194+
},
17195+
"languages_url": {
17196+
"type": "string",
17197+
"x-go-name": "LanguagesURL"
17198+
},
1719117199
"mirror": {
1719217200
"type": "boolean",
1719317201
"x-go-name": "Mirror"

web_src/js/features/repo-issue.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,9 +496,11 @@ export function initRepoPullRequestReview() {
496496
<tr class="add-comment" data-line-type="${lineType}">
497497
${isSplit ? `
498498
<td class="lines-num"></td>
499+
<td class="lines-escape"></td>
499500
<td class="lines-type-marker"></td>
500501
<td class="add-comment-left"></td>
501502
<td class="lines-num"></td>
503+
<td class="lines-escape"></td>
502504
<td class="lines-type-marker"></td>
503505
<td class="add-comment-right"></td>
504506
` : `

0 commit comments

Comments
 (0)