mirror of
https://github.com/go-gitea/gitea.git
synced 2025-11-13 02:02:53 +09:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9879e23c57 | ||
|
|
56a3b50136 | ||
|
|
9a8532d928 | ||
|
|
d29a0fc3be | ||
|
|
04517e17d6 | ||
|
|
3a222ee416 | ||
|
|
add85f5a85 | ||
|
|
76ad83f05e | ||
|
|
714ecd9f1e | ||
|
|
a08856606e | ||
|
|
7be2d7b136 | ||
|
|
6f3596e33c | ||
|
|
0305a73633 | ||
|
|
6cd1ccef3d | ||
|
|
ea0fe83888 | ||
|
|
1cec7f5ab5 | ||
|
|
1cb1101d44 | ||
|
|
653dff4e57 | ||
|
|
b661bbaed7 | ||
|
|
20ae184967 | ||
|
|
15b44496ec | ||
|
|
0d0ff5e32a | ||
|
|
f25f7c592f | ||
|
|
e8cf04bad7 | ||
|
|
251fdaaf41 | ||
|
|
f572fb906f | ||
|
|
9340269d84 | ||
|
|
34650b925b | ||
|
|
718e0db12e | ||
|
|
6110ddc280 |
@@ -9,7 +9,6 @@ linters:
|
|||||||
- unused
|
- unused
|
||||||
- structcheck
|
- structcheck
|
||||||
- varcheck
|
- varcheck
|
||||||
- golint
|
|
||||||
- dupl
|
- dupl
|
||||||
#- gocyclo # The cyclomatic complexety of a lot of functions is too high, we should refactor those another time.
|
#- gocyclo # The cyclomatic complexety of a lot of functions is too high, we should refactor those another time.
|
||||||
- gofmt
|
- gofmt
|
||||||
|
|||||||
31
CHANGELOG.md
31
CHANGELOG.md
@@ -4,6 +4,37 @@ This changelog goes through all the changes that have been made in each release
|
|||||||
without substantial changes to our git log; to see the highlights of what has
|
without substantial changes to our git log; to see the highlights of what has
|
||||||
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||||
|
|
||||||
|
## [1.15.7](https://github.com/go-gitea/gitea/releases/tag/v1.15.7) - 2021-12-01
|
||||||
|
|
||||||
|
* ENHANCEMENTS
|
||||||
|
* Only allow webhook to send requests to allowed hosts (#17482) (#17510)
|
||||||
|
* Fix login redirection links (#17451) (#17473)
|
||||||
|
* BUGFIXES
|
||||||
|
* Fix database inconsistent when admin change user email (#17549) (#17840)
|
||||||
|
* Use correct user on releases (#17806) (#17818)
|
||||||
|
* Fix commit count in tag view (#17698) (#17790)
|
||||||
|
* Fix close issue but time watcher still running (#17643) (#17761)
|
||||||
|
* Fix Migrate Description (#17692) (#17727)
|
||||||
|
* Fix bug when project board get open issue number (#17703) (#17726)
|
||||||
|
* Return 400 but not 500 when request archive with wrong format (#17691) (#17700)
|
||||||
|
* Fix bug when read mysql database max lifetime (#17682) (#17690)
|
||||||
|
* Fix database deadlock when update issue labels (#17649) (#17665)
|
||||||
|
* Fix bug on detect issue/comment writer (#17592)
|
||||||
|
* Remove appSubUrl from pasted images (#17572) (#17588)
|
||||||
|
* Make `ParsePatch` more robust (#17573) (#17580)
|
||||||
|
* Fix stats upon searching issues (#17566) (#17578)
|
||||||
|
* Escape issue titles in comments list (#17555) (#17556)
|
||||||
|
* Fix zero created time bug on commit api (#17546) (#17547)
|
||||||
|
* Fix database keyword quote problem on migration v161 (#17522) (#17523)
|
||||||
|
* Fix email with + when active (#17518) (#17520)
|
||||||
|
* Stop double encoding blame commit messages (#17498) (#17500)
|
||||||
|
* Quote the table name in CountOrphanedObjects (#17487) (#17488)
|
||||||
|
* Run Migrate in Install rather than just SyncTables (#17475) (#17486)
|
||||||
|
* BUILD
|
||||||
|
* Fix golangci-lint warnings (#17598 et al) (#17668)
|
||||||
|
* MISC
|
||||||
|
* Preserve color when inverting emojis (#17797) (#17799)
|
||||||
|
|
||||||
## [1.15.6](https://github.com/go-gitea/gitea/releases/tag/v1.15.6) - 2021-10-28
|
## [1.15.6](https://github.com/go-gitea/gitea/releases/tag/v1.15.6) - 2021-10-28
|
||||||
|
|
||||||
* BUGFIXES
|
* BUGFIXES
|
||||||
|
|||||||
3
build.go
3
build.go
@@ -2,7 +2,8 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//+build vendor
|
//go:build vendor
|
||||||
|
// +build vendor
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build ignore
|
||||||
// +build ignore
|
// +build ignore
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build ignore
|
||||||
// +build ignore
|
// +build ignore
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
//go:build ignore
|
||||||
// +build ignore
|
// +build ignore
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
//go:build ignore
|
||||||
// +build ignore
|
// +build ignore
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
// gocovmerge takes the results from multiple `go test -coverprofile` runs and
|
// gocovmerge takes the results from multiple `go test -coverprofile` runs and
|
||||||
// merges them into one profile
|
// merges them into one profile
|
||||||
|
|
||||||
|
//go:build ignore
|
||||||
// +build ignore
|
// +build ignore
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -43,7 +43,11 @@ func runDocs(ctx *cli.Context) error {
|
|||||||
// Clean up markdown. The following bug was fixed in v2, but is present in v1.
|
// Clean up markdown. The following bug was fixed in v2, but is present in v1.
|
||||||
// It affects markdown output (even though the issue is referring to man pages)
|
// It affects markdown output (even though the issue is referring to man pages)
|
||||||
// https://github.com/urfave/cli/issues/1040
|
// https://github.com/urfave/cli/issues/1040
|
||||||
docs = docs[strings.Index(docs, "#"):]
|
firstHashtagIndex := strings.Index(docs, "#")
|
||||||
|
|
||||||
|
if firstHashtagIndex > 0 {
|
||||||
|
docs = docs[firstHashtagIndex:]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out := os.Stdout
|
out := os.Stdout
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build bindata
|
||||||
// +build bindata
|
// +build bindata
|
||||||
|
|
||||||
package cmd
|
package cmd
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !bindata
|
||||||
// +build !bindata
|
// +build !bindata
|
||||||
|
|
||||||
package cmd
|
package cmd
|
||||||
|
|||||||
@@ -194,6 +194,10 @@ func listen(m http.Handler, handleRedirector bool) error {
|
|||||||
listenAddr = net.JoinHostPort(listenAddr, setting.HTTPPort)
|
listenAddr = net.JoinHostPort(listenAddr, setting.HTTPPort)
|
||||||
}
|
}
|
||||||
log.Info("Listen: %v://%s%s", setting.Protocol, listenAddr, setting.AppSubURL)
|
log.Info("Listen: %v://%s%s", setting.Protocol, listenAddr, setting.AppSubURL)
|
||||||
|
// This can be useful for users, many users do wrong to their config and get strange behaviors behind a reverse-proxy.
|
||||||
|
// A user may fix the configuration mistake when he sees this log.
|
||||||
|
// And this is also very helpful to maintainers to provide help to users to resolve their configuration problems.
|
||||||
|
log.Info("AppURL(ROOT_URL): %s", setting.AppURL)
|
||||||
|
|
||||||
if setting.LFS.StartServer {
|
if setting.LFS.StartServer {
|
||||||
log.Info("LFS server enabled")
|
log.Info("LFS server enabled")
|
||||||
|
|||||||
@@ -1388,6 +1388,13 @@ PATH =
|
|||||||
;; Deliver timeout in seconds
|
;; Deliver timeout in seconds
|
||||||
;DELIVER_TIMEOUT = 5
|
;DELIVER_TIMEOUT = 5
|
||||||
;;
|
;;
|
||||||
|
;; Webhook can only call allowed hosts for security reasons. Comma separated list, eg: external, 192.168.1.0/24, *.mydomain.com
|
||||||
|
;; Built-in: loopback (for localhost), private (for LAN/intranet), external (for public hosts on internet), * (for all hosts)
|
||||||
|
;; CIDR list: 1.2.3.0/8, 2001:db8::/32
|
||||||
|
;; Wildcard hosts: *.mydomain.com, 192.168.100.*
|
||||||
|
;; Default to * for 1.15.x, external for 1.16 and later
|
||||||
|
;ALLOWED_HOST_LIST = *
|
||||||
|
;;
|
||||||
;; Allow insecure certification
|
;; Allow insecure certification
|
||||||
;SKIP_TLS_VERIFY = false
|
;SKIP_TLS_VERIFY = false
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -545,6 +545,14 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type
|
|||||||
|
|
||||||
- `QUEUE_LENGTH`: **1000**: Hook task queue length. Use caution when editing this value.
|
- `QUEUE_LENGTH`: **1000**: Hook task queue length. Use caution when editing this value.
|
||||||
- `DELIVER_TIMEOUT`: **5**: Delivery timeout (sec) for shooting webhooks.
|
- `DELIVER_TIMEOUT`: **5**: Delivery timeout (sec) for shooting webhooks.
|
||||||
|
- `ALLOWED_HOST_LIST`: `*`: Default to `*` for 1.15.x, `external` for 1.16 and later. Webhook can only call allowed hosts for security reasons. Comma separated list.
|
||||||
|
- Built-in networks:
|
||||||
|
- `loopback`: 127.0.0.0/8 for IPv4 and ::1/128 for IPv6, localhost is included.
|
||||||
|
- `private`: RFC 1918 (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) and RFC 4193 (FC00::/7). Also called LAN/Intranet.
|
||||||
|
- `external`: A valid non-private unicast IP, you can access all hosts on public internet.
|
||||||
|
- `*`: All hosts are allowed.
|
||||||
|
- CIDR list: `1.2.3.0/8` for IPv4 and `2001:db8::/32` for IPv6
|
||||||
|
- Wildcard hosts: `*.mydomain.com`, `192.168.100.*`
|
||||||
- `SKIP_TLS_VERIFY`: **false**: Allow insecure certification.
|
- `SKIP_TLS_VERIFY`: **false**: Allow insecure certification.
|
||||||
- `PAGING_NUM`: **10**: Number of webhook history events that are shown in one page.
|
- `PAGING_NUM`: **10**: Number of webhook history events that are shown in one page.
|
||||||
- `PROXY_URL`: ****: Proxy server URL, support http://, https//, socks://, blank will follow environment http_proxy/https_proxy
|
- `PROXY_URL`: ****: Proxy server URL, support http://, https//, socks://, blank will follow environment http_proxy/https_proxy
|
||||||
|
|||||||
44
integrations/api_repo_archive_test.go
Normal file
44
integrations/api_repo_archive_test.go
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package integrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/models"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAPIDownloadArchive(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
|
||||||
|
repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)
|
||||||
|
user2 := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)
|
||||||
|
session := loginUser(t, user2.LowerName)
|
||||||
|
token := getTokenForLoggedInUser(t, session)
|
||||||
|
|
||||||
|
link, _ := url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/archive/master.zip", user2.Name, repo.Name))
|
||||||
|
link.RawQuery = url.Values{"token": {token}}.Encode()
|
||||||
|
resp := MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK)
|
||||||
|
bs, err := io.ReadAll(resp.Body)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.EqualValues(t, 320, len(bs))
|
||||||
|
|
||||||
|
link, _ = url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/archive/master.tar.gz", user2.Name, repo.Name))
|
||||||
|
link.RawQuery = url.Values{"token": {token}}.Encode()
|
||||||
|
resp = MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK)
|
||||||
|
bs, err = io.ReadAll(resp.Body)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.EqualValues(t, 266, len(bs))
|
||||||
|
|
||||||
|
link, _ = url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/archive/master", user2.Name, repo.Name))
|
||||||
|
link.RawQuery = url.Values{"token": {token}}.Encode()
|
||||||
|
MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusBadRequest)
|
||||||
|
}
|
||||||
@@ -302,7 +302,7 @@ func DeleteOrphanedIssues() error {
|
|||||||
// CountOrphanedObjects count subjects with have no existing refobject anymore
|
// CountOrphanedObjects count subjects with have no existing refobject anymore
|
||||||
func CountOrphanedObjects(subject, refobject, joinCond string) (int64, error) {
|
func CountOrphanedObjects(subject, refobject, joinCond string) (int64, error) {
|
||||||
return x.Table("`"+subject+"`").
|
return x.Table("`"+subject+"`").
|
||||||
Join("LEFT", refobject, joinCond).
|
Join("LEFT", "`"+refobject+"`", joinCond).
|
||||||
Where(builder.IsNull{"`" + refobject + "`.id"}).
|
Where(builder.IsNull{"`" + refobject + "`.id"}).
|
||||||
Count("id")
|
Count("id")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1517,12 +1517,12 @@ func GetIssueStats(opts *IssueStatsOptions) (*IssueStats, error) {
|
|||||||
func getIssueStatsChunk(opts *IssueStatsOptions, issueIDs []int64) (*IssueStats, error) {
|
func getIssueStatsChunk(opts *IssueStatsOptions, issueIDs []int64) (*IssueStats, error) {
|
||||||
stats := &IssueStats{}
|
stats := &IssueStats{}
|
||||||
|
|
||||||
countSession := func(opts *IssueStatsOptions) *xorm.Session {
|
countSession := func(opts *IssueStatsOptions, issueIDs []int64) *xorm.Session {
|
||||||
sess := x.
|
sess := x.
|
||||||
Where("issue.repo_id = ?", opts.RepoID)
|
Where("issue.repo_id = ?", opts.RepoID)
|
||||||
|
|
||||||
if len(opts.IssueIDs) > 0 {
|
if len(issueIDs) > 0 {
|
||||||
sess.In("issue.id", opts.IssueIDs)
|
sess.In("issue.id", issueIDs)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(opts.Labels) > 0 && opts.Labels != "0" {
|
if len(opts.Labels) > 0 && opts.Labels != "0" {
|
||||||
@@ -1572,13 +1572,13 @@ func getIssueStatsChunk(opts *IssueStatsOptions, issueIDs []int64) (*IssueStats,
|
|||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
stats.OpenCount, err = countSession(opts).
|
stats.OpenCount, err = countSession(opts, issueIDs).
|
||||||
And("issue.is_closed = ?", false).
|
And("issue.is_closed = ?", false).
|
||||||
Count(new(Issue))
|
Count(new(Issue))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return stats, err
|
return stats, err
|
||||||
}
|
}
|
||||||
stats.ClosedCount, err = countSession(opts).
|
stats.ClosedCount, err = countSession(opts, issueIDs).
|
||||||
And("issue.is_closed = ?", true).
|
And("issue.is_closed = ?", true).
|
||||||
Count(new(Issue))
|
Count(new(Issue))
|
||||||
return stats, err
|
return stats, err
|
||||||
|
|||||||
@@ -13,6 +13,26 @@ import (
|
|||||||
"xorm.io/xorm"
|
"xorm.io/xorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ErrIssueStopwatchNotExist represents an error that stopwatch is not exist
|
||||||
|
type ErrIssueStopwatchNotExist struct {
|
||||||
|
UserID int64
|
||||||
|
IssueID int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err ErrIssueStopwatchNotExist) Error() string {
|
||||||
|
return fmt.Sprintf("issue stopwatch doesn't exist[uid: %d, issue_id: %d", err.UserID, err.IssueID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrIssueStopwatchAlreadyExist represents an error that stopwatch is already exist
|
||||||
|
type ErrIssueStopwatchAlreadyExist struct {
|
||||||
|
UserID int64
|
||||||
|
IssueID int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err ErrIssueStopwatchAlreadyExist) Error() string {
|
||||||
|
return fmt.Sprintf("issue stopwatch already exists[uid: %d, issue_id: %d", err.UserID, err.IssueID)
|
||||||
|
}
|
||||||
|
|
||||||
// Stopwatch represents a stopwatch for time tracking.
|
// Stopwatch represents a stopwatch for time tracking.
|
||||||
type Stopwatch struct {
|
type Stopwatch struct {
|
||||||
ID int64 `xorm:"pk autoincr"`
|
ID int64 `xorm:"pk autoincr"`
|
||||||
@@ -74,91 +94,141 @@ func hasUserStopwatch(e Engine, userID int64) (exists bool, sw *Stopwatch, err e
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FinishIssueStopwatchIfPossible if stopwatch exist then finish it otherwise ignore
|
||||||
|
func FinishIssueStopwatchIfPossible(user *User, issue *Issue) error {
|
||||||
|
_, exists, err := getStopwatch(x, user.ID, issue.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return FinishIssueStopwatch(user, issue)
|
||||||
|
}
|
||||||
|
|
||||||
// CreateOrStopIssueStopwatch will create or remove a stopwatch and will log it into issue's timeline.
|
// CreateOrStopIssueStopwatch will create or remove a stopwatch and will log it into issue's timeline.
|
||||||
func CreateOrStopIssueStopwatch(user *User, issue *Issue) error {
|
func CreateOrStopIssueStopwatch(user *User, issue *Issue) error {
|
||||||
|
_, exists, err := getStopwatch(x, user.ID, issue.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if exists {
|
||||||
|
return FinishIssueStopwatch(user, issue)
|
||||||
|
}
|
||||||
|
return CreateIssueStopwatch(user, issue)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FinishIssueStopwatch if stopwatch exist then finish it otherwise return an error
|
||||||
|
func FinishIssueStopwatch(user *User, issue *Issue) error {
|
||||||
sess := x.NewSession()
|
sess := x.NewSession()
|
||||||
defer sess.Close()
|
defer sess.Close()
|
||||||
if err := sess.Begin(); err != nil {
|
if err := sess.Begin(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := createOrStopIssueStopwatch(sess, user, issue); err != nil {
|
if err := finishIssueStopwatch(sess, user, issue); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return sess.Commit()
|
return sess.Commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
func createOrStopIssueStopwatch(e *xorm.Session, user *User, issue *Issue) error {
|
func finishIssueStopwatch(e *xorm.Session, user *User, issue *Issue) error {
|
||||||
sw, exists, err := getStopwatch(e, user.ID, issue.ID)
|
sw, exists, err := getStopwatch(e, user.ID, issue.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if !exists {
|
||||||
|
return ErrIssueStopwatchNotExist{
|
||||||
|
UserID: user.ID,
|
||||||
|
IssueID: issue.ID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create tracked time out of the time difference between start date and actual date
|
||||||
|
timediff := time.Now().Unix() - int64(sw.CreatedUnix)
|
||||||
|
|
||||||
|
// Create TrackedTime
|
||||||
|
tt := &TrackedTime{
|
||||||
|
Created: time.Now(),
|
||||||
|
IssueID: issue.ID,
|
||||||
|
UserID: user.ID,
|
||||||
|
Time: timediff,
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := e.Insert(tt); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := issue.loadRepo(e); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := createComment(e, &CreateCommentOptions{
|
||||||
|
Doer: user,
|
||||||
|
Issue: issue,
|
||||||
|
Repo: issue.Repo,
|
||||||
|
Content: SecToTime(timediff),
|
||||||
|
Type: CommentTypeStopTracking,
|
||||||
|
TimeID: tt.ID,
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = e.Delete(sw)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateIssueStopwatch creates a stopwatch if not exist, otherwise return an error
|
||||||
|
func CreateIssueStopwatch(user *User, issue *Issue) error {
|
||||||
|
sess := x.NewSession()
|
||||||
|
defer sess.Close()
|
||||||
|
if err := sess.Begin(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := createIssueStopwatch(sess, user, issue); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return sess.Commit()
|
||||||
|
}
|
||||||
|
|
||||||
|
func createIssueStopwatch(e *xorm.Session, user *User, issue *Issue) error {
|
||||||
if err := issue.loadRepo(e); err != nil {
|
if err := issue.loadRepo(e); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if another stopwatch is running: stop it
|
||||||
|
exists, sw, err := hasUserStopwatch(e, user.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if exists {
|
if exists {
|
||||||
// Create tracked time out of the time difference between start date and actual date
|
issue, err := getIssueByID(e, sw.IssueID)
|
||||||
timediff := time.Now().Unix() - int64(sw.CreatedUnix)
|
|
||||||
|
|
||||||
// Create TrackedTime
|
|
||||||
tt := &TrackedTime{
|
|
||||||
Created: time.Now(),
|
|
||||||
IssueID: issue.ID,
|
|
||||||
UserID: user.ID,
|
|
||||||
Time: timediff,
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := e.Insert(tt); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := createComment(e, &CreateCommentOptions{
|
|
||||||
Doer: user,
|
|
||||||
Issue: issue,
|
|
||||||
Repo: issue.Repo,
|
|
||||||
Content: SecToTime(timediff),
|
|
||||||
Type: CommentTypeStopTracking,
|
|
||||||
TimeID: tt.ID,
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if _, err := e.Delete(sw); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// if another stopwatch is running: stop it
|
|
||||||
exists, sw, err := hasUserStopwatch(e, user.ID)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if exists {
|
if err := finishIssueStopwatch(e, user, issue); err != nil {
|
||||||
issue, err := getIssueByID(e, sw.IssueID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := createOrStopIssueStopwatch(e, user, issue); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create stopwatch
|
|
||||||
sw = &Stopwatch{
|
|
||||||
UserID: user.ID,
|
|
||||||
IssueID: issue.ID,
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := e.Insert(sw); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if _, err := createComment(e, &CreateCommentOptions{
|
// Create stopwatch
|
||||||
Doer: user,
|
sw = &Stopwatch{
|
||||||
Issue: issue,
|
UserID: user.ID,
|
||||||
Repo: issue.Repo,
|
IssueID: issue.ID,
|
||||||
Type: CommentTypeStartTracking,
|
}
|
||||||
}); err != nil {
|
|
||||||
return err
|
if _, err := e.Insert(sw); err != nil {
|
||||||
}
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := issue.loadRepo(e); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := createComment(e, &CreateCommentOptions{
|
||||||
|
Doer: user,
|
||||||
|
Issue: issue,
|
||||||
|
Repo: issue.Repo,
|
||||||
|
Type: CommentTypeStartTracking,
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,9 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -417,3 +419,43 @@ func TestIssue_ResolveMentions(t *testing.T) {
|
|||||||
// Private repo, whole team
|
// Private repo, whole team
|
||||||
testSuccess("user17", "big_test_private_4", "user15", []string{"user17/owners"}, []int64{18})
|
testSuccess("user17", "big_test_private_4", "user15", []string{"user17/owners"}, []int64{18})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCorrectIssueStats(t *testing.T) {
|
||||||
|
assert.NoError(t, PrepareTestDatabase())
|
||||||
|
|
||||||
|
// Because the condition is to have chunked database look-ups,
|
||||||
|
// We have to more issues than `maxQueryParameters`, we will insert.
|
||||||
|
// maxQueryParameters + 10 issues into the testDatabase.
|
||||||
|
// Each new issues will have a constant description "Bugs are nasty"
|
||||||
|
// Which will be used later on.
|
||||||
|
|
||||||
|
issueAmount := maxQueryParameters + 10
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
for i := 0; i < issueAmount; i++ {
|
||||||
|
wg.Add(1)
|
||||||
|
go func(i int) {
|
||||||
|
testInsertIssue(t, fmt.Sprintf("Issue %d", i+1), "Bugs are nasty", 0)
|
||||||
|
wg.Done()
|
||||||
|
}(i)
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
// Now we will get all issueID's that match the "Bugs are nasty" query.
|
||||||
|
total, ids, err := SearchIssueIDsByKeyword("Bugs are nasty", []int64{1}, issueAmount, 0)
|
||||||
|
|
||||||
|
// Just to be sure.
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.EqualValues(t, issueAmount, total)
|
||||||
|
|
||||||
|
// Now we will call the GetIssueStats with these IDs and if working,
|
||||||
|
// get the correct stats back.
|
||||||
|
issueStats, err := GetIssueStats(&IssueStatsOptions{
|
||||||
|
RepoID: 1,
|
||||||
|
IssueIDs: ids,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Now check the values.
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.EqualValues(t, issueStats.OpenCount, issueAmount)
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ package migrations
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
@@ -762,8 +763,14 @@ func dropTableColumns(sess *xorm.Session, tableName string, columnNames ...strin
|
|||||||
}
|
}
|
||||||
tableSQL := string(res[0]["sql"])
|
tableSQL := string(res[0]["sql"])
|
||||||
|
|
||||||
|
// Get the string offset for column definitions: `CREATE TABLE ( column-definitions... )`
|
||||||
|
columnDefinitionsIndex := strings.Index(tableSQL, "(")
|
||||||
|
if columnDefinitionsIndex < 0 {
|
||||||
|
return errors.New("couldn't find column definitions")
|
||||||
|
}
|
||||||
|
|
||||||
// Separate out the column definitions
|
// Separate out the column definitions
|
||||||
tableSQL = tableSQL[strings.Index(tableSQL, "("):]
|
tableSQL = tableSQL[columnDefinitionsIndex:]
|
||||||
|
|
||||||
// Remove the required columnNames
|
// Remove the required columnNames
|
||||||
for _, name := range columnNames {
|
for _, name := range columnNames {
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
package migrations
|
package migrations
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"xorm.io/xorm"
|
"xorm.io/xorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -40,8 +42,17 @@ func convertTaskTypeToString(x *xorm.Engine) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// to keep the migration could be rerun
|
||||||
|
exist, err := x.Dialect().IsColumnExist(x.DB(), context.Background(), "hook_task", "type")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !exist {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
for i, s := range hookTaskTypes {
|
for i, s := range hookTaskTypes {
|
||||||
if _, err := x.Exec("UPDATE hook_task set typ = ? where type=?", s, i); err != nil {
|
if _, err := x.Exec("UPDATE hook_task set typ = ? where `type`=?", s, i); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
package migrations
|
package migrations
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
@@ -19,6 +20,22 @@ func renameTaskErrorsToMessage(x *xorm.Engine) error {
|
|||||||
Status int `xorm:"index"`
|
Status int `xorm:"index"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This migration maybe rerun so that we should check if it has been run
|
||||||
|
messageExist, err := x.Dialect().IsColumnExist(x.DB(), context.Background(), "task", "message")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if messageExist {
|
||||||
|
errorsExist, err := x.Dialect().IsColumnExist(x.DB(), context.Background(), "task", "errors")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !errorsExist {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sess := x.NewSession()
|
sess := x.NewSession()
|
||||||
defer sess.Close()
|
defer sess.Close()
|
||||||
if err := sess.Begin(); err != nil {
|
if err := sess.Begin(); err != nil {
|
||||||
@@ -29,6 +46,13 @@ func renameTaskErrorsToMessage(x *xorm.Engine) error {
|
|||||||
return fmt.Errorf("error on Sync2: %v", err)
|
return fmt.Errorf("error on Sync2: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if messageExist {
|
||||||
|
// if both errors and message exist, drop message at first
|
||||||
|
if err := dropTableColumns(sess, "task", "message"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case setting.Database.UseMySQL:
|
case setting.Database.UseMySQL:
|
||||||
if _, err := sess.Exec("ALTER TABLE `task` CHANGE errors message text"); err != nil {
|
if _, err := sess.Exec("ALTER TABLE `task` CHANGE errors message text"); err != nil {
|
||||||
|
|||||||
@@ -179,16 +179,35 @@ func syncTables() error {
|
|||||||
return x.StoreEngine("InnoDB").Sync2(tables...)
|
return x.StoreEngine("InnoDB").Sync2(tables...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTestEngine sets a new test xorm.Engine
|
// NewInstallTestEngine creates a new xorm.Engine for testing during install
|
||||||
func NewTestEngine() (err error) {
|
//
|
||||||
|
// This function will cause the basic database schema to be created
|
||||||
|
func NewInstallTestEngine(ctx context.Context, migrateFunc func(*xorm.Engine) error) (err error) {
|
||||||
x, err = GetNewEngine()
|
x, err = GetNewEngine()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Connect to database: %v", err)
|
return fmt.Errorf("failed to connect to database: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
x.SetMapper(names.GonicMapper{})
|
x.SetMapper(names.GonicMapper{})
|
||||||
x.SetLogger(NewXORMLogger(!setting.IsProd()))
|
x.SetLogger(NewXORMLogger(!setting.IsProd()))
|
||||||
x.ShowSQL(!setting.IsProd())
|
x.ShowSQL(!setting.IsProd())
|
||||||
|
|
||||||
|
x.SetDefaultContext(ctx)
|
||||||
|
|
||||||
|
if err = x.Ping(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have to run migrateFunc here in case the user is re-running installation on a previously created DB.
|
||||||
|
// If we do not then table schemas will be changed and there will be conflicts when the migrations run properly.
|
||||||
|
//
|
||||||
|
// Installation should only be being re-run if users want to recover an old database.
|
||||||
|
// However, we should think carefully about should we support re-install on an installed instance,
|
||||||
|
// as there may be other problems due to secret reinitialization.
|
||||||
|
if err = migrateFunc(x); err != nil {
|
||||||
|
return fmt.Errorf("migrate: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
return syncTables()
|
return syncTables()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -115,7 +115,9 @@ func (p *Project) NumClosedIssues() int {
|
|||||||
func (p *Project) NumOpenIssues() int {
|
func (p *Project) NumOpenIssues() int {
|
||||||
c, err := x.Table("project_issue").
|
c, err := x.Table("project_issue").
|
||||||
Join("INNER", "issue", "project_issue.issue_id=issue.id").
|
Join("INNER", "issue", "project_issue.issue_id=issue.id").
|
||||||
Where("project_issue.project_id=? AND issue.is_closed=?", p.ID, false).Count("issue.id")
|
Where("project_issue.project_id=? AND issue.is_closed=?", p.ID, false).
|
||||||
|
Cols("issue_id").
|
||||||
|
Count()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,9 +77,6 @@ var (
|
|||||||
// ErrEmailNotActivated e-mail address has not been activated error
|
// ErrEmailNotActivated e-mail address has not been activated error
|
||||||
ErrEmailNotActivated = errors.New("E-mail address has not been activated")
|
ErrEmailNotActivated = errors.New("E-mail address has not been activated")
|
||||||
|
|
||||||
// ErrUserNameIllegal user name contains illegal characters error
|
|
||||||
ErrUserNameIllegal = errors.New("User name contains illegal characters")
|
|
||||||
|
|
||||||
// ErrLoginSourceNotActived login source is not actived error
|
// ErrLoginSourceNotActived login source is not actived error
|
||||||
ErrLoginSourceNotActived = errors.New("Login source is not actived")
|
ErrLoginSourceNotActived = errors.New("Login source is not actived")
|
||||||
|
|
||||||
@@ -1072,18 +1069,46 @@ func validateUser(u *User) error {
|
|||||||
return ValidateEmail(u.Email)
|
return ValidateEmail(u.Email)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateUser(e Engine, u *User) error {
|
func updateUser(e Engine, u *User, changePrimaryEmail bool) error {
|
||||||
if err := validateUser(u); err != nil {
|
if err := validateUser(u); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if changePrimaryEmail {
|
||||||
|
var emailAddress EmailAddress
|
||||||
|
has, err := e.Where("lower_email=?", strings.ToLower(u.Email)).Get(&emailAddress)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !has {
|
||||||
|
// 1. Update old primary email
|
||||||
|
if _, err = e.Where("uid=? AND is_primary=?", u.ID, true).Cols("is_primary").Update(&EmailAddress{
|
||||||
|
IsPrimary: false,
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
emailAddress.Email = u.Email
|
||||||
|
emailAddress.UID = u.ID
|
||||||
|
emailAddress.IsActivated = true
|
||||||
|
emailAddress.IsPrimary = true
|
||||||
|
if _, err := e.Insert(&emailAddress); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else if _, err := e.ID(emailAddress).Cols("is_primary").Update(&EmailAddress{
|
||||||
|
IsPrimary: true,
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_, err := e.ID(u.ID).AllCols().Update(u)
|
_, err := e.ID(u.ID).AllCols().Update(u)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateUser updates user's information.
|
// UpdateUser updates user's information.
|
||||||
func UpdateUser(u *User) error {
|
func UpdateUser(u *User, changePrimaryEmail bool) error {
|
||||||
return updateUser(x, u)
|
return updateUser(x, u, changePrimaryEmail)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateUserCols update user according special columns
|
// UpdateUserCols update user according special columns
|
||||||
@@ -1112,7 +1137,7 @@ func UpdateUserSetting(u *User) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err = updateUser(sess, u); err != nil {
|
if err = updateUser(sess, u, false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return sess.Commit()
|
return sess.Commit()
|
||||||
|
|||||||
@@ -475,17 +475,17 @@ func TestUpdateUser(t *testing.T) {
|
|||||||
user := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
|
user := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
|
||||||
|
|
||||||
user.KeepActivityPrivate = true
|
user.KeepActivityPrivate = true
|
||||||
assert.NoError(t, UpdateUser(user))
|
assert.NoError(t, UpdateUser(user, false))
|
||||||
user = AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
|
user = AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
|
||||||
assert.True(t, user.KeepActivityPrivate)
|
assert.True(t, user.KeepActivityPrivate)
|
||||||
|
|
||||||
setting.Service.AllowedUserVisibilityModesSlice = []bool{true, false, false}
|
setting.Service.AllowedUserVisibilityModesSlice = []bool{true, false, false}
|
||||||
user.KeepActivityPrivate = false
|
user.KeepActivityPrivate = false
|
||||||
user.Visibility = structs.VisibleTypePrivate
|
user.Visibility = structs.VisibleTypePrivate
|
||||||
assert.Error(t, UpdateUser(user))
|
assert.Error(t, UpdateUser(user, false))
|
||||||
user = AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
|
user = AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
|
||||||
assert.True(t, user.KeepActivityPrivate)
|
assert.True(t, user.KeepActivityPrivate)
|
||||||
|
|
||||||
user.Email = "no mail@mail.org"
|
user.Email = "no mail@mail.org"
|
||||||
assert.Error(t, UpdateUser(user))
|
assert.Error(t, UpdateUser(user, true))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
//go:build pam
|
||||||
// +build pam
|
// +build pam
|
||||||
|
|
||||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
// +build !pam
|
|
||||||
|
|
||||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !pam
|
||||||
|
// +build !pam
|
||||||
|
|
||||||
package pam
|
package pam
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
//go:build pam
|
||||||
// +build pam
|
// +build pam
|
||||||
|
|
||||||
// Copyright 2021 The Gitea Authors. All rights reserved.
|
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ type Repository struct {
|
|||||||
Commit *git.Commit
|
Commit *git.Commit
|
||||||
Tag *git.Tag
|
Tag *git.Tag
|
||||||
GitRepo *git.Repository
|
GitRepo *git.Repository
|
||||||
|
RefName string
|
||||||
BranchName string
|
BranchName string
|
||||||
TagName string
|
TagName string
|
||||||
TreePath string
|
TreePath string
|
||||||
@@ -190,9 +191,9 @@ func (r *Repository) BranchNameSubURL() string {
|
|||||||
case r.IsViewBranch:
|
case r.IsViewBranch:
|
||||||
return "branch/" + r.BranchName
|
return "branch/" + r.BranchName
|
||||||
case r.IsViewTag:
|
case r.IsViewTag:
|
||||||
return "tag/" + r.BranchName
|
return "tag/" + r.TagName
|
||||||
case r.IsViewCommit:
|
case r.IsViewCommit:
|
||||||
return "commit/" + r.BranchName
|
return "commit/" + r.CommitID
|
||||||
}
|
}
|
||||||
log.Error("Unknown view type for repo: %v", r)
|
log.Error("Unknown view type for repo: %v", r)
|
||||||
return ""
|
return ""
|
||||||
@@ -562,8 +563,6 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) {
|
|||||||
ctx.Data["Branches"] = brs
|
ctx.Data["Branches"] = brs
|
||||||
ctx.Data["BranchesCount"] = len(brs)
|
ctx.Data["BranchesCount"] = len(brs)
|
||||||
|
|
||||||
ctx.Data["TagName"] = ctx.Repo.TagName
|
|
||||||
|
|
||||||
// If not branch selected, try default one.
|
// If not branch selected, try default one.
|
||||||
// If default branch doesn't exists, fall back to some other branch.
|
// If default branch doesn't exists, fall back to some other branch.
|
||||||
if len(ctx.Repo.BranchName) == 0 {
|
if len(ctx.Repo.BranchName) == 0 {
|
||||||
@@ -572,9 +571,9 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) {
|
|||||||
} else if len(brs) > 0 {
|
} else if len(brs) > 0 {
|
||||||
ctx.Repo.BranchName = brs[0]
|
ctx.Repo.BranchName = brs[0]
|
||||||
}
|
}
|
||||||
|
ctx.Repo.RefName = ctx.Repo.BranchName
|
||||||
}
|
}
|
||||||
ctx.Data["BranchName"] = ctx.Repo.BranchName
|
ctx.Data["BranchName"] = ctx.Repo.BranchName
|
||||||
ctx.Data["CommitID"] = ctx.Repo.CommitID
|
|
||||||
|
|
||||||
// People who have push access or have forked repository can propose a new pull request.
|
// People who have push access or have forked repository can propose a new pull request.
|
||||||
canPush := ctx.Repo.CanWrite(models.UnitTypeCode) || (ctx.IsSigned && ctx.User.HasForkedRepo(ctx.Repo.Repository.ID))
|
canPush := ctx.Repo.CanWrite(models.UnitTypeCode) || (ctx.IsSigned && ctx.User.HasForkedRepo(ctx.Repo.Repository.ID))
|
||||||
@@ -759,7 +758,6 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
|
|||||||
// Get default branch.
|
// Get default branch.
|
||||||
if len(ctx.Params("*")) == 0 {
|
if len(ctx.Params("*")) == 0 {
|
||||||
refName = ctx.Repo.Repository.DefaultBranch
|
refName = ctx.Repo.Repository.DefaultBranch
|
||||||
ctx.Repo.BranchName = refName
|
|
||||||
if !ctx.Repo.GitRepo.IsBranchExist(refName) {
|
if !ctx.Repo.GitRepo.IsBranchExist(refName) {
|
||||||
brs, _, err := ctx.Repo.GitRepo.GetBranches(0, 0)
|
brs, _, err := ctx.Repo.GitRepo.GetBranches(0, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -773,6 +771,8 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
|
|||||||
}
|
}
|
||||||
refName = brs[0]
|
refName = brs[0]
|
||||||
}
|
}
|
||||||
|
ctx.Repo.RefName = refName
|
||||||
|
ctx.Repo.BranchName = refName
|
||||||
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName)
|
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("GetBranchCommit", err)
|
ctx.ServerError("GetBranchCommit", err)
|
||||||
@@ -783,9 +783,10 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
refName = getRefName(ctx, refType)
|
refName = getRefName(ctx, refType)
|
||||||
ctx.Repo.BranchName = refName
|
ctx.Repo.RefName = refName
|
||||||
if refType.RefTypeIncludesBranches() && ctx.Repo.GitRepo.IsBranchExist(refName) {
|
if refType.RefTypeIncludesBranches() && ctx.Repo.GitRepo.IsBranchExist(refName) {
|
||||||
ctx.Repo.IsViewBranch = true
|
ctx.Repo.IsViewBranch = true
|
||||||
|
ctx.Repo.BranchName = refName
|
||||||
|
|
||||||
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName)
|
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -796,6 +797,8 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
|
|||||||
|
|
||||||
} else if refType.RefTypeIncludesTags() && ctx.Repo.GitRepo.IsTagExist(refName) {
|
} else if refType.RefTypeIncludesTags() && ctx.Repo.GitRepo.IsTagExist(refName) {
|
||||||
ctx.Repo.IsViewTag = true
|
ctx.Repo.IsViewTag = true
|
||||||
|
ctx.Repo.TagName = refName
|
||||||
|
|
||||||
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetTagCommit(refName)
|
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetTagCommit(refName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("GetTagCommit", err)
|
ctx.ServerError("GetTagCommit", err)
|
||||||
@@ -837,6 +840,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
|
|||||||
|
|
||||||
ctx.Data["BranchName"] = ctx.Repo.BranchName
|
ctx.Data["BranchName"] = ctx.Repo.BranchName
|
||||||
ctx.Data["BranchNameSubURL"] = ctx.Repo.BranchNameSubURL()
|
ctx.Data["BranchNameSubURL"] = ctx.Repo.BranchNameSubURL()
|
||||||
|
ctx.Data["TagName"] = ctx.Repo.TagName
|
||||||
ctx.Data["CommitID"] = ctx.Repo.CommitID
|
ctx.Data["CommitID"] = ctx.Repo.CommitID
|
||||||
ctx.Data["TreePath"] = ctx.Repo.TreePath
|
ctx.Data["TreePath"] = ctx.Repo.TreePath
|
||||||
ctx.Data["IsViewBranch"] = ctx.Repo.IsViewBranch
|
ctx.Data["IsViewBranch"] = ctx.Repo.IsViewBranch
|
||||||
|
|||||||
@@ -147,8 +147,9 @@ func ToCommit(repo *models.Repository, commit *git.Commit, userCache map[string]
|
|||||||
|
|
||||||
return &api.Commit{
|
return &api.Commit{
|
||||||
CommitMeta: &api.CommitMeta{
|
CommitMeta: &api.CommitMeta{
|
||||||
URL: repo.APIURL() + "/git/commits/" + commit.ID.String(),
|
URL: repo.APIURL() + "/git/commits/" + commit.ID.String(),
|
||||||
SHA: commit.ID.String(),
|
SHA: commit.ID.String(),
|
||||||
|
Created: commit.Committer.When,
|
||||||
},
|
},
|
||||||
HTMLURL: repo.HTMLURL() + "/commit/" + commit.ID.String(),
|
HTMLURL: repo.HTMLURL() + "/commit/" + commit.ID.String(),
|
||||||
RepoCommit: &api.RepoCommit{
|
RepoCommit: &api.RepoCommit{
|
||||||
@@ -169,8 +170,9 @@ func ToCommit(repo *models.Repository, commit *git.Commit, userCache map[string]
|
|||||||
},
|
},
|
||||||
Message: commit.Message(),
|
Message: commit.Message(),
|
||||||
Tree: &api.CommitMeta{
|
Tree: &api.CommitMeta{
|
||||||
URL: repo.APIURL() + "/git/trees/" + commit.ID.String(),
|
URL: repo.APIURL() + "/git/trees/" + commit.ID.String(),
|
||||||
SHA: commit.ID.String(),
|
SHA: commit.ID.String(),
|
||||||
|
Created: commit.Committer.When,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Author: apiAuthor,
|
Author: apiAuthor,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gogit
|
||||||
// +build gogit
|
// +build gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !gogit
|
||||||
// +build !gogit
|
// +build !gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build race
|
||||||
// +build race
|
// +build race
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gogit
|
||||||
// +build gogit
|
// +build gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gogit
|
||||||
// +build gogit
|
// +build gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !gogit
|
||||||
// +build !gogit
|
// +build !gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gogit
|
||||||
// +build gogit
|
// +build gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !gogit
|
||||||
// +build !gogit
|
// +build !gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gogit
|
||||||
// +build gogit
|
// +build gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !gogit
|
||||||
// +build !gogit
|
// +build !gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gogit
|
||||||
// +build gogit
|
// +build gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gogit
|
||||||
// +build gogit
|
// +build gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !gogit
|
||||||
// +build !gogit
|
// +build !gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !gogit
|
||||||
// +build !gogit
|
// +build !gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gogit
|
||||||
// +build gogit
|
// +build gogit
|
||||||
|
|
||||||
package pipeline
|
package pipeline
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !gogit
|
||||||
// +build !gogit
|
// +build !gogit
|
||||||
|
|
||||||
package pipeline
|
package pipeline
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gogit
|
||||||
// +build gogit
|
// +build gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !gogit
|
||||||
// +build !gogit
|
// +build !gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gogit
|
||||||
// +build gogit
|
// +build gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !gogit
|
||||||
// +build !gogit
|
// +build !gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gogit
|
||||||
// +build gogit
|
// +build gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !gogit
|
||||||
// +build !gogit
|
// +build !gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gogit
|
||||||
// +build gogit
|
// +build gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !gogit
|
||||||
// +build !gogit
|
// +build !gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gogit
|
||||||
// +build gogit
|
// +build gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gogit
|
||||||
// +build gogit
|
// +build gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !gogit
|
||||||
// +build !gogit
|
// +build !gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gogit
|
||||||
// +build gogit
|
// +build gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !gogit
|
||||||
// +build !gogit
|
// +build !gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gogit
|
||||||
// +build gogit
|
// +build gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !gogit
|
||||||
// +build !gogit
|
// +build !gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gogit
|
||||||
// +build gogit
|
// +build gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !gogit
|
||||||
// +build !gogit
|
// +build !gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gogit
|
||||||
// +build gogit
|
// +build gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !gogit
|
||||||
// +build !gogit
|
// +build !gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gogit
|
||||||
// +build gogit
|
// +build gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !gogit
|
||||||
// +build !gogit
|
// +build !gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -52,9 +52,7 @@ func getRefURL(refURL, urlPrefix, repoFullName, sshDomain string) string {
|
|||||||
urlPrefixHostname = prefixURL.Host
|
urlPrefixHostname = prefixURL.Host
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasSuffix(urlPrefix, "/") {
|
urlPrefix = strings.TrimSuffix(urlPrefix, "/")
|
||||||
urlPrefix = urlPrefix[:len(urlPrefix)-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: Need to consider branch - which will require changes in modules/git/commit.go:GetSubModules
|
// FIXME: Need to consider branch - which will require changes in modules/git/commit.go:GetSubModules
|
||||||
// Relative url prefix check (according to git submodule documentation)
|
// Relative url prefix check (according to git submodule documentation)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gogit
|
||||||
// +build gogit
|
// +build gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !gogit
|
||||||
// +build !gogit
|
// +build !gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gogit
|
||||||
// +build gogit
|
// +build gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !gogit
|
||||||
// +build !gogit
|
// +build !gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gogit
|
||||||
// +build gogit
|
// +build gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gogit
|
||||||
// +build gogit
|
// +build gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !gogit
|
||||||
// +build !gogit
|
// +build !gogit
|
||||||
|
|
||||||
package git
|
package git
|
||||||
|
|||||||
@@ -217,11 +217,9 @@ func newRefsFromRefNames(refNames []byte) []git.Reference {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
refName := string(refNameBytes)
|
refName := string(refNameBytes)
|
||||||
if strings.HasPrefix(refName, "tag: ") {
|
refName = strings.TrimPrefix(refName, "tag: ")
|
||||||
refName = strings.TrimPrefix(refName, "tag: ")
|
refName = strings.TrimPrefix(refName, "HEAD -> ")
|
||||||
} else if strings.HasPrefix(refName, "HEAD -> ") {
|
|
||||||
refName = strings.TrimPrefix(refName, "HEAD -> ")
|
|
||||||
}
|
|
||||||
refs = append(refs, git.Reference{
|
refs = append(refs, git.Reference{
|
||||||
Name: refName,
|
Name: refName,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
// +build !windows
|
|
||||||
|
|
||||||
// Copyright 2019 The Gitea Authors. All rights reserved.
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !windows
|
||||||
|
// +build !windows
|
||||||
|
|
||||||
package graceful
|
package graceful
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
// +build windows
|
|
||||||
|
|
||||||
// Copyright 2019 The Gitea Authors. All rights reserved.
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
// This code is heavily inspired by the archived gofacebook/gracenet/net.go handler
|
// This code is heavily inspired by the archived gofacebook/gracenet/net.go handler
|
||||||
|
|
||||||
|
//go:build windows
|
||||||
|
// +build windows
|
||||||
|
|
||||||
package graceful
|
package graceful
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
// +build !windows
|
|
||||||
|
|
||||||
// Copyright 2019 The Gitea Authors. All rights reserved.
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
// This code is heavily inspired by the archived gofacebook/gracenet/net.go handler
|
// This code is heavily inspired by the archived gofacebook/gracenet/net.go handler
|
||||||
|
|
||||||
|
//go:build !windows
|
||||||
|
// +build !windows
|
||||||
|
|
||||||
package graceful
|
package graceful
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
// +build windows
|
|
||||||
|
|
||||||
// Copyright 2019 The Gitea Authors. All rights reserved.
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
// This code is heavily inspired by the archived gofacebook/gracenet/net.go handler
|
// This code is heavily inspired by the archived gofacebook/gracenet/net.go handler
|
||||||
|
|
||||||
|
//go:build windows
|
||||||
|
// +build windows
|
||||||
|
|
||||||
package graceful
|
package graceful
|
||||||
|
|
||||||
import "net"
|
import "net"
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
// +build !windows
|
|
||||||
|
|
||||||
// Copyright 2019 The Gitea Authors. All rights reserved.
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
// This code is heavily inspired by the archived gofacebook/gracenet/net.go handler
|
// This code is heavily inspired by the archived gofacebook/gracenet/net.go handler
|
||||||
|
|
||||||
|
//go:build !windows
|
||||||
|
// +build !windows
|
||||||
|
|
||||||
package graceful
|
package graceful
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
94
modules/hostmatcher/hostmatcher.go
Normal file
94
modules/hostmatcher/hostmatcher.go
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package hostmatcher
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
// HostMatchList is used to check if a host or IP is in a list.
|
||||||
|
// If you only need to do wildcard matching, consider to use modules/matchlist
|
||||||
|
type HostMatchList struct {
|
||||||
|
hosts []string
|
||||||
|
ipNets []*net.IPNet
|
||||||
|
}
|
||||||
|
|
||||||
|
// MatchBuiltinAll all hosts are matched
|
||||||
|
const MatchBuiltinAll = "*"
|
||||||
|
|
||||||
|
// MatchBuiltinExternal A valid non-private unicast IP, all hosts on public internet are matched
|
||||||
|
const MatchBuiltinExternal = "external"
|
||||||
|
|
||||||
|
// MatchBuiltinPrivate RFC 1918 (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) and RFC 4193 (FC00::/7). Also called LAN/Intranet.
|
||||||
|
const MatchBuiltinPrivate = "private"
|
||||||
|
|
||||||
|
// MatchBuiltinLoopback 127.0.0.0/8 for IPv4 and ::1/128 for IPv6, localhost is included.
|
||||||
|
const MatchBuiltinLoopback = "loopback"
|
||||||
|
|
||||||
|
// ParseHostMatchList parses the host list HostMatchList
|
||||||
|
func ParseHostMatchList(hostList string) *HostMatchList {
|
||||||
|
hl := &HostMatchList{}
|
||||||
|
for _, s := range strings.Split(hostList, ",") {
|
||||||
|
s = strings.ToLower(strings.TrimSpace(s))
|
||||||
|
if s == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
_, ipNet, err := net.ParseCIDR(s)
|
||||||
|
if err == nil {
|
||||||
|
hl.ipNets = append(hl.ipNets, ipNet)
|
||||||
|
} else {
|
||||||
|
hl.hosts = append(hl.hosts, s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hl
|
||||||
|
}
|
||||||
|
|
||||||
|
// MatchesHostOrIP checks if the host or IP matches an allow/deny(block) list
|
||||||
|
func (hl *HostMatchList) MatchesHostOrIP(host string, ip net.IP) bool {
|
||||||
|
var matched bool
|
||||||
|
host = strings.ToLower(host)
|
||||||
|
ipStr := ip.String()
|
||||||
|
loop:
|
||||||
|
for _, hostInList := range hl.hosts {
|
||||||
|
switch hostInList {
|
||||||
|
case "":
|
||||||
|
continue
|
||||||
|
case MatchBuiltinAll:
|
||||||
|
matched = true
|
||||||
|
break loop
|
||||||
|
case MatchBuiltinExternal:
|
||||||
|
if matched = ip.IsGlobalUnicast() && !util.IsIPPrivate(ip); matched {
|
||||||
|
break loop
|
||||||
|
}
|
||||||
|
case MatchBuiltinPrivate:
|
||||||
|
if matched = util.IsIPPrivate(ip); matched {
|
||||||
|
break loop
|
||||||
|
}
|
||||||
|
case MatchBuiltinLoopback:
|
||||||
|
if matched = ip.IsLoopback(); matched {
|
||||||
|
break loop
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if matched, _ = filepath.Match(hostInList, host); matched {
|
||||||
|
break loop
|
||||||
|
}
|
||||||
|
if matched, _ = filepath.Match(hostInList, ipStr); matched {
|
||||||
|
break loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !matched {
|
||||||
|
for _, ipNet := range hl.ipNets {
|
||||||
|
if matched = ipNet.Contains(ip); matched {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return matched
|
||||||
|
}
|
||||||
119
modules/hostmatcher/hostmatcher_test.go
Normal file
119
modules/hostmatcher/hostmatcher_test.go
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package hostmatcher
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestHostOrIPMatchesList(t *testing.T) {
|
||||||
|
type tc struct {
|
||||||
|
host string
|
||||||
|
ip net.IP
|
||||||
|
expected bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// for IPv6: "::1" is loopback, "fd00::/8" is private
|
||||||
|
|
||||||
|
hl := ParseHostMatchList("private, External, *.myDomain.com, 169.254.1.0/24")
|
||||||
|
cases := []tc{
|
||||||
|
{"", net.IPv4zero, false},
|
||||||
|
{"", net.IPv6zero, false},
|
||||||
|
|
||||||
|
{"", net.ParseIP("127.0.0.1"), false},
|
||||||
|
{"", net.ParseIP("::1"), false},
|
||||||
|
|
||||||
|
{"", net.ParseIP("10.0.1.1"), true},
|
||||||
|
{"", net.ParseIP("192.168.1.1"), true},
|
||||||
|
{"", net.ParseIP("fd00::1"), true},
|
||||||
|
|
||||||
|
{"", net.ParseIP("8.8.8.8"), true},
|
||||||
|
{"", net.ParseIP("1001::1"), true},
|
||||||
|
|
||||||
|
{"mydomain.com", net.IPv4zero, false},
|
||||||
|
{"sub.mydomain.com", net.IPv4zero, true},
|
||||||
|
|
||||||
|
{"", net.ParseIP("169.254.1.1"), true},
|
||||||
|
{"", net.ParseIP("169.254.2.2"), false},
|
||||||
|
}
|
||||||
|
for _, c := range cases {
|
||||||
|
assert.Equalf(t, c.expected, hl.MatchesHostOrIP(c.host, c.ip), "case %s(%v)", c.host, c.ip)
|
||||||
|
}
|
||||||
|
|
||||||
|
hl = ParseHostMatchList("loopback")
|
||||||
|
cases = []tc{
|
||||||
|
{"", net.IPv4zero, false},
|
||||||
|
{"", net.ParseIP("127.0.0.1"), true},
|
||||||
|
{"", net.ParseIP("10.0.1.1"), false},
|
||||||
|
{"", net.ParseIP("192.168.1.1"), false},
|
||||||
|
{"", net.ParseIP("8.8.8.8"), false},
|
||||||
|
|
||||||
|
{"", net.ParseIP("::1"), true},
|
||||||
|
{"", net.ParseIP("fd00::1"), false},
|
||||||
|
{"", net.ParseIP("1000::1"), false},
|
||||||
|
|
||||||
|
{"mydomain.com", net.IPv4zero, false},
|
||||||
|
}
|
||||||
|
for _, c := range cases {
|
||||||
|
assert.Equalf(t, c.expected, hl.MatchesHostOrIP(c.host, c.ip), "case %s(%v)", c.host, c.ip)
|
||||||
|
}
|
||||||
|
|
||||||
|
hl = ParseHostMatchList("private")
|
||||||
|
cases = []tc{
|
||||||
|
{"", net.IPv4zero, false},
|
||||||
|
{"", net.ParseIP("127.0.0.1"), false},
|
||||||
|
{"", net.ParseIP("10.0.1.1"), true},
|
||||||
|
{"", net.ParseIP("192.168.1.1"), true},
|
||||||
|
{"", net.ParseIP("8.8.8.8"), false},
|
||||||
|
|
||||||
|
{"", net.ParseIP("::1"), false},
|
||||||
|
{"", net.ParseIP("fd00::1"), true},
|
||||||
|
{"", net.ParseIP("1000::1"), false},
|
||||||
|
|
||||||
|
{"mydomain.com", net.IPv4zero, false},
|
||||||
|
}
|
||||||
|
for _, c := range cases {
|
||||||
|
assert.Equalf(t, c.expected, hl.MatchesHostOrIP(c.host, c.ip), "case %s(%v)", c.host, c.ip)
|
||||||
|
}
|
||||||
|
|
||||||
|
hl = ParseHostMatchList("external")
|
||||||
|
cases = []tc{
|
||||||
|
{"", net.IPv4zero, false},
|
||||||
|
{"", net.ParseIP("127.0.0.1"), false},
|
||||||
|
{"", net.ParseIP("10.0.1.1"), false},
|
||||||
|
{"", net.ParseIP("192.168.1.1"), false},
|
||||||
|
{"", net.ParseIP("8.8.8.8"), true},
|
||||||
|
|
||||||
|
{"", net.ParseIP("::1"), false},
|
||||||
|
{"", net.ParseIP("fd00::1"), false},
|
||||||
|
{"", net.ParseIP("1000::1"), true},
|
||||||
|
|
||||||
|
{"mydomain.com", net.IPv4zero, false},
|
||||||
|
}
|
||||||
|
for _, c := range cases {
|
||||||
|
assert.Equalf(t, c.expected, hl.MatchesHostOrIP(c.host, c.ip), "case %s(%v)", c.host, c.ip)
|
||||||
|
}
|
||||||
|
|
||||||
|
hl = ParseHostMatchList("*")
|
||||||
|
cases = []tc{
|
||||||
|
{"", net.IPv4zero, true},
|
||||||
|
{"", net.ParseIP("127.0.0.1"), true},
|
||||||
|
{"", net.ParseIP("10.0.1.1"), true},
|
||||||
|
{"", net.ParseIP("192.168.1.1"), true},
|
||||||
|
{"", net.ParseIP("8.8.8.8"), true},
|
||||||
|
|
||||||
|
{"", net.ParseIP("::1"), true},
|
||||||
|
{"", net.ParseIP("fd00::1"), true},
|
||||||
|
{"", net.ParseIP("1000::1"), true},
|
||||||
|
|
||||||
|
{"mydomain.com", net.IPv4zero, true},
|
||||||
|
}
|
||||||
|
for _, c := range cases {
|
||||||
|
assert.Equalf(t, c.expected, hl.MatchesHostOrIP(c.host, c.ip), "case %s(%v)", c.host, c.ip)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -174,6 +174,10 @@ func NewBleveIndexer(indexDir string) (*BleveIndexer, bool, error) {
|
|||||||
indexDir: indexDir,
|
indexDir: indexDir,
|
||||||
}
|
}
|
||||||
created, err := indexer.init()
|
created, err := indexer.init()
|
||||||
|
if err != nil {
|
||||||
|
indexer.Close()
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
return indexer, created, err
|
return indexer, created, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -83,7 +83,10 @@ func NewElasticSearchIndexer(url, indexerName string) (*ElasticSearchIndexer, bo
|
|||||||
indexerAliasName: indexerName,
|
indexerAliasName: indexerName,
|
||||||
}
|
}
|
||||||
exists, err := indexer.init()
|
exists, err := indexer.init()
|
||||||
|
if err != nil {
|
||||||
|
indexer.Close()
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
return indexer, !exists, err
|
return indexer, !exists, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -188,9 +188,6 @@ func Init() {
|
|||||||
|
|
||||||
rIndexer, populate, err = NewBleveIndexer(setting.Indexer.RepoPath)
|
rIndexer, populate, err = NewBleveIndexer(setting.Indexer.RepoPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if rIndexer != nil {
|
|
||||||
rIndexer.Close()
|
|
||||||
}
|
|
||||||
cancel()
|
cancel()
|
||||||
indexer.Close()
|
indexer.Close()
|
||||||
close(waitChannel)
|
close(waitChannel)
|
||||||
@@ -208,9 +205,6 @@ func Init() {
|
|||||||
|
|
||||||
rIndexer, populate, err = NewElasticSearchIndexer(setting.Indexer.RepoConnStr, setting.Indexer.RepoIndexerName)
|
rIndexer, populate, err = NewElasticSearchIndexer(setting.Indexer.RepoConnStr, setting.Indexer.RepoIndexerName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if rIndexer != nil {
|
|
||||||
rIndexer.Close()
|
|
||||||
}
|
|
||||||
cancel()
|
cancel()
|
||||||
indexer.Close()
|
indexer.Close()
|
||||||
close(waitChannel)
|
close(waitChannel)
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ func handle(data ...queue.Data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func initStatsQueue() error {
|
func initStatsQueue() error {
|
||||||
statsQueue = queue.CreateUniqueQueue("repo_stats_update", handle, int64(0)).(queue.UniqueQueue)
|
statsQueue = queue.CreateUniqueQueue("repo_stats_update", handle, int64(0))
|
||||||
if statsQueue == nil {
|
if statsQueue == nil {
|
||||||
return fmt.Errorf("Unable to create repo_stats_update Queue")
|
return fmt.Errorf("Unable to create repo_stats_update Queue")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,9 +29,7 @@ func endpointFromCloneURL(rawurl string) *url.URL {
|
|||||||
return ep
|
return ep
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasSuffix(ep.Path, "/") {
|
ep.Path = strings.TrimSuffix(ep.Path, "/")
|
||||||
ep.Path = ep.Path[:len(ep.Path)-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
if ep.Scheme == "file" {
|
if ep.Scheme == "file" {
|
||||||
return ep
|
return ep
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gogit
|
||||||
// +build gogit
|
// +build gogit
|
||||||
|
|
||||||
package lfs
|
package lfs
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !gogit
|
||||||
// +build !gogit
|
// +build !gogit
|
||||||
|
|
||||||
package lfs
|
package lfs
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ type Footnote struct {
|
|||||||
func (n *Footnote) Dump(source []byte, level int) {
|
func (n *Footnote) Dump(source []byte, level int) {
|
||||||
m := map[string]string{}
|
m := map[string]string{}
|
||||||
m["Index"] = fmt.Sprintf("%v", n.Index)
|
m["Index"] = fmt.Sprintf("%v", n.Index)
|
||||||
m["Ref"] = fmt.Sprintf("%s", n.Ref)
|
m["Ref"] = string(n.Ref)
|
||||||
m["Name"] = fmt.Sprintf("%v", n.Name)
|
m["Name"] = fmt.Sprintf("%v", n.Name)
|
||||||
ast.DumpHelper(n, source, level, m, nil)
|
ast.DumpHelper(n, source, level, m, nil)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ func (g *GiteaLocalUploader) CreateRepo(repo *base.Repository, opts base.Migrate
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
r.DefaultBranch = repo.DefaultBranch
|
r.DefaultBranch = repo.DefaultBranch
|
||||||
|
r.Description = repo.Description
|
||||||
|
|
||||||
r, err = repository.MigrateRepositoryGitData(g.ctx, owner, r, base.MigrateOptions{
|
r, err = repository.MigrateRepositoryGitData(g.ctx, owner, r, base.MigrateOptions{
|
||||||
RepoName: g.repoName,
|
RepoName: g.repoName,
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ func IsMigrateURLAllowed(remoteURL string, doer *models.User) error {
|
|||||||
return &models.ErrInvalidCloneAddr{Host: u.Host, NotResolvedIP: true}
|
return &models.ErrInvalidCloneAddr{Host: u.Host, NotResolvedIP: true}
|
||||||
}
|
}
|
||||||
for _, addr := range addrList {
|
for _, addr := range addrList {
|
||||||
if isIPPrivate(addr) || !addr.IsGlobalUnicast() {
|
if util.IsIPPrivate(addr) || !addr.IsGlobalUnicast() {
|
||||||
return &models.ErrInvalidCloneAddr{Host: u.Host, PrivateNet: addr.String(), IsPermissionDenied: true}
|
return &models.ErrInvalidCloneAddr{Host: u.Host, PrivateNet: addr.String(), IsPermissionDenied: true}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -486,16 +486,3 @@ func Init() error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// isIPPrivate reports whether ip is a private address, according to
|
|
||||||
// RFC 1918 (IPv4 addresses) and RFC 4193 (IPv6 addresses).
|
|
||||||
// from https://github.com/golang/go/pull/42793
|
|
||||||
// TODO remove if https://github.com/golang/go/issues/29146 got resolved
|
|
||||||
func isIPPrivate(ip net.IP) bool {
|
|
||||||
if ip4 := ip.To4(); ip4 != nil {
|
|
||||||
return ip4[0] == 10 ||
|
|
||||||
(ip4[0] == 172 && ip4[1]&0xf0 == 16) ||
|
|
||||||
(ip4[0] == 192 && ip4[1] == 168)
|
|
||||||
}
|
|
||||||
return len(ip) == net.IPv6len && ip[0]&0xfe == 0xfc
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ func (m *webhookNotifier) NotifyIssueChangeTitle(doer *models.User, issue *model
|
|||||||
},
|
},
|
||||||
Issue: convert.ToAPIIssue(issue),
|
Issue: convert.ToAPIIssue(issue),
|
||||||
Repository: convert.ToRepo(issue.Repo, mode),
|
Repository: convert.ToRepo(issue.Repo, mode),
|
||||||
Sender: convert.ToUser(issue.Poster, nil),
|
Sender: convert.ToUser(doer, nil),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -766,12 +766,12 @@ func sendReleaseHook(doer *models.User, rel *models.Release, action api.HookRele
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
mode, _ := models.AccessLevel(rel.Publisher, rel.Repo)
|
mode, _ := models.AccessLevel(doer, rel.Repo)
|
||||||
if err := webhook_services.PrepareWebhooks(rel.Repo, models.HookEventRelease, &api.ReleasePayload{
|
if err := webhook_services.PrepareWebhooks(rel.Repo, models.HookEventRelease, &api.ReleasePayload{
|
||||||
Action: action,
|
Action: action,
|
||||||
Release: convert.ToRelease(rel),
|
Release: convert.ToRelease(rel),
|
||||||
Repository: convert.ToRepo(rel.Repo, mode),
|
Repository: convert.ToRepo(rel.Repo, mode),
|
||||||
Sender: convert.ToUser(rel.Publisher, nil),
|
Sender: convert.ToUser(doer, nil),
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
log.Error("PrepareWebhooks: %v", err)
|
log.Error("PrepareWebhooks: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
// +build !bindata
|
|
||||||
|
|
||||||
// Copyright 2016 The Gitea Authors. All rights reserved.
|
// Copyright 2016 The Gitea Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !bindata
|
||||||
|
// +build !bindata
|
||||||
|
|
||||||
package options
|
package options
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//+build bindata
|
//go:build bindata
|
||||||
|
// +build bindata
|
||||||
|
|
||||||
package options
|
package options
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
//go:build bindata
|
||||||
// +build bindata
|
// +build bindata
|
||||||
|
|
||||||
// Copyright 2016 The Gitea Authors. All rights reserved.
|
// Copyright 2016 The Gitea Authors. All rights reserved.
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
// +build !bindata
|
|
||||||
|
|
||||||
// Copyright 2016 The Gitea Authors. All rights reserved.
|
// Copyright 2016 The Gitea Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !bindata
|
||||||
|
// +build !bindata
|
||||||
|
|
||||||
package public
|
package public
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//+build bindata
|
//go:build bindata
|
||||||
|
// +build bindata
|
||||||
|
|
||||||
package public
|
package public
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user