mirror of
https://github.com/go-gitea/gitea.git
synced 2026-09-08 14:03:24 +09:00
chore: enable forcetypeassert linter, fix issues (#38804)
Enable [`forcetypeassert`](https://github.com/gostaticanalysis/forcetypeassert) linter to prevent unchecked type assertions. ~650 issues fixed, most fixes were clean, some use `setting.PanicInDevOrTesting`. The only behaviour changes are where code would previously send a 500 error or panic, a 4xx error is now emitted. Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
@@ -11,6 +11,7 @@ linters:
|
|||||||
- dupl
|
- dupl
|
||||||
- errcheck
|
- errcheck
|
||||||
- forbidigo
|
- forbidigo
|
||||||
|
- forcetypeassert
|
||||||
- gocheckcompilerdirectives
|
- gocheckcompilerdirectives
|
||||||
- gocritic
|
- gocritic
|
||||||
- govet
|
- govet
|
||||||
|
|||||||
+27
-17
@@ -354,13 +354,10 @@ func findLdapSecurityProtocolByName(name string) (ldap.SecurityProtocol, bool) {
|
|||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
|
|
||||||
// getAuthSource gets the login source by its id defined in the command line flags.
|
// getAuthSourceOfType gets the login source by id.
|
||||||
// It returns an error if the id is not set, does not match any source or if the source is not of expected type.
|
// It returns an error if the id does not match any source or if the source is not of the expected type.
|
||||||
func (a *authService) getAuthSource(ctx context.Context, c *cli.Command, authType auth.Type) (*auth.Source, error) {
|
func (a *authService) getAuthSourceOfType(ctx context.Context, id int64, authType auth.Type) (*auth.Source, error) {
|
||||||
if err := argsSet(c, "id"); err != nil {
|
authSource, err := a.getAuthSourceByID(ctx, id)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
authSource, err := a.getAuthSourceByID(ctx, c.Int64("id"))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -372,6 +369,15 @@ func (a *authService) getAuthSource(ctx context.Context, c *cli.Command, authTyp
|
|||||||
return authSource, nil
|
return authSource, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getAuthSource gets the login source by its id defined in the command line flags.
|
||||||
|
// It returns an error if the id is not set, does not match any source or if the source is not of expected type.
|
||||||
|
func (a *authService) getAuthSource(ctx context.Context, c *cli.Command, authType auth.Type) (*auth.Source, error) {
|
||||||
|
if err := argsSet(c, "id"); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return a.getAuthSourceOfType(ctx, c.Int64("id"), authType)
|
||||||
|
}
|
||||||
|
|
||||||
// addLdapBindDn adds a new LDAP via Bind DN authentication source.
|
// addLdapBindDn adds a new LDAP via Bind DN authentication source.
|
||||||
func (a *authService) addLdapBindDn(ctx context.Context, c *cli.Command) error {
|
func (a *authService) addLdapBindDn(ctx context.Context, c *cli.Command) error {
|
||||||
if err := argsSet(c, "name", "security-protocol", "host", "port", "user-search-base", "user-filter", "email-attribute"); err != nil {
|
if err := argsSet(c, "name", "security-protocol", "host", "port", "user-search-base", "user-filter", "email-attribute"); err != nil {
|
||||||
@@ -381,16 +387,17 @@ func (a *authService) addLdapBindDn(ctx context.Context, c *cli.Command) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ldapConfig := &ldap.Source{
|
||||||
|
Enabled: true, // always true
|
||||||
|
}
|
||||||
authSource := &auth.Source{
|
authSource := &auth.Source{
|
||||||
Type: auth.LDAP,
|
Type: auth.LDAP,
|
||||||
IsActive: true, // active by default
|
IsActive: true, // active by default
|
||||||
Cfg: &ldap.Source{
|
Cfg: ldapConfig,
|
||||||
Enabled: true, // always true
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
parseAuthSourceLdap(c, authSource)
|
parseAuthSourceLdap(c, authSource)
|
||||||
if err := parseLdapConfig(c, authSource.Cfg.(*ldap.Source)); err != nil {
|
if err := parseLdapConfig(c, ldapConfig); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -407,9 +414,10 @@ func (a *authService) updateLdapBindDn(ctx context.Context, c *cli.Command) erro
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
ldapConfig := auth.MustSourceCfg[*ldap.Source](authSource)
|
||||||
|
|
||||||
parseAuthSourceLdap(c, authSource)
|
parseAuthSourceLdap(c, authSource)
|
||||||
if err := parseLdapConfig(c, authSource.Cfg.(*ldap.Source)); err != nil {
|
if err := parseLdapConfig(c, ldapConfig); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -426,16 +434,17 @@ func (a *authService) addLdapSimpleAuth(ctx context.Context, c *cli.Command) err
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ldapConfig := &ldap.Source{
|
||||||
|
Enabled: true, // always true
|
||||||
|
}
|
||||||
authSource := &auth.Source{
|
authSource := &auth.Source{
|
||||||
Type: auth.DLDAP,
|
Type: auth.DLDAP,
|
||||||
IsActive: true, // active by default
|
IsActive: true, // active by default
|
||||||
Cfg: &ldap.Source{
|
Cfg: ldapConfig,
|
||||||
Enabled: true, // always true
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
parseAuthSourceLdap(c, authSource)
|
parseAuthSourceLdap(c, authSource)
|
||||||
if err := parseLdapConfig(c, authSource.Cfg.(*ldap.Source)); err != nil {
|
if err := parseLdapConfig(c, ldapConfig); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -452,9 +461,10 @@ func (a *authService) updateLdapSimpleAuth(ctx context.Context, c *cli.Command)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
ldapConfig := auth.MustSourceCfg[*ldap.Source](authSource)
|
||||||
|
|
||||||
parseAuthSourceLdap(c, authSource)
|
parseAuthSourceLdap(c, authSource)
|
||||||
if err := parseLdapConfig(c, authSource.Cfg.(*ldap.Source)); err != nil {
|
if err := parseLdapConfig(c, ldapConfig); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -221,12 +221,11 @@ func (a *authService) runUpdateOauth(ctx context.Context, c *cli.Command) error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
source, err := a.getAuthSourceByID(ctx, c.Int64("id"))
|
source, err := a.getAuthSourceOfType(ctx, c.Int64("id"), auth_model.OAuth2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
oAuth2Config := auth_model.MustSourceCfg[*oauth2.Source](source)
|
||||||
oAuth2Config := source.Cfg.(*oauth2.Source)
|
|
||||||
|
|
||||||
if c.IsSet("name") {
|
if c.IsSet("name") {
|
||||||
source.Name = c.String("name")
|
source.Name = c.String("name")
|
||||||
|
|||||||
@@ -175,12 +175,11 @@ func (a *authService) runUpdateSMTP(ctx context.Context, c *cli.Command) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
source, err := a.getAuthSourceByID(ctx, c.Int64("id"))
|
source, err := a.getAuthSourceOfType(ctx, c.Int64("id"), auth_model.SMTP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
smtpConfig := auth_model.MustSourceCfg[*smtp.Source](source)
|
||||||
smtpConfig := source.Cfg.(*smtp.Source)
|
|
||||||
|
|
||||||
if err := parseSMTPConfig(c, smtpConfig); err != nil {
|
if err := parseSMTPConfig(c, smtpConfig); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ package v1_14
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -106,8 +107,8 @@ func FixPublisherIDforTagReleases(ctx context.Context, x base.EngineMigration) e
|
|||||||
|
|
||||||
commit, err := gitRepo.GetTagCommit(ctx, release.TagName)
|
commit, err := gitRepo.GetTagCommit(ctx, release.TagName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if git.IsErrNotExist(err) {
|
if errNotExist, ok := errors.AsType[git.ErrNotExist](err); ok {
|
||||||
log.Warn("Unable to find commit %s for Tag: %s in [%d]%s/%s. Cannot update publisher ID.", err.(git.ErrNotExist).ID, release.TagName, repo.ID, repo.OwnerName, repo.Name)
|
log.Warn("Unable to find commit %s for Tag: %s in [%d]%s/%s. Cannot update publisher ID.", errNotExist.ID, release.TagName, repo.ID, repo.OwnerName, repo.Name)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
log.Error("Error whilst getting commit for Tag: %s in [%d]%s/%s. Error: %v", release.TagName, repo.ID, repo.OwnerName, repo.Name, err)
|
log.Error("Error whilst getting commit for Tag: %s in [%d]%s/%s. Error: %v", release.TagName, repo.ID, repo.OwnerName, repo.Name, err)
|
||||||
@@ -118,8 +119,8 @@ func FixPublisherIDforTagReleases(ctx context.Context, x base.EngineMigration) e
|
|||||||
log.Warn("Tag: %s in Repo[%d]%s/%s does not have a tagger.", release.TagName, repo.ID, repo.OwnerName, repo.Name)
|
log.Warn("Tag: %s in Repo[%d]%s/%s does not have a tagger.", release.TagName, repo.ID, repo.OwnerName, repo.Name)
|
||||||
commit, err = gitRepo.GetCommit(ctx, commit.ID.String())
|
commit, err = gitRepo.GetCommit(ctx, commit.ID.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if git.IsErrNotExist(err) {
|
if errNotExist, ok := errors.AsType[git.ErrNotExist](err); ok {
|
||||||
log.Warn("Unable to find commit %s for Tag: %s in [%d]%s/%s. Cannot update publisher ID.", err.(git.ErrNotExist).ID, release.TagName, repo.ID, repo.OwnerName, repo.Name)
|
log.Warn("Unable to find commit %s for Tag: %s in [%d]%s/%s. Cannot update publisher ID.", errNotExist.ID, release.TagName, repo.ID, repo.OwnerName, repo.Name)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
log.Error("Error whilst getting commit for Tag: %s in [%d]%s/%s. Error: %v", release.TagName, repo.ID, repo.OwnerName, repo.Name, err)
|
log.Error("Error whilst getting commit for Tag: %s in [%d]%s/%s. Error: %v", release.TagName, repo.ID, repo.OwnerName, repo.Name, err)
|
||||||
|
|||||||
@@ -51,16 +51,16 @@ func AddPullRequestRebaseWithMerge(_ context.Context, x base.EngineMigration) er
|
|||||||
// Allow the new merge style if all other merge styles are allowed
|
// Allow the new merge style if all other merge styles are allowed
|
||||||
allowMergeRebase := true
|
allowMergeRebase := true
|
||||||
|
|
||||||
if allowMerge, ok := unit.Config["AllowMerge"]; ok {
|
if allowMerge, ok := unit.Config["AllowMerge"].(bool); ok {
|
||||||
allowMergeRebase = allowMergeRebase && allowMerge.(bool)
|
allowMergeRebase = allowMergeRebase && allowMerge
|
||||||
}
|
}
|
||||||
|
|
||||||
if allowRebase, ok := unit.Config["AllowRebase"]; ok {
|
if allowRebase, ok := unit.Config["AllowRebase"].(bool); ok {
|
||||||
allowMergeRebase = allowMergeRebase && allowRebase.(bool)
|
allowMergeRebase = allowMergeRebase && allowRebase
|
||||||
}
|
}
|
||||||
|
|
||||||
if allowSquash, ok := unit.Config["AllowSquash"]; ok {
|
if allowSquash, ok := unit.Config["AllowSquash"].(bool); ok {
|
||||||
allowMergeRebase = allowMergeRebase && allowSquash.(bool)
|
allowMergeRebase = allowMergeRebase && allowSquash
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := unit.Config["AllowRebaseMerge"]; !ok {
|
if _, ok := unit.Config["AllowRebaseMerge"]; !ok {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import (
|
|||||||
"gitea.dev/modules/util"
|
"gitea.dev/modules/util"
|
||||||
|
|
||||||
"golang.org/x/crypto/ssh"
|
"golang.org/x/crypto/ssh"
|
||||||
|
"xorm.io/builder"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AuthorizedStringCommentPrefix is a magic tag
|
// AuthorizedStringCommentPrefix is a magic tag
|
||||||
@@ -162,8 +163,8 @@ func appendAuthorizedKeysToFile(keys ...*PublicKey) error {
|
|||||||
|
|
||||||
// RegeneratePublicKeys regenerates the authorized_keys file
|
// RegeneratePublicKeys regenerates the authorized_keys file
|
||||||
func RegeneratePublicKeys(ctx context.Context, t io.Writer) error {
|
func RegeneratePublicKeys(ctx context.Context, t io.Writer) error {
|
||||||
if err := db.GetEngine(ctx).Where("type != ?", KeyTypePrincipal).Iterate(new(PublicKey), func(idx int, bean any) (err error) {
|
if err := db.Iterate(ctx, builder.Neq{"type": KeyTypePrincipal}, func(ctx context.Context, key *PublicKey) error {
|
||||||
return WriteAuthorizedStringForValidKey(bean.(*PublicKey), t)
|
return WriteAuthorizedStringForValidKey(key, t)
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-20
@@ -98,20 +98,12 @@ type RegisterableSource interface {
|
|||||||
|
|
||||||
var registeredConfigs = map[Type]func() Config{}
|
var registeredConfigs = map[Type]func() Config{}
|
||||||
|
|
||||||
// RegisterTypeConfig register a config for a provided type
|
// RegisterTypeConfig register a config for a provided type, the exemplar argument only serves type inference
|
||||||
func RegisterTypeConfig(typ Type, exemplar Config) {
|
func RegisterTypeConfig[T interface {
|
||||||
if reflect.TypeOf(exemplar).Kind() == reflect.Pointer {
|
*E
|
||||||
// Pointer:
|
Config
|
||||||
registeredConfigs[typ] = func() Config {
|
}, E any](typ Type, _ T) {
|
||||||
return reflect.New(reflect.ValueOf(exemplar).Elem().Type()).Interface().(Config)
|
registeredConfigs[typ] = func() Config { return T(new(E)) }
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not a Pointer
|
|
||||||
registeredConfigs[typ] = func() Config {
|
|
||||||
return reflect.New(reflect.TypeOf(exemplar)).Elem().Interface().(Config)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Source represents an external way for authorizing users.
|
// Source represents an external way for authorizing users.
|
||||||
@@ -188,6 +180,16 @@ func (source *Source) IsSSPI() bool {
|
|||||||
return source.Type == SSPI
|
return source.Type == SSPI
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MustSourceCfg returns the source's config as T. The registry populates Cfg from the
|
||||||
|
// source type, so a mismatch is a programming error the caller can't recover from.
|
||||||
|
func MustSourceCfg[T Config](source *Source) T {
|
||||||
|
cfg, ok := source.Cfg.(T)
|
||||||
|
if !ok {
|
||||||
|
panic(fmt.Errorf("auth source %q (id=%d, type=%s) has config %T, expected %s", source.Name, source.ID, source.Type, source.Cfg, reflect.TypeFor[T]()))
|
||||||
|
}
|
||||||
|
return cfg
|
||||||
|
}
|
||||||
|
|
||||||
// HasTLS returns true of this source supports TLS.
|
// HasTLS returns true of this source supports TLS.
|
||||||
func (source *Source) HasTLS() bool {
|
func (source *Source) HasTLS() bool {
|
||||||
hasTLSer, ok := source.Cfg.(HasTLSer)
|
hasTLSer, ok := source.Cfg.(HasTLSer)
|
||||||
@@ -371,12 +373,6 @@ type ErrSourceAlreadyExist struct {
|
|||||||
Name string
|
Name string
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsErrSourceAlreadyExist checks if an error is a ErrSourceAlreadyExist.
|
|
||||||
func IsErrSourceAlreadyExist(err error) bool {
|
|
||||||
_, ok := err.(ErrSourceAlreadyExist)
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
func (err ErrSourceAlreadyExist) Error() string {
|
func (err ErrSourceAlreadyExist) Error() string {
|
||||||
return fmt.Sprintf("login source already exists [name: %s]", err.Name)
|
return fmt.Sprintf("login source already exists [name: %s]", err.Name)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
"gitea.dev/models/unittest"
|
"gitea.dev/models/unittest"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestInTransaction(t *testing.T) {
|
func TestInTransaction(t *testing.T) {
|
||||||
@@ -107,7 +108,8 @@ func TestContextSafety(t *testing.T) {
|
|||||||
_ = db.GetEngine(ctx).Iterate(&TestModel1{}, func(i int, bean any) error {
|
_ = db.GetEngine(ctx).Iterate(&TestModel1{}, func(i int, bean any) error {
|
||||||
// here: db.GetEngine(ctx) is always the unclosed "Iterate" *Session with autoResetStatement=false,
|
// here: db.GetEngine(ctx) is always the unclosed "Iterate" *Session with autoResetStatement=false,
|
||||||
// and the internal states (including "cond" and others) are always there and not be reset in this callback.
|
// and the internal states (including "cond" and others) are always there and not be reset in this callback.
|
||||||
m1 := bean.(*TestModel1)
|
m1, ok := bean.(*TestModel1)
|
||||||
|
require.True(t, ok)
|
||||||
assert.EqualValues(t, i+1, m1.ID)
|
assert.EqualValues(t, i+1, m1.ID)
|
||||||
|
|
||||||
// here: XORM bug, it fails because the SQL becomes "WHERE id=-1", "WHERE id=-1 AND id=-2", "WHERE id=-1 AND id=-2 AND id=-3" ...
|
// here: XORM bug, it fails because the SQL becomes "WHERE id=-1", "WHERE id=-1 AND id=-2", "WHERE id=-1 AND id=-2 AND id=-3" ...
|
||||||
|
|||||||
@@ -14,12 +14,6 @@ type ErrCancelled struct {
|
|||||||
Message string
|
Message string
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsErrCancelled checks if an error is a ErrCancelled.
|
|
||||||
func IsErrCancelled(err error) bool {
|
|
||||||
_, ok := err.(ErrCancelled)
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
func (err ErrCancelled) Error() string {
|
func (err ErrCancelled) Error() string {
|
||||||
return "Cancelled: " + err.Message
|
return "Cancelled: " + err.Message
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -239,6 +239,15 @@ func GetPackageDescriptorWithCache(ctx context.Context, pv *PackageVersion, c *c
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DescriptorMetadata returns the descriptor's metadata, which getPackageDescriptor has created from the package type
|
||||||
|
func DescriptorMetadata[T interface{ *E }, E any](pd *PackageDescriptor) T {
|
||||||
|
metadata, ok := pd.Metadata.(T)
|
||||||
|
if !ok {
|
||||||
|
panic(fmt.Errorf("package %s of type %s has metadata type %T instead of %T", pd.Package.Name, pd.Package.Type, pd.Metadata, metadata))
|
||||||
|
}
|
||||||
|
return metadata
|
||||||
|
}
|
||||||
|
|
||||||
// GetPackageFileDescriptor gets a package file descriptor for a package file
|
// GetPackageFileDescriptor gets a package file descriptor for a package file
|
||||||
func GetPackageFileDescriptor(ctx context.Context, pf *PackageFile) (*PackageFileDescriptor, error) {
|
func GetPackageFileDescriptor(ctx context.Context, pf *PackageFile) (*PackageFileDescriptor, error) {
|
||||||
return getPackageFileDescriptor(ctx, pf, cache.NewEphemeralCache())
|
return getPackageFileDescriptor(ctx, pf, cache.NewEphemeralCache())
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ package repo
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"gitea.dev/models/db"
|
"gitea.dev/models/db"
|
||||||
"gitea.dev/models/perm"
|
"gitea.dev/models/perm"
|
||||||
@@ -295,44 +296,56 @@ func (r *RepoUnit) Unit() unit.Unit {
|
|||||||
return unit.Units[r.Type]
|
return unit.Units[r.Type]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// unitConfig returns the unit's config, which BeforeSet has created from the unit type
|
||||||
|
func unitConfig[T interface {
|
||||||
|
*E
|
||||||
|
convert.Conversion
|
||||||
|
}, E any](r *RepoUnit) T {
|
||||||
|
config, ok := r.Config.(T)
|
||||||
|
if !ok {
|
||||||
|
panic(fmt.Errorf("repo unit %d of type %s has config type %T instead of %T", r.ID, r.Type.LogString(), r.Config, config))
|
||||||
|
}
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
// CodeConfig returns config for unit.TypeCode
|
// CodeConfig returns config for unit.TypeCode
|
||||||
func (r *RepoUnit) CodeConfig() *UnitConfig {
|
func (r *RepoUnit) CodeConfig() *UnitConfig {
|
||||||
return r.Config.(*UnitConfig)
|
return unitConfig[*UnitConfig](r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PullRequestsConfig returns config for unit.TypePullRequests
|
// PullRequestsConfig returns config for unit.TypePullRequests
|
||||||
func (r *RepoUnit) PullRequestsConfig() *PullRequestsConfig {
|
func (r *RepoUnit) PullRequestsConfig() *PullRequestsConfig {
|
||||||
return r.Config.(*PullRequestsConfig)
|
return unitConfig[*PullRequestsConfig](r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReleasesConfig returns config for unit.TypeReleases
|
// ReleasesConfig returns config for unit.TypeReleases
|
||||||
func (r *RepoUnit) ReleasesConfig() *UnitConfig {
|
func (r *RepoUnit) ReleasesConfig() *UnitConfig {
|
||||||
return r.Config.(*UnitConfig)
|
return unitConfig[*UnitConfig](r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExternalWikiConfig returns config for unit.TypeExternalWiki
|
// ExternalWikiConfig returns config for unit.TypeExternalWiki
|
||||||
func (r *RepoUnit) ExternalWikiConfig() *ExternalWikiConfig {
|
func (r *RepoUnit) ExternalWikiConfig() *ExternalWikiConfig {
|
||||||
return r.Config.(*ExternalWikiConfig)
|
return unitConfig[*ExternalWikiConfig](r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IssuesConfig returns config for unit.TypeIssues
|
// IssuesConfig returns config for unit.TypeIssues
|
||||||
func (r *RepoUnit) IssuesConfig() *IssuesConfig {
|
func (r *RepoUnit) IssuesConfig() *IssuesConfig {
|
||||||
return r.Config.(*IssuesConfig)
|
return unitConfig[*IssuesConfig](r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExternalTrackerConfig returns config for unit.TypeExternalTracker
|
// ExternalTrackerConfig returns config for unit.TypeExternalTracker
|
||||||
func (r *RepoUnit) ExternalTrackerConfig() *ExternalTrackerConfig {
|
func (r *RepoUnit) ExternalTrackerConfig() *ExternalTrackerConfig {
|
||||||
return r.Config.(*ExternalTrackerConfig)
|
return unitConfig[*ExternalTrackerConfig](r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionsConfig returns config for unit.ActionsConfig
|
// ActionsConfig returns config for unit.ActionsConfig
|
||||||
func (r *RepoUnit) ActionsConfig() *ActionsConfig {
|
func (r *RepoUnit) ActionsConfig() *ActionsConfig {
|
||||||
return r.Config.(*ActionsConfig)
|
return unitConfig[*ActionsConfig](r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProjectsConfig returns config for unit.ProjectsConfig
|
// ProjectsConfig returns config for unit.ProjectsConfig
|
||||||
func (r *RepoUnit) ProjectsConfig() *ProjectsConfig {
|
func (r *RepoUnit) ProjectsConfig() *ProjectsConfig {
|
||||||
return r.Config.(*ProjectsConfig)
|
return unitConfig[*ProjectsConfig](r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getUnitsByRepoID(ctx context.Context, repoID int64) (units []*RepoUnit, err error) {
|
func getUnitsByRepoID(ctx context.Context, repoID int64) (units []*RepoUnit, err error) {
|
||||||
|
|||||||
@@ -34,7 +34,8 @@ type FixtureItem struct {
|
|||||||
|
|
||||||
type fixturesLoaderInternal struct {
|
type fixturesLoaderInternal struct {
|
||||||
xormEngine *xorm.Engine
|
xormEngine *xorm.Engine
|
||||||
tableSyncMap sync.Map
|
tableSyncMu sync.Mutex
|
||||||
|
tableSynced map[string]bool
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
dbType schemas.DBType
|
dbType schemas.DBType
|
||||||
fixtures map[string]*FixtureItem
|
fixtures map[string]*FixtureItem
|
||||||
@@ -152,32 +153,35 @@ func (f *fixturesLoaderInternal) Load() error {
|
|||||||
|
|
||||||
ctx := context.WithValue(context.Background(), db.ContextKeyTestFixtures, true)
|
ctx := context.WithValue(context.Background(), db.ContextKeyTestFixtures, true)
|
||||||
|
|
||||||
|
f.tableSyncMu.Lock()
|
||||||
|
defer f.tableSyncMu.Unlock()
|
||||||
|
|
||||||
for _, fixture := range f.fixtures {
|
for _, fixture := range f.fixtures {
|
||||||
synced, existing := f.tableSyncMap.Load(fixture.tableName)
|
synced, existing := f.tableSynced[fixture.tableName]
|
||||||
if synced == true || !existing {
|
if synced || !existing {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := f.loadFixtures(tx, fixture); err != nil {
|
if err := f.loadFixtures(tx, fixture); err != nil {
|
||||||
return fmt.Errorf("failed to load fixtures from %s: %w", fixture.fileFullPath, err)
|
return fmt.Errorf("failed to load fixtures from %s: %w", fixture.fileFullPath, err)
|
||||||
}
|
}
|
||||||
f.tableSyncMap.Store(fixture.tableName, true)
|
f.tableSynced[fixture.tableName] = true
|
||||||
}
|
}
|
||||||
if err = tx.Commit(); err != nil {
|
if err = tx.Commit(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
f.tableSyncMap.Range(func(k, v any) bool {
|
for tableName, synced := range f.tableSynced {
|
||||||
tableName, synced := k.(string), v.(bool)
|
|
||||||
if !synced && f.fixtures[tableName] == nil {
|
if !synced && f.fixtures[tableName] == nil {
|
||||||
_, _ = f.xormEngine.Context(ctx).Exec("DELETE FROM `" + tableName + "`")
|
_, _ = f.xormEngine.Context(ctx).Exec("DELETE FROM `" + tableName + "`")
|
||||||
}
|
}
|
||||||
f.tableSyncMap.Store(tableName, true)
|
f.tableSynced[tableName] = true
|
||||||
return true
|
}
|
||||||
})
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *fixturesLoaderInternal) MarkTableChanged(tableName string) {
|
func (f *fixturesLoaderInternal) MarkTableChanged(tableName string) {
|
||||||
f.tableSyncMap.Store(tableName, false)
|
f.tableSyncMu.Lock()
|
||||||
|
defer f.tableSyncMu.Unlock()
|
||||||
|
f.tableSynced[tableName] = false
|
||||||
}
|
}
|
||||||
|
|
||||||
func FixturesFileFullPaths(dir string, files []string) (map[string]*FixtureItem, error) {
|
func FixturesFileFullPaths(dir string, files []string) (map[string]*FixtureItem, error) {
|
||||||
@@ -212,7 +216,7 @@ func NewFixturesLoader(x *xorm.Engine, opts FixturesOptions) (FixturesLoader, er
|
|||||||
return nil, fmt.Errorf("failed to get fixtures files: %w", err)
|
return nil, fmt.Errorf("failed to get fixtures files: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
f := &fixturesLoaderInternal{xormEngine: x, db: x.DB().DB, dbType: x.Dialect().URI().DBType, fixtures: fixtureItems}
|
f := &fixturesLoaderInternal{xormEngine: x, db: x.DB().DB, dbType: x.Dialect().URI().DBType, fixtures: fixtureItems, tableSynced: map[string]bool{}}
|
||||||
switch f.dbType {
|
switch f.dbType {
|
||||||
case schemas.SQLITE:
|
case schemas.SQLITE:
|
||||||
f.quoteObject = func(s string) string { return fmt.Sprintf(`"%s"`, s) }
|
f.quoteObject = func(s string) string { return fmt.Sprintf(`"%s"`, s) }
|
||||||
@@ -233,7 +237,7 @@ func NewFixturesLoader(x *xorm.Engine, opts FixturesOptions) (FixturesLoader, er
|
|||||||
xormBeans, _ := db.NamesToBean()
|
xormBeans, _ := db.NamesToBean()
|
||||||
for _, bean := range xormBeans {
|
for _, bean := range xormBeans {
|
||||||
beanTableName := x.TableName(bean)
|
beanTableName := x.TableName(bean)
|
||||||
f.tableSyncMap.Store(trimTableNameQuotes(beanTableName), false)
|
f.tableSynced[trimTableNameQuotes(beanTableName)] = false
|
||||||
}
|
}
|
||||||
return f, nil
|
return f, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ func MatchScopedWorkflows(
|
|||||||
parsed []*ParsedScopedWorkflow,
|
parsed []*ParsedScopedWorkflow,
|
||||||
consumerGitRepo *git.Repository,
|
consumerGitRepo *git.Repository,
|
||||||
consumerCommit *git.Commit,
|
consumerCommit *git.Commit,
|
||||||
triggedEvent webhook_module.HookEventType,
|
inputEvent webhook_module.HookEventType,
|
||||||
payload api.Payloader,
|
payload api.Payloader,
|
||||||
) (matched, filtered []*DetectedWorkflow) {
|
) (matched, filtered []*DetectedWorkflow) {
|
||||||
for _, p := range parsed {
|
for _, p := range parsed {
|
||||||
@@ -78,7 +78,7 @@ func MatchScopedWorkflows(
|
|||||||
TriggerEvent: evt,
|
TriggerEvent: evt,
|
||||||
Content: p.Content,
|
Content: p.Content,
|
||||||
}
|
}
|
||||||
switch detectWorkflowMatch(ctx, consumerGitRepo, consumerCommit, triggedEvent, payload, evt) {
|
switch detectWorkflowMatch(ctx, consumerGitRepo, consumerCommit, inputEvent, payload, evt) {
|
||||||
case detectMatched:
|
case detectMatched:
|
||||||
matched = append(matched, dwf)
|
matched = append(matched, dwf)
|
||||||
case detectFilteredOut:
|
case detectFilteredOut:
|
||||||
|
|||||||
@@ -266,12 +266,22 @@ func DetectScheduledWorkflows(ctx context.Context, gitRepo *git.Repository, comm
|
|||||||
return wfs, nil
|
return wfs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func detectWorkflowMatch(ctx context.Context, gitRepo *git.Repository, commit *git.Commit, triggedEvent webhook_module.HookEventType, payload api.Payloader, evt *jobparser.Event) detectResult {
|
// payloadAs returns the payload as the type the event is expected to carry
|
||||||
if !canGithubEventMatch(evt.Name, triggedEvent) {
|
func payloadAs[T api.Payloader](payload api.Payloader, inputEvent webhook_module.HookEventType) T {
|
||||||
|
typedPayload, ok := payload.(T)
|
||||||
|
if !ok {
|
||||||
|
// the event type determines the payload type, so a mismatch can only be a programming error
|
||||||
|
panic(fmt.Errorf("event %q was triggered with payload type %T instead of %T", inputEvent, payload, typedPayload))
|
||||||
|
}
|
||||||
|
return typedPayload
|
||||||
|
}
|
||||||
|
|
||||||
|
func detectWorkflowMatch(ctx context.Context, gitRepo *git.Repository, commit *git.Commit, inputEvent webhook_module.HookEventType, payload api.Payloader, evt *jobparser.Event) detectResult {
|
||||||
|
if !canGithubEventMatch(evt.Name, inputEvent) {
|
||||||
return detectNotApplicable
|
return detectNotApplicable
|
||||||
}
|
}
|
||||||
|
|
||||||
switch triggedEvent {
|
switch inputEvent {
|
||||||
case // events with no activity types
|
case // events with no activity types
|
||||||
webhook_module.HookEventCreate,
|
webhook_module.HookEventCreate,
|
||||||
webhook_module.HookEventDelete,
|
webhook_module.HookEventDelete,
|
||||||
@@ -279,21 +289,23 @@ func detectWorkflowMatch(ctx context.Context, gitRepo *git.Repository, commit *g
|
|||||||
webhook_module.HookEventWiki,
|
webhook_module.HookEventWiki,
|
||||||
webhook_module.HookEventSchedule:
|
webhook_module.HookEventSchedule:
|
||||||
if len(evt.Acts()) != 0 {
|
if len(evt.Acts()) != 0 {
|
||||||
log.Warn("Ignore unsupported %s event arguments %v", triggedEvent, evt.Acts())
|
log.Warn("Ignore unsupported %s event arguments %v", inputEvent, evt.Acts())
|
||||||
}
|
}
|
||||||
// no special filter parameters for these events, just return true if name matched
|
// no special filter parameters for these events, just return true if name matched
|
||||||
return detectMatched
|
return detectMatched
|
||||||
|
|
||||||
case // push
|
case // push
|
||||||
webhook_module.HookEventPush:
|
webhook_module.HookEventPush:
|
||||||
return matchPushEvent(ctx, gitRepo, commit, payload.(*api.PushPayload), evt)
|
pushPayload := payloadAs[*api.PushPayload](payload, inputEvent)
|
||||||
|
return matchPushEvent(ctx, gitRepo, commit, pushPayload, evt)
|
||||||
|
|
||||||
case // issues
|
case // issues
|
||||||
webhook_module.HookEventIssues,
|
webhook_module.HookEventIssues,
|
||||||
webhook_module.HookEventIssueAssign,
|
webhook_module.HookEventIssueAssign,
|
||||||
webhook_module.HookEventIssueLabel,
|
webhook_module.HookEventIssueLabel,
|
||||||
webhook_module.HookEventIssueMilestone:
|
webhook_module.HookEventIssueMilestone:
|
||||||
if matchIssuesEvent(payload.(*api.IssuePayload), evt) {
|
issuePayload := payloadAs[*api.IssuePayload](payload, inputEvent)
|
||||||
|
if matchIssuesEvent(issuePayload, evt) {
|
||||||
return detectMatched
|
return detectMatched
|
||||||
}
|
}
|
||||||
return detectNotApplicable
|
return detectNotApplicable
|
||||||
@@ -303,7 +315,8 @@ func detectWorkflowMatch(ctx context.Context, gitRepo *git.Repository, commit *g
|
|||||||
// `pull_request_comment` is same as `issue_comment`
|
// `pull_request_comment` is same as `issue_comment`
|
||||||
// See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_comment-use-issue_comment
|
// See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_comment-use-issue_comment
|
||||||
webhook_module.HookEventPullRequestComment:
|
webhook_module.HookEventPullRequestComment:
|
||||||
if matchIssueCommentEvent(payload.(*api.IssueCommentPayload), evt) {
|
issueCommentPayload := payloadAs[*api.IssueCommentPayload](payload, inputEvent)
|
||||||
|
if matchIssueCommentEvent(issueCommentPayload, evt) {
|
||||||
return detectMatched
|
return detectMatched
|
||||||
}
|
}
|
||||||
return detectNotApplicable
|
return detectNotApplicable
|
||||||
@@ -315,46 +328,52 @@ func detectWorkflowMatch(ctx context.Context, gitRepo *git.Repository, commit *g
|
|||||||
webhook_module.HookEventPullRequestLabel,
|
webhook_module.HookEventPullRequestLabel,
|
||||||
webhook_module.HookEventPullRequestReviewRequest,
|
webhook_module.HookEventPullRequestReviewRequest,
|
||||||
webhook_module.HookEventPullRequestMilestone:
|
webhook_module.HookEventPullRequestMilestone:
|
||||||
return matchPullRequestEvent(ctx, gitRepo, commit, payload.(*api.PullRequestPayload), evt)
|
pullRequestPayload := payloadAs[*api.PullRequestPayload](payload, inputEvent)
|
||||||
|
return matchPullRequestEvent(ctx, gitRepo, commit, pullRequestPayload, evt)
|
||||||
|
|
||||||
case // pull_request_review
|
case // pull_request_review
|
||||||
webhook_module.HookEventPullRequestReviewApproved,
|
webhook_module.HookEventPullRequestReviewApproved,
|
||||||
webhook_module.HookEventPullRequestReviewRejected:
|
webhook_module.HookEventPullRequestReviewRejected:
|
||||||
if matchPullRequestReviewEvent(payload.(*api.PullRequestPayload), evt) {
|
reviewPayload := payloadAs[*api.PullRequestPayload](payload, inputEvent)
|
||||||
|
if matchPullRequestReviewEvent(reviewPayload, evt) {
|
||||||
return detectMatched
|
return detectMatched
|
||||||
}
|
}
|
||||||
return detectNotApplicable
|
return detectNotApplicable
|
||||||
|
|
||||||
case // pull_request_review_comment
|
case // pull_request_review_comment
|
||||||
webhook_module.HookEventPullRequestReviewComment:
|
webhook_module.HookEventPullRequestReviewComment:
|
||||||
if matchPullRequestReviewCommentEvent(payload.(*api.PullRequestPayload), evt) {
|
reviewCommentPayload := payloadAs[*api.PullRequestPayload](payload, inputEvent)
|
||||||
|
if matchPullRequestReviewCommentEvent(reviewCommentPayload, evt) {
|
||||||
return detectMatched
|
return detectMatched
|
||||||
}
|
}
|
||||||
return detectNotApplicable
|
return detectNotApplicable
|
||||||
|
|
||||||
case // release
|
case // release
|
||||||
webhook_module.HookEventRelease:
|
webhook_module.HookEventRelease:
|
||||||
if matchReleaseEvent(payload.(*api.ReleasePayload), evt) {
|
releasePayload := payloadAs[*api.ReleasePayload](payload, inputEvent)
|
||||||
|
if matchReleaseEvent(releasePayload, evt) {
|
||||||
return detectMatched
|
return detectMatched
|
||||||
}
|
}
|
||||||
return detectNotApplicable
|
return detectNotApplicable
|
||||||
|
|
||||||
case // registry_package
|
case // registry_package
|
||||||
webhook_module.HookEventPackage:
|
webhook_module.HookEventPackage:
|
||||||
if matchPackageEvent(payload.(*api.PackagePayload), evt) {
|
packagePayload := payloadAs[*api.PackagePayload](payload, inputEvent)
|
||||||
|
if matchPackageEvent(packagePayload, evt) {
|
||||||
return detectMatched
|
return detectMatched
|
||||||
}
|
}
|
||||||
return detectNotApplicable
|
return detectNotApplicable
|
||||||
|
|
||||||
case // workflow_run
|
case // workflow_run
|
||||||
webhook_module.HookEventWorkflowRun:
|
webhook_module.HookEventWorkflowRun:
|
||||||
if matchWorkflowRunEvent(payload.(*api.WorkflowRunPayload), evt) {
|
workflowRunPayload := payloadAs[*api.WorkflowRunPayload](payload, inputEvent)
|
||||||
|
if matchWorkflowRunEvent(workflowRunPayload, evt) {
|
||||||
return detectMatched
|
return detectMatched
|
||||||
}
|
}
|
||||||
return detectNotApplicable
|
return detectNotApplicable
|
||||||
|
|
||||||
default:
|
default:
|
||||||
log.Warn("unsupported event %q", triggedEvent)
|
log.Warn("unsupported event %q", inputEvent)
|
||||||
return detectNotApplicable
|
return detectNotApplicable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,9 @@ func TestEmbed(t *testing.T) {
|
|||||||
assert.Equal(t, "a", string(content))
|
assert.Equal(t, "a", string(content))
|
||||||
fi, err := fs.Stat(efs, "a.txt")
|
fi, err := fs.Stat(efs, "a.txt")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, ok := fi.(EmbeddedFileInfo).GetGzipContent()
|
fiEmbedded, ok := fi.(EmbeddedFileInfo)
|
||||||
|
require.True(t, ok)
|
||||||
|
_, ok = fiEmbedded.GetGzipContent()
|
||||||
assert.False(t, ok)
|
assert.False(t, ok)
|
||||||
|
|
||||||
// test a compressed file
|
// test a compressed file
|
||||||
@@ -48,7 +50,9 @@ func TestEmbed(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.False(t, fi.Mode().IsDir())
|
assert.False(t, fi.Mode().IsDir())
|
||||||
assert.True(t, fi.Mode().IsRegular())
|
assert.True(t, fi.Mode().IsRegular())
|
||||||
gzipContent, ok := fi.(EmbeddedFileInfo).GetGzipContent()
|
fiEmbedded, ok = fi.(EmbeddedFileInfo)
|
||||||
|
require.True(t, ok)
|
||||||
|
gzipContent, ok := fiEmbedded.GetGzipContent()
|
||||||
assert.True(t, ok)
|
assert.True(t, ok)
|
||||||
assert.Greater(t, len(gzipContent), 1)
|
assert.Greater(t, len(gzipContent), 1)
|
||||||
assert.Less(t, len(gzipContent), 1000)
|
assert.Less(t, len(gzipContent), 1000)
|
||||||
@@ -82,7 +86,7 @@ func TestEmbed(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
hi, err := hf.Stat()
|
hi, err := hf.Stat()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
fiEmbedded, ok := hi.(EmbeddedFileInfo)
|
fiEmbedded, ok = hi.(EmbeddedFileInfo)
|
||||||
require.True(t, ok)
|
require.True(t, ok)
|
||||||
gzipContent, ok = fiEmbedded.GetGzipContent()
|
gzipContent, ok = fiEmbedded.GetGzipContent()
|
||||||
assert.True(t, ok)
|
assert.True(t, ok)
|
||||||
|
|||||||
@@ -64,15 +64,17 @@ func CreateTimeLimitCode[T time.Time | string](data string, minutes int, startTi
|
|||||||
const format = "200601021504"
|
const format = "200601021504"
|
||||||
|
|
||||||
var start time.Time
|
var start time.Time
|
||||||
var startTimeAny any = startTimeGeneric
|
switch startTime := any(startTimeGeneric).(type) {
|
||||||
if t, ok := startTimeAny.(time.Time); ok {
|
case time.Time:
|
||||||
start = t
|
start = startTime
|
||||||
} else {
|
case string:
|
||||||
var err error
|
var err error
|
||||||
start, err = time.ParseInLocation(format, startTimeAny.(string), time.Local)
|
start, err = time.ParseInLocation(format, startTime, time.Local)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "" // return an invalid code because the "parse" failed
|
return "" // return an invalid code because the "parse" failed
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("unsupported start time type %T", startTime)) // it shouldn't happen
|
||||||
}
|
}
|
||||||
startStr := start.Format(format)
|
startStr := start.Format(format)
|
||||||
end := start.Add(time.Minute * time.Duration(minutes))
|
end := start.Add(time.Minute * time.Duration(minutes))
|
||||||
|
|||||||
Vendored
+1
-1
@@ -25,7 +25,7 @@ func TestWithCacheContext(t *testing.T) {
|
|||||||
c.Put(field, "my_config1", 1)
|
c.Put(field, "my_config1", 1)
|
||||||
v, _ = c.Get(field, "my_config1")
|
v, _ = c.Get(field, "my_config1")
|
||||||
assert.NotNil(t, v)
|
assert.NotNil(t, v)
|
||||||
assert.Equal(t, 1, v.(int))
|
assert.Equal(t, 1, v)
|
||||||
|
|
||||||
c.Delete(field, "my_config1")
|
c.Delete(field, "my_config1")
|
||||||
c.Delete(field, "my_config2") // remove a non-exist key
|
c.Delete(field, "my_config2") // remove a non-exist key
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ func getLastCommitForPathsByCommitNode(ctx context.Context, gitRepo *Repository,
|
|||||||
|
|
||||||
// We do a tree traversal with nodes sorted by commit time
|
// We do a tree traversal with nodes sorted by commit time
|
||||||
heap := binaryheap.NewWith(func(a, b any) int {
|
heap := binaryheap.NewWith(func(a, b any) int {
|
||||||
if a.(*commitAndPaths).commit.CommitTime().Before(b.(*commitAndPaths).commit.CommitTime()) {
|
if a.(*commitAndPaths).commit.CommitTime().Before(b.(*commitAndPaths).commit.CommitTime()) { //nolint:forcetypeassert // this heap only ever holds *commitAndPaths
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
return -1
|
return -1
|
||||||
@@ -110,7 +110,7 @@ heaploop:
|
|||||||
if !ok {
|
if !ok {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
current := cIn.(*commitAndPaths)
|
current := cIn.(*commitAndPaths) //nolint:forcetypeassert // this heap only ever holds *commitAndPaths
|
||||||
|
|
||||||
// Load the parent commits for the one we are currently examining
|
// Load the parent commits for the one we are currently examining
|
||||||
numParents := current.commit.NumParents()
|
numParents := current.commit.NumParents()
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ func (repo *Repository) GetTagInfos(ctx context.Context, page, pageSize int) ([]
|
|||||||
sortTagsByTime(tags)
|
sortTagsByTime(tags)
|
||||||
tagsTotal = len(tags)
|
tagsTotal = len(tags)
|
||||||
if page != 0 {
|
if page != 0 {
|
||||||
tags = util.PaginateSlice(tags, page, pageSize).([]*Tag)
|
tags = util.PaginateSlice(tags, page, pageSize)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}).
|
}).
|
||||||
|
|||||||
@@ -174,8 +174,10 @@ func TestGlob(t *testing.T) {
|
|||||||
} {
|
} {
|
||||||
g, err := Compile(test.pattern, test.delimiters...)
|
g, err := Compile(test.pattern, test.delimiters...)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
compiler, ok := g.(*globCompiler)
|
||||||
|
require.True(t, ok)
|
||||||
result := g.Match(test.match)
|
result := g.Match(test.match)
|
||||||
assert.Equal(t, test.should, result, "pattern %q matching %q should be %v but got %v, compiled=%s", test.pattern, test.match, test.should, result, g.(*globCompiler).regexpPattern)
|
assert.Equal(t, test.should, result, "pattern %q matching %q should be %v but got %v, compiled=%s", test.pattern, test.match, test.should, result, compiler.regexpPattern)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ func TestLockAndDo(t *testing.T) {
|
|||||||
locker := newTestRedisLocker(t)
|
locker := newTestRedisLocker(t)
|
||||||
defaultLocker.Store(new(locker))
|
defaultLocker.Store(new(locker))
|
||||||
testLockAndDo(t)
|
testLockAndDo(t)
|
||||||
require.NoError(t, locker.(*redisLocker).Close())
|
rl, ok := locker.(*redisLocker)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.NoError(t, rl.Close())
|
||||||
})
|
})
|
||||||
t.Run("memory", func(t *testing.T) {
|
t.Run("memory", func(t *testing.T) {
|
||||||
defaultLocker.Store(new(NewMemoryLocker()))
|
defaultLocker.Store(new(NewMemoryLocker()))
|
||||||
|
|||||||
@@ -26,13 +26,17 @@ func TestLocker(t *testing.T) {
|
|||||||
defer test.MockVariableValue(&redisLockExpiry, 5*time.Second)() // make it shorter for testing
|
defer test.MockVariableValue(&redisLockExpiry, 5*time.Second)() // make it shorter for testing
|
||||||
locker := newTestRedisLocker(t)
|
locker := newTestRedisLocker(t)
|
||||||
testLocker(t, locker)
|
testLocker(t, locker)
|
||||||
testRedisLocker(t, locker.(*redisLocker))
|
rl, ok := locker.(*redisLocker)
|
||||||
require.NoError(t, locker.(*redisLocker).Close())
|
require.True(t, ok)
|
||||||
|
testRedisLocker(t, rl)
|
||||||
|
require.NoError(t, rl.Close())
|
||||||
})
|
})
|
||||||
t.Run("memory", func(t *testing.T) {
|
t.Run("memory", func(t *testing.T) {
|
||||||
locker := NewMemoryLocker()
|
locker := NewMemoryLocker()
|
||||||
testLocker(t, locker)
|
testLocker(t, locker)
|
||||||
testMemoryLocker(t, locker.(*memoryLocker))
|
ml, ok := locker.(*memoryLocker)
|
||||||
|
require.True(t, ok)
|
||||||
|
testMemoryLocker(t, ml)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +166,8 @@ func testRedisLocker(t *testing.T, locker *redisLocker) {
|
|||||||
// It simulates that there are some problems with extending like network issues or redis server down.
|
// It simulates that there are some problems with extending like network issues or redis server down.
|
||||||
v, ok := locker.mutexM.Load("test")
|
v, ok := locker.mutexM.Load("test")
|
||||||
require.True(t, ok)
|
require.True(t, ok)
|
||||||
m := v.(*redsync.Mutex)
|
m, ok := v.(*redsync.Mutex)
|
||||||
|
require.True(t, ok)
|
||||||
_, _ = m.Unlock() // release it to make it impossible to extend
|
_, _ = m.Unlock() // release it to make it impossible to extend
|
||||||
|
|
||||||
// In current design, callers can't know the lock can't be extended.
|
// In current design, callers can't know the lock can't be extended.
|
||||||
|
|||||||
@@ -52,11 +52,10 @@ func (l *redisLocker) Lock(ctx context.Context, key string) (ReleaseFunc, error)
|
|||||||
func (l *redisLocker) TryLock(ctx context.Context, key string) (bool, ReleaseFunc, error) {
|
func (l *redisLocker) TryLock(ctx context.Context, key string) (bool, ReleaseFunc, error) {
|
||||||
f, err := l.lock(ctx, key, 1)
|
f, err := l.lock(ctx, key, 1)
|
||||||
|
|
||||||
var (
|
if _, taken := errors.AsType[*redsync.ErrTaken](err); taken {
|
||||||
errTaken *redsync.ErrTaken
|
return false, f, nil
|
||||||
errNodeTaken *redsync.ErrNodeTaken
|
}
|
||||||
)
|
if _, nodeTaken := errors.AsType[*redsync.ErrNodeTaken](err); nodeTaken {
|
||||||
if errors.As(err, &errTaken) || errors.As(err, &errNodeTaken) {
|
|
||||||
return false, f, nil
|
return false, f, nil
|
||||||
}
|
}
|
||||||
return err == nil, f, err
|
return err == nil, f, err
|
||||||
@@ -112,7 +111,7 @@ func (l *redisLocker) startExtend() {
|
|||||||
|
|
||||||
toExtend := make([]*redsync.Mutex, 0)
|
toExtend := make([]*redsync.Mutex, 0)
|
||||||
l.mutexM.Range(func(_, value any) bool {
|
l.mutexM.Range(func(_, value any) bool {
|
||||||
m := value.(*redsync.Mutex)
|
m := value.(*redsync.Mutex) //nolint:forcetypeassert // mutexM only ever holds *redsync.Mutex
|
||||||
|
|
||||||
// Extend the lock if it is not expired.
|
// Extend the lock if it is not expired.
|
||||||
// Although the mutex will be removed from the map before it is released,
|
// Although the mutex will be removed from the map before it is released,
|
||||||
|
|||||||
@@ -177,13 +177,15 @@ func GetListenerTCP(network string, address *net.TCPAddr) (*net.TCPListener, err
|
|||||||
// look for a provided listener
|
// look for a provided listener
|
||||||
for i, l := range providedListeners {
|
for i, l := range providedListeners {
|
||||||
if isSameAddr(l.Addr(), address) {
|
if isSameAddr(l.Addr(), address) {
|
||||||
|
tcpListener := l.(*net.TCPListener) //nolint:forcetypeassert // a listener matching a *net.TCPAddr is a *net.TCPListener
|
||||||
|
|
||||||
providedListeners = append(providedListeners[:i], providedListeners[i+1:]...)
|
providedListeners = append(providedListeners[:i], providedListeners[i+1:]...)
|
||||||
needsUnlink := providedListenersToUnlink[i]
|
needsUnlink := providedListenersToUnlink[i]
|
||||||
providedListenersToUnlink = append(providedListenersToUnlink[:i], providedListenersToUnlink[i+1:]...)
|
providedListenersToUnlink = append(providedListenersToUnlink[:i], providedListenersToUnlink[i+1:]...)
|
||||||
|
|
||||||
activeListeners = append(activeListeners, l)
|
activeListeners = append(activeListeners, l)
|
||||||
activeListenersToUnlink = append(activeListenersToUnlink, needsUnlink)
|
activeListenersToUnlink = append(activeListenersToUnlink, needsUnlink)
|
||||||
return l.(*net.TCPListener), nil
|
return tcpListener, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,13 +213,14 @@ func GetListenerUnix(network string, address *net.UnixAddr) (*net.UnixListener,
|
|||||||
// look for a provided listener
|
// look for a provided listener
|
||||||
for i, l := range providedListeners {
|
for i, l := range providedListeners {
|
||||||
if isSameAddr(l.Addr(), address) {
|
if isSameAddr(l.Addr(), address) {
|
||||||
|
unixListener := l.(*net.UnixListener) //nolint:forcetypeassert // a listener matching a *net.UnixAddr is a *net.UnixListener
|
||||||
|
|
||||||
providedListeners = append(providedListeners[:i], providedListeners[i+1:]...)
|
providedListeners = append(providedListeners[:i], providedListeners[i+1:]...)
|
||||||
needsUnlink := providedListenersToUnlink[i]
|
needsUnlink := providedListenersToUnlink[i]
|
||||||
providedListenersToUnlink = append(providedListenersToUnlink[:i], providedListenersToUnlink[i+1:]...)
|
providedListenersToUnlink = append(providedListenersToUnlink[:i], providedListenersToUnlink[i+1:]...)
|
||||||
|
|
||||||
activeListenersToUnlink = append(activeListenersToUnlink, needsUnlink)
|
activeListenersToUnlink = append(activeListenersToUnlink, needsUnlink)
|
||||||
activeListeners = append(activeListeners, l)
|
activeListeners = append(activeListeners, l)
|
||||||
unixListener := l.(*net.UnixListener)
|
|
||||||
if needsUnlink {
|
if needsUnlink {
|
||||||
unixListener.SetUnlinkOnClose(true)
|
unixListener.SetUnlinkOnClose(true)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,10 +44,14 @@ func RestartProcess() (int, error) {
|
|||||||
// Extract the fds from the listeners.
|
// Extract the fds from the listeners.
|
||||||
files := make([]*os.File, len(listeners))
|
files := make([]*os.File, len(listeners))
|
||||||
for i, l := range listeners {
|
for i, l := range listeners {
|
||||||
var err error
|
|
||||||
// Now, all our listeners actually have File() functions so instead of
|
// Now, all our listeners actually have File() functions so instead of
|
||||||
// individually casting we just use a hacky interface
|
// individually casting we just use a hacky interface
|
||||||
files[i], err = l.(filer).File()
|
lf, ok := l.(filer)
|
||||||
|
if !ok {
|
||||||
|
return 0, fmt.Errorf("listener %T does not provide a File", l)
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
files[i], err = lf.File()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ package graceful
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -260,7 +261,11 @@ func (wl *wrappedListener) Accept() (c net.Conn, err error) {
|
|||||||
|
|
||||||
func (wl *wrappedListener) File() (*os.File, error) {
|
func (wl *wrappedListener) File() (*os.File, error) {
|
||||||
// returns a dup(2) - FD_CLOEXEC flag *not* set so the listening socket can be passed to child processes
|
// returns a dup(2) - FD_CLOEXEC flag *not* set so the listening socket can be passed to child processes
|
||||||
return wl.Listener.(filer).File()
|
lf, ok := wl.Listener.(filer)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("listener %T does not provide a File", wl.Listener)
|
||||||
|
}
|
||||||
|
return lf.File()
|
||||||
}
|
}
|
||||||
|
|
||||||
type wrappedConn struct {
|
type wrappedConn struct {
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ func (t *traceBuiltinSpan) toString(out *strings.Builder, indent int) {
|
|||||||
}
|
}
|
||||||
out.WriteString("\n")
|
out.WriteString("\n")
|
||||||
for _, c := range t.ts.children {
|
for _, c := range t.ts.children {
|
||||||
span := c.internalSpans[t.internalSpanIdx].(*traceBuiltinSpan)
|
span := c.internalSpans[t.internalSpanIdx].(*traceBuiltinSpan) //nolint:forcetypeassert // this tracer only stores its own spans
|
||||||
span.toString(out, indent+2)
|
span.toString(out, indent+2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
// "vendor span" is a simple demo for a span from a vendor library
|
// "vendor span" is a simple demo for a span from a vendor library
|
||||||
@@ -82,7 +83,9 @@ func TestTraceStarter(t *testing.T) {
|
|||||||
collectSpanNames(fullName, c)
|
collectSpanNames(fullName, c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
collectSpanNames("", span.internalSpans[0].(*testTraceSpan).vendorSpan)
|
rootSpan, ok := span.internalSpans[0].(*testTraceSpan)
|
||||||
|
require.True(t, ok)
|
||||||
|
collectSpanNames("", rootSpan.vendorSpan)
|
||||||
assert.Equal(t, []string{
|
assert.Equal(t, []string{
|
||||||
"/root",
|
"/root",
|
||||||
"/root/span1",
|
"/root/span1",
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import (
|
|||||||
"gitea.dev/modules/indexer/code/internal"
|
"gitea.dev/modules/indexer/code/internal"
|
||||||
indexer_internal "gitea.dev/modules/indexer/internal"
|
indexer_internal "gitea.dev/modules/indexer/internal"
|
||||||
inner_bleve "gitea.dev/modules/indexer/internal/bleve"
|
inner_bleve "gitea.dev/modules/indexer/internal/bleve"
|
||||||
|
"gitea.dev/modules/json"
|
||||||
"gitea.dev/modules/setting"
|
"gitea.dev/modules/setting"
|
||||||
"gitea.dev/modules/timeutil"
|
"gitea.dev/modules/timeutil"
|
||||||
"gitea.dev/modules/typesniffer"
|
"gitea.dev/modules/typesniffer"
|
||||||
@@ -330,6 +331,17 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int
|
|||||||
|
|
||||||
searchResults := make([]*internal.SearchResult, len(result.Hits))
|
searchResults := make([]*internal.SearchResult, len(result.Hits))
|
||||||
for i, hit := range result.Hits {
|
for i, hit := range result.Hits {
|
||||||
|
content, okContent := hit.Fields["Content"].(string)
|
||||||
|
language, okLanguage := hit.Fields["Language"].(string)
|
||||||
|
commitID, okCommitID := hit.Fields["CommitID"].(string)
|
||||||
|
updatedAt, okUpdatedAt := hit.Fields["UpdatedAt"].(string)
|
||||||
|
repoID, okRepoID := hit.Fields["RepoID"].(float64)
|
||||||
|
if !okContent || !okLanguage || !okCommitID || !okUpdatedAt || !okRepoID {
|
||||||
|
hitFieldsJson, _ := json.Marshal(hit.Fields)
|
||||||
|
setting.PanicInDevOrTesting("unexpected field types in search hit %q: %s", hit.ID, string(hitFieldsJson))
|
||||||
|
return 0, nil, nil, fmt.Errorf("unexpected field types in search hit %q", hit.ID)
|
||||||
|
}
|
||||||
|
|
||||||
startIndex, endIndex := -1, -1
|
startIndex, endIndex := -1, -1
|
||||||
for _, locations := range hit.Locations["Content"] {
|
for _, locations := range hit.Locations["Content"] {
|
||||||
location := locations[0]
|
location := locations[0]
|
||||||
@@ -343,21 +355,20 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(hit.Locations["Filename"]) > 0 {
|
if len(hit.Locations["Filename"]) > 0 {
|
||||||
startIndex, endIndex = internal.FilenameMatchIndexPos(hit.Fields["Content"].(string))
|
startIndex, endIndex = internal.FilenameMatchIndexPos(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
language := hit.Fields["Language"].(string)
|
|
||||||
var updatedUnix timeutil.TimeStamp
|
var updatedUnix timeutil.TimeStamp
|
||||||
if t, err := time.Parse(time.RFC3339, hit.Fields["UpdatedAt"].(string)); err == nil {
|
if t, err := time.Parse(time.RFC3339, updatedAt); err == nil {
|
||||||
updatedUnix = timeutil.TimeStamp(t.Unix())
|
updatedUnix = timeutil.TimeStamp(t.Unix())
|
||||||
}
|
}
|
||||||
searchResults[i] = &internal.SearchResult{
|
searchResults[i] = &internal.SearchResult{
|
||||||
RepoID: int64(hit.Fields["RepoID"].(float64)),
|
RepoID: int64(repoID),
|
||||||
StartIndex: startIndex,
|
StartIndex: startIndex,
|
||||||
EndIndex: endIndex,
|
EndIndex: endIndex,
|
||||||
Filename: internal.FilenameOfIndexerID(hit.ID),
|
Filename: internal.FilenameOfIndexerID(hit.ID),
|
||||||
Content: hit.Fields["Content"].(string),
|
Content: content,
|
||||||
CommitID: hit.Fields["CommitID"].(string),
|
CommitID: commitID,
|
||||||
UpdatedUnix: updatedUnix,
|
UpdatedUnix: updatedUnix,
|
||||||
Language: language,
|
Language: language,
|
||||||
Color: enry.GetColor(language),
|
Color: enry.GetColor(language),
|
||||||
|
|||||||
@@ -261,12 +261,21 @@ func convertResult(searchResult *es.SearchResponse, kw string, pageSize int) (in
|
|||||||
return 0, nil, nil, err
|
return 0, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
content, okContent := res["content"].(string)
|
||||||
|
language, okLanguage := res["language"].(string)
|
||||||
|
commitID, okCommitID := res["commit_id"].(string)
|
||||||
|
updatedAt, okUpdatedAt := res["updated_at"].(float64)
|
||||||
|
if !okContent || !okLanguage || !okCommitID || !okUpdatedAt {
|
||||||
|
setting.PanicInDevOrTesting("unexpected field types in search hit %q: %s", hit.ID, string(hit.Source))
|
||||||
|
return 0, nil, nil, fmt.Errorf("unexpected field types in search hit %q", hit.ID)
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: There is no way to get the position the keyword on the content currently on the same request.
|
// FIXME: There is no way to get the position the keyword on the content currently on the same request.
|
||||||
// So we get it from content, this may made the query slower. See
|
// So we get it from content, this may made the query slower. See
|
||||||
// https://discuss.elastic.co/t/fetching-position-of-keyword-in-matched-document/94291
|
// https://discuss.elastic.co/t/fetching-position-of-keyword-in-matched-document/94291
|
||||||
var startIndex, endIndex int
|
var startIndex, endIndex int
|
||||||
if c, ok := hit.Highlight["filename"]; ok && len(c) > 0 {
|
if c, ok := hit.Highlight["filename"]; ok && len(c) > 0 {
|
||||||
startIndex, endIndex = internal.FilenameMatchIndexPos(res["content"].(string))
|
startIndex, endIndex = internal.FilenameMatchIndexPos(content)
|
||||||
} else if c, ok := hit.Highlight["content"]; ok && len(c) > 0 {
|
} else if c, ok := hit.Highlight["content"]; ok && len(c) > 0 {
|
||||||
// FIXME: Since the highlighting content will include <em> and </em> for the keywords,
|
// FIXME: Since the highlighting content will include <em> and </em> for the keywords,
|
||||||
// now we should find the positions. But how to avoid html content which contains the
|
// now we should find the positions. But how to avoid html content which contains the
|
||||||
@@ -279,14 +288,12 @@ func convertResult(searchResult *es.SearchResponse, kw string, pageSize int) (in
|
|||||||
panic(fmt.Sprintf("2===%#v", hit.Highlight))
|
panic(fmt.Sprintf("2===%#v", hit.Highlight))
|
||||||
}
|
}
|
||||||
|
|
||||||
language := res["language"].(string)
|
|
||||||
|
|
||||||
hits = append(hits, &internal.SearchResult{
|
hits = append(hits, &internal.SearchResult{
|
||||||
RepoID: repoID,
|
RepoID: repoID,
|
||||||
Filename: fileName,
|
Filename: fileName,
|
||||||
CommitID: res["commit_id"].(string),
|
CommitID: commitID,
|
||||||
Content: res["content"].(string),
|
Content: content,
|
||||||
UpdatedUnix: timeutil.TimeStamp(res["updated_at"].(float64)),
|
UpdatedUnix: timeutil.TimeStamp(updatedAt),
|
||||||
Language: language,
|
Language: language,
|
||||||
StartIndex: startIndex,
|
StartIndex: startIndex,
|
||||||
EndIndex: endIndex,
|
EndIndex: endIndex,
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ var _ EventWriter = (*eventWriterConn)(nil)
|
|||||||
|
|
||||||
func NewEventWriterConn(writerName string, writerMode WriterMode) EventWriter {
|
func NewEventWriterConn(writerName string, writerMode WriterMode) EventWriter {
|
||||||
w := &eventWriterConn{EventWriterBaseImpl: NewEventWriterBase(writerName, "conn", writerMode)}
|
w := &eventWriterConn{EventWriterBaseImpl: NewEventWriterBase(writerName, "conn", writerMode)}
|
||||||
opt := writerMode.WriterOption.(WriterConnOption)
|
opt := writerMode.WriterOption.(WriterConnOption) //nolint:forcetypeassert // a conn writer is only created with WriterConnOption
|
||||||
w.connWriter = connWriter{
|
w.connWriter = connWriter{
|
||||||
ReconnectOnMsg: opt.ReconnectOnMsg,
|
ReconnectOnMsg: opt.ReconnectOnMsg,
|
||||||
Reconnect: opt.Reconnect,
|
Reconnect: opt.Reconnect,
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ var _ EventWriter = (*eventWriterConsole)(nil)
|
|||||||
|
|
||||||
func NewEventWriterConsole(name string, mode WriterMode) EventWriter {
|
func NewEventWriterConsole(name string, mode WriterMode) EventWriter {
|
||||||
w := &eventWriterConsole{EventWriterBaseImpl: NewEventWriterBase(name, "console", mode)}
|
w := &eventWriterConsole{EventWriterBaseImpl: NewEventWriterBase(name, "console", mode)}
|
||||||
opt := mode.WriterOption.(WriterConsoleOption)
|
opt := mode.WriterOption.(WriterConsoleOption) //nolint:forcetypeassert // a console writer is only created with WriterConsoleOption
|
||||||
if opt.Stderr {
|
if opt.Stderr {
|
||||||
w.OutputWriteCloser = util.NopCloser{Writer: os.Stderr}
|
w.OutputWriteCloser = util.NopCloser{Writer: os.Stderr}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ var _ EventWriter = (*eventWriterFile)(nil)
|
|||||||
|
|
||||||
func NewEventWriterFile(name string, mode WriterMode) EventWriter {
|
func NewEventWriterFile(name string, mode WriterMode) EventWriter {
|
||||||
w := &eventWriterFile{EventWriterBaseImpl: NewEventWriterBase(name, "file", mode)}
|
w := &eventWriterFile{EventWriterBaseImpl: NewEventWriterBase(name, "file", mode)}
|
||||||
opt := mode.WriterOption.(WriterFileOption)
|
opt := mode.WriterOption.(WriterFileOption) //nolint:forcetypeassert // a file writer is only created with WriterFileOption
|
||||||
var err error
|
var err error
|
||||||
w.fileWriter, err = rotatingfilewriter.Open(opt.FileName, &rotatingfilewriter.Options{
|
w.fileWriter, err = rotatingfilewriter.Open(opt.FileName, &rotatingfilewriter.Options{
|
||||||
Rotate: opt.LogRotate,
|
Rotate: opt.LogRotate,
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSharedWorker(t *testing.T) {
|
func TestSharedWorker(t *testing.T) {
|
||||||
@@ -37,6 +38,8 @@ func TestSharedWorker(t *testing.T) {
|
|||||||
|
|
||||||
m.Close()
|
m.Close()
|
||||||
|
|
||||||
logs := w.(*dummyWriter).FetchLogs()
|
dw, ok := w.(*dummyWriter)
|
||||||
|
require.True(t, ok)
|
||||||
|
logs := dw.FetchLogs()
|
||||||
assert.Equal(t, []string{"msg-1\n", "msg-2\n", "msg-3\n"}, logs)
|
assert.Equal(t, []string{"msg-1\n", "msg-2\n", "msg-3\n"}, logs)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -237,10 +237,8 @@ func (b *footnoteBlockParser) Continue(node ast.Node, reader text.Reader, pc par
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *footnoteBlockParser) Close(node ast.Node, reader text.Reader, pc parser.Context) {
|
func (b *footnoteBlockParser) Close(node ast.Node, reader text.Reader, pc parser.Context) {
|
||||||
var list *FootnoteList
|
list, _ := pc.Get(footnoteListKey).(*FootnoteList)
|
||||||
if tlist := pc.Get(footnoteListKey); tlist != nil {
|
if list == nil {
|
||||||
list = tlist.(*FootnoteList)
|
|
||||||
} else {
|
|
||||||
list = NewFootnoteList()
|
list = NewFootnoteList()
|
||||||
pc.Set(footnoteListKey, list)
|
pc.Set(footnoteListKey, list)
|
||||||
node.Parent().InsertBefore(node.Parent(), node, list)
|
node.Parent().InsertBefore(node.Parent(), node, list)
|
||||||
@@ -295,17 +293,14 @@ func (s *footnoteParser) Parse(parent ast.Node, block text.Reader, pc parser.Con
|
|||||||
value := block.Value(text.NewSegment(segment.Start+open, segment.Start+closes))
|
value := block.Value(text.NewSegment(segment.Start+open, segment.Start+closes))
|
||||||
block.Advance(closes + 1)
|
block.Advance(closes + 1)
|
||||||
|
|
||||||
var list *FootnoteList
|
list, _ := pc.Get(footnoteListKey).(*FootnoteList)
|
||||||
if tlist := pc.Get(footnoteListKey); tlist != nil {
|
|
||||||
list = tlist.(*FootnoteList)
|
|
||||||
}
|
|
||||||
if list == nil {
|
if list == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
index := 0
|
index := 0
|
||||||
name := []byte{}
|
name := []byte{}
|
||||||
for def := list.FirstChild(); def != nil; def = def.NextSibling() {
|
for def := list.FirstChild(); def != nil; def = def.NextSibling() {
|
||||||
d := def.(*Footnote)
|
d := def.(*Footnote) //nolint:forcetypeassert // a FootnoteList only holds *Footnote children
|
||||||
if bytes.Equal(d.Ref, value) {
|
if bytes.Equal(d.Ref, value) {
|
||||||
if d.Index < 0 {
|
if d.Index < 0 {
|
||||||
list.Count++
|
list.Count++
|
||||||
@@ -339,10 +334,8 @@ func NewFootnoteASTTransformer() parser.ASTTransformer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *footnoteASTTransformer) Transform(node *ast.Document, reader text.Reader, pc parser.Context) {
|
func (a *footnoteASTTransformer) Transform(node *ast.Document, reader text.Reader, pc parser.Context) {
|
||||||
var list *FootnoteList
|
list, _ := pc.Get(footnoteListKey).(*FootnoteList)
|
||||||
if tlist := pc.Get(footnoteListKey); tlist != nil {
|
if list == nil {
|
||||||
list = tlist.(*FootnoteList)
|
|
||||||
} else {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
pc.Set(footnoteListKey, nil)
|
pc.Set(footnoteListKey, nil)
|
||||||
@@ -352,18 +345,16 @@ func (a *footnoteASTTransformer) Transform(node *ast.Document, reader text.Reade
|
|||||||
if fc := container.LastChild(); fc != nil && ast.IsParagraph(fc) {
|
if fc := container.LastChild(); fc != nil && ast.IsParagraph(fc) {
|
||||||
container = fc
|
container = fc
|
||||||
}
|
}
|
||||||
footnoteNode := footnote.(*Footnote)
|
footnoteNode := footnote.(*Footnote) //nolint:forcetypeassert // a FootnoteList only holds *Footnote children
|
||||||
index := footnoteNode.Index
|
if footnoteNode.Index < 0 {
|
||||||
name := footnoteNode.Name
|
|
||||||
if index < 0 {
|
|
||||||
list.RemoveChild(list, footnote)
|
list.RemoveChild(list, footnote)
|
||||||
} else {
|
} else {
|
||||||
container.AppendChild(container, NewFootnoteBackLink(index, name))
|
container.AppendChild(container, NewFootnoteBackLink(footnoteNode.Index, footnoteNode.Name))
|
||||||
}
|
}
|
||||||
footnote = next
|
footnote = next
|
||||||
}
|
}
|
||||||
list.SortChildren(func(n1, n2 ast.Node) int {
|
list.SortChildren(func(n1, n2 ast.Node) int {
|
||||||
if n1.(*Footnote).Index < n2.(*Footnote).Index {
|
if n1.(*Footnote).Index < n2.(*Footnote).Index { //nolint:forcetypeassert // a FootnoteList only holds *Footnote children
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
return 1
|
return 1
|
||||||
@@ -403,7 +394,7 @@ func (r *FootnoteHTMLRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegist
|
|||||||
|
|
||||||
func (r *FootnoteHTMLRenderer) renderFootnoteLink(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
|
func (r *FootnoteHTMLRenderer) renderFootnoteLink(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
|
||||||
if entering {
|
if entering {
|
||||||
n := node.(*FootnoteLink)
|
n := node.(*FootnoteLink) //nolint:forcetypeassert // registered for KindFootnoteLink only
|
||||||
is := strconv.Itoa(n.Index)
|
is := strconv.Itoa(n.Index)
|
||||||
_, _ = w.WriteString(`<sup id="fnref:user-content-`)
|
_, _ = w.WriteString(`<sup id="fnref:user-content-`)
|
||||||
_, _ = w.Write(n.Name)
|
_, _ = w.Write(n.Name)
|
||||||
@@ -418,7 +409,7 @@ func (r *FootnoteHTMLRenderer) renderFootnoteLink(w util.BufWriter, source []byt
|
|||||||
|
|
||||||
func (r *FootnoteHTMLRenderer) renderFootnoteBackLink(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
|
func (r *FootnoteHTMLRenderer) renderFootnoteBackLink(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
|
||||||
if entering {
|
if entering {
|
||||||
n := node.(*FootnoteBackLink)
|
n := node.(*FootnoteBackLink) //nolint:forcetypeassert // registered for KindFootnoteBackLink only
|
||||||
_, _ = w.WriteString(` <a href="#fnref:user-content-`)
|
_, _ = w.WriteString(` <a href="#fnref:user-content-`)
|
||||||
_, _ = w.Write(n.Name)
|
_, _ = w.Write(n.Name)
|
||||||
_, _ = w.WriteString(`" class="footnote-backref" role="doc-backlink">`)
|
_, _ = w.WriteString(`" class="footnote-backref" role="doc-backlink">`)
|
||||||
@@ -429,7 +420,7 @@ func (r *FootnoteHTMLRenderer) renderFootnoteBackLink(w util.BufWriter, source [
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *FootnoteHTMLRenderer) renderFootnote(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
|
func (r *FootnoteHTMLRenderer) renderFootnote(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
|
||||||
n := node.(*Footnote)
|
n := node.(*Footnote) //nolint:forcetypeassert // registered for KindFootnote only
|
||||||
if entering {
|
if entering {
|
||||||
_, _ = w.WriteString(`<li id="fn:user-content-`)
|
_, _ = w.WriteString(`<li id="fn:user-content-`)
|
||||||
_, _ = w.Write(n.Name)
|
_, _ = w.Write(n.Name)
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ func (g *ASTTransformer) applyElementDir(n ast.Node) {
|
|||||||
// Transform transforms the given AST tree.
|
// Transform transforms the given AST tree.
|
||||||
func (g *ASTTransformer) Transform(node *ast.Document, reader text.Reader, pc parser.Context) {
|
func (g *ASTTransformer) Transform(node *ast.Document, reader text.Reader, pc parser.Context) {
|
||||||
firstChild := node.FirstChild()
|
firstChild := node.FirstChild()
|
||||||
ctx := pc.Get(renderContextKey).(*markup.RenderContext)
|
ctx := pc.Get(renderContextKey).(*markup.RenderContext) //nolint:forcetypeassert // the renderer always seeds this key before parsing
|
||||||
rc := pc.Get(renderConfigKey).(*RenderConfig)
|
rc := pc.Get(renderConfigKey).(*RenderConfig) //nolint:forcetypeassert // the renderer always seeds this key before parsing
|
||||||
|
|
||||||
tocMode := ""
|
tocMode := ""
|
||||||
if rc.yamlNode != nil {
|
if rc.yamlNode != nil {
|
||||||
@@ -150,9 +150,7 @@ func (r *HTMLRenderer) renderCodeBlock(w util.BufWriter, source []byte, n ast.No
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *HTMLRenderer) renderDocument(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
|
func (r *HTMLRenderer) renderDocument(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
|
||||||
n := node.(*ast.Document)
|
if val, has := node.AttributeString("lang"); has {
|
||||||
|
|
||||||
if val, has := n.AttributeString("lang"); has {
|
|
||||||
var err error
|
var err error
|
||||||
if entering {
|
if entering {
|
||||||
_, err = w.WriteString("<div")
|
_, err = w.WriteString("<div")
|
||||||
@@ -212,7 +210,7 @@ func (r *HTMLRenderer) renderRawHTML(w util.BufWriter, source []byte, node ast.N
|
|||||||
if !entering {
|
if !entering {
|
||||||
return ast.WalkContinue, nil
|
return ast.WalkContinue, nil
|
||||||
}
|
}
|
||||||
n := node.(*RawHTML)
|
n := node.(*RawHTML) //nolint:forcetypeassert // registered for KindRawHTML only
|
||||||
_, err := w.WriteString(string(r.renderInternal.ProtectSafeAttrs(n.rawHTML)))
|
_, err := w.WriteString(string(r.renderInternal.ProtectSafeAttrs(n.rawHTML)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ast.WalkStop, err
|
return ast.WalkStop, err
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ func (b *blockParser) Open(parent ast.Node, reader text.Reader, pc parser.Contex
|
|||||||
|
|
||||||
// Continue parses the current line and returns a result of parsing.
|
// Continue parses the current line and returns a result of parsing.
|
||||||
func (b *blockParser) Continue(node ast.Node, reader text.Reader, pc parser.Context) parser.State {
|
func (b *blockParser) Continue(node ast.Node, reader text.Reader, pc parser.Context) parser.State {
|
||||||
block := node.(*Block)
|
block := node.(*Block) //nolint:forcetypeassert // this parser only ever opens *Block nodes
|
||||||
if block.Closed {
|
if block.Closed {
|
||||||
return parser.Close
|
return parser.Close
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ func (r *BlockRenderer) writeLines(w util.BufWriter, source []byte, n gast.Node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *BlockRenderer) renderBlock(w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) {
|
func (r *BlockRenderer) renderBlock(w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) {
|
||||||
n := node.(*Block)
|
n := node.(*Block) //nolint:forcetypeassert // registered for KindBlock only
|
||||||
if entering {
|
if entering {
|
||||||
codeHTML := giteaUtil.Iif[template.HTML](n.Inline, "", `<pre class="code-block is-loading">`) + `<code class="language-math">`
|
codeHTML := giteaUtil.Iif[template.HTML](n.Inline, "", `<pre class="code-block is-loading">`) + `<code class="language-math">`
|
||||||
_, _ = w.WriteString(string(r.renderInternal.ProtectSafeAttrs(codeHTML)))
|
_, _ = w.WriteString(string(r.renderInternal.ProtectSafeAttrs(codeHTML)))
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ func (n *Inline) Inline() {}
|
|||||||
// IsBlank returns if this inline node is empty
|
// IsBlank returns if this inline node is empty
|
||||||
func (n *Inline) IsBlank(source []byte) bool {
|
func (n *Inline) IsBlank(source []byte) bool {
|
||||||
for c := n.FirstChild(); c != nil; c = c.NextSibling() {
|
for c := n.FirstChild(); c != nil; c = c.NextSibling() {
|
||||||
text := c.(*ast.Text).Segment
|
text := c.(*ast.Text) //nolint:forcetypeassert // an inline math node only holds text children
|
||||||
if !util.IsBlank(text.Value(source)) {
|
if !util.IsBlank(text.Segment.Value(source)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,12 +160,12 @@ func trimBlock(node *Inline, block text.Reader) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// trim first space and last space
|
// trim first space and last space
|
||||||
first := node.FirstChild().(*ast.Text)
|
first := node.FirstChild().(*ast.Text) //nolint:forcetypeassert // an inline math node only holds text children
|
||||||
if !(!first.Segment.IsEmpty() && block.Source()[first.Segment.Start] == ' ') {
|
if !(!first.Segment.IsEmpty() && block.Source()[first.Segment.Start] == ' ') {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
last := node.LastChild().(*ast.Text)
|
last := node.LastChild().(*ast.Text) //nolint:forcetypeassert // an inline math node only holds text children
|
||||||
if !(!last.Segment.IsEmpty() && block.Source()[last.Segment.Stop-1] == ' ') {
|
if !(!last.Segment.IsEmpty() && block.Source()[last.Segment.Stop-1] == ' ') {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ func (r *InlineRenderer) renderInline(w util.BufWriter, source []byte, n ast.Nod
|
|||||||
if entering {
|
if entering {
|
||||||
_, _ = w.WriteString(string(r.renderInternal.ProtectSafeAttrs(`<code class="language-math">`)))
|
_, _ = w.WriteString(string(r.renderInternal.ProtectSafeAttrs(`<code class="language-math">`)))
|
||||||
for c := n.FirstChild(); c != nil; c = c.NextSibling() {
|
for c := n.FirstChild(); c != nil; c = c.NextSibling() {
|
||||||
segment := c.(*ast.Text).Segment
|
segment := c.(*ast.Text).Segment //nolint:forcetypeassert // an inline math node only holds text children
|
||||||
value := util.EscapeHTML(segment.Value(source))
|
value := util.EscapeHTML(segment.Value(source))
|
||||||
if bytes.HasSuffix(value, []byte("\n")) {
|
if bytes.HasSuffix(value, []byte("\n")) {
|
||||||
_, _ = w.Write(value[:len(value)-1])
|
_, _ = w.Write(value[:len(value)-1])
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import (
|
|||||||
// renderAttention renders a quote marked with i.e. "> **Note**" or "> [!Warning]" with a corresponding svg
|
// renderAttention renders a quote marked with i.e. "> **Note**" or "> [!Warning]" with a corresponding svg
|
||||||
func (r *HTMLRenderer) renderAttention(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
|
func (r *HTMLRenderer) renderAttention(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
|
||||||
if entering {
|
if entering {
|
||||||
n := node.(*Attention)
|
n := node.(*Attention) //nolint:forcetypeassert // registered for KindAttention only
|
||||||
var octiconName string
|
var octiconName string
|
||||||
switch n.AttentionType {
|
switch n.AttentionType {
|
||||||
case "tip":
|
case "tip":
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (r *HTMLRenderer) renderTaskCheckBoxListItem(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
|
func (r *HTMLRenderer) renderTaskCheckBoxListItem(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
|
||||||
n := node.(*TaskCheckBoxListItem)
|
n := node.(*TaskCheckBoxListItem) //nolint:forcetypeassert // registered for KindTaskCheckBoxListItem only
|
||||||
if entering {
|
if entering {
|
||||||
if n.Attributes() != nil {
|
if n.Attributes() != nil {
|
||||||
_, _ = w.WriteString("<li")
|
_, _ = w.WriteString("<li")
|
||||||
@@ -60,7 +60,7 @@ func (g *ASTTransformer) transformList(_ *markup.RenderContext, v *ast.List, rc
|
|||||||
v.RemoveChildren(v)
|
v.RemoveChildren(v)
|
||||||
|
|
||||||
for _, child := range children {
|
for _, child := range children {
|
||||||
listItem := child.(*ast.ListItem)
|
listItem := child.(*ast.ListItem) //nolint:forcetypeassert // a list only holds list items
|
||||||
if !child.HasChildren() || !child.FirstChild().HasChildren() {
|
if !child.HasChildren() || !child.FirstChild().HasChildren() {
|
||||||
v.AppendChild(v, child)
|
v.AppendChild(v, child)
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ func TestMigrationJSON_IssueOK(t *testing.T) {
|
|||||||
func TestMigrationJSON_IssueFail(t *testing.T) {
|
func TestMigrationJSON_IssueFail(t *testing.T) {
|
||||||
issues := make([]*Issue, 0, 10)
|
issues := make([]*Issue, 0, 10)
|
||||||
err := Load("file_format_testdata/issue_b.json", &issues, true)
|
err := Load("file_format_testdata/issue_b.json", &issues, true)
|
||||||
if _, ok := err.(*jsonschema.ValidationError); ok {
|
if validationErr, ok := err.(*jsonschema.ValidationError); ok {
|
||||||
errors := strings.Split(err.(*jsonschema.ValidationError).GoString(), "\n")
|
errors := strings.Split(validationErr.GoString(), "\n")
|
||||||
assert.Contains(t, errors[1], "missing properties")
|
assert.Contains(t, errors[1], "missing properties")
|
||||||
assert.Contains(t, errors[1], "poster_id")
|
assert.Contains(t, errors[1], "poster_id")
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -56,21 +56,30 @@ func NewMultiHasher() *MultiHasher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// marshalHash saves the state of a hash, every stdlib hash implements the marshaler interfaces
|
||||||
|
func marshalHash(h hash.Hash) ([]byte, error) {
|
||||||
|
return h.(encoding.BinaryMarshaler).MarshalBinary() //nolint:forcetypeassert // every hash used here is a stdlib hash
|
||||||
|
}
|
||||||
|
|
||||||
|
func unmarshalHash(h hash.Hash, state []byte) error {
|
||||||
|
return h.(encoding.BinaryUnmarshaler).UnmarshalBinary(state) //nolint:forcetypeassert // every hash used here is a stdlib hash
|
||||||
|
}
|
||||||
|
|
||||||
// MarshalBinary implements encoding.BinaryMarshaler
|
// MarshalBinary implements encoding.BinaryMarshaler
|
||||||
func (h *MultiHasher) MarshalBinary() ([]byte, error) {
|
func (h *MultiHasher) MarshalBinary() ([]byte, error) {
|
||||||
md5Bytes, err := h.md5.(encoding.BinaryMarshaler).MarshalBinary()
|
md5Bytes, err := marshalHash(h.md5)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sha1Bytes, err := h.sha1.(encoding.BinaryMarshaler).MarshalBinary()
|
sha1Bytes, err := marshalHash(h.sha1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sha256Bytes, err := h.sha256.(encoding.BinaryMarshaler).MarshalBinary()
|
sha256Bytes, err := marshalHash(h.sha256)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sha512Bytes, err := h.sha512.(encoding.BinaryMarshaler).MarshalBinary()
|
sha512Bytes, err := marshalHash(h.sha512)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -89,22 +98,22 @@ func (h *MultiHasher) UnmarshalBinary(b []byte) error {
|
|||||||
return errors.New("invalid hash state size")
|
return errors.New("invalid hash state size")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := h.md5.(encoding.BinaryUnmarshaler).UnmarshalBinary(b[:marshaledSizeMD5]); err != nil {
|
if err := unmarshalHash(h.md5, b[:marshaledSizeMD5]); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
b = b[marshaledSizeMD5:]
|
b = b[marshaledSizeMD5:]
|
||||||
if err := h.sha1.(encoding.BinaryUnmarshaler).UnmarshalBinary(b[:marshaledSizeSHA1]); err != nil {
|
if err := unmarshalHash(h.sha1, b[:marshaledSizeSHA1]); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
b = b[marshaledSizeSHA1:]
|
b = b[marshaledSizeSHA1:]
|
||||||
if err := h.sha256.(encoding.BinaryUnmarshaler).UnmarshalBinary(b[:marshaledSizeSHA256]); err != nil {
|
if err := unmarshalHash(h.sha256, b[:marshaledSizeSHA256]); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
b = b[marshaledSizeSHA256:]
|
b = b[marshaledSizeSHA256:]
|
||||||
return h.sha512.(encoding.BinaryUnmarshaler).UnmarshalBinary(b[:marshaledSizeSHA512])
|
return unmarshalHash(h.sha512, b[:marshaledSizeSHA512])
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write implements io.Writer
|
// Write implements io.Writer
|
||||||
|
|||||||
@@ -107,13 +107,13 @@ func (e *MarshalEncoder) marshal(v any) error {
|
|||||||
return e.marshalArray(val)
|
return e.marshalArray(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch typ.Name() {
|
switch obj := val.Interface().(type) {
|
||||||
case "RubyUserMarshal":
|
case RubyUserMarshal:
|
||||||
return e.marshalUserMarshal(val.Interface().(RubyUserMarshal))
|
return e.marshalUserMarshal(obj)
|
||||||
case "RubyUserDef":
|
case RubyUserDef:
|
||||||
return e.marshalUserDef(val.Interface().(RubyUserDef))
|
return e.marshalUserDef(obj)
|
||||||
case "RubyObject":
|
case RubyObject:
|
||||||
return e.marshalObject(val.Interface().(RubyObject))
|
return e.marshalObject(obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ErrUnsupportedType
|
return ErrUnsupportedType
|
||||||
|
|||||||
@@ -5,13 +5,25 @@ package reqctx
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"maps"
|
"maps"
|
||||||
|
"reflect"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"gitea.dev/modules/process"
|
"gitea.dev/modules/process"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// MustContextValue returns the value stored under key. A missing or mistyped value can only
|
||||||
|
// be a programming error, and callers can't do anything useful with a zero value, so it panics.
|
||||||
|
func MustContextValue[T any](ctx context.Context, key any) T {
|
||||||
|
value, ok := ctx.Value(key).(T)
|
||||||
|
if !ok {
|
||||||
|
panic(fmt.Sprintf("context value %v is %T, expected %s", key, ctx.Value(key), reflect.TypeFor[T]()))
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
type ContextDataProvider interface {
|
type ContextDataProvider interface {
|
||||||
GetData() ContextData
|
GetData() ContextData
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ func RegenerateSession(resp http.ResponseWriter, req *http.Request) (Store, erro
|
|||||||
f(resp, req)
|
f(resp, req)
|
||||||
}
|
}
|
||||||
if setting.IsInTesting {
|
if setting.IsInTesting {
|
||||||
if store := req.Context().Value(MockStoreContextKey); store != nil {
|
if store, ok := req.Context().Value(MockStoreContextKey).(Store); ok {
|
||||||
return store.(Store), nil
|
return store, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return session.RegenerateSession(resp, req)
|
return session.RegenerateSession(resp, req)
|
||||||
@@ -37,8 +37,8 @@ func RegenerateSession(resp http.ResponseWriter, req *http.Request) (Store, erro
|
|||||||
|
|
||||||
func GetContextSession(req *http.Request) Store {
|
func GetContextSession(req *http.Request) Store {
|
||||||
if setting.IsInTesting {
|
if setting.IsInTesting {
|
||||||
if store := req.Context().Value(MockStoreContextKey); store != nil {
|
if store, ok := req.Context().Value(MockStoreContextKey).(Store); ok {
|
||||||
return store.(Store)
|
return store
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return session.GetSession(req)
|
return session.GetSession(req)
|
||||||
|
|||||||
+1
-1
@@ -99,7 +99,7 @@ func renderHTML(icon string, others ...any) (_ template.HTML, usingCache bool) {
|
|||||||
cacheKey := svgCacheKey{icon, size, class}
|
cacheKey := svgCacheKey{icon, size, class}
|
||||||
cachedHTML, cached := svgCache.Load(cacheKey)
|
cachedHTML, cached := svgCache.Load(cacheKey)
|
||||||
if cached && !svgItem.mocking {
|
if cached && !svgItem.mocking {
|
||||||
return cachedHTML.(template.HTML), true
|
return cachedHTML.(template.HTML), true //nolint:forcetypeassert // svgCache only ever holds template.HTML
|
||||||
}
|
}
|
||||||
|
|
||||||
// the code is somewhat hacky, but it just works, because the SVG contents are all normalized
|
// the code is somewhat hacky, but it just works, because the SVG contents are all normalized
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ func applyOp2(op operator, n1, n2 Num) Num {
|
|||||||
f2, _ := util.ToFloat64(n2.Value)
|
f2, _ := util.ToFloat64(n2.Value)
|
||||||
return applyOp2Generic(op, f1, f2)
|
return applyOp2Generic(op, f1, f2)
|
||||||
}
|
}
|
||||||
return applyOp2Generic(op, n1.Value.(int64), n2.Value.(int64))
|
return applyOp2Generic(op, n1.Value.(int64), n2.Value.(int64)) //nolint:forcetypeassert // castFloat64 above already ruled out float
|
||||||
}
|
}
|
||||||
|
|
||||||
func toOp(v any) (operator, error) {
|
func toOp(v any) (operator, error) {
|
||||||
@@ -321,13 +321,13 @@ func fnSum(nums []Num) Num {
|
|||||||
if castFloat64(nums) {
|
if castFloat64(nums) {
|
||||||
var sum float64
|
var sum float64
|
||||||
for _, num := range nums {
|
for _, num := range nums {
|
||||||
sum += num.Value.(float64)
|
sum += num.Value.(float64) //nolint:forcetypeassert // castFloat64 reported every value is float64
|
||||||
}
|
}
|
||||||
return Num{sum}
|
return Num{sum}
|
||||||
}
|
}
|
||||||
var sum int64
|
var sum int64
|
||||||
for _, num := range nums {
|
for _, num := range nums {
|
||||||
sum += num.Value.(int64)
|
sum += num.Value.(int64) //nolint:forcetypeassert // castFloat64 ruled out float, so every value is int64
|
||||||
}
|
}
|
||||||
return Num{sum}
|
return Num{sum}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func tokens(s string) (a []any) {
|
func tokens(s string) (a []any) {
|
||||||
@@ -21,7 +22,9 @@ func tokens(s string) (a []any) {
|
|||||||
func TestEval(t *testing.T) {
|
func TestEval(t *testing.T) {
|
||||||
n, err := Expr(0, "/", 0.0)
|
n, err := Expr(0, "/", 0.0)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.True(t, math.IsNaN(n.Value.(float64)))
|
nan, ok := n.Value.(float64)
|
||||||
|
require.True(t, ok)
|
||||||
|
assert.True(t, math.IsNaN(nan))
|
||||||
|
|
||||||
_, err = Expr(nil)
|
_, err = Expr(nil)
|
||||||
assert.ErrorContains(t, err, "unsupported token type")
|
assert.ErrorContains(t, err, "unsupported token type")
|
||||||
|
|||||||
@@ -166,9 +166,9 @@ func newScopedTemplateSet(all *template.Template, name string) (*scopedTemplateS
|
|||||||
var collectErr error // only need to collect the one error
|
var collectErr error // only need to collect the one error
|
||||||
collectTemplates = func(nodes []parse.Node) {
|
collectTemplates = func(nodes []parse.Node) {
|
||||||
for _, node := range nodes {
|
for _, node := range nodes {
|
||||||
if node.Type() == parse.NodeTemplate {
|
switch node := node.(type) {
|
||||||
nodeTemplate := node.(*parse.TemplateNode)
|
case *parse.TemplateNode:
|
||||||
subName := nodeTemplate.Name
|
subName := node.Name
|
||||||
if ts.htmlTemplates[subName] == nil {
|
if ts.htmlTemplates[subName] == nil {
|
||||||
subTmpl := all.Lookup(subName)
|
subTmpl := all.Lookup(subName)
|
||||||
if subTmpl == nil {
|
if subTmpl == nil {
|
||||||
@@ -185,26 +185,22 @@ func newScopedTemplateSet(all *template.Template, name string) (*scopedTemplateS
|
|||||||
collectTemplates(subTmpl.Tree.Root.Nodes)
|
collectTemplates(subTmpl.Tree.Root.Nodes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if node.Type() == parse.NodeList {
|
case *parse.ListNode:
|
||||||
nodeList := node.(*parse.ListNode)
|
collectTemplates(node.Nodes)
|
||||||
collectTemplates(nodeList.Nodes)
|
case *parse.IfNode:
|
||||||
} else if node.Type() == parse.NodeIf {
|
collectTemplates(node.BranchNode.List.Nodes)
|
||||||
nodeIf := node.(*parse.IfNode)
|
if node.BranchNode.ElseList != nil {
|
||||||
collectTemplates(nodeIf.BranchNode.List.Nodes)
|
collectTemplates(node.BranchNode.ElseList.Nodes)
|
||||||
if nodeIf.BranchNode.ElseList != nil {
|
|
||||||
collectTemplates(nodeIf.BranchNode.ElseList.Nodes)
|
|
||||||
}
|
}
|
||||||
} else if node.Type() == parse.NodeRange {
|
case *parse.RangeNode:
|
||||||
nodeRange := node.(*parse.RangeNode)
|
collectTemplates(node.BranchNode.List.Nodes)
|
||||||
collectTemplates(nodeRange.BranchNode.List.Nodes)
|
if node.BranchNode.ElseList != nil {
|
||||||
if nodeRange.BranchNode.ElseList != nil {
|
collectTemplates(node.BranchNode.ElseList.Nodes)
|
||||||
collectTemplates(nodeRange.BranchNode.ElseList.Nodes)
|
|
||||||
}
|
}
|
||||||
} else if node.Type() == parse.NodeWith {
|
case *parse.WithNode:
|
||||||
nodeWith := node.(*parse.WithNode)
|
collectTemplates(node.BranchNode.List.Nodes)
|
||||||
collectTemplates(nodeWith.BranchNode.List.Nodes)
|
if node.BranchNode.ElseList != nil {
|
||||||
if nodeWith.BranchNode.ElseList != nil {
|
collectTemplates(node.BranchNode.ElseList.Nodes)
|
||||||
collectTemplates(nodeWith.BranchNode.ElseList.Nodes)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,10 @@ func NewRenderUtils(ctx reqctx.RequestContext) *RenderUtils {
|
|||||||
return &RenderUtils{ctx: ctx, avatarUtils: NewAvatarUtils(ctx)}
|
return &RenderUtils{ctx: ctx, avatarUtils: NewAvatarUtils(ctx)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ut *RenderUtils) locale() translation.Locale {
|
||||||
|
return ut.ctx.Value(translation.ContextKey).(translation.Locale) //nolint:forcetypeassert // the render context always carries a locale
|
||||||
|
}
|
||||||
|
|
||||||
// RenderCommitMessage renders commit message title (only title)
|
// RenderCommitMessage renders commit message title (only title)
|
||||||
func (ut *RenderUtils) RenderCommitMessage(msg string, repo *repo.Repository) template.HTML {
|
func (ut *RenderUtils) RenderCommitMessage(msg string, repo *repo.Repository) template.HTML {
|
||||||
msgLine := strings.TrimSpace(msg)
|
msgLine := strings.TrimSpace(msg)
|
||||||
@@ -98,7 +102,7 @@ func (ut *RenderUtils) RenderIssueSimpleTitle(text string) template.HTML {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ut *RenderUtils) RenderLabel(label *issues_model.Label) template.HTML {
|
func (ut *RenderUtils) RenderLabel(label *issues_model.Label) template.HTML {
|
||||||
locale := ut.ctx.Value(translation.ContextKey).(translation.Locale)
|
locale := ut.locale()
|
||||||
var extraCSSClasses string
|
var extraCSSClasses string
|
||||||
textColor := util.ContrastColor(label.Color)
|
textColor := util.ContrastColor(label.Color)
|
||||||
labelScope := label.ExclusiveScope()
|
labelScope := label.ExclusiveScope()
|
||||||
@@ -279,7 +283,7 @@ func (ut *RenderUtils) RenderUnicodeEscapeToggleButton(escapeStatus *charset.Esc
|
|||||||
if escapeStatus == nil || !escapeStatus.Escaped {
|
if escapeStatus == nil || !escapeStatus.Escaped {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
locale := ut.ctx.Value(translation.ContextKey).(translation.Locale)
|
locale := ut.locale()
|
||||||
var title template.HTML
|
var title template.HTML
|
||||||
if escapeStatus.HasAmbiguous {
|
if escapeStatus.HasAmbiguous {
|
||||||
title += locale.Tr("repo.ambiguous_runes_line")
|
title += locale.Tr("repo.ambiguous_runes_line")
|
||||||
@@ -376,7 +380,7 @@ func (ut *RenderUtils) AvatarStackPushCommit(pushCommit *repository.PushCommit)
|
|||||||
|
|
||||||
// AvatarStackWithNames renders the avatar stack plus a label: `name` / `a and b` / `N people` (opens popup).
|
// AvatarStackWithNames renders the avatar stack plus a label: `name` / `a and b` / `N people` (opens popup).
|
||||||
func (ut *RenderUtils) AvatarStackWithNames(data *user_model.AvatarStackData) template.HTML {
|
func (ut *RenderUtils) AvatarStackWithNames(data *user_model.AvatarStackData) template.HTML {
|
||||||
locale := ut.ctx.Value(translation.ContextKey).(translation.Locale)
|
locale := ut.locale()
|
||||||
participants := data.Participants
|
participants := data.Participants
|
||||||
|
|
||||||
var b htmlutil.HTMLBuilder
|
var b htmlutil.HTMLBuilder
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import (
|
|||||||
"gitea.dev/modules/htmlutil"
|
"gitea.dev/modules/htmlutil"
|
||||||
"gitea.dev/modules/setting"
|
"gitea.dev/modules/setting"
|
||||||
"gitea.dev/modules/svg"
|
"gitea.dev/modules/svg"
|
||||||
"gitea.dev/modules/translation"
|
|
||||||
"gitea.dev/modules/util"
|
"gitea.dev/modules/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -35,7 +34,7 @@ func (ut *RenderUtils) RenderTimelineEventBadge(c *issues_model.Comment) templat
|
|||||||
|
|
||||||
func (ut *RenderUtils) RenderTimelineEventComment(c *issues_model.Comment, createdStr template.HTML) template.HTML {
|
func (ut *RenderUtils) RenderTimelineEventComment(c *issues_model.Comment, createdStr template.HTML) template.HTML {
|
||||||
if c.Type == issues_model.CommentTypeChangeTitle {
|
if c.Type == issues_model.CommentTypeChangeTitle {
|
||||||
locale := ut.ctx.Value(translation.ContextKey).(translation.Locale)
|
locale := ut.locale()
|
||||||
isToggle, isWip := commentTimelineEventIsWipToggle(c)
|
isToggle, isWip := commentTimelineEventIsWipToggle(c)
|
||||||
if !isToggle {
|
if !isToggle {
|
||||||
return locale.Tr("repo.issues.change_title_at", ut.RenderEmoji(c.OldTitle), ut.RenderEmoji(c.NewTitle), createdStr)
|
return locale.Tr("repo.issues.change_title_at", ut.RenderEmoji(c.OldTitle), ut.RenderEmoji(c.NewTitle), createdStr)
|
||||||
|
|||||||
@@ -72,12 +72,16 @@ func (store *localeStore) AddLocaleByJSON(langName, langDesc string, source, mor
|
|||||||
l.idxToMsgMap[idx] = v
|
l.idxToMsgMap[idx] = v
|
||||||
case map[string]any:
|
case map[string]any:
|
||||||
for key, val := range v {
|
for key, val := range v {
|
||||||
|
valStr, ok := val.(string)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unsupported value type %T for key %q", val, trKey+"."+key)
|
||||||
|
}
|
||||||
idx, ok := store.trKeyToIdxMap[trKey+"."+key]
|
idx, ok := store.trKeyToIdxMap[trKey+"."+key]
|
||||||
if !ok {
|
if !ok {
|
||||||
idx = len(store.trKeyToIdxMap)
|
idx = len(store.trKeyToIdxMap)
|
||||||
store.trKeyToIdxMap[trKey+"."+key] = idx
|
store.trKeyToIdxMap[trKey+"."+key] = idx
|
||||||
}
|
}
|
||||||
l.idxToMsgMap[idx] = val.(string)
|
l.idxToMsgMap[idx] = valStr
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unsupported value type %T for key %q", v, trKey)
|
return fmt.Errorf("unsupported value type %T for key %q", v, trKey)
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import (
|
|||||||
// httpClient returns an HTTP client that honors Gitea's proxy configuration.
|
// httpClient returns an HTTP client that honors Gitea's proxy configuration.
|
||||||
var httpClient = util.OnceValue[*http.Client]{
|
var httpClient = util.OnceValue[*http.Client]{
|
||||||
Func: func() *http.Client {
|
Func: func() *http.Client {
|
||||||
transport := http.DefaultTransport.(*http.Transport).Clone()
|
transport := http.DefaultTransport.(*http.Transport).Clone() //nolint:forcetypeassert // Golang stdlib
|
||||||
transport.Proxy = proxy.Proxy()
|
transport.Proxy = proxy.Proxy()
|
||||||
return &http.Client{Transport: transport}
|
return &http.Client{Transport: transport}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestErrorTranslatable(t *testing.T) {
|
func TestErrorTranslatable(t *testing.T) {
|
||||||
@@ -16,8 +17,10 @@ func TestErrorTranslatable(t *testing.T) {
|
|||||||
err = ErrorWrapTranslatable(io.EOF, "key", 1)
|
err = ErrorWrapTranslatable(io.EOF, "key", 1)
|
||||||
assert.ErrorIs(t, err, io.EOF)
|
assert.ErrorIs(t, err, io.EOF)
|
||||||
assert.Equal(t, "EOF", err.Error())
|
assert.Equal(t, "EOF", err.Error())
|
||||||
assert.Equal(t, "key", err.(*errorTranslatableWrapper).trKey)
|
wrapped, ok := err.(*errorTranslatableWrapper)
|
||||||
assert.Equal(t, []any{1}, err.(*errorTranslatableWrapper).trArgs)
|
require.True(t, ok)
|
||||||
|
assert.Equal(t, "key", wrapped.trKey)
|
||||||
|
assert.Equal(t, []any{1}, wrapped.trArgs)
|
||||||
|
|
||||||
err = ErrorWrap(err, "new msg %d", 100)
|
err = ErrorWrap(err, "new msg %d", 100)
|
||||||
assert.ErrorIs(t, err, io.EOF)
|
assert.ErrorIs(t, err, io.EOF)
|
||||||
@@ -25,5 +28,7 @@ func TestErrorTranslatable(t *testing.T) {
|
|||||||
|
|
||||||
errTr := ErrorAsTranslatable(err)
|
errTr := ErrorAsTranslatable(err)
|
||||||
assert.Equal(t, "EOF", errTr.Error())
|
assert.Equal(t, "EOF", errTr.Error())
|
||||||
assert.Equal(t, "key", errTr.(*errorTranslatableWrapper).trKey)
|
wrapped, ok = errTr.(*errorTranslatableWrapper)
|
||||||
|
require.True(t, ok)
|
||||||
|
assert.Equal(t, "key", wrapped.trKey)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestKeygen(t *testing.T) {
|
func TestKeygen(t *testing.T) {
|
||||||
@@ -55,6 +56,8 @@ func TestSignUsingKeys(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
err = rsa.VerifyPKCS1v15(pubParsed.(*rsa.PublicKey), crypto.SHA256, d, sig)
|
pubKey, ok := pubParsed.(*rsa.PublicKey)
|
||||||
|
require.True(t, ok)
|
||||||
|
err = rsa.VerifyPKCS1v15(pubKey, crypto.SHA256, d, sig)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
// Copyright 2025 The Gitea Authors. All rights reserved.
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
package util
|
|
||||||
|
|
||||||
func GetMapValueOrDefault[T any](m map[string]any, key string, defaultValue T) T {
|
|
||||||
if value, ok := m[key]; ok {
|
|
||||||
if v, ok := value.(T); ok {
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return defaultValue
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
// Copyright 2025 The Gitea Authors. All rights reserved.
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
package util
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestGetMapValueOrDefault(t *testing.T) {
|
|
||||||
testMap := map[string]any{
|
|
||||||
"key1": "value1",
|
|
||||||
"key2": 42,
|
|
||||||
"key3": nil,
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.Equal(t, "value1", GetMapValueOrDefault(testMap, "key1", "default"))
|
|
||||||
assert.Equal(t, 42, GetMapValueOrDefault(testMap, "key2", 0))
|
|
||||||
|
|
||||||
assert.Equal(t, "default", GetMapValueOrDefault(testMap, "key4", "default"))
|
|
||||||
assert.Equal(t, 100, GetMapValueOrDefault(testMap, "key5", 100))
|
|
||||||
|
|
||||||
assert.Equal(t, "default", GetMapValueOrDefault(testMap, "key3", "default"))
|
|
||||||
}
|
|
||||||
@@ -3,31 +3,24 @@
|
|||||||
|
|
||||||
package util
|
package util
|
||||||
|
|
||||||
import "reflect"
|
|
||||||
|
|
||||||
// PaginateSlice cut a slice as per pagination options
|
// PaginateSlice cut a slice as per pagination options
|
||||||
// if page = 0 it do not paginate
|
// if page = 0 it do not paginate
|
||||||
func PaginateSlice(list any, page, pageSize int) any {
|
func PaginateSlice[S ~[]E, E any](list S, page, pageSize int) S {
|
||||||
if page <= 0 || pageSize <= 0 {
|
if page <= 0 || pageSize <= 0 {
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
if reflect.TypeOf(list).Kind() != reflect.Slice {
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
|
|
||||||
listValue := reflect.ValueOf(list)
|
|
||||||
|
|
||||||
page--
|
page--
|
||||||
|
|
||||||
if page*pageSize >= listValue.Len() {
|
if page*pageSize >= len(list) {
|
||||||
return listValue.Slice(listValue.Len(), listValue.Len()).Interface()
|
return list[len(list):]
|
||||||
}
|
}
|
||||||
|
|
||||||
listValue = listValue.Slice(page*pageSize, listValue.Len())
|
list = list[page*pageSize:]
|
||||||
|
|
||||||
if listValue.Len() > pageSize {
|
if len(list) > pageSize {
|
||||||
return listValue.Slice(0, pageSize).Interface()
|
return list[:pageSize]
|
||||||
}
|
}
|
||||||
|
|
||||||
return listValue.Interface()
|
return list
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,24 +11,19 @@ import (
|
|||||||
|
|
||||||
func TestPaginateSlice(t *testing.T) {
|
func TestPaginateSlice(t *testing.T) {
|
||||||
stringSlice := []string{"a", "b", "c", "d", "e"}
|
stringSlice := []string{"a", "b", "c", "d", "e"}
|
||||||
result, ok := PaginateSlice(stringSlice, 1, 2).([]string)
|
result := PaginateSlice(stringSlice, 1, 2)
|
||||||
assert.True(t, ok)
|
|
||||||
assert.Equal(t, []string{"a", "b"}, result)
|
assert.Equal(t, []string{"a", "b"}, result)
|
||||||
|
|
||||||
result, ok = PaginateSlice(stringSlice, 100, 2).([]string)
|
result = PaginateSlice(stringSlice, 100, 2)
|
||||||
assert.True(t, ok)
|
|
||||||
assert.Equal(t, []string{}, result)
|
assert.Equal(t, []string{}, result)
|
||||||
|
|
||||||
result, ok = PaginateSlice(stringSlice, 3, 2).([]string)
|
result = PaginateSlice(stringSlice, 3, 2)
|
||||||
assert.True(t, ok)
|
|
||||||
assert.Equal(t, []string{"e"}, result)
|
assert.Equal(t, []string{"e"}, result)
|
||||||
|
|
||||||
result, ok = PaginateSlice(stringSlice, 1, 0).([]string)
|
result = PaginateSlice(stringSlice, 1, 0)
|
||||||
assert.True(t, ok)
|
|
||||||
assert.Equal(t, []string{"a", "b", "c", "d", "e"}, result)
|
assert.Equal(t, []string{"a", "b", "c", "d", "e"}, result)
|
||||||
|
|
||||||
result, ok = PaginateSlice(stringSlice, 1, -1).([]string)
|
result = PaginateSlice(stringSlice, 1, -1)
|
||||||
assert.True(t, ok)
|
|
||||||
assert.Equal(t, []string{"a", "b", "c", "d", "e"}, result)
|
assert.Equal(t, []string{"a", "b", "c", "d", "e"}, result)
|
||||||
|
|
||||||
type Test struct {
|
type Test struct {
|
||||||
@@ -36,11 +31,9 @@ func TestPaginateSlice(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
testVar := []*Test{{Val: 2}, {Val: 3}, {Val: 4}}
|
testVar := []*Test{{Val: 2}, {Val: 3}, {Val: 4}}
|
||||||
testVar, ok = PaginateSlice(testVar, 1, 50).([]*Test)
|
testVar = PaginateSlice(testVar, 1, 50)
|
||||||
assert.True(t, ok)
|
|
||||||
assert.Equal(t, []*Test{{Val: 2}, {Val: 3}, {Val: 4}}, testVar)
|
assert.Equal(t, []*Test{{Val: 2}, {Val: 3}, {Val: 4}}, testVar)
|
||||||
|
|
||||||
testVar, ok = PaginateSlice(testVar, 2, 2).([]*Test)
|
testVar = PaginateSlice(testVar, 2, 2)
|
||||||
assert.True(t, ok)
|
|
||||||
assert.Equal(t, []*Test{{Val: 4}}, testVar)
|
assert.Equal(t, []*Test{{Val: 4}}, testVar)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ func FastCryptoRandomBytes(length int) []byte {
|
|||||||
// ChaCha8 is about 20x times faster than system's crypto/rand.
|
// ChaCha8 is about 20x times faster than system's crypto/rand.
|
||||||
// It is suitable for UUIDs, session IDs, etc
|
// It is suitable for UUIDs, session IDs, etc
|
||||||
pool := chaCha8RandPool()
|
pool := chaCha8RandPool()
|
||||||
chaCha8Rand := pool.Get().(*rand2.ChaCha8)
|
chaCha8Rand := pool.Get().(*rand2.ChaCha8) //nolint:forcetypeassert // the pool's New only ever makes *rand2.ChaCha8
|
||||||
defer pool.Put(chaCha8Rand)
|
defer pool.Put(chaCha8Rand)
|
||||||
buf := make([]byte, length)
|
buf := make([]byte, length)
|
||||||
_, _ = chaCha8Rand.Read(buf)
|
_, _ = chaCha8Rand.Read(buf)
|
||||||
@@ -270,15 +270,16 @@ func OptionalArg[T any](optArg []T, defaultValue ...T) (ret T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type EnumConst[T comparable] interface {
|
type EnumConst[T comparable] interface {
|
||||||
|
comparable
|
||||||
EnumValues() []T
|
EnumValues() []T
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnumValue returns the value if it's in the enum const's values,
|
// EnumValue returns the value if it's in the enum const's values,
|
||||||
// otherwise returns the first item of enums as default value.
|
// otherwise returns the first item of enums as default value.
|
||||||
func EnumValue[T comparable](val EnumConst[T]) (ret T, valid bool) {
|
func EnumValue[T EnumConst[T]](val T) (ret T, valid bool) {
|
||||||
enums := val.EnumValues()
|
enums := val.EnumValues()
|
||||||
if slices.Contains(enums, val.(T)) {
|
if slices.Contains(enums, val) {
|
||||||
return val.(T), true
|
return val, true
|
||||||
}
|
}
|
||||||
return enums[0], false
|
return enums[0], false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
package web
|
package web
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"reflect"
|
"reflect"
|
||||||
@@ -37,8 +38,12 @@ func SetForm(dataStore reqctx.ContextDataProvider, obj any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetForm returns the validate form information
|
// GetForm returns the validate form information
|
||||||
func GetForm(dataStore reqctx.RequestDataStore) any {
|
func GetForm[T any](dataStore reqctx.RequestDataStore) T {
|
||||||
return dataStore.GetData()["__form"]
|
form, ok := dataStore.GetData()["__form"].(T)
|
||||||
|
if !ok {
|
||||||
|
panic(fmt.Errorf("bound form %T does not match the requested type %s", dataStore.GetData()["__form"], reflect.TypeFor[T]()))
|
||||||
|
}
|
||||||
|
return form
|
||||||
}
|
}
|
||||||
|
|
||||||
// Router defines a route based on chi's router
|
// Router defines a route based on chi's router
|
||||||
|
|||||||
@@ -54,10 +54,10 @@ func (manager *loggerRequestManager) startSlowQueryDetector(threshold time.Durat
|
|||||||
|
|
||||||
// print logs for slow requests
|
// print logs for slow requests
|
||||||
manager.reqRecords.Range(func(key, value any) bool {
|
manager.reqRecords.Range(func(key, value any) bool {
|
||||||
index, record := key.(uint64), value.(*requestRecord)
|
record := value.(*requestRecord) //nolint:forcetypeassert // reqRecords only ever holds *requestRecord
|
||||||
if now.Sub(record.startTime) >= threshold {
|
if now.Sub(record.startTime) >= threshold {
|
||||||
manager.logPrint(StillExecutingEvent, record)
|
manager.logPrint(StillExecutingEvent, record)
|
||||||
manager.reqRecords.Delete(index)
|
manager.reqRecords.Delete(key)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ import (
|
|||||||
"gitea.dev/modules/json"
|
"gitea.dev/modules/json"
|
||||||
"gitea.dev/modules/log"
|
"gitea.dev/modules/log"
|
||||||
"gitea.dev/modules/optional"
|
"gitea.dev/modules/optional"
|
||||||
|
"gitea.dev/modules/reqctx"
|
||||||
"gitea.dev/modules/setting"
|
"gitea.dev/modules/setting"
|
||||||
"gitea.dev/modules/storage"
|
"gitea.dev/modules/storage"
|
||||||
"gitea.dev/modules/util"
|
"gitea.dev/modules/util"
|
||||||
@@ -98,7 +99,7 @@ type ArtifactContext struct {
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
web.RegisterResponseStatusProvider[*ArtifactContext](func(req *http.Request) web_types.ResponseStatusProvider {
|
web.RegisterResponseStatusProvider[*ArtifactContext](func(req *http.Request) web_types.ResponseStatusProvider {
|
||||||
return req.Context().Value(artifactContextKey).(*ArtifactContext)
|
return reqctx.MustContextValue[*ArtifactContext](req.Context(), artifactContextKey)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -323,7 +323,7 @@ func mergeChunksForArtifact(ctx *ArtifactContext, chunks []*chunkFileItem, st st
|
|||||||
readers := make([]io.Reader, 0, len(allChunks))
|
readers := make([]io.Reader, 0, len(allChunks))
|
||||||
closeReaders := func() {
|
closeReaders := func() {
|
||||||
for _, r := range readers {
|
for _, r := range readers {
|
||||||
_ = r.(io.Closer).Close() // it guarantees to be io.Closer by the following loop's Open function
|
_ = r.(io.Closer).Close() //nolint:forcetypeassert // it guarantees to be io.Closer by the following loop's Open function
|
||||||
}
|
}
|
||||||
readers = nil
|
readers = nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ func SearchPackages(ctx *context.Context) {
|
|||||||
crates = append(crates, &SearchResultCrate{
|
crates = append(crates, &SearchResultCrate{
|
||||||
Name: pd.Package.Name,
|
Name: pd.Package.Name,
|
||||||
LatestVersion: pd.Version.Version,
|
LatestVersion: pd.Version.Version,
|
||||||
Description: pd.Metadata.(*cargo_module.Metadata).Description,
|
Description: packages_model.DescriptorMetadata[*cargo_module.Metadata](pd).Description,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,12 @@ func (a *Auth) Verify(req *http.Request, w http.ResponseWriter, store auth.DataS
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := verifySignedHeaders(req, version, pub.(*rsa.PublicKey)); err != nil {
|
rsaPub, ok := pub.(*rsa.PublicKey)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("public key is not a RSA key")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := verifySignedHeaders(req, version, rsaPub); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ func PackagesUniverse(ctx *context.Context) {
|
|||||||
LocationType: "opscode",
|
LocationType: "opscode",
|
||||||
LocationPath: baseURL,
|
LocationPath: baseURL,
|
||||||
DownloadURL: fmt.Sprintf("%s/cookbooks/%s/versions/%s/download", baseURL, url.PathEscape(pd.Package.Name), pd.Version.Version),
|
DownloadURL: fmt.Sprintf("%s/cookbooks/%s/versions/%s/download", baseURL, url.PathEscape(pd.Package.Name), pd.Version.Version),
|
||||||
Dependencies: pd.Metadata.(*chef_module.Metadata).Dependencies,
|
Dependencies: packages_model.DescriptorMetadata[*chef_module.Metadata](pd).Dependencies,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +128,7 @@ func EnumeratePackages(ctx *context.Context) {
|
|||||||
|
|
||||||
items := make([]*Item, 0, len(pds))
|
items := make([]*Item, 0, len(pds))
|
||||||
for _, pd := range pds {
|
for _, pd := range pds {
|
||||||
metadata := pd.Metadata.(*chef_module.Metadata)
|
metadata := packages_model.DescriptorMetadata[*chef_module.Metadata](pd)
|
||||||
|
|
||||||
items = append(items, &Item{
|
items = append(items, &Item{
|
||||||
CookbookName: pd.Package.Name,
|
CookbookName: pd.Package.Name,
|
||||||
@@ -193,7 +193,7 @@ func PackageMetadata(ctx *context.Context) {
|
|||||||
|
|
||||||
latest := pds[len(pds)-1]
|
latest := pds[len(pds)-1]
|
||||||
|
|
||||||
metadata := latest.Metadata.(*chef_module.Metadata)
|
metadata := packages_model.DescriptorMetadata[*chef_module.Metadata](latest)
|
||||||
|
|
||||||
ctx.JSON(http.StatusOK, &Result{
|
ctx.JSON(http.StatusOK, &Result{
|
||||||
Name: latest.Package.Name,
|
Name: latest.Package.Name,
|
||||||
@@ -241,7 +241,7 @@ func PackageVersionMetadata(ctx *context.Context) {
|
|||||||
|
|
||||||
baseURL := fmt.Sprintf("%sapi/packages/%s/chef/api/v1/cookbooks/%s", setting.AppURL, ctx.Package.Owner.Name, url.PathEscape(pd.Package.Name))
|
baseURL := fmt.Sprintf("%sapi/packages/%s/chef/api/v1/cookbooks/%s", setting.AppURL, ctx.Package.Owner.Name, url.PathEscape(pd.Package.Name))
|
||||||
|
|
||||||
metadata := pd.Metadata.(*chef_module.Metadata)
|
metadata := packages_model.DescriptorMetadata[*chef_module.Metadata](pd)
|
||||||
|
|
||||||
ctx.JSON(http.StatusOK, &Result{
|
ctx.JSON(http.StatusOK, &Result{
|
||||||
Version: pd.Version.Version,
|
Version: pd.Version.Version,
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ func createSearchResultResponse(total int64, pds []*packages_model.PackageDescri
|
|||||||
for _, pd := range pds {
|
for _, pd := range pds {
|
||||||
results = append(results, &SearchResult{
|
results = append(results, &SearchResult{
|
||||||
Name: pd.Package.Name,
|
Name: pd.Package.Name,
|
||||||
Description: pd.Metadata.(*composer_module.Metadata).Description,
|
Description: packages_model.DescriptorMetadata[*composer_module.Metadata](pd).Description,
|
||||||
Downloads: pd.Version.DownloadCount,
|
Downloads: pd.Version.DownloadCount,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -111,7 +111,7 @@ func createPackageMetadataResponse(ctx *context.Context, registryURL string, pds
|
|||||||
Version: pd.Version.Version,
|
Version: pd.Version.Version,
|
||||||
Type: packageType,
|
Type: packageType,
|
||||||
Created: pd.Version.CreatedUnix.AsLocalTime(),
|
Created: pd.Version.CreatedUnix.AsLocalTime(),
|
||||||
Metadata: pd.Metadata.(*composer_module.Metadata),
|
Metadata: packages_model.DescriptorMetadata[*composer_module.Metadata](pd),
|
||||||
Dist: Dist{
|
Dist: Dist{
|
||||||
Type: "zip",
|
Type: "zip",
|
||||||
URL: fmt.Sprintf("%s/files/%s/%s/%s", registryURL, url.PathEscape(pd.Package.LowerName), url.PathEscape(pd.Version.LowerVersion), url.PathEscape(pd.Files[0].File.LowerName)),
|
URL: fmt.Sprintf("%s/files/%s/%s/%s", registryURL, url.PathEscape(pd.Package.LowerName), url.PathEscape(pd.Version.LowerVersion), url.PathEscape(pd.Files[0].File.LowerName)),
|
||||||
|
|||||||
@@ -103,6 +103,14 @@ func ExtractPathParameters(ctx *context.Context) {
|
|||||||
ctx.Data[packageReferenceKey] = pref
|
ctx.Data[packageReferenceKey] = pref
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getRecipeReference(ctx *context.Context) *conan_module.RecipeReference {
|
||||||
|
return ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference) //nolint:forcetypeassert // must be valid
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPackageReference(ctx *context.Context) *conan_module.PackageReference {
|
||||||
|
return ctx.Data[packageReferenceKey].(*conan_module.PackageReference) //nolint:forcetypeassert // must be valid
|
||||||
|
}
|
||||||
|
|
||||||
// Ping reports the server capabilities
|
// Ping reports the server capabilities
|
||||||
func Ping(ctx *context.Context) {
|
func Ping(ctx *context.Context) {
|
||||||
ctx.RespHeader().Add("X-Conan-Server-Capabilities", "revisions") // complex_search,checksum_deploy,matrix_params
|
ctx.RespHeader().Add("X-Conan-Server-Capabilities", "revisions") // complex_search,checksum_deploy,matrix_params
|
||||||
@@ -164,20 +172,20 @@ func CheckCredentials(ctx *context.Context) {
|
|||||||
|
|
||||||
// RecipeSnapshot displays the recipe files with their md5 hash
|
// RecipeSnapshot displays the recipe files with their md5 hash
|
||||||
func RecipeSnapshot(ctx *context.Context) {
|
func RecipeSnapshot(ctx *context.Context) {
|
||||||
rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference)
|
rref := getRecipeReference(ctx)
|
||||||
|
|
||||||
serveSnapshot(ctx, rref.AsKey())
|
serveSnapshot(ctx, rref.AsKey())
|
||||||
}
|
}
|
||||||
|
|
||||||
// RecipeSnapshot displays the package files with their md5 hash
|
// RecipeSnapshot displays the package files with their md5 hash
|
||||||
func PackageSnapshot(ctx *context.Context) {
|
func PackageSnapshot(ctx *context.Context) {
|
||||||
pref := ctx.Data[packageReferenceKey].(*conan_module.PackageReference)
|
pref := getPackageReference(ctx)
|
||||||
|
|
||||||
serveSnapshot(ctx, pref.AsKey())
|
serveSnapshot(ctx, pref.AsKey())
|
||||||
}
|
}
|
||||||
|
|
||||||
func serveSnapshot(ctx *context.Context, fileKey string) {
|
func serveSnapshot(ctx *context.Context, fileKey string) {
|
||||||
rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference)
|
rref := getRecipeReference(ctx)
|
||||||
|
|
||||||
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeConan, rref.Name, rref.Version)
|
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeConan, rref.Name, rref.Version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -217,7 +225,7 @@ func serveSnapshot(ctx *context.Context, fileKey string) {
|
|||||||
|
|
||||||
// RecipeDownloadURLs displays the recipe files with their download url
|
// RecipeDownloadURLs displays the recipe files with their download url
|
||||||
func RecipeDownloadURLs(ctx *context.Context) {
|
func RecipeDownloadURLs(ctx *context.Context) {
|
||||||
rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference)
|
rref := getRecipeReference(ctx)
|
||||||
|
|
||||||
serveDownloadURLs(
|
serveDownloadURLs(
|
||||||
ctx,
|
ctx,
|
||||||
@@ -228,7 +236,7 @@ func RecipeDownloadURLs(ctx *context.Context) {
|
|||||||
|
|
||||||
// PackageDownloadURLs displays the package files with their download url
|
// PackageDownloadURLs displays the package files with their download url
|
||||||
func PackageDownloadURLs(ctx *context.Context) {
|
func PackageDownloadURLs(ctx *context.Context) {
|
||||||
pref := ctx.Data[packageReferenceKey].(*conan_module.PackageReference)
|
pref := getPackageReference(ctx)
|
||||||
|
|
||||||
serveDownloadURLs(
|
serveDownloadURLs(
|
||||||
ctx,
|
ctx,
|
||||||
@@ -238,7 +246,7 @@ func PackageDownloadURLs(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func serveDownloadURLs(ctx *context.Context, fileKey, downloadURL string) {
|
func serveDownloadURLs(ctx *context.Context, fileKey, downloadURL string) {
|
||||||
rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference)
|
rref := getRecipeReference(ctx)
|
||||||
|
|
||||||
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeConan, rref.Name, rref.Version)
|
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeConan, rref.Name, rref.Version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -274,7 +282,7 @@ func serveDownloadURLs(ctx *context.Context, fileKey, downloadURL string) {
|
|||||||
|
|
||||||
// RecipeUploadURLs displays the upload urls for the provided recipe files
|
// RecipeUploadURLs displays the upload urls for the provided recipe files
|
||||||
func RecipeUploadURLs(ctx *context.Context) {
|
func RecipeUploadURLs(ctx *context.Context) {
|
||||||
rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference)
|
rref := getRecipeReference(ctx)
|
||||||
|
|
||||||
serveUploadURLs(
|
serveUploadURLs(
|
||||||
ctx,
|
ctx,
|
||||||
@@ -285,7 +293,7 @@ func RecipeUploadURLs(ctx *context.Context) {
|
|||||||
|
|
||||||
// PackageUploadURLs displays the upload urls for the provided package files
|
// PackageUploadURLs displays the upload urls for the provided package files
|
||||||
func PackageUploadURLs(ctx *context.Context) {
|
func PackageUploadURLs(ctx *context.Context) {
|
||||||
pref := ctx.Data[packageReferenceKey].(*conan_module.PackageReference)
|
pref := getPackageReference(ctx)
|
||||||
|
|
||||||
serveUploadURLs(
|
serveUploadURLs(
|
||||||
ctx,
|
ctx,
|
||||||
@@ -315,21 +323,21 @@ func serveUploadURLs(ctx *context.Context, fileFilter container.Set[string], upl
|
|||||||
|
|
||||||
// UploadRecipeFile handles the upload of a recipe file
|
// UploadRecipeFile handles the upload of a recipe file
|
||||||
func UploadRecipeFile(ctx *context.Context) {
|
func UploadRecipeFile(ctx *context.Context) {
|
||||||
rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference)
|
rref := getRecipeReference(ctx)
|
||||||
|
|
||||||
uploadFile(ctx, recipeFileList, rref.AsKey())
|
uploadFile(ctx, recipeFileList, rref.AsKey())
|
||||||
}
|
}
|
||||||
|
|
||||||
// UploadPackageFile handles the upload of a package file
|
// UploadPackageFile handles the upload of a package file
|
||||||
func UploadPackageFile(ctx *context.Context) {
|
func UploadPackageFile(ctx *context.Context) {
|
||||||
pref := ctx.Data[packageReferenceKey].(*conan_module.PackageReference)
|
pref := getPackageReference(ctx)
|
||||||
|
|
||||||
uploadFile(ctx, packageFileList, pref.AsKey())
|
uploadFile(ctx, packageFileList, pref.AsKey())
|
||||||
}
|
}
|
||||||
|
|
||||||
func uploadFile(ctx *context.Context, fileFilter container.Set[string], fileKey string) {
|
func uploadFile(ctx *context.Context, fileFilter container.Set[string], fileKey string) {
|
||||||
rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference)
|
rref := getRecipeReference(ctx)
|
||||||
pref := ctx.Data[packageReferenceKey].(*conan_module.PackageReference)
|
pref := getPackageReference(ctx)
|
||||||
|
|
||||||
filename := ctx.PathParam("filename")
|
filename := ctx.PathParam("filename")
|
||||||
if !fileFilter.Contains(filename) {
|
if !fileFilter.Contains(filename) {
|
||||||
@@ -454,20 +462,20 @@ func uploadFile(ctx *context.Context, fileFilter container.Set[string], fileKey
|
|||||||
|
|
||||||
// DownloadRecipeFile serves the content of the requested recipe file
|
// DownloadRecipeFile serves the content of the requested recipe file
|
||||||
func DownloadRecipeFile(ctx *context.Context) {
|
func DownloadRecipeFile(ctx *context.Context) {
|
||||||
rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference)
|
rref := getRecipeReference(ctx)
|
||||||
|
|
||||||
downloadFile(ctx, recipeFileList, rref.AsKey())
|
downloadFile(ctx, recipeFileList, rref.AsKey())
|
||||||
}
|
}
|
||||||
|
|
||||||
// DownloadPackageFile serves the content of the requested package file
|
// DownloadPackageFile serves the content of the requested package file
|
||||||
func DownloadPackageFile(ctx *context.Context) {
|
func DownloadPackageFile(ctx *context.Context) {
|
||||||
pref := ctx.Data[packageReferenceKey].(*conan_module.PackageReference)
|
pref := getPackageReference(ctx)
|
||||||
|
|
||||||
downloadFile(ctx, packageFileList, pref.AsKey())
|
downloadFile(ctx, packageFileList, pref.AsKey())
|
||||||
}
|
}
|
||||||
|
|
||||||
func downloadFile(ctx *context.Context, fileFilter container.Set[string], fileKey string) {
|
func downloadFile(ctx *context.Context, fileFilter container.Set[string], fileKey string) {
|
||||||
rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference)
|
rref := getRecipeReference(ctx)
|
||||||
|
|
||||||
filename := ctx.PathParam("filename")
|
filename := ctx.PathParam("filename")
|
||||||
if !fileFilter.Contains(filename) {
|
if !fileFilter.Contains(filename) {
|
||||||
@@ -503,7 +511,7 @@ func downloadFile(ctx *context.Context, fileFilter container.Set[string], fileKe
|
|||||||
|
|
||||||
// DeleteRecipeV1 deletes the requested recipe(s)
|
// DeleteRecipeV1 deletes the requested recipe(s)
|
||||||
func DeleteRecipeV1(ctx *context.Context) {
|
func DeleteRecipeV1(ctx *context.Context) {
|
||||||
rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference)
|
rref := getRecipeReference(ctx)
|
||||||
|
|
||||||
if err := deleteRecipeOrPackage(ctx, rref, true, nil, false); err != nil {
|
if err := deleteRecipeOrPackage(ctx, rref, true, nil, false); err != nil {
|
||||||
if errors.Is(err, packages_model.ErrPackageNotExist) || errors.Is(err, conan_model.ErrPackageReferenceNotExist) {
|
if errors.Is(err, packages_model.ErrPackageNotExist) || errors.Is(err, conan_model.ErrPackageReferenceNotExist) {
|
||||||
@@ -518,7 +526,7 @@ func DeleteRecipeV1(ctx *context.Context) {
|
|||||||
|
|
||||||
// DeleteRecipeV2 deletes the requested recipe(s) respecting its revisions
|
// DeleteRecipeV2 deletes the requested recipe(s) respecting its revisions
|
||||||
func DeleteRecipeV2(ctx *context.Context) {
|
func DeleteRecipeV2(ctx *context.Context) {
|
||||||
rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference)
|
rref := getRecipeReference(ctx)
|
||||||
|
|
||||||
if err := deleteRecipeOrPackage(ctx, rref, rref.Revision == "", nil, false); err != nil {
|
if err := deleteRecipeOrPackage(ctx, rref, rref.Revision == "", nil, false); err != nil {
|
||||||
if errors.Is(err, packages_model.ErrPackageNotExist) || errors.Is(err, conan_model.ErrPackageReferenceNotExist) {
|
if errors.Is(err, packages_model.ErrPackageNotExist) || errors.Is(err, conan_model.ErrPackageReferenceNotExist) {
|
||||||
@@ -533,7 +541,7 @@ func DeleteRecipeV2(ctx *context.Context) {
|
|||||||
|
|
||||||
// DeletePackageV1 deletes the requested package(s)
|
// DeletePackageV1 deletes the requested package(s)
|
||||||
func DeletePackageV1(ctx *context.Context) {
|
func DeletePackageV1(ctx *context.Context) {
|
||||||
rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference)
|
rref := getRecipeReference(ctx)
|
||||||
|
|
||||||
type PackageReferences struct {
|
type PackageReferences struct {
|
||||||
References []string `json:"package_ids"`
|
References []string `json:"package_ids"`
|
||||||
@@ -582,8 +590,8 @@ func DeletePackageV1(ctx *context.Context) {
|
|||||||
|
|
||||||
// DeletePackageV2 deletes the requested package(s) respecting its revisions
|
// DeletePackageV2 deletes the requested package(s) respecting its revisions
|
||||||
func DeletePackageV2(ctx *context.Context) {
|
func DeletePackageV2(ctx *context.Context) {
|
||||||
rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference)
|
rref := getRecipeReference(ctx)
|
||||||
pref := ctx.Data[packageReferenceKey].(*conan_module.PackageReference)
|
pref := getPackageReference(ctx)
|
||||||
|
|
||||||
if pref != nil { // has package reference
|
if pref != nil { // has package reference
|
||||||
if err := deleteRecipeOrPackage(ctx, rref, false, pref, pref.Revision == ""); err != nil {
|
if err := deleteRecipeOrPackage(ctx, rref, false, pref, pref.Revision == ""); err != nil {
|
||||||
@@ -693,7 +701,7 @@ func deleteRecipeOrPackage(apictx *context.Context, rref *conan_module.RecipeRef
|
|||||||
|
|
||||||
// ListRecipeRevisions gets a list of all recipe revisions
|
// ListRecipeRevisions gets a list of all recipe revisions
|
||||||
func ListRecipeRevisions(ctx *context.Context) {
|
func ListRecipeRevisions(ctx *context.Context) {
|
||||||
rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference)
|
rref := getRecipeReference(ctx)
|
||||||
|
|
||||||
revisions, err := conan_model.GetRecipeRevisions(ctx, ctx.Package.Owner.ID, rref)
|
revisions, err := conan_model.GetRecipeRevisions(ctx, ctx.Package.Owner.ID, rref)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -706,7 +714,7 @@ func ListRecipeRevisions(ctx *context.Context) {
|
|||||||
|
|
||||||
// ListPackageRevisions gets a list of all package revisions
|
// ListPackageRevisions gets a list of all package revisions
|
||||||
func ListPackageRevisions(ctx *context.Context) {
|
func ListPackageRevisions(ctx *context.Context) {
|
||||||
pref := ctx.Data[packageReferenceKey].(*conan_module.PackageReference)
|
pref := getPackageReference(ctx)
|
||||||
|
|
||||||
revisions, err := conan_model.GetPackageRevisions(ctx, ctx.Package.Owner.ID, pref)
|
revisions, err := conan_model.GetPackageRevisions(ctx, ctx.Package.Owner.ID, pref)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -742,7 +750,7 @@ func listRevisions(ctx *context.Context, revisions []*conan_model.PropertyValue)
|
|||||||
|
|
||||||
// LatestRecipeRevision gets the latest recipe revision
|
// LatestRecipeRevision gets the latest recipe revision
|
||||||
func LatestRecipeRevision(ctx *context.Context) {
|
func LatestRecipeRevision(ctx *context.Context) {
|
||||||
rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference)
|
rref := getRecipeReference(ctx)
|
||||||
|
|
||||||
revision, err := conan_model.GetLastRecipeRevision(ctx, ctx.Package.Owner.ID, rref)
|
revision, err := conan_model.GetLastRecipeRevision(ctx, ctx.Package.Owner.ID, rref)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -759,7 +767,7 @@ func LatestRecipeRevision(ctx *context.Context) {
|
|||||||
|
|
||||||
// LatestPackageRevision gets the latest package revision
|
// LatestPackageRevision gets the latest package revision
|
||||||
func LatestPackageRevision(ctx *context.Context) {
|
func LatestPackageRevision(ctx *context.Context) {
|
||||||
pref := ctx.Data[packageReferenceKey].(*conan_module.PackageReference)
|
pref := getPackageReference(ctx)
|
||||||
|
|
||||||
revision, err := conan_model.GetLastPackageRevision(ctx, ctx.Package.Owner.ID, pref)
|
revision, err := conan_model.GetLastPackageRevision(ctx, ctx.Package.Owner.ID, pref)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -776,20 +784,20 @@ func LatestPackageRevision(ctx *context.Context) {
|
|||||||
|
|
||||||
// ListRecipeRevisionFiles gets a list of all recipe revision files
|
// ListRecipeRevisionFiles gets a list of all recipe revision files
|
||||||
func ListRecipeRevisionFiles(ctx *context.Context) {
|
func ListRecipeRevisionFiles(ctx *context.Context) {
|
||||||
rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference)
|
rref := getRecipeReference(ctx)
|
||||||
|
|
||||||
listRevisionFiles(ctx, rref.AsKey())
|
listRevisionFiles(ctx, rref.AsKey())
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListPackageRevisionFiles gets a list of all package revision files
|
// ListPackageRevisionFiles gets a list of all package revision files
|
||||||
func ListPackageRevisionFiles(ctx *context.Context) {
|
func ListPackageRevisionFiles(ctx *context.Context) {
|
||||||
pref := ctx.Data[packageReferenceKey].(*conan_module.PackageReference)
|
pref := getPackageReference(ctx)
|
||||||
|
|
||||||
listRevisionFiles(ctx, pref.AsKey())
|
listRevisionFiles(ctx, pref.AsKey())
|
||||||
}
|
}
|
||||||
|
|
||||||
func listRevisionFiles(ctx *context.Context, fileKey string) {
|
func listRevisionFiles(ctx *context.Context, fileKey string) {
|
||||||
rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference)
|
rref := getRecipeReference(ctx)
|
||||||
|
|
||||||
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeConan, rref.Name, rref.Version)
|
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeConan, rref.Name, rref.Version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ func SearchPackagesV2(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func searchPackages(ctx *context.Context, searchAllRevisions bool) {
|
func searchPackages(ctx *context.Context, searchAllRevisions bool) {
|
||||||
rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference)
|
rref := getRecipeReference(ctx)
|
||||||
|
|
||||||
if !searchAllRevisions && rref.Revision == "" {
|
if !searchAllRevisions && rref.Revision == "" {
|
||||||
lastRevision, err := conan_model.GetLastRecipeRevision(ctx, ctx.Package.Owner.ID, rref)
|
lastRevision, err := conan_model.GetLastRecipeRevision(ctx, ctx.Package.Owner.ID, rref)
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ func EnumeratePackages(ctx *context.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
versionMetadata := pd.Metadata.(*conda_module.VersionMetadata)
|
versionMetadata := packages_model.DescriptorMetadata[*conda_module.VersionMetadata](pd)
|
||||||
|
|
||||||
pi := &PackageInfo{
|
pi := &PackageInfo{
|
||||||
Name: pd.PackageProperties.GetByName(conda_module.PropertyName),
|
Name: pd.PackageProperties.GetByName(conda_module.PropertyName),
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ func enumeratePackages(ctx *context.Context, format string, opts *cran_model.Sea
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
metadata := pd.Metadata.(*cran_module.Metadata)
|
metadata := packages_model.DescriptorMetadata[*cran_module.Metadata](pd)
|
||||||
|
|
||||||
fmt.Fprintln(w, "Package:", pd.Package.Name)
|
fmt.Fprintln(w, "Package:", pd.Package.Name)
|
||||||
fmt.Fprintln(w, "Version:", pd.Version.Version)
|
fmt.Fprintln(w, "Version:", pd.Version.Version)
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ func createPackageMetadataResponse(registryURL string, pds []*packages_model.Pac
|
|||||||
|
|
||||||
latest := pds[len(pds)-1]
|
latest := pds[len(pds)-1]
|
||||||
|
|
||||||
metadata := latest.Metadata.(*npm_module.Metadata)
|
metadata := packages_model.DescriptorMetadata[*npm_module.Metadata](latest)
|
||||||
|
|
||||||
return &npm_module.PackageMetadata{
|
return &npm_module.PackageMetadata{
|
||||||
ID: latest.Package.Name,
|
ID: latest.Package.Name,
|
||||||
@@ -67,7 +67,7 @@ func createPackageMetadataResponse(registryURL string, pds []*packages_model.Pac
|
|||||||
func createPackageMetadataVersion(registryURL string, pd *packages_model.PackageDescriptor) *npm_module.PackageMetadataVersion {
|
func createPackageMetadataVersion(registryURL string, pd *packages_model.PackageDescriptor) *npm_module.PackageMetadataVersion {
|
||||||
hashBytes, _ := hex.DecodeString(pd.Files[0].Blob.HashSHA512)
|
hashBytes, _ := hex.DecodeString(pd.Files[0].Blob.HashSHA512)
|
||||||
|
|
||||||
metadata := pd.Metadata.(*npm_module.Metadata)
|
metadata := packages_model.DescriptorMetadata[*npm_module.Metadata](pd)
|
||||||
|
|
||||||
return &npm_module.PackageMetadataVersion{
|
return &npm_module.PackageMetadataVersion{
|
||||||
ID: fmt.Sprintf("%s@%s", pd.Package.Name, pd.Version.Version),
|
ID: fmt.Sprintf("%s@%s", pd.Package.Name, pd.Version.Version),
|
||||||
@@ -107,7 +107,7 @@ func createPackageMetadataVersion(registryURL string, pd *packages_model.Package
|
|||||||
func createPackageSearchResponse(pds []*packages_model.PackageDescriptor, total int64) *npm_module.PackageSearch {
|
func createPackageSearchResponse(pds []*packages_model.PackageDescriptor, total int64) *npm_module.PackageSearch {
|
||||||
objects := make([]*npm_module.PackageSearchObject, 0, len(pds))
|
objects := make([]*npm_module.PackageSearchObject, 0, len(pds))
|
||||||
for _, pd := range pds {
|
for _, pd := range pds {
|
||||||
metadata := pd.Metadata.(*npm_module.Metadata)
|
metadata := packages_model.DescriptorMetadata[*npm_module.Metadata](pd)
|
||||||
|
|
||||||
scope := metadata.Scope
|
scope := metadata.Scope
|
||||||
if scope == "" {
|
if scope == "" {
|
||||||
|
|||||||
@@ -332,12 +332,8 @@ func createFeedResponse(l *linkBuilder, totalEntries int64, pds []*packages_mode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createEntryResponse(l *linkBuilder, pd *packages_model.PackageDescriptor) *FeedEntry {
|
|
||||||
return createEntry(l, pd, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
func createEntry(l *linkBuilder, pd *packages_model.PackageDescriptor, withNamespace bool) *FeedEntry {
|
func createEntry(l *linkBuilder, pd *packages_model.PackageDescriptor, withNamespace bool) *FeedEntry {
|
||||||
metadata := pd.Metadata.(*nuget_module.Metadata)
|
metadata := packages_model.DescriptorMetadata[*nuget_module.Metadata](pd)
|
||||||
|
|
||||||
id := l.GetPackageMetadataURL(pd.Package.Name, pd.Version.Version)
|
id := l.GetPackageMetadataURL(pd.Package.Name, pd.Version.Version)
|
||||||
|
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ func createRegistrationIndexResponse(l *linkBuilder, pds []*packages_model.Packa
|
|||||||
}
|
}
|
||||||
|
|
||||||
func createRegistrationIndexPageItem(l *linkBuilder, pd *packages_model.PackageDescriptor) *RegistrationIndexPageItem {
|
func createRegistrationIndexPageItem(l *linkBuilder, pd *packages_model.PackageDescriptor) *RegistrationIndexPageItem {
|
||||||
metadata := pd.Metadata.(*nuget_module.Metadata)
|
metadata := packages_model.DescriptorMetadata[*nuget_module.Metadata](pd)
|
||||||
|
|
||||||
return &RegistrationIndexPageItem{
|
return &RegistrationIndexPageItem{
|
||||||
RegistrationLeafURL: l.GetRegistrationLeafURL(pd.Package.Name, pd.Version.Version),
|
RegistrationLeafURL: l.GetRegistrationLeafURL(pd.Package.Name, pd.Version.Version),
|
||||||
@@ -120,7 +120,7 @@ func createRegistrationIndexPageItem(l *linkBuilder, pd *packages_model.PackageD
|
|||||||
CatalogLeafURL: l.GetRegistrationLeafURL(pd.Package.Name, pd.Version.Version),
|
CatalogLeafURL: l.GetRegistrationLeafURL(pd.Package.Name, pd.Version.Version),
|
||||||
Authors: metadata.Authors,
|
Authors: metadata.Authors,
|
||||||
Copyright: metadata.Copyright,
|
Copyright: metadata.Copyright,
|
||||||
DependencyGroups: createDependencyGroups(pd),
|
DependencyGroups: createDependencyGroups(metadata),
|
||||||
Description: metadata.Description,
|
Description: metadata.Description,
|
||||||
IconURL: metadata.IconURL,
|
IconURL: metadata.IconURL,
|
||||||
ID: pd.Package.Name,
|
ID: pd.Package.Name,
|
||||||
@@ -139,9 +139,7 @@ func createRegistrationIndexPageItem(l *linkBuilder, pd *packages_model.PackageD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createDependencyGroups(pd *packages_model.PackageDescriptor) []*PackageDependencyGroup {
|
func createDependencyGroups(metadata *nuget_module.Metadata) []*PackageDependencyGroup {
|
||||||
metadata := pd.Metadata.(*nuget_module.Metadata)
|
|
||||||
|
|
||||||
dependencyGroups := make([]*PackageDependencyGroup, 0, len(metadata.Dependencies))
|
dependencyGroups := make([]*PackageDependencyGroup, 0, len(metadata.Dependencies))
|
||||||
for k, v := range metadata.Dependencies {
|
for k, v := range metadata.Dependencies {
|
||||||
dependencies := make([]*PackageDependency, 0, len(v))
|
dependencies := make([]*PackageDependency, 0, len(v))
|
||||||
@@ -172,7 +170,7 @@ type RegistrationLeafResponse struct {
|
|||||||
func createRegistrationLeafResponse(l *linkBuilder, pd *packages_model.PackageDescriptor) *RegistrationLeafResponse {
|
func createRegistrationLeafResponse(l *linkBuilder, pd *packages_model.PackageDescriptor) *RegistrationLeafResponse {
|
||||||
registrationLeafURL := l.GetRegistrationLeafURL(pd.Package.Name, pd.Version.Version)
|
registrationLeafURL := l.GetRegistrationLeafURL(pd.Package.Name, pd.Version.Version)
|
||||||
packageDownloadURL := l.GetPackageDownloadURL(pd.Package.Name, pd.Version.Version)
|
packageDownloadURL := l.GetPackageDownloadURL(pd.Package.Name, pd.Version.Version)
|
||||||
metadata := pd.Metadata.(*nuget_module.Metadata)
|
metadata := packages_model.DescriptorMetadata[*nuget_module.Metadata](pd)
|
||||||
return &RegistrationLeafResponse{
|
return &RegistrationLeafResponse{
|
||||||
RegistrationLeafURL: registrationLeafURL,
|
RegistrationLeafURL: registrationLeafURL,
|
||||||
RegistrationIndexURL: l.GetRegistrationIndexURL(pd.Package.Name),
|
RegistrationIndexURL: l.GetRegistrationIndexURL(pd.Package.Name),
|
||||||
@@ -182,7 +180,7 @@ func createRegistrationLeafResponse(l *linkBuilder, pd *packages_model.PackageDe
|
|||||||
CatalogLeafURL: registrationLeafURL,
|
CatalogLeafURL: registrationLeafURL,
|
||||||
Authors: metadata.Authors,
|
Authors: metadata.Authors,
|
||||||
Copyright: metadata.Copyright,
|
Copyright: metadata.Copyright,
|
||||||
DependencyGroups: createDependencyGroups(pd),
|
DependencyGroups: createDependencyGroups(metadata),
|
||||||
Description: metadata.Description,
|
Description: metadata.Description,
|
||||||
IconURL: metadata.IconURL,
|
IconURL: metadata.IconURL,
|
||||||
ID: pd.Package.Name,
|
ID: pd.Package.Name,
|
||||||
@@ -290,13 +288,13 @@ func createSearchResult(l *linkBuilder, pds []*packages_model.PackageDescriptor)
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
metadata := latest.Metadata.(*nuget_module.Metadata)
|
metadata := packages_model.DescriptorMetadata[*nuget_module.Metadata](latest)
|
||||||
|
|
||||||
return &SearchResult{
|
return &SearchResult{
|
||||||
Authors: metadata.Authors,
|
Authors: metadata.Authors,
|
||||||
Copyright: metadata.Copyright,
|
Copyright: metadata.Copyright,
|
||||||
Description: metadata.Description,
|
Description: metadata.Description,
|
||||||
DependencyGroups: createDependencyGroups(latest),
|
DependencyGroups: createDependencyGroups(metadata),
|
||||||
IconURL: metadata.IconURL,
|
IconURL: metadata.IconURL,
|
||||||
ID: latest.Package.Name,
|
ID: latest.Package.Name,
|
||||||
IsPrerelease: latest.Version.IsPrerelease(),
|
IsPrerelease: latest.Version.IsPrerelease(),
|
||||||
|
|||||||
@@ -267,9 +267,10 @@ func RegistrationLeafV2(ctx *context.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
resp := createEntryResponse(
|
resp := createEntry(
|
||||||
&linkBuilder{Base: setting.AppURL + "api/packages/" + ctx.Package.Owner.Name + "/nuget"},
|
&linkBuilder{Base: setting.AppURL + "api/packages/" + ctx.Package.Owner.Name + "/nuget"},
|
||||||
pd,
|
pd,
|
||||||
|
true,
|
||||||
)
|
)
|
||||||
|
|
||||||
xmlResponse(ctx, http.StatusOK, resp)
|
xmlResponse(ctx, http.StatusOK, resp)
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ func packageDescriptorToMetadata(baseURL string, pd *packages_model.PackageDescr
|
|||||||
Version: pd.Version.Version,
|
Version: pd.Version.Version,
|
||||||
ArchiveURL: fmt.Sprintf("%s/files/%s.tar.gz", baseURL, url.PathEscape(pd.Version.Version)),
|
ArchiveURL: fmt.Sprintf("%s/files/%s.tar.gz", baseURL, url.PathEscape(pd.Version.Version)),
|
||||||
Published: pd.Version.CreatedUnix.AsLocalTime(),
|
Published: pd.Version.CreatedUnix.AsLocalTime(),
|
||||||
Pubspec: pd.Metadata.(*pub_module.Metadata).Pubspec,
|
Pubspec: packages_model.DescriptorMetadata[*pub_module.Metadata](pd).Pubspec,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ func enumeratePackages(ctx *context.Context, filename string, pvs []*packages_mo
|
|||||||
Name: "Gem::Version",
|
Name: "Gem::Version",
|
||||||
Value: []string{p.Version.Version},
|
Value: []string{p.Version.Version},
|
||||||
},
|
},
|
||||||
p.Metadata.(*rubygems_module.Metadata).Platform,
|
packages_model.DescriptorMetadata[*rubygems_module.Metadata](p).Platform,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,7 +126,7 @@ func ServePackageSpecification(ctx *context.Context) {
|
|||||||
zw := zlib.NewWriter(ctx.Resp)
|
zw := zlib.NewWriter(ctx.Resp)
|
||||||
defer zw.Close()
|
defer zw.Close()
|
||||||
|
|
||||||
metadata := pd.Metadata.(*rubygems_module.Metadata)
|
metadata := packages_model.DescriptorMetadata[*rubygems_module.Metadata](pd)
|
||||||
|
|
||||||
// create a Ruby Gem::Specification object
|
// create a Ruby Gem::Specification object
|
||||||
spec := &rubygems_module.RubyUserDef{
|
spec := &rubygems_module.RubyUserDef{
|
||||||
@@ -405,7 +405,7 @@ func makePackageVersionDependency(ctx *context.Context, version *packages_model.
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
metadata := pd.Metadata.(*rubygems_module.Metadata)
|
metadata := packages_model.DescriptorMetadata[*rubygems_module.Metadata](pd)
|
||||||
fullFilename := makeGemFullFileName(pd.Package.Name, version.Version, metadata.Platform)
|
fullFilename := makeGemFullFileName(pd.Package.Name, version.Version, metadata.Platform)
|
||||||
file, err := packages_model.GetFileForVersionByName(ctx, version.ID, fullFilename, "")
|
file, err := packages_model.GetFileForVersionByName(ctx, version.ID, fullFilename, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ func PackageVersionMetadata(ctx *context.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
metadata := pd.Metadata.(*swift_module.Metadata)
|
metadata := packages_model.DescriptorMetadata[*swift_module.Metadata](pd)
|
||||||
repositoryURLs := make([]string, 0, len(pd.VersionProperties))
|
repositoryURLs := make([]string, 0, len(pd.VersionProperties))
|
||||||
for _, property := range pd.VersionProperties {
|
for _, property := range pd.VersionProperties {
|
||||||
if property.Name == swift_module.PropertyRepositoryURL {
|
if property.Name == swift_module.PropertyRepositoryURL {
|
||||||
@@ -278,7 +278,7 @@ func DownloadManifest(ctx *context.Context) {
|
|||||||
swiftVersion = swift_module.TrimmedVersionString(v)
|
swiftVersion = swift_module.TrimmedVersionString(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m, ok := pd.Metadata.(*swift_module.Metadata).Manifests[swiftVersion]
|
m, ok := packages_model.DescriptorMetadata[*swift_module.Metadata](pd).Manifests[swiftVersion]
|
||||||
if !ok {
|
if !ok {
|
||||||
setResponseHeaders(ctx.Resp, &headers{
|
setResponseHeaders(ctx.Resp, &headers{
|
||||||
Status: http.StatusSeeOther,
|
Status: http.StatusSeeOther,
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ func EnumeratePackageVersions(ctx *context.Context) {
|
|||||||
|
|
||||||
ctx.JSON(http.StatusOK, &packageMetadata{
|
ctx.JSON(http.StatusOK, &packageMetadata{
|
||||||
Name: pds[0].Package.Name,
|
Name: pds[0].Package.Name,
|
||||||
Description: pds[len(pds)-1].Metadata.(*vagrant_module.Metadata).Description,
|
Description: packages_model.DescriptorMetadata[*vagrant_module.Metadata](pds[len(pds)-1]).Description,
|
||||||
Versions: versions,
|
Versions: versions,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ func ListCronTasks(ctx *context.APIContext) {
|
|||||||
count := len(tasks)
|
count := len(tasks)
|
||||||
|
|
||||||
listOpts := utils.GetListOptions(ctx)
|
listOpts := utils.GetListOptions(ctx)
|
||||||
tasks = util.PaginateSlice(tasks, listOpts.Page, listOpts.PageSize).(cron.TaskTable)
|
tasks = util.PaginateSlice(tasks, listOpts.Page, listOpts.PageSize)
|
||||||
|
|
||||||
res := make([]structs.Cron, len(tasks))
|
res := make([]structs.Cron, len(tasks))
|
||||||
for i, task := range tasks {
|
for i, task := range tasks {
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ func CreateHook(ctx *context.APIContext) {
|
|||||||
// "201":
|
// "201":
|
||||||
// "$ref": "#/responses/Hook"
|
// "$ref": "#/responses/Hook"
|
||||||
|
|
||||||
form := web.GetForm(ctx).(*api.CreateHookOption)
|
form := web.GetForm[*api.CreateHookOption](ctx)
|
||||||
|
|
||||||
utils.AddSystemHook(ctx, form)
|
utils.AddSystemHook(ctx, form)
|
||||||
}
|
}
|
||||||
@@ -166,7 +166,7 @@ func EditHook(ctx *context.APIContext) {
|
|||||||
// "200":
|
// "200":
|
||||||
// "$ref": "#/responses/Hook"
|
// "$ref": "#/responses/Hook"
|
||||||
|
|
||||||
form := web.GetForm(ctx).(*api.EditHookOption)
|
form := web.GetForm[*api.EditHookOption](ctx)
|
||||||
|
|
||||||
// TODO in body params
|
// TODO in body params
|
||||||
hookID := ctx.PathParamInt64("id")
|
hookID := ctx.PathParamInt64("id")
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ func CreateOrg(ctx *context.APIContext) {
|
|||||||
// "422":
|
// "422":
|
||||||
// "$ref": "#/responses/validationError"
|
// "$ref": "#/responses/validationError"
|
||||||
|
|
||||||
form := web.GetForm(ctx).(*api.CreateOrgOption)
|
form := web.GetForm[*api.CreateOrgOption](ctx)
|
||||||
|
|
||||||
visibility := api.VisibleTypePublic
|
visibility := api.VisibleTypePublic
|
||||||
if form.Visibility != "" {
|
if form.Visibility != "" {
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ func CreateRepo(ctx *context.APIContext) {
|
|||||||
// "422":
|
// "422":
|
||||||
// "$ref": "#/responses/validationError"
|
// "$ref": "#/responses/validationError"
|
||||||
|
|
||||||
form := web.GetForm(ctx).(*api.CreateRepoOption)
|
form := web.GetForm[*api.CreateRepoOption](ctx)
|
||||||
|
|
||||||
repo.CreateUserRepo(ctx, ctx.ContextUser, *form)
|
repo.CreateUserRepo(ctx, ctx.ContextUser, *form)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ func CreateUser(ctx *context.APIContext) {
|
|||||||
// "422":
|
// "422":
|
||||||
// "$ref": "#/responses/validationError"
|
// "$ref": "#/responses/validationError"
|
||||||
|
|
||||||
form := web.GetForm(ctx).(*api.CreateUserOption)
|
form := web.GetForm[*api.CreateUserOption](ctx)
|
||||||
|
|
||||||
u := &user_model.User{
|
u := &user_model.User{
|
||||||
Name: form.Username,
|
Name: form.Username,
|
||||||
@@ -190,7 +190,7 @@ func EditUser(ctx *context.APIContext) {
|
|||||||
// "422":
|
// "422":
|
||||||
// "$ref": "#/responses/validationError"
|
// "$ref": "#/responses/validationError"
|
||||||
|
|
||||||
form := web.GetForm(ctx).(*api.EditUserOption)
|
form := web.GetForm[*api.EditUserOption](ctx)
|
||||||
|
|
||||||
authOpts := &user_service.UpdateAuthOptions{
|
authOpts := &user_service.UpdateAuthOptions{
|
||||||
LoginSource: optional.FromNonDefault(form.SourceID),
|
LoginSource: optional.FromNonDefault(form.SourceID),
|
||||||
@@ -340,7 +340,7 @@ func CreatePublicKey(ctx *context.APIContext) {
|
|||||||
// "422":
|
// "422":
|
||||||
// "$ref": "#/responses/validationError"
|
// "$ref": "#/responses/validationError"
|
||||||
|
|
||||||
form := web.GetForm(ctx).(*api.CreateKeyOption)
|
form := web.GetForm[*api.CreateKeyOption](ctx)
|
||||||
|
|
||||||
user.CreateUserPublicKey(ctx, *form, ctx.ContextUser.ID)
|
user.CreateUserPublicKey(ctx, *form, ctx.ContextUser.ID)
|
||||||
}
|
}
|
||||||
@@ -551,7 +551,7 @@ func RenameUser(ctx *context.APIContext) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
newName := web.GetForm(ctx).(*api.RenameUserOption).NewName
|
newName := web.GetForm[*api.RenameUserOption](ctx).NewName
|
||||||
|
|
||||||
// Check if username has been changed
|
// Check if username has been changed
|
||||||
if err := user_service.RenameUser(ctx, ctx.ContextUser, newName, ctx.Doer); err != nil {
|
if err := user_service.RenameUser(ctx, ctx.ContextUser, newName, ctx.Doer); err != nil {
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ func AddUserBadges(ctx *context.APIContext) {
|
|||||||
// "403":
|
// "403":
|
||||||
// "$ref": "#/responses/forbidden"
|
// "$ref": "#/responses/forbidden"
|
||||||
|
|
||||||
form := web.GetForm(ctx).(*api.UserBadgeOption)
|
form := web.GetForm[*api.UserBadgeOption](ctx)
|
||||||
badges := prepareBadgesForReplaceOrAdd(*form)
|
badges := prepareBadgesForReplaceOrAdd(*form)
|
||||||
|
|
||||||
if err := user_model.AddUserBadges(ctx, ctx.ContextUser, badges); err != nil {
|
if err := user_model.AddUserBadges(ctx, ctx.ContextUser, badges); err != nil {
|
||||||
@@ -102,7 +102,7 @@ func DeleteUserBadges(ctx *context.APIContext) {
|
|||||||
// "422":
|
// "422":
|
||||||
// "$ref": "#/responses/validationError"
|
// "$ref": "#/responses/validationError"
|
||||||
|
|
||||||
form := web.GetForm(ctx).(*api.UserBadgeOption)
|
form := web.GetForm[*api.UserBadgeOption](ctx)
|
||||||
badges := prepareBadgesForReplaceOrAdd(*form)
|
badges := prepareBadgesForReplaceOrAdd(*form)
|
||||||
|
|
||||||
if err := user_model.RemoveUserBadges(ctx, ctx.ContextUser, badges); err != nil {
|
if err := user_model.RemoveUserBadges(ctx, ctx.ContextUser, badges); err != nil {
|
||||||
|
|||||||
@@ -396,7 +396,7 @@ func reqUsersExploreEnabled() func(ctx *context.APIContext) {
|
|||||||
|
|
||||||
func reqBasicOrRevProxyAuth() func(ctx *context.APIContext) {
|
func reqBasicOrRevProxyAuth() func(ctx *context.APIContext) {
|
||||||
return func(ctx *context.APIContext) {
|
return func(ctx *context.APIContext) {
|
||||||
if ctx.IsSigned && setting.Service.EnableReverseProxyAuthAPI && ctx.Data["AuthedMethod"].(string) == auth.ReverseProxyMethodName {
|
if ctx.IsSigned && setting.Service.EnableReverseProxyAuthAPI && ctx.Data["AuthedMethod"] == auth.ReverseProxyMethodName {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !ctx.IsBasicAuth {
|
if !ctx.IsBasicAuth {
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ func Markup(ctx *context.APIContext) {
|
|||||||
// "422":
|
// "422":
|
||||||
// "$ref": "#/responses/validationError"
|
// "$ref": "#/responses/validationError"
|
||||||
|
|
||||||
form := web.GetForm(ctx).(*api.MarkupOption)
|
form := web.GetForm[*api.MarkupOption](ctx)
|
||||||
mode := util.Iif(form.Wiki, "wiki", form.Mode) //nolint:staticcheck // form.Wiki is deprecated
|
mode := util.Iif(form.Wiki, "wiki", form.Mode) //nolint:staticcheck // form.Wiki is deprecated
|
||||||
common.RenderMarkup(ctx.Base, ctx.Repo, mode, form.Text, form.Context, form.FilePath)
|
common.RenderMarkup(ctx.Base, ctx.Repo, mode, form.Text, form.Context, form.FilePath)
|
||||||
}
|
}
|
||||||
@@ -58,7 +58,7 @@ func Markdown(ctx *context.APIContext) {
|
|||||||
// "422":
|
// "422":
|
||||||
// "$ref": "#/responses/validationError"
|
// "$ref": "#/responses/validationError"
|
||||||
|
|
||||||
form := web.GetForm(ctx).(*api.MarkdownOption)
|
form := web.GetForm[*api.MarkdownOption](ctx)
|
||||||
mode := util.Iif(form.Wiki, "wiki", form.Mode) //nolint:staticcheck // form.Wiki is deprecated
|
mode := util.Iif(form.Wiki, "wiki", form.Mode) //nolint:staticcheck // form.Wiki is deprecated
|
||||||
common.RenderMarkup(ctx.Base, ctx.Repo, mode, form.Text, form.Context, "")
|
common.RenderMarkup(ctx.Base, ctx.Repo, mode, form.Text, form.Context, "")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ func (Action) CreateOrUpdateSecret(ctx *context.APIContext) {
|
|||||||
// "404":
|
// "404":
|
||||||
// "$ref": "#/responses/notFound"
|
// "$ref": "#/responses/notFound"
|
||||||
|
|
||||||
opt := web.GetForm(ctx).(*api.CreateOrUpdateSecretOption)
|
opt := web.GetForm[*api.CreateOrUpdateSecretOption](ctx)
|
||||||
|
|
||||||
_, created, err := secret_service.CreateOrUpdateSecret(ctx, ctx.Org.Organization.ID, 0, ctx.PathParam("secretname"), opt.Data, opt.Description)
|
_, created, err := secret_service.CreateOrUpdateSecret(ctx, ctx.Org.Organization.ID, 0, ctx.PathParam("secretname"), opt.Data, opt.Description)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -373,7 +373,7 @@ func (Action) CreateVariable(ctx *context.APIContext) {
|
|||||||
// "500":
|
// "500":
|
||||||
// "$ref": "#/responses/error"
|
// "$ref": "#/responses/error"
|
||||||
|
|
||||||
opt := web.GetForm(ctx).(*api.CreateVariableOption)
|
opt := web.GetForm[*api.CreateVariableOption](ctx)
|
||||||
|
|
||||||
ownerID := ctx.Org.Organization.ID
|
ownerID := ctx.Org.Organization.ID
|
||||||
variableName := ctx.PathParam("variablename")
|
variableName := ctx.PathParam("variablename")
|
||||||
@@ -437,7 +437,7 @@ func (Action) UpdateVariable(ctx *context.APIContext) {
|
|||||||
// "404":
|
// "404":
|
||||||
// "$ref": "#/responses/notFound"
|
// "$ref": "#/responses/notFound"
|
||||||
|
|
||||||
opt := web.GetForm(ctx).(*api.UpdateVariableOption)
|
opt := web.GetForm[*api.UpdateVariableOption](ctx)
|
||||||
|
|
||||||
v, err := actions_service.GetVariable(ctx, actions_model.FindVariablesOpts{
|
v, err := actions_service.GetVariable(ctx, actions_model.FindVariablesOpts{
|
||||||
OwnerID: ctx.Org.Organization.ID,
|
OwnerID: ctx.Org.Organization.ID,
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ func UpdateAvatar(ctx *context.APIContext) {
|
|||||||
// "$ref": "#/responses/empty"
|
// "$ref": "#/responses/empty"
|
||||||
// "404":
|
// "404":
|
||||||
// "$ref": "#/responses/notFound"
|
// "$ref": "#/responses/notFound"
|
||||||
form := web.GetForm(ctx).(*api.UpdateUserAvatarOption)
|
form := web.GetForm[*api.UpdateUserAvatarOption](ctx)
|
||||||
|
|
||||||
content, err := base64.StdEncoding.DecodeString(form.Image)
|
content, err := base64.StdEncoding.DecodeString(form.Image)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ func CreateHook(ctx *context.APIContext) {
|
|||||||
utils.AddOwnerHook(
|
utils.AddOwnerHook(
|
||||||
ctx,
|
ctx,
|
||||||
ctx.ContextUser,
|
ctx.ContextUser,
|
||||||
web.GetForm(ctx).(*api.CreateHookOption),
|
web.GetForm[*api.CreateHookOption](ctx),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,7 +151,7 @@ func EditHook(ctx *context.APIContext) {
|
|||||||
utils.EditOwnerHook(
|
utils.EditOwnerHook(
|
||||||
ctx,
|
ctx,
|
||||||
ctx.ContextUser,
|
ctx.ContextUser,
|
||||||
web.GetForm(ctx).(*api.EditHookOption),
|
web.GetForm[*api.EditHookOption](ctx),
|
||||||
ctx.PathParamInt64("id"),
|
ctx.PathParamInt64("id"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ func CreateLabel(ctx *context.APIContext) {
|
|||||||
// "$ref": "#/responses/notFound"
|
// "$ref": "#/responses/notFound"
|
||||||
// "422":
|
// "422":
|
||||||
// "$ref": "#/responses/validationError"
|
// "$ref": "#/responses/validationError"
|
||||||
form := web.GetForm(ctx).(*api.CreateLabelOption)
|
form := web.GetForm[*api.CreateLabelOption](ctx)
|
||||||
form.Color = strings.Trim(form.Color, " ")
|
form.Color = strings.Trim(form.Color, " ")
|
||||||
color, err := label.NormalizeColor(form.Color)
|
color, err := label.NormalizeColor(form.Color)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -189,7 +189,7 @@ func EditLabel(ctx *context.APIContext) {
|
|||||||
// "$ref": "#/responses/notFound"
|
// "$ref": "#/responses/notFound"
|
||||||
// "422":
|
// "422":
|
||||||
// "$ref": "#/responses/validationError"
|
// "$ref": "#/responses/validationError"
|
||||||
form := web.GetForm(ctx).(*api.EditLabelOption)
|
form := web.GetForm[*api.EditLabelOption](ctx)
|
||||||
l, err := issues_model.GetLabelInOrgByID(ctx, ctx.Org.Organization.ID, ctx.PathParamInt64("id"))
|
l, err := issues_model.GetLabelInOrgByID(ctx, ctx.Org.Organization.ID, ctx.PathParamInt64("id"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if issues_model.IsErrOrgLabelNotExist(err) {
|
if issues_model.IsErrOrgLabelNotExist(err) {
|
||||||
|
|||||||
@@ -261,7 +261,7 @@ func Create(ctx *context.APIContext) {
|
|||||||
// "$ref": "#/responses/forbidden"
|
// "$ref": "#/responses/forbidden"
|
||||||
// "422":
|
// "422":
|
||||||
// "$ref": "#/responses/validationError"
|
// "$ref": "#/responses/validationError"
|
||||||
form := web.GetForm(ctx).(*api.CreateOrgOption)
|
form := web.GetForm[*api.CreateOrgOption](ctx)
|
||||||
if !ctx.Doer.CanCreateOrganization() {
|
if !ctx.Doer.CanCreateOrganization() {
|
||||||
ctx.APIError(http.StatusForbidden, "not allowed to create org")
|
ctx.APIError(http.StatusForbidden, "not allowed to create org")
|
||||||
return
|
return
|
||||||
@@ -358,7 +358,7 @@ func Rename(ctx *context.APIContext) {
|
|||||||
// "422":
|
// "422":
|
||||||
// "$ref": "#/responses/validationError"
|
// "$ref": "#/responses/validationError"
|
||||||
|
|
||||||
form := web.GetForm(ctx).(*api.RenameOrgOption)
|
form := web.GetForm[*api.RenameOrgOption](ctx)
|
||||||
orgUser := ctx.Org.Organization.AsUser()
|
orgUser := ctx.Org.Organization.AsUser()
|
||||||
if err := user_service.RenameUser(ctx, orgUser, form.NewName, ctx.Doer); err != nil {
|
if err := user_service.RenameUser(ctx, orgUser, form.NewName, ctx.Doer); err != nil {
|
||||||
if user_model.IsErrUserAlreadyExist(err) || db.IsErrNameReserved(err) || db.IsErrNamePatternNotAllowed(err) || db.IsErrNameCharsNotAllowed(err) {
|
if user_model.IsErrUserAlreadyExist(err) || db.IsErrNameReserved(err) || db.IsErrNamePatternNotAllowed(err) || db.IsErrNameCharsNotAllowed(err) {
|
||||||
@@ -397,7 +397,7 @@ func Edit(ctx *context.APIContext) {
|
|||||||
// "404":
|
// "404":
|
||||||
// "$ref": "#/responses/notFound"
|
// "$ref": "#/responses/notFound"
|
||||||
|
|
||||||
form := web.GetForm(ctx).(*api.EditOrgOption)
|
form := web.GetForm[*api.EditOrgOption](ctx)
|
||||||
|
|
||||||
if err := org.UpdateOrgEmailAddress(ctx, ctx.Org.Organization, form.Email); err != nil {
|
if err := org.UpdateOrgEmailAddress(ctx, ctx.Org.Organization, form.Email); err != nil {
|
||||||
if errors.Is(err, util.ErrInvalidArgument) {
|
if errors.Is(err, util.ErrInvalidArgument) {
|
||||||
|
|||||||
@@ -214,7 +214,7 @@ func CreateTeam(ctx *context.APIContext) {
|
|||||||
// "$ref": "#/responses/notFound"
|
// "$ref": "#/responses/notFound"
|
||||||
// "422":
|
// "422":
|
||||||
// "$ref": "#/responses/validationError"
|
// "$ref": "#/responses/validationError"
|
||||||
form := web.GetForm(ctx).(*api.CreateTeamOption)
|
form := web.GetForm[*api.CreateTeamOption](ctx)
|
||||||
teamPermission := perm.ParseAccessMode(string(form.Permission), perm.AccessModeNone, perm.AccessModeAdmin)
|
teamPermission := perm.ParseAccessMode(string(form.Permission), perm.AccessModeNone, perm.AccessModeAdmin)
|
||||||
team := &organization.Team{
|
team := &organization.Team{
|
||||||
OrgID: ctx.Org.Organization.ID,
|
OrgID: ctx.Org.Organization.ID,
|
||||||
@@ -282,7 +282,7 @@ func EditTeam(ctx *context.APIContext) {
|
|||||||
// "404":
|
// "404":
|
||||||
// "$ref": "#/responses/notFound"
|
// "$ref": "#/responses/notFound"
|
||||||
|
|
||||||
form := web.GetForm(ctx).(*api.EditTeamOption)
|
form := web.GetForm[*api.EditTeamOption](ctx)
|
||||||
team := ctx.Org.Team
|
team := ctx.Org.Team
|
||||||
if err := team.LoadUnits(ctx); err != nil {
|
if err := team.LoadUnits(ctx); err != nil {
|
||||||
ctx.APIErrorInternal(err)
|
ctx.APIErrorInternal(err)
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ func (Action) CreateOrUpdateSecret(ctx *context.APIContext) {
|
|||||||
|
|
||||||
repo := ctx.Repo.Repository
|
repo := ctx.Repo.Repository
|
||||||
|
|
||||||
opt := web.GetForm(ctx).(*api.CreateOrUpdateSecretOption)
|
opt := web.GetForm[*api.CreateOrUpdateSecretOption](ctx)
|
||||||
|
|
||||||
_, created, err := secret_service.CreateOrUpdateSecret(ctx, 0, repo.ID, ctx.PathParam("secretname"), opt.Data, opt.Description)
|
_, created, err := secret_service.CreateOrUpdateSecret(ctx, 0, repo.ID, ctx.PathParam("secretname"), opt.Data, opt.Description)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -346,7 +346,7 @@ func (Action) CreateVariable(ctx *context.APIContext) {
|
|||||||
// "500":
|
// "500":
|
||||||
// "$ref": "#/responses/error"
|
// "$ref": "#/responses/error"
|
||||||
|
|
||||||
opt := web.GetForm(ctx).(*api.CreateVariableOption)
|
opt := web.GetForm[*api.CreateVariableOption](ctx)
|
||||||
|
|
||||||
repoID := ctx.Repo.Repository.ID
|
repoID := ctx.Repo.Repository.ID
|
||||||
variableName := ctx.PathParam("variablename")
|
variableName := ctx.PathParam("variablename")
|
||||||
@@ -413,7 +413,7 @@ func (Action) UpdateVariable(ctx *context.APIContext) {
|
|||||||
// "404":
|
// "404":
|
||||||
// "$ref": "#/responses/notFound"
|
// "$ref": "#/responses/notFound"
|
||||||
|
|
||||||
opt := web.GetForm(ctx).(*api.UpdateVariableOption)
|
opt := web.GetForm[*api.UpdateVariableOption](ctx)
|
||||||
|
|
||||||
v, err := actions_service.GetVariable(ctx, actions_model.FindVariablesOpts{
|
v, err := actions_service.GetVariable(ctx, actions_model.FindVariablesOpts{
|
||||||
RepoID: ctx.Repo.Repository.ID,
|
RepoID: ctx.Repo.Repository.ID,
|
||||||
@@ -1170,7 +1170,7 @@ func ActionsDispatchWorkflow(ctx *context.APIContext) {
|
|||||||
// "$ref": "#/responses/validationError"
|
// "$ref": "#/responses/validationError"
|
||||||
|
|
||||||
workflowID := ctx.PathParam("workflow_id")
|
workflowID := ctx.PathParam("workflow_id")
|
||||||
opt := web.GetForm(ctx).(*api.CreateActionWorkflowDispatch)
|
opt := web.GetForm[*api.CreateActionWorkflowDispatch](ctx)
|
||||||
if opt.Ref == "" {
|
if opt.Ref == "" {
|
||||||
ctx.APIError(http.StatusUnprocessableEntity, "ref is required parameter")
|
ctx.APIError(http.StatusUnprocessableEntity, "ref is required parameter")
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ func UpdateAvatar(ctx *context.APIContext) {
|
|||||||
// "$ref": "#/responses/empty"
|
// "$ref": "#/responses/empty"
|
||||||
// "404":
|
// "404":
|
||||||
// "$ref": "#/responses/notFound"
|
// "$ref": "#/responses/notFound"
|
||||||
form := web.GetForm(ctx).(*api.UpdateRepoAvatarOption)
|
form := web.GetForm[*api.UpdateRepoAvatarOption](ctx)
|
||||||
|
|
||||||
content, err := base64.StdEncoding.DecodeString(form.Image)
|
content, err := base64.StdEncoding.DecodeString(form.Image)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user