mirror of
https://gitea.com/gitea/tea.git
synced 2026-04-26 02:03:30 +02:00
Compare commits
9 Commits
v0.14.0
...
lunny/fix_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
465a6f01ee | ||
|
|
a58c35c3e2 | ||
|
|
b43f36abd4 | ||
|
|
783ac7684a | ||
|
|
ab7dc97518 | ||
|
|
d0b7ea09e8 | ||
|
|
469a6d3466 | ||
|
|
20914a1375 | ||
|
|
3c1c9b2904 |
@@ -39,7 +39,7 @@ jobs:
|
|||||||
make unit-test-coverage
|
make unit-test-coverage
|
||||||
services:
|
services:
|
||||||
gitea:
|
gitea:
|
||||||
image: docker.gitea.com/gitea:1.25.5
|
image: docker.gitea.com/gitea:1.26.0
|
||||||
cmd:
|
cmd:
|
||||||
- bash
|
- bash
|
||||||
- -c
|
- -c
|
||||||
|
|||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -17,3 +17,5 @@ dist/
|
|||||||
.direnv/
|
.direnv/
|
||||||
result
|
result
|
||||||
result-*
|
result-*
|
||||||
|
|
||||||
|
.DS_Store
|
||||||
@@ -15,13 +15,13 @@ import (
|
|||||||
"github.com/urfave/cli/v3"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CmdRepos represents to login a gitea server.
|
// CmdRepos represents the command to manage repositories.
|
||||||
var CmdRepos = cli.Command{
|
var CmdRepos = cli.Command{
|
||||||
Name: "repos",
|
Name: "repos",
|
||||||
Aliases: []string{"repo"},
|
Aliases: []string{"repo"},
|
||||||
Category: catEntities,
|
Category: catEntities,
|
||||||
Usage: "Show repository details",
|
Usage: "Manage repositories",
|
||||||
Description: "Show repository details",
|
Description: "Manage repositories",
|
||||||
ArgsUsage: "[<repo owner>/<repo name>]",
|
ArgsUsage: "[<repo owner>/<repo name>]",
|
||||||
Action: runRepos,
|
Action: runRepos,
|
||||||
Commands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
|
|||||||
@@ -89,30 +89,26 @@ func runWebhooksCreate(ctx stdctx.Context, cmd *cli.Command) error {
|
|||||||
config["secret"] = secret
|
config["secret"] = secret
|
||||||
}
|
}
|
||||||
|
|
||||||
if branchFilter != "" {
|
|
||||||
config["branch_filter"] = branchFilter
|
|
||||||
}
|
|
||||||
|
|
||||||
if authHeader != "" {
|
|
||||||
config["authorization_header"] = authHeader
|
|
||||||
}
|
|
||||||
|
|
||||||
var hook *gitea.Hook
|
var hook *gitea.Hook
|
||||||
if c.IsGlobal {
|
if c.IsGlobal {
|
||||||
return fmt.Errorf("global webhooks not yet supported in this version")
|
return fmt.Errorf("global webhooks not yet supported in this version")
|
||||||
} else if len(c.Org) > 0 {
|
} else if len(c.Org) > 0 {
|
||||||
hook, _, err = client.CreateOrgHook(c.Org, gitea.CreateHookOption{
|
hook, _, err = client.CreateOrgHook(c.Org, gitea.CreateHookOption{
|
||||||
Type: webhookType,
|
Type: webhookType,
|
||||||
Config: config,
|
Config: config,
|
||||||
Events: events,
|
Events: events,
|
||||||
Active: active,
|
Active: active,
|
||||||
|
BranchFilter: branchFilter,
|
||||||
|
AuthorizationHeader: authHeader,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
hook, _, err = client.CreateRepoHook(c.Owner, c.Repo, gitea.CreateHookOption{
|
hook, _, err = client.CreateRepoHook(c.Owner, c.Repo, gitea.CreateHookOption{
|
||||||
Type: webhookType,
|
Type: webhookType,
|
||||||
Config: config,
|
Config: config,
|
||||||
Events: events,
|
Events: events,
|
||||||
Active: active,
|
Active: active,
|
||||||
|
BranchFilter: branchFilter,
|
||||||
|
AuthorizationHeader: authHeader,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -79,8 +79,6 @@ func TestWebhookConfigConstruction(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
url string
|
url string
|
||||||
secret string
|
secret string
|
||||||
branchFilter string
|
|
||||||
authHeader string
|
|
||||||
expectedKeys []string
|
expectedKeys []string
|
||||||
expectedValues map[string]string
|
expectedValues map[string]string
|
||||||
}{
|
}{
|
||||||
@@ -106,44 +104,16 @@ func TestWebhookConfigConstruction(t *testing.T) {
|
|||||||
"secret": "my-secret",
|
"secret": "my-secret",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "Config with branch filter",
|
|
||||||
url: "https://example.com/webhook",
|
|
||||||
branchFilter: "main,develop",
|
|
||||||
expectedKeys: []string{"url", "http_method", "content_type", "branch_filter"},
|
|
||||||
expectedValues: map[string]string{
|
|
||||||
"url": "https://example.com/webhook",
|
|
||||||
"http_method": "post",
|
|
||||||
"content_type": "json",
|
|
||||||
"branch_filter": "main,develop",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Config with auth header",
|
|
||||||
url: "https://example.com/webhook",
|
|
||||||
authHeader: "Bearer token123",
|
|
||||||
expectedKeys: []string{"url", "http_method", "content_type", "authorization_header"},
|
|
||||||
expectedValues: map[string]string{
|
|
||||||
"url": "https://example.com/webhook",
|
|
||||||
"http_method": "post",
|
|
||||||
"content_type": "json",
|
|
||||||
"authorization_header": "Bearer token123",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "Complete config",
|
name: "Complete config",
|
||||||
url: "https://example.com/webhook",
|
url: "https://example.com/webhook",
|
||||||
secret: "secret123",
|
secret: "secret123",
|
||||||
branchFilter: "main",
|
expectedKeys: []string{"url", "http_method", "content_type", "secret"},
|
||||||
authHeader: "X-Token: abc",
|
|
||||||
expectedKeys: []string{"url", "http_method", "content_type", "secret", "branch_filter", "authorization_header"},
|
|
||||||
expectedValues: map[string]string{
|
expectedValues: map[string]string{
|
||||||
"url": "https://example.com/webhook",
|
"url": "https://example.com/webhook",
|
||||||
"http_method": "post",
|
"http_method": "post",
|
||||||
"content_type": "json",
|
"content_type": "json",
|
||||||
"secret": "secret123",
|
"secret": "secret123",
|
||||||
"branch_filter": "main",
|
|
||||||
"authorization_header": "X-Token: abc",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -159,12 +129,6 @@ func TestWebhookConfigConstruction(t *testing.T) {
|
|||||||
if tt.secret != "" {
|
if tt.secret != "" {
|
||||||
config["secret"] = tt.secret
|
config["secret"] = tt.secret
|
||||||
}
|
}
|
||||||
if tt.branchFilter != "" {
|
|
||||||
config["branch_filter"] = tt.branchFilter
|
|
||||||
}
|
|
||||||
if tt.authHeader != "" {
|
|
||||||
config["authorization_header"] = tt.authHeader
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check all expected keys exist
|
// Check all expected keys exist
|
||||||
for _, key := range tt.expectedKeys {
|
for _, key := range tt.expectedKeys {
|
||||||
@@ -184,11 +148,13 @@ func TestWebhookConfigConstruction(t *testing.T) {
|
|||||||
|
|
||||||
func TestWebhookCreateOptions(t *testing.T) {
|
func TestWebhookCreateOptions(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
webhookType string
|
webhookType string
|
||||||
events []string
|
events []string
|
||||||
active bool
|
active bool
|
||||||
config map[string]string
|
config map[string]string
|
||||||
|
branchFilter string
|
||||||
|
authHeader string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "Gitea webhook",
|
name: "Gitea webhook",
|
||||||
@@ -200,6 +166,8 @@ func TestWebhookCreateOptions(t *testing.T) {
|
|||||||
"http_method": "post",
|
"http_method": "post",
|
||||||
"content_type": "json",
|
"content_type": "json",
|
||||||
},
|
},
|
||||||
|
branchFilter: "main",
|
||||||
|
authHeader: "X-Token: abc",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Slack webhook",
|
name: "Slack webhook",
|
||||||
@@ -228,16 +196,20 @@ func TestWebhookCreateOptions(t *testing.T) {
|
|||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
option := gitea.CreateHookOption{
|
option := gitea.CreateHookOption{
|
||||||
Type: gitea.HookType(tt.webhookType),
|
Type: gitea.HookType(tt.webhookType),
|
||||||
Config: tt.config,
|
Config: tt.config,
|
||||||
Events: tt.events,
|
Events: tt.events,
|
||||||
Active: tt.active,
|
Active: tt.active,
|
||||||
|
BranchFilter: tt.branchFilter,
|
||||||
|
AuthorizationHeader: tt.authHeader,
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal(t, gitea.HookType(tt.webhookType), option.Type)
|
assert.Equal(t, gitea.HookType(tt.webhookType), option.Type)
|
||||||
assert.Equal(t, tt.events, option.Events)
|
assert.Equal(t, tt.events, option.Events)
|
||||||
assert.Equal(t, tt.active, option.Active)
|
assert.Equal(t, tt.active, option.Active)
|
||||||
assert.Equal(t, tt.config, option.Config)
|
assert.Equal(t, tt.config, option.Config)
|
||||||
|
assert.Equal(t, tt.branchFilter, option.BranchFilter)
|
||||||
|
assert.Equal(t, tt.authHeader, option.AuthorizationHeader)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,11 +97,14 @@ func runWebhooksUpdate(ctx stdctx.Context, cmd *cli.Command) error {
|
|||||||
if cmd.IsSet("secret") {
|
if cmd.IsSet("secret") {
|
||||||
config["secret"] = cmd.String("secret")
|
config["secret"] = cmd.String("secret")
|
||||||
}
|
}
|
||||||
|
branchFilter := hook.BranchFilter
|
||||||
if cmd.IsSet("branch-filter") {
|
if cmd.IsSet("branch-filter") {
|
||||||
config["branch_filter"] = cmd.String("branch-filter")
|
branchFilter = cmd.String("branch-filter")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
authHeader := hook.AuthorizationHeader
|
||||||
if cmd.IsSet("authorization-header") {
|
if cmd.IsSet("authorization-header") {
|
||||||
config["authorization_header"] = cmd.String("authorization-header")
|
authHeader = cmd.String("authorization-header")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update events if specified
|
// Update events if specified
|
||||||
@@ -126,15 +129,19 @@ func runWebhooksUpdate(ctx stdctx.Context, cmd *cli.Command) error {
|
|||||||
return fmt.Errorf("global webhooks not yet supported in this version")
|
return fmt.Errorf("global webhooks not yet supported in this version")
|
||||||
} else if len(c.Org) > 0 {
|
} else if len(c.Org) > 0 {
|
||||||
_, err = client.EditOrgHook(c.Org, int64(webhookID), gitea.EditHookOption{
|
_, err = client.EditOrgHook(c.Org, int64(webhookID), gitea.EditHookOption{
|
||||||
Config: config,
|
Config: config,
|
||||||
Events: events,
|
Events: events,
|
||||||
Active: &active,
|
Active: &active,
|
||||||
|
BranchFilter: branchFilter,
|
||||||
|
AuthorizationHeader: authHeader,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
_, err = client.EditRepoHook(c.Owner, c.Repo, int64(webhookID), gitea.EditHookOption{
|
_, err = client.EditRepoHook(c.Owner, c.Repo, int64(webhookID), gitea.EditHookOption{
|
||||||
Config: config,
|
Config: config,
|
||||||
Events: events,
|
Events: events,
|
||||||
Active: &active,
|
Active: &active,
|
||||||
|
BranchFilter: branchFilter,
|
||||||
|
AuthorizationHeader: authHeader,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -128,12 +128,10 @@ func TestUpdateActiveInactiveFlags(t *testing.T) {
|
|||||||
func TestUpdateConfigPreservation(t *testing.T) {
|
func TestUpdateConfigPreservation(t *testing.T) {
|
||||||
// Test that existing configuration is preserved when not updated
|
// Test that existing configuration is preserved when not updated
|
||||||
originalConfig := map[string]string{
|
originalConfig := map[string]string{
|
||||||
"url": "https://old.example.com/webhook",
|
"url": "https://old.example.com/webhook",
|
||||||
"secret": "old-secret",
|
"secret": "old-secret",
|
||||||
"branch_filter": "main",
|
"http_method": "post",
|
||||||
"authorization_header": "Bearer old-token",
|
"content_type": "json",
|
||||||
"http_method": "post",
|
|
||||||
"content_type": "json",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
@@ -147,53 +145,32 @@ func TestUpdateConfigPreservation(t *testing.T) {
|
|||||||
"url": "https://new.example.com/webhook",
|
"url": "https://new.example.com/webhook",
|
||||||
},
|
},
|
||||||
expectedConfig: map[string]string{
|
expectedConfig: map[string]string{
|
||||||
"url": "https://new.example.com/webhook",
|
"url": "https://new.example.com/webhook",
|
||||||
"secret": "old-secret",
|
"secret": "old-secret",
|
||||||
"branch_filter": "main",
|
"http_method": "post",
|
||||||
"authorization_header": "Bearer old-token",
|
"content_type": "json",
|
||||||
"http_method": "post",
|
|
||||||
"content_type": "json",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Update secret and auth header",
|
name: "Update secret",
|
||||||
updates: map[string]string{
|
updates: map[string]string{
|
||||||
"secret": "new-secret",
|
"secret": "new-secret",
|
||||||
"authorization_header": "X-Token: new-token",
|
|
||||||
},
|
},
|
||||||
expectedConfig: map[string]string{
|
expectedConfig: map[string]string{
|
||||||
"url": "https://old.example.com/webhook",
|
"url": "https://old.example.com/webhook",
|
||||||
"secret": "new-secret",
|
"secret": "new-secret",
|
||||||
"branch_filter": "main",
|
"http_method": "post",
|
||||||
"authorization_header": "X-Token: new-token",
|
"content_type": "json",
|
||||||
"http_method": "post",
|
|
||||||
"content_type": "json",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Clear branch filter",
|
|
||||||
updates: map[string]string{
|
|
||||||
"branch_filter": "",
|
|
||||||
},
|
|
||||||
expectedConfig: map[string]string{
|
|
||||||
"url": "https://old.example.com/webhook",
|
|
||||||
"secret": "old-secret",
|
|
||||||
"branch_filter": "",
|
|
||||||
"authorization_header": "Bearer old-token",
|
|
||||||
"http_method": "post",
|
|
||||||
"content_type": "json",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "No updates",
|
name: "No updates",
|
||||||
updates: map[string]string{},
|
updates: map[string]string{},
|
||||||
expectedConfig: map[string]string{
|
expectedConfig: map[string]string{
|
||||||
"url": "https://old.example.com/webhook",
|
"url": "https://old.example.com/webhook",
|
||||||
"secret": "old-secret",
|
"secret": "old-secret",
|
||||||
"branch_filter": "main",
|
"http_method": "post",
|
||||||
"authorization_header": "Bearer old-token",
|
"content_type": "json",
|
||||||
"http_method": "post",
|
|
||||||
"content_type": "json",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -217,6 +194,61 @@ func TestUpdateConfigPreservation(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUpdateBranchFilterAndAuthHeaderHandling(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
originalBranchFilter string
|
||||||
|
originalAuthHeader string
|
||||||
|
setBranchFilter bool
|
||||||
|
newBranchFilter string
|
||||||
|
setAuthorizationHeader bool
|
||||||
|
newAuthHeader string
|
||||||
|
expectedBranchFilter string
|
||||||
|
expectedAuthHeader string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Preserve values",
|
||||||
|
originalBranchFilter: "main",
|
||||||
|
originalAuthHeader: "Bearer old-token",
|
||||||
|
expectedBranchFilter: "main",
|
||||||
|
expectedAuthHeader: "Bearer old-token",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Update branch filter",
|
||||||
|
originalBranchFilter: "main",
|
||||||
|
setBranchFilter: true,
|
||||||
|
newBranchFilter: "develop",
|
||||||
|
expectedBranchFilter: "develop",
|
||||||
|
expectedAuthHeader: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Update authorization header",
|
||||||
|
originalAuthHeader: "Bearer old-token",
|
||||||
|
setAuthorizationHeader: true,
|
||||||
|
newAuthHeader: "X-Token: new-token",
|
||||||
|
expectedBranchFilter: "",
|
||||||
|
expectedAuthHeader: "X-Token: new-token",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
branchFilter := tt.originalBranchFilter
|
||||||
|
if tt.setBranchFilter {
|
||||||
|
branchFilter = tt.newBranchFilter
|
||||||
|
}
|
||||||
|
|
||||||
|
authHeader := tt.originalAuthHeader
|
||||||
|
if tt.setAuthorizationHeader {
|
||||||
|
authHeader = tt.newAuthHeader
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, tt.expectedBranchFilter, branchFilter)
|
||||||
|
assert.Equal(t, tt.expectedAuthHeader, authHeader)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestUpdateEventsHandling(t *testing.T) {
|
func TestUpdateEventsHandling(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
|||||||
@@ -1065,7 +1065,7 @@ Delete users Organizations
|
|||||||
|
|
||||||
## repos, repo
|
## repos, repo
|
||||||
|
|
||||||
Show repository details
|
Manage repositories
|
||||||
|
|
||||||
**--fields, -f**="": Comma-separated list of fields to print. Available values:
|
**--fields, -f**="": Comma-separated list of fields to print. Available values:
|
||||||
description,forks,id,name,owner,stars,ssh,updated,url,permission,type
|
description,forks,id,name,owner,stars,ssh,updated,url,permission,type
|
||||||
|
|||||||
6
go.mod
6
go.mod
@@ -5,7 +5,7 @@ go 1.26
|
|||||||
require (
|
require (
|
||||||
charm.land/glamour/v2 v2.0.0
|
charm.land/glamour/v2 v2.0.0
|
||||||
charm.land/huh/v2 v2.0.3
|
charm.land/huh/v2 v2.0.3
|
||||||
charm.land/lipgloss/v2 v2.0.2
|
charm.land/lipgloss/v2 v2.0.3
|
||||||
code.gitea.io/gitea-vet v0.2.3
|
code.gitea.io/gitea-vet v0.2.3
|
||||||
code.gitea.io/sdk/gitea v0.24.1
|
code.gitea.io/sdk/gitea v0.24.1
|
||||||
gitea.com/noerw/unidiff-comments v0.0.0-20220822113322-50f4daa0e35c
|
gitea.com/noerw/unidiff-comments v0.0.0-20220822113322-50f4daa0e35c
|
||||||
@@ -13,7 +13,7 @@ require (
|
|||||||
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de
|
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de
|
||||||
github.com/enescakir/emoji v1.0.0
|
github.com/enescakir/emoji v1.0.0
|
||||||
github.com/go-authgate/sdk-go v0.6.1
|
github.com/go-authgate/sdk-go v0.6.1
|
||||||
github.com/go-git/go-git/v5 v5.17.2
|
github.com/go-git/go-git/v5 v5.18.0
|
||||||
github.com/muesli/termenv v0.16.0
|
github.com/muesli/termenv v0.16.0
|
||||||
github.com/olekukonko/tablewriter v1.1.4
|
github.com/olekukonko/tablewriter v1.1.4
|
||||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
|
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
|
||||||
@@ -42,7 +42,7 @@ require (
|
|||||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
github.com/charmbracelet/colorprofile v0.4.3 // indirect
|
github.com/charmbracelet/colorprofile v0.4.3 // indirect
|
||||||
github.com/charmbracelet/ultraviolet v0.0.0-20260330092749-0f94982c930b // indirect
|
github.com/charmbracelet/ultraviolet v0.0.0-20260330092749-0f94982c930b // indirect
|
||||||
github.com/charmbracelet/x/ansi v0.11.6 // indirect
|
github.com/charmbracelet/x/ansi v0.11.7 // indirect
|
||||||
github.com/charmbracelet/x/exp/ordered v0.1.0 // indirect
|
github.com/charmbracelet/x/exp/ordered v0.1.0 // indirect
|
||||||
github.com/charmbracelet/x/exp/slice v0.0.0-20260406091427-a791e22d5143 // indirect
|
github.com/charmbracelet/x/exp/slice v0.0.0-20260406091427-a791e22d5143 // indirect
|
||||||
github.com/charmbracelet/x/exp/strings v0.1.0 // indirect
|
github.com/charmbracelet/x/exp/strings v0.1.0 // indirect
|
||||||
|
|||||||
6
go.sum
6
go.sum
@@ -8,6 +8,8 @@ charm.land/huh/v2 v2.0.3 h1:2cJsMqEPwSywGHvdlKsJyQKPtSJLVnFKyFbsYZTlLkU=
|
|||||||
charm.land/huh/v2 v2.0.3/go.mod h1:93eEveeeqn47MwiC3tf+2atZ2l7Is88rAtmZNZ8x9Wc=
|
charm.land/huh/v2 v2.0.3/go.mod h1:93eEveeeqn47MwiC3tf+2atZ2l7Is88rAtmZNZ8x9Wc=
|
||||||
charm.land/lipgloss/v2 v2.0.2 h1:xFolbF8JdpNkM2cEPTfXEcW1p6NRzOWTSamRfYEw8cs=
|
charm.land/lipgloss/v2 v2.0.2 h1:xFolbF8JdpNkM2cEPTfXEcW1p6NRzOWTSamRfYEw8cs=
|
||||||
charm.land/lipgloss/v2 v2.0.2/go.mod h1:KjPle2Qd3YmvP1KL5OMHiHysGcNwq6u83MUjYkFvEkM=
|
charm.land/lipgloss/v2 v2.0.2/go.mod h1:KjPle2Qd3YmvP1KL5OMHiHysGcNwq6u83MUjYkFvEkM=
|
||||||
|
charm.land/lipgloss/v2 v2.0.3 h1:yM2zJ4Cf5Y51b7RHIwioil4ApI/aypFXXVHSwlM6RzU=
|
||||||
|
charm.land/lipgloss/v2 v2.0.3/go.mod h1:7myLU9iG/3xluAWzpY/fSxYYHCgoKTie7laxk6ATwXA=
|
||||||
code.gitea.io/gitea-vet v0.2.3 h1:gdFmm6WOTM65rE8FUBTRzeQZYzXePKSSB1+r574hWwI=
|
code.gitea.io/gitea-vet v0.2.3 h1:gdFmm6WOTM65rE8FUBTRzeQZYzXePKSSB1+r574hWwI=
|
||||||
code.gitea.io/gitea-vet v0.2.3/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFjGGfE=
|
code.gitea.io/gitea-vet v0.2.3/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFjGGfE=
|
||||||
code.gitea.io/sdk/gitea v0.24.1 h1:hpaqcdGcBmfMpV7JSbBJVwE99qo+WqGreJYKrDKEyW8=
|
code.gitea.io/sdk/gitea v0.24.1 h1:hpaqcdGcBmfMpV7JSbBJVwE99qo+WqGreJYKrDKEyW8=
|
||||||
@@ -57,6 +59,8 @@ github.com/charmbracelet/ultraviolet v0.0.0-20260330092749-0f94982c930b h1:ASDO9
|
|||||||
github.com/charmbracelet/ultraviolet v0.0.0-20260330092749-0f94982c930b/go.mod h1:Vo8TffMf0q7Uho/n8e6XpBZvOWtd3g39yX+9P5rRutA=
|
github.com/charmbracelet/ultraviolet v0.0.0-20260330092749-0f94982c930b/go.mod h1:Vo8TffMf0q7Uho/n8e6XpBZvOWtd3g39yX+9P5rRutA=
|
||||||
github.com/charmbracelet/x/ansi v0.11.6 h1:GhV21SiDz/45W9AnV2R61xZMRri5NlLnl6CVF7ihZW8=
|
github.com/charmbracelet/x/ansi v0.11.6 h1:GhV21SiDz/45W9AnV2R61xZMRri5NlLnl6CVF7ihZW8=
|
||||||
github.com/charmbracelet/x/ansi v0.11.6/go.mod h1:2JNYLgQUsyqaiLovhU2Rv/pb8r6ydXKS3NIttu3VGZQ=
|
github.com/charmbracelet/x/ansi v0.11.6/go.mod h1:2JNYLgQUsyqaiLovhU2Rv/pb8r6ydXKS3NIttu3VGZQ=
|
||||||
|
github.com/charmbracelet/x/ansi v0.11.7 h1:kzv1kJvjg2S3r9KHo8hDdHFQLEqn4RBCb39dAYC84jI=
|
||||||
|
github.com/charmbracelet/x/ansi v0.11.7/go.mod h1:9qGpnAVYz+8ACONkZBUWPtL7lulP9No6p1epAihUZwQ=
|
||||||
github.com/charmbracelet/x/conpty v0.1.1 h1:s1bUxjoi7EpqiXysVtC+a8RrvPPNcNvAjfi4jxsAuEs=
|
github.com/charmbracelet/x/conpty v0.1.1 h1:s1bUxjoi7EpqiXysVtC+a8RrvPPNcNvAjfi4jxsAuEs=
|
||||||
github.com/charmbracelet/x/conpty v0.1.1/go.mod h1:OmtR77VODEFbiTzGE9G1XiRJAga6011PIm4u5fTNZpk=
|
github.com/charmbracelet/x/conpty v0.1.1/go.mod h1:OmtR77VODEFbiTzGE9G1XiRJAga6011PIm4u5fTNZpk=
|
||||||
github.com/charmbracelet/x/errors v0.0.0-20240508181413-e8d8b6e2de86 h1:JSt3B+U9iqk37QUU2Rvb6DSBYRLtWqFqfxf8l5hOZUA=
|
github.com/charmbracelet/x/errors v0.0.0-20240508181413-e8d8b6e2de86 h1:JSt3B+U9iqk37QUU2Rvb6DSBYRLtWqFqfxf8l5hOZUA=
|
||||||
@@ -122,6 +126,8 @@ github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMj
|
|||||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
|
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
|
||||||
github.com/go-git/go-git/v5 v5.17.2 h1:B+nkdlxdYrvyFK4GPXVU8w1U+YkbsgciIR7f2sZJ104=
|
github.com/go-git/go-git/v5 v5.17.2 h1:B+nkdlxdYrvyFK4GPXVU8w1U+YkbsgciIR7f2sZJ104=
|
||||||
github.com/go-git/go-git/v5 v5.17.2/go.mod h1:pW/VmeqkanRFqR6AljLcs7EA7FbZaN5MQqO7oZADXpo=
|
github.com/go-git/go-git/v5 v5.17.2/go.mod h1:pW/VmeqkanRFqR6AljLcs7EA7FbZaN5MQqO7oZADXpo=
|
||||||
|
github.com/go-git/go-git/v5 v5.18.0 h1:O831KI+0PR51hM2kep6T8k+w0/LIAD490gvqMCvL5hM=
|
||||||
|
github.com/go-git/go-git/v5 v5.18.0/go.mod h1:pW/VmeqkanRFqR6AljLcs7EA7FbZaN5MQqO7oZADXpo=
|
||||||
github.com/goccy/go-json v0.10.6 h1:p8HrPJzOakx/mn/bQtjgNjdTcN+/S6FcG2CTtQOrHVU=
|
github.com/goccy/go-json v0.10.6 h1:p8HrPJzOakx/mn/bQtjgNjdTcN+/S6FcG2CTtQOrHVU=
|
||||||
github.com/goccy/go-json v0.10.6/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
github.com/goccy/go-json v0.10.6/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||||
github.com/godbus/dbus/v5 v5.2.2 h1:TUR3TgtSVDmjiXOgAAyaZbYmIeP3DPkld3jgKGV8mXQ=
|
github.com/godbus/dbus/v5 v5.2.2 h1:TUR3TgtSVDmjiXOgAAyaZbYmIeP3DPkld3jgKGV8mXQ=
|
||||||
|
|||||||
@@ -83,6 +83,8 @@ func InitCommand(cmd *cli.Command) (*TeaContext, error) {
|
|||||||
}
|
}
|
||||||
if repoFlagPathExists {
|
if repoFlagPathExists {
|
||||||
repoPath = repoFlag
|
repoPath = repoFlag
|
||||||
|
} else {
|
||||||
|
c.RepoSlug = repoFlag
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,12 +92,6 @@ func InitCommand(cmd *cli.Command) (*TeaContext, error) {
|
|||||||
remoteFlag = config.GetPreferences().FlagDefaults.Remote
|
remoteFlag = config.GetPreferences().FlagDefaults.Remote
|
||||||
}
|
}
|
||||||
|
|
||||||
if repoPath == "" {
|
|
||||||
if repoPath, err = os.Getwd(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create env login before repo context detection so it participates in remote URL matching
|
// Create env login before repo context detection so it participates in remote URL matching
|
||||||
var extraLogins []config.Login
|
var extraLogins []config.Login
|
||||||
envLogin := GetLoginByEnvVar()
|
envLogin := GetLoginByEnvVar()
|
||||||
@@ -108,17 +104,20 @@ func InitCommand(cmd *cli.Command) (*TeaContext, error) {
|
|||||||
|
|
||||||
// try to read local git repo & extract context: if repoFlag specifies a valid path, read repo in that dir,
|
// try to read local git repo & extract context: if repoFlag specifies a valid path, read repo in that dir,
|
||||||
// otherwise attempt PWD. if no repo is found, continue with default login
|
// otherwise attempt PWD. if no repo is found, continue with default login
|
||||||
if c.LocalRepo, c.Login, c.RepoSlug, err = contextFromLocalRepo(repoPath, remoteFlag, extraLogins); err != nil {
|
if c.RepoSlug == "" {
|
||||||
if err == errNotAGiteaRepo || err == gogit.ErrRepositoryNotExists {
|
if repoPath == "" {
|
||||||
// we can deal with that, commands needing the optional values use ctx.Ensure()
|
if repoPath, err = os.Getwd(); err != nil {
|
||||||
} else {
|
return nil, err
|
||||||
return nil, err
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if len(repoFlag) != 0 && !repoFlagPathExists {
|
if c.LocalRepo, c.Login, c.RepoSlug, err = contextFromLocalRepo(repoPath, remoteFlag, extraLogins); err != nil {
|
||||||
// if repoFlag is not a valid path, use it to override repoSlug
|
if err == errNotAGiteaRepo || err == gogit.ErrRepositoryNotExists {
|
||||||
c.RepoSlug = repoFlag
|
// we can deal with that, commands needing the optional values use ctx.Ensure()
|
||||||
|
} else {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If env vars are set, always use the env login (but repo slug was already
|
// If env vars are set, always use the env login (but repo slug was already
|
||||||
|
|||||||
@@ -4,9 +4,14 @@
|
|||||||
package context
|
package context
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/tea/modules/config"
|
"code.gitea.io/tea/modules/config"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_MatchLogins(t *testing.T) {
|
func Test_MatchLogins(t *testing.T) {
|
||||||
@@ -65,3 +70,47 @@ func Test_MatchLogins(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestInitCommand_WithRepoSlugSkipsLocalRepoDetection(t *testing.T) {
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
config.SetConfigForTesting(config.LocalConfig{
|
||||||
|
Logins: []config.Login{{
|
||||||
|
Name: "test-login",
|
||||||
|
URL: "https://gitea.example.com",
|
||||||
|
Token: "token",
|
||||||
|
User: "login-user",
|
||||||
|
Default: true,
|
||||||
|
}},
|
||||||
|
})
|
||||||
|
|
||||||
|
cmd := exec.Command("git", "init", "--object-format=sha256", tmpDir)
|
||||||
|
cmd.Env = os.Environ()
|
||||||
|
require.NoError(t, cmd.Run())
|
||||||
|
|
||||||
|
oldWd, err := os.Getwd()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, os.Chdir(tmpDir))
|
||||||
|
t.Cleanup(func() {
|
||||||
|
require.NoError(t, os.Chdir(oldWd))
|
||||||
|
})
|
||||||
|
|
||||||
|
cliCmd := cli.Command{
|
||||||
|
Name: "branches",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.StringFlag{Name: "login"},
|
||||||
|
&cli.StringFlag{Name: "repo"},
|
||||||
|
&cli.StringFlag{Name: "remote"},
|
||||||
|
&cli.StringFlag{Name: "output"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
require.NoError(t, cliCmd.Set("repo", "owner/repo"))
|
||||||
|
|
||||||
|
ctx, err := InitCommand(&cliCmd)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "owner", ctx.Owner)
|
||||||
|
require.Equal(t, "repo", ctx.Repo)
|
||||||
|
require.Equal(t, "owner/repo", ctx.RepoSlug)
|
||||||
|
require.Nil(t, ctx.LocalRepo)
|
||||||
|
require.NotNil(t, ctx.Login)
|
||||||
|
require.Equal(t, "test-login", ctx.Login.Name)
|
||||||
|
}
|
||||||
|
|||||||
@@ -67,13 +67,21 @@ func WebhookDetails(hook *gitea.Hook) {
|
|||||||
if method, ok := hook.Config["http_method"]; ok {
|
if method, ok := hook.Config["http_method"]; ok {
|
||||||
fmt.Printf("- **HTTP Method**: %s\n", method)
|
fmt.Printf("- **HTTP Method**: %s\n", method)
|
||||||
}
|
}
|
||||||
if branchFilter, ok := hook.Config["branch_filter"]; ok && branchFilter != "" {
|
branchFilter := hook.BranchFilter
|
||||||
|
if branchFilter == "" {
|
||||||
|
branchFilter = hook.Config["branch_filter"]
|
||||||
|
}
|
||||||
|
if branchFilter != "" {
|
||||||
fmt.Printf("- **Branch Filter**: %s\n", branchFilter)
|
fmt.Printf("- **Branch Filter**: %s\n", branchFilter)
|
||||||
}
|
}
|
||||||
if _, hasSecret := hook.Config["secret"]; hasSecret {
|
if _, hasSecret := hook.Config["secret"]; hasSecret {
|
||||||
fmt.Printf("- **Secret**: (configured)\n")
|
fmt.Printf("- **Secret**: (configured)\n")
|
||||||
}
|
}
|
||||||
if _, hasAuth := hook.Config["authorization_header"]; hasAuth {
|
hasAuth := hook.AuthorizationHeader != ""
|
||||||
|
if !hasAuth {
|
||||||
|
_, hasAuth = hook.Config["authorization_header"]
|
||||||
|
}
|
||||||
|
if hasAuth {
|
||||||
fmt.Printf("- **Authorization Header**: (configured)\n")
|
fmt.Printf("- **Authorization Header**: (configured)\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,17 +81,17 @@ func TestWebhookDetails(t *testing.T) {
|
|||||||
ID: 123,
|
ID: 123,
|
||||||
Type: "gitea",
|
Type: "gitea",
|
||||||
Config: map[string]string{
|
Config: map[string]string{
|
||||||
"url": "https://example.com/webhook",
|
"url": "https://example.com/webhook",
|
||||||
"content_type": "json",
|
"content_type": "json",
|
||||||
"http_method": "post",
|
"http_method": "post",
|
||||||
"branch_filter": "main,develop",
|
"secret": "secret-value",
|
||||||
"secret": "secret-value",
|
|
||||||
"authorization_header": "Bearer token123",
|
|
||||||
},
|
},
|
||||||
Events: []string{"push", "pull_request", "issues"},
|
BranchFilter: "main,develop",
|
||||||
Active: true,
|
AuthorizationHeader: "Bearer token123",
|
||||||
Created: now.Add(-24 * time.Hour),
|
Events: []string{"push", "pull_request", "issues"},
|
||||||
Updated: now,
|
Active: true,
|
||||||
|
Created: now.Add(-24 * time.Hour),
|
||||||
|
Updated: now,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -238,16 +238,14 @@ func TestWebhookConfigHandling(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "Config with all fields",
|
name: "Config with all fields",
|
||||||
config: map[string]string{
|
config: map[string]string{
|
||||||
"url": "https://example.com/webhook",
|
"url": "https://example.com/webhook",
|
||||||
"secret": "my-secret",
|
"secret": "my-secret",
|
||||||
"authorization_header": "Bearer token",
|
"content_type": "json",
|
||||||
"content_type": "json",
|
"http_method": "post",
|
||||||
"http_method": "post",
|
|
||||||
"branch_filter": "main",
|
|
||||||
},
|
},
|
||||||
expectedURL: "https://example.com/webhook",
|
expectedURL: "https://example.com/webhook",
|
||||||
hasSecret: true,
|
hasSecret: true,
|
||||||
hasAuthHeader: true,
|
hasAuthHeader: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Config with minimal fields",
|
name: "Config with minimal fields",
|
||||||
@@ -341,17 +339,17 @@ func TestWebhookDetailsFormatting(t *testing.T) {
|
|||||||
ID: 123,
|
ID: 123,
|
||||||
Type: "gitea",
|
Type: "gitea",
|
||||||
Config: map[string]string{
|
Config: map[string]string{
|
||||||
"url": "https://example.com/webhook",
|
"url": "https://example.com/webhook",
|
||||||
"content_type": "json",
|
"content_type": "json",
|
||||||
"http_method": "post",
|
"http_method": "post",
|
||||||
"branch_filter": "main,develop",
|
"secret": "secret-value",
|
||||||
"secret": "secret-value",
|
|
||||||
"authorization_header": "Bearer token123",
|
|
||||||
},
|
},
|
||||||
Events: []string{"push", "pull_request", "issues"},
|
BranchFilter: "main,develop",
|
||||||
Active: true,
|
AuthorizationHeader: "Bearer token123",
|
||||||
Created: now.Add(-24 * time.Hour),
|
Events: []string{"push", "pull_request", "issues"},
|
||||||
Updated: now,
|
Active: true,
|
||||||
|
Created: now.Add(-24 * time.Hour),
|
||||||
|
Updated: now,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that all expected fields are included in details
|
// Test that all expected fields are included in details
|
||||||
@@ -379,8 +377,8 @@ func TestWebhookDetailsFormatting(t *testing.T) {
|
|||||||
assert.Equal(t, "https://example.com/webhook", hook.Config["url"])
|
assert.Equal(t, "https://example.com/webhook", hook.Config["url"])
|
||||||
assert.Equal(t, "json", hook.Config["content_type"])
|
assert.Equal(t, "json", hook.Config["content_type"])
|
||||||
assert.Equal(t, "post", hook.Config["http_method"])
|
assert.Equal(t, "post", hook.Config["http_method"])
|
||||||
assert.Equal(t, "main,develop", hook.Config["branch_filter"])
|
assert.Equal(t, "main,develop", hook.BranchFilter)
|
||||||
assert.Contains(t, hook.Config, "secret")
|
assert.Contains(t, hook.Config, "secret")
|
||||||
assert.Contains(t, hook.Config, "authorization_header")
|
assert.Equal(t, "Bearer token123", hook.AuthorizationHeader)
|
||||||
assert.Equal(t, []string{"push", "pull_request", "issues"}, hook.Events)
|
assert.Equal(t, []string{"push", "pull_request", "issues"}, hook.Events)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user